42
42
# -c <config file> - Optional path to an examples file.
43
43
# If not proved the default is 'examples.json'
44
44
# -T <github_token> - GitHub token for secure access (required)
45
- # -l <logging level> - Optional Level for providing logging output. Can be one of,
46
- # CRITICAL, ERROR, WARNING, INFO, DEBUG
47
- # If not provided the default is 'INFO'
48
45
# -f - Update forked repos. This will use the 'github-user' parameter in
49
46
# the 'via-fork' section.
50
47
# -b - Update branched repos. This will use the "src-branch" and
75
72
import examples_lib as lib
76
73
from examples_lib import SUPPORTED_TOOLCHAINS
77
74
75
+ userlog = logging .getLogger ("Update" )
76
+
77
+ # Set logging level
78
+ userlog .setLevel (logging .DEBUG )
79
+
80
+ # Everything is output to the log file
81
+ logfile = os .path .join (os .getcwd (), 'update.log' )
82
+ fh = logging .FileHandler (logfile )
83
+ fh .setLevel (logging .DEBUG )
84
+
85
+ # create console handler with a higher log level
86
+ ch = logging .StreamHandler ()
87
+ ch .setLevel (logging .INFO )
88
+
89
+ formatter = logging .Formatter ('%(name)s: %(levelname)s - %(message)s' )
90
+ ch .setFormatter (formatter )
91
+ fh .setFormatter (formatter )
92
+
93
+ # add the handlers to the logger
94
+ userlog .addHandler (fh )
95
+ userlog .addHandler (ch )
96
+
78
97
def run_cmd (command , exit_on_failure = False ):
79
- """ Run a system command and return the result status
98
+ """ Run a system command returning a status result
80
99
81
- Description:
100
+ This is just a wrapper for the run_cmd_with_output() function, but
101
+ only returns the status of the call.
82
102
83
- Passes a command to the system and returns a True/False result, once the
84
- command has been executed, indicating success/failure. Commands are passed
85
- as a list of tokens.
86
- E.g. The command 'git remote -v' would be passed in as ['git', 'remote', '-v']
87
-
88
103
Args:
89
104
command - system command as a list of tokens
90
105
exit_on_failure - If True exit the program on failure (default = False)
91
106
92
107
Returns:
93
108
return_code - True/False indicating the success/failure of the command
94
109
"""
95
- update_log .debug ('[Exec] %s' , ' ' .join (command ))
96
- return_code = subprocess .call (command , shell = True )
97
-
98
- if return_code :
99
- update_log .warning ("Command '%s' failed with return code: %s" ,
100
- ' ' .join (command ), return_code )
101
- if exit_on_failure :
102
- sys .exit (1 )
103
-
110
+ return_code , _ = run_cmd_with_output (command , exit_on_failure )
104
111
return return_code
105
112
106
113
def run_cmd_with_output (command , exit_on_failure = False ):
107
- """ Run a system command and return the result status plus output
114
+ """ Run a system command returning a status result and any command output
108
115
109
- Description:
110
-
111
116
Passes a command to the system and returns a True/False result once the
112
117
command has been executed, indicating success/failure. If the command was
113
118
successful then the output from the command is returned to the caller.
114
- Commands are passed as a list of tokens .
115
- E.g. The command 'git remote -v' would be passed in as [' git', ' remote', '-v']
119
+ Commands are passed as a string .
120
+ E.g. The command 'git remote -v' would be passed in as " git remote -v"
116
121
117
122
Args:
118
- command - system command as a list of tokens
123
+ command - system command as a string
119
124
exit_on_failure - If True exit the program on failure (default = False)
120
125
121
126
Returns:
122
- returncode - True/False indicating the success/failure of the command
127
+ return_code - True/False indicating the success/failure of the command
123
128
output - The output of the command if it was successful, else empty string
124
129
"""
125
- update_log .debug ('[Exec] %s' , ' ' .join (command ))
130
+ text = '[Exec] ' + command
131
+ userlog .debug (text )
126
132
returncode = 0
127
133
output = ""
128
134
try :
129
135
output = subprocess .check_output (command , shell = True )
130
136
except subprocess .CalledProcessError as e :
131
- update_log . warning ( "Command '%s' failed with return code: %s" ,
132
- ' ' . join ( command ), e . returncode )
137
+ text = "The command " + str ( command ) + " failed with return code: " + str ( e . returncode )
138
+ userlog . warning ( text )
133
139
returncode = e .returncode
134
140
if exit_on_failure :
135
141
sys .exit (1 )
136
142
return returncode , output
137
143
144
+
138
145
def rmtree_readonly (directory ):
139
146
""" Deletes a readonly directory tree.
140
147
@@ -198,7 +205,7 @@ def upgrade_single_example(example, tag, directory, ref):
198
205
199
206
os .rename ("mbed-os.lib" , "mbed-os.lib_bak" )
200
207
else :
201
- update_log .error ("Failed to backup mbed-os.lib prior to updating." )
208
+ userlog .error ("Failed to backup mbed-os.lib prior to updating." )
202
209
return False
203
210
204
211
# mbed-os.lib file contains one line with the following format
@@ -221,7 +228,7 @@ def upgrade_single_example(example, tag, directory, ref):
221
228
222
229
if updated :
223
230
# Setup and run the git add command
224
- cmd = [ ' git' , ' add' , ' mbed-os.lib' ]
231
+ cmd = " git add mbed-os.lib"
225
232
return_code = run_cmd (cmd )
226
233
227
234
os .chdir (cwd )
@@ -242,12 +249,12 @@ def prepare_fork(arm_example):
242
249
"""
243
250
244
251
logstr = "In: " + os .getcwd ()
245
- update_log .debug (logstr )
252
+ userlog .debug (logstr )
246
253
247
- for cmd in [[ ' git' , ' remote' , ' add' , ' armmbed' , arm_example ] ,
248
- [ ' git' , ' fetch' , ' armmbed' ] ,
249
- [ ' git' , ' reset' , ' --hard' , ' armmbed/master' ] ,
250
- [ ' git' , ' push' , '-f' , ' origin' ] ]:
254
+ for cmd in [" git remote add armmbed " + str ( arm_example ) ,
255
+ " git fetch armmbed" ,
256
+ " git reset --hard armmbed/master" ,
257
+ " git push -f origin" ]:
251
258
run_cmd (cmd , exit_on_failure = True )
252
259
253
260
def prepare_branch (src , dst ):
@@ -265,25 +272,34 @@ def prepare_branch(src, dst):
265
272
266
273
"""
267
274
268
- update_log .debug ("Preparing branch: %s" , dst )
275
+ userlog .debug ("Preparing branch: %s" , dst )
269
276
270
277
# Check if branch already exists or not.
271
- cmd = ['git' , 'branch' ]
278
+ # We can use the 'git branch -r' command. This returns all the remote branches for
279
+ # the current repo.
280
+ # The output consists of a list of lines of the form:
281
+ # origin/<branch>
282
+ # From these we need to extract just the branch names to a list and then check if
283
+ # the specified dst exists in that list
284
+ branches = []
285
+ cmd = "git branch -r"
272
286
_ , output = run_cmd_with_output (cmd , exit_on_failure = True )
273
287
274
- if not dst in output :
288
+ branches = [line .split ('/' )[1 ] for line in output .split ('\n ' ) if 'origin' in line and not '->' in line ]
289
+
290
+ if not dst in branches :
275
291
276
292
# OOB branch does not exist thus create it, first ensuring we are on
277
293
# the src branch and then check it out
278
294
279
- for cmd in [[ ' git' , ' checkout' , src ] ,
280
- [ ' git' , ' checkout' , '-b' , dst ] ,
281
- [ ' git' , ' push' , '-u' , ' origin' , dst ] ]:
295
+ for cmd in [" git checkout " + str ( src ) ,
296
+ " git checkout -b " + str ( dst ) ,
297
+ " git push -u origin " + str ( dst ) ]:
282
298
283
299
run_cmd (cmd , exit_on_failure = True )
284
300
285
301
else :
286
- cmd = [ ' git' , ' checkout' , dst ]
302
+ cmd = " git checkout " + str ( dst )
287
303
run_cmd (cmd , exit_on_failure = True )
288
304
289
305
def upgrade_example (github , example , tag , ref , user , src , dst , template ):
@@ -321,18 +337,18 @@ def upgrade_example(github, example, tag, ref, user, src, dst, template):
321
337
user = 'ARMmbed'
322
338
323
339
ret = False
324
- update_log .info ("Updating example '%s'" , example ['name' ])
325
- update_log .debug ("User: %s" , user )
326
- update_log .debug ("Src branch: %s" , (src or "None" ))
327
- update_log .debug ("Dst branch: %s" , (dst or "None" ))
340
+ userlog .info ("Updating example '%s'" , example ['name' ])
341
+ userlog .debug ("User: %s" , user )
342
+ userlog .debug ("Src branch: %s" , (src or "None" ))
343
+ userlog .debug ("Dst branch: %s" , (dst or "None" ))
328
344
329
345
cwd = os .getcwd ()
330
346
331
347
update_repo = "https://github.com/" + user + '/' + example ['name' ]
332
- update_log .debug ("Update repository: %s" , update_repo )
348
+ userlog .debug ("Update repository: %s" , update_repo )
333
349
334
350
# Clone the example repo
335
- clone_cmd = [ ' git' , ' clone' , update_repo ]
351
+ clone_cmd = " git clone " + str ( update_repo )
336
352
return_code = run_cmd (clone_cmd )
337
353
338
354
if not return_code :
@@ -353,30 +369,27 @@ def upgrade_example(github, example, tag, ref, user, src, dst, template):
353
369
os .chdir (cwd )
354
370
return False
355
371
356
- # Setup the default commit message
357
- commit_message = 'Updating mbed-os to ' + tag
358
-
359
372
# Setup and run the commit command
360
- commit_cmd = [ ' git' , ' commit' , '-m' , commit_message ]
373
+ commit_cmd = " git commit -m \" Updating mbed-os to " + tag + " \" "
361
374
return_code = run_cmd (commit_cmd )
362
375
if not return_code :
363
376
364
377
# Setup and run the push command
365
- push_cmd = [ ' git' , ' push' , ' origin' ]
378
+ push_cmd = " git push origin"
366
379
return_code = run_cmd (push_cmd )
367
380
368
381
if not return_code :
369
382
# If the user is not ARMmbed then a fork is being used
370
383
if user != 'ARMmbed' :
371
384
372
385
upstream_repo = 'ARMmbed/' + example ['name' ]
373
- update_log .debug ("Upstream repository: %s" , upstream_repo )
386
+ userlog .debug ("Upstream repository: %s" , upstream_repo )
374
387
# Check access to mbed-os repo
375
388
try :
376
389
repo = github .get_repo (upstream_repo , False )
377
390
378
391
except :
379
- update_log .error ("Upstream repo: %s, does not exist - skipping" , upstream_repo )
392
+ userlog .error ("Upstream repo: %s, does not exist - skipping" , upstream_repo )
380
393
return False
381
394
382
395
jinja_loader = FileSystemLoader (template )
@@ -391,15 +404,15 @@ def upgrade_example(github, example, tag, ref, user, src, dst, template):
391
404
ret = True
392
405
except GithubException as e :
393
406
# Default to False
394
- update_log .error ("Pull request creation failed with error: %s" , e )
407
+ userlog .error ("Pull request creation failed with error: %s" , e )
395
408
else :
396
409
ret = True
397
410
else :
398
- update_log .error ("Git push command failed." )
411
+ userlog .error ("Git push command failed." )
399
412
else :
400
- update_log .error ("Git commit command failed." )
413
+ userlog .error ("Git commit command failed." )
401
414
else :
402
- update_log .error ("Git clone %s failed" , update_repo )
415
+ userlog .error ("Git clone %s failed" , update_repo )
403
416
404
417
os .chdir (cwd )
405
418
return ret
@@ -413,7 +426,7 @@ def create_work_directory(path):
413
426
414
427
"""
415
428
if os .path .exists (path ):
416
- update_log .info ("'%s' directory already exists. Deleting..." , path )
429
+ userlog .info ("'%s' directory already exists. Deleting..." , path )
417
430
rmtree_readonly (path )
418
431
419
432
os .makedirs (path )
@@ -424,28 +437,17 @@ def create_work_directory(path):
424
437
formatter_class = argparse .RawDescriptionHelpFormatter )
425
438
parser .add_argument ('-c' , '--config_file' , help = "Path to the configuration file (default is 'examples.json')" , default = 'examples.json' )
426
439
parser .add_argument ('-T' , '--github_token' , help = "GitHub token for secure access" )
427
- parser .add_argument ('-l' , '--log-level' ,
428
- help = "Level for providing logging output" ,
429
- default = 'INFO' )
430
440
431
441
exclusive = parser .add_mutually_exclusive_group (required = True )
432
442
exclusive .add_argument ('-f' , '--fork' , help = "Update a fork" , action = 'store_true' )
433
443
exclusive .add_argument ('-b' , '--branch' , help = "Update a branch" , action = 'store_true' )
434
444
435
445
args = parser .parse_args ()
436
446
437
- default = getattr (logging , 'INFO' )
438
- level = getattr (logging , args .log_level .upper (), default )
439
-
440
- # Set logging level
441
- logging .basicConfig (level = level )
442
-
443
- update_log = logging .getLogger ("Update" )
444
-
445
447
# Load the config file
446
448
with open (os .path .join (os .path .dirname (__file__ ), args .config_file )) as config :
447
449
if not config :
448
- update_log .error ("Failed to load config file '%s'" , args .config_file )
450
+ userlog .error ("Failed to load config file '%s'" , args .config_file )
449
451
sys .exit (1 )
450
452
json_data = json .load (config )
451
453
@@ -470,11 +472,11 @@ def create_work_directory(path):
470
472
exit (1 )
471
473
472
474
# Get the github sha corresponding to the specified mbed-os tag
473
- cmd = [ ' git' , ' rev-list' , '-1' , tag ]
475
+ cmd = " git rev-list -1 " + tag
474
476
return_code , ref = run_cmd_with_output (cmd )
475
477
476
478
if return_code :
477
- update_log .error ("Could not obtain SHA for tag: %s" , tag )
479
+ userlog .error ("Could not obtain SHA for tag: %s" , tag )
478
480
sys .exit (1 )
479
481
480
482
# Loop through the examples
@@ -499,11 +501,11 @@ def create_work_directory(path):
499
501
os .chdir ('../' )
500
502
501
503
# Finish the script and report the results
502
- update_log .info ("Finished updating examples" )
504
+ userlog .info ("Finished updating examples" )
503
505
if successes :
504
506
for success in successes :
505
- update_log .info (" SUCCEEDED: %s" , success )
507
+ userlog .info (" SUCCEEDED: %s" , success )
506
508
507
509
if failures :
508
510
for fail in failures :
509
- update_log .info (" FAILED: %s" , fail )
511
+ userlog .info (" FAILED: %s" , fail )
0 commit comments