64
64
import subprocess
65
65
import re
66
66
import hglib
67
+ import argparse
67
68
68
69
# Be sure that the tools directory is in the search path
69
70
ROOT = abspath (join (dirname (__file__ ), ".." ))
73
74
74
75
OFFICIAL_MBED_LIBRARY_BUILD = get_mbed_official_release ('2' )
75
76
76
- def log_message (str ):
77
- """ Depending on the value of the global variable, dbg, writes a log message provided in
78
- str to stdout.
79
-
80
- Args:
81
- str - log string.
82
-
83
- """
84
- global dbg
85
- if dbg :
86
- print str
87
- sys .stdout .flush ()
88
-
89
-
90
77
def get_compilation_failure (messages ):
91
78
""" Reads the json formatted 'messages' and checks for compilation errors.
92
79
If there is a genuine compilation error then there should be a new message containing
@@ -124,25 +111,29 @@ def invoke_api(payload, url, auth, polls, begin="start/"):
124
111
"""
125
112
126
113
# send task to api
127
- log_message (url + begin + "| data: " + str (payload ))
114
+ logging . debug (url + begin + "| data: " + str (payload ))
128
115
r = requests .post (url + begin , data = payload , auth = auth )
129
- log_message (r .request .body )
130
-
116
+ logging . debug (r .request .body )
117
+
131
118
if r .status_code != 200 :
132
119
raise Exception ("Error while talking to the mbed API" )
133
120
134
121
response = r .json ()
135
- log_message (response )
122
+ logging . debug (response )
136
123
uuid = response ['result' ]['data' ]['task_id' ]
137
- log_message ("Task accepted and given ID: %s" % uuid )
138
- sys .stdout .write ("\t \t Compiling: " )
124
+ logging .debug ("Task accepted and given ID: %s" , uuid )
139
125
result = False
140
126
fail_type = None
127
+
128
+ # It currently seems to take the onlide IDE API ~30s to process the compile request and
129
+ # provide a response. Set the poll time to half that in case it does manage to compile
130
+ # quicker.
131
+ poll_delay = 15
132
+ logging .debug ("Running with a poll for response delay of: %ss" , poll_delay )
141
133
142
134
# poll for output
143
- for check in range (0 , polls ):
144
- sys .stdout .write ('.' )
145
- time .sleep (1 )
135
+ for check in range (polls ):
136
+ time .sleep (poll_delay )
146
137
r = requests .get (url + "output/%s" % uuid , auth = auth )
147
138
response = r .json ()
148
139
if response ['result' ]['data' ]['task_complete' ]:
@@ -153,13 +144,15 @@ def invoke_api(payload, url, auth, polls, begin="start/"):
153
144
# 3) Internal failure of the online compiler
154
145
result = bool (response ['result' ]['data' ]['compilation_success' ])
155
146
if result :
156
- sys . stdout . write ( "SUCCESSFUL \n " )
147
+ logging . info ( " \t \t Compilation SUCCESSFUL \n " )
157
148
else :
158
149
# Did this fail due to a genuine compilation error or a failue of the api itself ?
159
- sys .stdout .write ("FAILURE \n " )
160
- sys .stdout .flush ()
150
+ logging .info ("\t \t Compilation FAILURE\n " )
161
151
fail_type = get_compilation_failure (response ['result' ]['data' ]['new_messages' ])
162
152
break
153
+ else :
154
+ logging .info ("\t \t Compilation FAILURE\n " )
155
+
163
156
if not result and fail_type == None :
164
157
fail_type = "Internal"
165
158
@@ -185,33 +178,30 @@ def build_repo(target, program, user, pw, polls=25, url="https://developer.mbed.
185
178
auth = (user , pw )
186
179
return invoke_api (payload , url , auth , polls )
187
180
188
- def run_cmd (command , print_warning_on_fail = True , exit_on_failure = False ):
181
+ def run_cmd (command , exit_on_failure = False ):
189
182
""" Passes a command to the system and returns a True/False result once the
190
183
command has been executed, indicating success/failure. Commands are passed
191
184
as a list of tokens.
192
185
E.g. The command 'git remote -v' would be passed in as ['git', 'remote', '-v']
193
186
194
187
Args:
195
188
command - system command as a list of tokens
196
- print_warning_on_fail - If True print any failure warning to the screen
197
- (default = True)
198
189
exit_on_failure - If True exit the program on failure (default = False)
199
190
200
191
Returns:
201
192
result - True/False indicating the success/failure of the command
202
193
"""
203
- print ('[Exec] %s' % ' ' .join (command ))
194
+ logging . debug ('[Exec] %s' , ' ' .join (command ))
204
195
return_code = subprocess .call (command , shell = True )
205
196
206
197
if return_code :
207
- if print_warning_on_fail :
208
- print ("The command '%s' failed with return code: %s" % (' ' .join (command ), return_code ))
198
+ logging .warning ("The command '%s' failed with return code: %s" , (' ' .join (command ), return_code ))
209
199
if exit_on_failure :
210
200
sys .exit (1 )
211
201
212
202
return return_code
213
203
214
- def run_cmd_with_output (command , print_warning_on_fail = True , exit_on_failure = False ):
204
+ def run_cmd_with_output (command , exit_on_failure = False ):
215
205
""" Passes a command to the system and returns a True/False result once the
216
206
command has been executed, indicating success/failure. If the command was
217
207
successful then the output from the command is returned to the caller.
@@ -220,22 +210,19 @@ def run_cmd_with_output(command, print_warning_on_fail=True, exit_on_failure=Fal
220
210
221
211
Args:
222
212
command - system command as a list of tokens
223
- print_warning_on_fail - If True print any failure warning to the screen
224
- (default = True)
225
213
exit_on_failure - If True exit the program on failure (default = False)
226
214
227
215
Returns:
228
216
result - True/False indicating the success/failure of the command
229
217
output - The output of the command if it was successful, else empty string
230
218
"""
231
- print ('[Exec] %s' % ' ' .join (command ))
219
+ logging . debug ('[Exec] %s' , ' ' .join (command ))
232
220
returncode = 0
233
221
output = ""
234
222
try :
235
223
output = subprocess .check_output (command , shell = True )
236
224
except subprocess .CalledProcessError as e :
237
- if print_warning_on_fail :
238
- print ("The command '%s' failed with return code: %s" % (' ' .join (command ), e .returncode ))
225
+ logging .warning ("The command '%s' failed with return code: %s" , (' ' .join (command ), e .returncode ))
239
226
returncode = e .returncode
240
227
if exit_on_failure :
241
228
sys .exit (1 )
@@ -255,15 +242,15 @@ def upgrade_test_repo(test, user, library, ref, repo_path):
255
242
Returns:
256
243
updated - True if library was updated, False otherwise
257
244
"""
258
- print ( " \n Updating test repo: '%s' to SHA: %s" % ( test , ref ) )
245
+ logging . info ( "Updating test repo: '%s' to SHA: %s", test , ref )
259
246
cwd = os .getcwd ()
260
247
261
248
repo = "https://" + user + '@developer.mbed.org/users/' + user + '/code/' + test
262
249
263
250
# Clone the repo if it doesn't already exist
264
251
path = abspath (repo_path + '/' + test )
265
252
if not os .path .exists (path ):
266
- print ("Test repo doesn't exist, cloning..." )
253
+ logging . info ("Test repo doesn't exist, cloning..." )
267
254
os .chdir (abspath (repo_path ))
268
255
clone_cmd = ['hg' , 'clone' , repo ]
269
256
run_cmd (clone_cmd , exit_on_failure = True )
@@ -282,7 +269,7 @@ def upgrade_test_repo(test, user, library, ref, repo_path):
282
269
283
270
os .rename (lib_file , bak_file )
284
271
else :
285
- print ("!! Error trying to backup lib file prior to updating." )
272
+ logging . error ("!! Error trying to backup lib file prior to updating." )
286
273
return False
287
274
288
275
# mbed 2 style lib file contains one line with the following format
@@ -318,7 +305,7 @@ def upgrade_test_repo(test, user, library, ref, repo_path):
318
305
run_cmd (cmd , exit_on_failure = True )
319
306
320
307
except :
321
- print ("Lib file already up to date and thus nothing to commit" )
308
+ logging . info ("Lib file already up to date and thus nothing to commit" )
322
309
323
310
os .chdir (cwd )
324
311
return updated
@@ -375,19 +362,27 @@ def get_latest_library_versions(repo_path):
375
362
return mbed , mbed_dev
376
363
377
364
if __name__ == '__main__' :
365
+
366
+ parser = argparse .ArgumentParser (description = __doc__ ,
367
+ formatter_class = argparse .RawDescriptionHelpFormatter )
368
+ parser .add_argument ('-l' , '--log-level' , help = "Level for providing logging output" , default = 'INFO' )
369
+ args = parser .parse_args ()
370
+
371
+ default = getattr (logging , 'INFO' )
372
+ level = getattr (logging , args .log_level .upper (), default )
373
+
374
+ # Set logging level
375
+ logging .basicConfig (level = level )
378
376
379
377
# Read configuration data
380
378
json_data = json .load (open (os .path .join (os .path .dirname (__file__ ), "check_release.json" )))
381
379
382
- # Debug output off by default
383
- dbg = False
384
380
385
381
supported_targets = []
386
382
387
383
# Get a list of the officially supported mbed-os 2 targets
388
384
for tgt in OFFICIAL_MBED_LIBRARY_BUILD :
389
- if 'ARM' in tgt [1 ]:
390
- supported_targets .append (tgt [0 ] )
385
+ supported_targets .append (tgt [0 ])
391
386
392
387
config = json_data ["config" ]
393
388
test_list = json_data ["test_list" ]
@@ -409,11 +404,11 @@ def get_latest_library_versions(repo_path):
409
404
mbed , mbed_dev = get_latest_library_versions (repo_path )
410
405
411
406
if not mbed or not mbed_dev :
412
- print ("Could not obtain latest versions of library files!!" )
407
+ logging . error ("Could not obtain latest versions of library files!!" )
413
408
exit (1 )
414
409
415
- print ("Latest mbed lib version = %s" % mbed )
416
- print ("Latest mbed-dev lib version = %s" % mbed_dev )
410
+ logging . info ("Latest mbed lib version = %s" , mbed )
411
+ logging . info ("Latest mbed-dev lib version = %s" , mbed_dev )
417
412
418
413
# First update test repos to latest versions of their embedded libraries
419
414
for test in test_list :
@@ -426,30 +421,27 @@ def get_latest_library_versions(repo_path):
426
421
427
422
# Compile each test for each supported target
428
423
for test in tests :
429
- print ("Test compiling program: %s\n " % test )
424
+ logging . info ("Test compiling program: %s\n " , test )
430
425
for target in supported_targets :
431
- print ("\t Target: %s" % target )
432
426
for retry in range (0 , retries ):
427
+ logging .info ("\t Compiling target: %s , attempt %u\n " , target , retry )
433
428
result , mesg = build_repo (target , test , user , password )
434
429
if not result :
435
430
if mesg == 'Internal' :
436
431
# Internal compiler error thus retry
437
- sys .stdout .write ("FAILURE \n " )
438
- sys .stdout .flush ()
439
432
continue
440
433
else :
441
434
# Genuine compilation error, thus print it out
442
- print ("\t \t Error: %s\n " % mesg )
435
+ logging . error ("\t \t Error: %s\n " , mesg )
443
436
444
437
passes += (int )(result )
445
438
break
446
439
else :
447
- print ("\t \t Program/Target compilation failed due to internal errors. Removing from considered list!\n " )
440
+ logging . error ("\t \t Program/Target compilation failed due to internal errors. Removing from considered list!\n " )
448
441
total -= 1
449
442
450
443
# Output a % pass rate, indicate a failure if not 100% successful
451
444
pass_rate = int (passes / total ) * 100
452
- print ("Pass percentage = %d\n " % pass_rate )
445
+ logging . info ("Pass percentage = %d\n " , pass_rate )
453
446
sys .exit (not (pass_rate == 100 ))
454
-
455
-
447
+
0 commit comments