the other jimmy / mbed-sdk-tools

Fork of mbed-sdk-tools by mbed official

Committer:
The Other Jimmy
Date:
Wed Jan 04 11:58:24 2017 -0600
Revision:
32:8ea194f6145b
Update tools to follow mbed-os tools release 5.3.1

Who changed what in which revision?

UserRevisionLine numberNew contents of line
The Other Jimmy 32:8ea194f6145b 1 #!/usr/bin/env python
The Other Jimmy 32:8ea194f6145b 2
The Other Jimmy 32:8ea194f6145b 3 import os
The Other Jimmy 32:8ea194f6145b 4 from os.path import dirname, abspath, basename
The Other Jimmy 32:8ea194f6145b 5 import sys
The Other Jimmy 32:8ea194f6145b 6 import argparse
The Other Jimmy 32:8ea194f6145b 7 import json
The Other Jimmy 32:8ea194f6145b 8 import subprocess
The Other Jimmy 32:8ea194f6145b 9 import shutil
The Other Jimmy 32:8ea194f6145b 10 import stat
The Other Jimmy 32:8ea194f6145b 11
The Other Jimmy 32:8ea194f6145b 12 ROOT = abspath(dirname(dirname(dirname(dirname(__file__)))))
The Other Jimmy 32:8ea194f6145b 13 sys.path.insert(0, ROOT)
The Other Jimmy 32:8ea194f6145b 14
The Other Jimmy 32:8ea194f6145b 15 import examples_lib as lib
The Other Jimmy 32:8ea194f6145b 16 from examples_lib import SUPPORTED_TOOLCHAINS
The Other Jimmy 32:8ea194f6145b 17
The Other Jimmy 32:8ea194f6145b 18 def run_cmd(command, print_warning_on_fail=True):
The Other Jimmy 32:8ea194f6145b 19 """ Takes the command specified and runs it in a sub-process, obtaining the return code.
The Other Jimmy 32:8ea194f6145b 20
The Other Jimmy 32:8ea194f6145b 21 Args:
The Other Jimmy 32:8ea194f6145b 22 command - command to run, provided as a list of individual fields which are combined into a
The Other Jimmy 32:8ea194f6145b 23 single command before passing to the sub-process call.
The Other Jimmy 32:8ea194f6145b 24 return_code - result of the command.
The Other Jimmy 32:8ea194f6145b 25
The Other Jimmy 32:8ea194f6145b 26 """
The Other Jimmy 32:8ea194f6145b 27 print('[Exec] %s' % ' '.join(command))
The Other Jimmy 32:8ea194f6145b 28 return_code = subprocess.call(command)
The Other Jimmy 32:8ea194f6145b 29
The Other Jimmy 32:8ea194f6145b 30 if return_code:
The Other Jimmy 32:8ea194f6145b 31 print("The command '%s' failed with return code: %s" % (' '.join(command), return_code))
The Other Jimmy 32:8ea194f6145b 32 print("Ignoring and moving on to the next example")
The Other Jimmy 32:8ea194f6145b 33
The Other Jimmy 32:8ea194f6145b 34 return return_code
The Other Jimmy 32:8ea194f6145b 35
The Other Jimmy 32:8ea194f6145b 36
The Other Jimmy 32:8ea194f6145b 37 def rmtree_readonly(directory):
The Other Jimmy 32:8ea194f6145b 38 """ Deletes a readonly directory tree.
The Other Jimmy 32:8ea194f6145b 39
The Other Jimmy 32:8ea194f6145b 40 Args:
The Other Jimmy 32:8ea194f6145b 41 directory - tree to delete
The Other Jimmy 32:8ea194f6145b 42 """
The Other Jimmy 32:8ea194f6145b 43 def remove_readonly(func, path, _):
The Other Jimmy 32:8ea194f6145b 44 os.chmod(path, stat.S_IWRITE)
The Other Jimmy 32:8ea194f6145b 45 func(path)
The Other Jimmy 32:8ea194f6145b 46
The Other Jimmy 32:8ea194f6145b 47 shutil.rmtree(directory, onerror=remove_readonly)
The Other Jimmy 32:8ea194f6145b 48
The Other Jimmy 32:8ea194f6145b 49 def find_all_examples(path):
The Other Jimmy 32:8ea194f6145b 50 """ Searches the path specified for sub-example folders, ie those containing an
The Other Jimmy 32:8ea194f6145b 51 mbed-os.lib file. If found adds the path to the sub-example to a list which is
The Other Jimmy 32:8ea194f6145b 52 then returned.
The Other Jimmy 32:8ea194f6145b 53
The Other Jimmy 32:8ea194f6145b 54 Args:
The Other Jimmy 32:8ea194f6145b 55 path - path to search.
The Other Jimmy 32:8ea194f6145b 56 examples - (returned) list of paths to example directories.
The Other Jimmy 32:8ea194f6145b 57
The Other Jimmy 32:8ea194f6145b 58 """
The Other Jimmy 32:8ea194f6145b 59 examples = []
The Other Jimmy 32:8ea194f6145b 60 for root, dirs, files in os.walk(path):
The Other Jimmy 32:8ea194f6145b 61 if 'mbed-os.lib' in files:
The Other Jimmy 32:8ea194f6145b 62 examples += [root]
The Other Jimmy 32:8ea194f6145b 63
The Other Jimmy 32:8ea194f6145b 64 return examples
The Other Jimmy 32:8ea194f6145b 65
The Other Jimmy 32:8ea194f6145b 66 def upgrade_single_example(example, tag, directory):
The Other Jimmy 32:8ea194f6145b 67 """ Updates the mbed-os.lib file in the example specified to correspond to the
The Other Jimmy 32:8ea194f6145b 68 version specified by the GitHub tag supplied. Also deals with
The Other Jimmy 32:8ea194f6145b 69 multiple sub-examples in the GitHub repo, updating them in the same way.
The Other Jimmy 32:8ea194f6145b 70
The Other Jimmy 32:8ea194f6145b 71 Args:
The Other Jimmy 32:8ea194f6145b 72 example - json example object containing the GitHub repo to update.
The Other Jimmy 32:8ea194f6145b 73 tag - GitHub tag corresponding to a version of mbed-os to upgrade to.
The Other Jimmy 32:8ea194f6145b 74 directory - directory path for the example.
The Other Jimmy 32:8ea194f6145b 75 returns - True if the upgrade was successful, False otherwise.
The Other Jimmy 32:8ea194f6145b 76
The Other Jimmy 32:8ea194f6145b 77 """
The Other Jimmy 32:8ea194f6145b 78 print("Upgrading single example at path '%s'" % directory)
The Other Jimmy 32:8ea194f6145b 79 cwd = os.getcwd()
The Other Jimmy 32:8ea194f6145b 80 os.chdir(directory)
The Other Jimmy 32:8ea194f6145b 81
The Other Jimmy 32:8ea194f6145b 82 return_code = None
The Other Jimmy 32:8ea194f6145b 83
The Other Jimmy 32:8ea194f6145b 84 # Change directories to the mbed-os library
The Other Jimmy 32:8ea194f6145b 85 if not os.path.exists('mbed-os'):
The Other Jimmy 32:8ea194f6145b 86 print("'mbed-os' directory not found in the root of '%s'" % directory)
The Other Jimmy 32:8ea194f6145b 87 print("Ignoring and moving on to the next example")
The Other Jimmy 32:8ea194f6145b 88 os.chdir(cwd)
The Other Jimmy 32:8ea194f6145b 89 return False
The Other Jimmy 32:8ea194f6145b 90
The Other Jimmy 32:8ea194f6145b 91 os.chdir('mbed-os')
The Other Jimmy 32:8ea194f6145b 92
The Other Jimmy 32:8ea194f6145b 93 # Setup and run the update command
The Other Jimmy 32:8ea194f6145b 94 update_cmd = ['mbed', 'update', tag]
The Other Jimmy 32:8ea194f6145b 95 return_code = run_cmd(update_cmd)
The Other Jimmy 32:8ea194f6145b 96
The Other Jimmy 32:8ea194f6145b 97 if return_code:
The Other Jimmy 32:8ea194f6145b 98 os.chdir(cwd)
The Other Jimmy 32:8ea194f6145b 99 return False
The Other Jimmy 32:8ea194f6145b 100
The Other Jimmy 32:8ea194f6145b 101 os.chdir('../')
The Other Jimmy 32:8ea194f6145b 102
The Other Jimmy 32:8ea194f6145b 103 # Setup and run the add command
The Other Jimmy 32:8ea194f6145b 104 add_cmd = ['git', 'add', 'mbed-os.lib']
The Other Jimmy 32:8ea194f6145b 105 return_code = run_cmd(add_cmd)
The Other Jimmy 32:8ea194f6145b 106
The Other Jimmy 32:8ea194f6145b 107 os.chdir(cwd)
The Other Jimmy 32:8ea194f6145b 108 return not return_code
The Other Jimmy 32:8ea194f6145b 109
The Other Jimmy 32:8ea194f6145b 110 def upgrade_example(example, tag):
The Other Jimmy 32:8ea194f6145b 111 """ Clones the example specified from GitHub and updates the associated mbed-os.lib file
The Other Jimmy 32:8ea194f6145b 112 to correspond to the version specified by the GitHub tag supplied. Also deals with
The Other Jimmy 32:8ea194f6145b 113 multiple sub-examples in the GitHub repo, updating them in the same way.
The Other Jimmy 32:8ea194f6145b 114
The Other Jimmy 32:8ea194f6145b 115 Args:
The Other Jimmy 32:8ea194f6145b 116 example - json example object containing the GitHub repo to update.
The Other Jimmy 32:8ea194f6145b 117 tag - GitHub tag corresponding to a version of mbed-os to upgrade to.
The Other Jimmy 32:8ea194f6145b 118
The Other Jimmy 32:8ea194f6145b 119 """
The Other Jimmy 32:8ea194f6145b 120 print("Updating example '%s'" % example['name'])
The Other Jimmy 32:8ea194f6145b 121 cwd = os.getcwd()
The Other Jimmy 32:8ea194f6145b 122
The Other Jimmy 32:8ea194f6145b 123 # Setup and run the import command
The Other Jimmy 32:8ea194f6145b 124 clone_cmd = ['git', 'clone', example['github']]
The Other Jimmy 32:8ea194f6145b 125 return_code = run_cmd(clone_cmd)
The Other Jimmy 32:8ea194f6145b 126
The Other Jimmy 32:8ea194f6145b 127 if return_code:
The Other Jimmy 32:8ea194f6145b 128 return False
The Other Jimmy 32:8ea194f6145b 129
The Other Jimmy 32:8ea194f6145b 130 # Find all examples
The Other Jimmy 32:8ea194f6145b 131 example_directories = find_all_examples(example['name'])
The Other Jimmy 32:8ea194f6145b 132
The Other Jimmy 32:8ea194f6145b 133 os.chdir(example['name'])
The Other Jimmy 32:8ea194f6145b 134
The Other Jimmy 32:8ea194f6145b 135 # Setup and run the update command
The Other Jimmy 32:8ea194f6145b 136 import_cmd = ['mbed', 'update']
The Other Jimmy 32:8ea194f6145b 137 return_code = run_cmd(import_cmd)
The Other Jimmy 32:8ea194f6145b 138 if return_code:
The Other Jimmy 32:8ea194f6145b 139 os.chdir(cwd)
The Other Jimmy 32:8ea194f6145b 140 return False
The Other Jimmy 32:8ea194f6145b 141
The Other Jimmy 32:8ea194f6145b 142 for example_directory in example_directories:
The Other Jimmy 32:8ea194f6145b 143 if not upgrade_single_example(example, tag, os.path.relpath(example_directory, example['name'])):
The Other Jimmy 32:8ea194f6145b 144 os.chdir(cwd)
The Other Jimmy 32:8ea194f6145b 145 return False
The Other Jimmy 32:8ea194f6145b 146
The Other Jimmy 32:8ea194f6145b 147 # Setup the default commit message
The Other Jimmy 32:8ea194f6145b 148 commit_message = 'Updating mbed-os to {{' + tag +'}}'
The Other Jimmy 32:8ea194f6145b 149
The Other Jimmy 32:8ea194f6145b 150 # Setup and run the commit command
The Other Jimmy 32:8ea194f6145b 151 commit_cmd = ['git', 'commit', '-m', commit_message]
The Other Jimmy 32:8ea194f6145b 152 return_code = run_cmd(commit_cmd)
The Other Jimmy 32:8ea194f6145b 153 if return_code:
The Other Jimmy 32:8ea194f6145b 154 if return_code == 1:
The Other Jimmy 32:8ea194f6145b 155 print("[WARNING] 'git commit' exited with a return code of 1. " + \
The Other Jimmy 32:8ea194f6145b 156 "This usually inidicates that no update was made. Still " + \
The Other Jimmy 32:8ea194f6145b 157 "attempting to create a tag.")
The Other Jimmy 32:8ea194f6145b 158 else:
The Other Jimmy 32:8ea194f6145b 159 os.chdir(cwd)
The Other Jimmy 32:8ea194f6145b 160 return False
The Other Jimmy 32:8ea194f6145b 161
The Other Jimmy 32:8ea194f6145b 162 # Setup and run the tag command
The Other Jimmy 32:8ea194f6145b 163 tag_cmd = ['git', 'tag', '-a', tag, '-m', tag]
The Other Jimmy 32:8ea194f6145b 164 return_code = run_cmd(tag_cmd)
The Other Jimmy 32:8ea194f6145b 165 if return_code:
The Other Jimmy 32:8ea194f6145b 166 os.chdir(cwd)
The Other Jimmy 32:8ea194f6145b 167 return False
The Other Jimmy 32:8ea194f6145b 168
The Other Jimmy 32:8ea194f6145b 169 # Setup and run the push command
The Other Jimmy 32:8ea194f6145b 170 push_cmd = ['git', 'push', 'origin', 'master']
The Other Jimmy 32:8ea194f6145b 171 return_code = run_cmd(push_cmd)
The Other Jimmy 32:8ea194f6145b 172
The Other Jimmy 32:8ea194f6145b 173 if return_code:
The Other Jimmy 32:8ea194f6145b 174 os.chdir(cwd)
The Other Jimmy 32:8ea194f6145b 175 return False
The Other Jimmy 32:8ea194f6145b 176
The Other Jimmy 32:8ea194f6145b 177 push_cmd = ['git', 'push', 'origin', tag]
The Other Jimmy 32:8ea194f6145b 178 return_code = run_cmd(push_cmd)
The Other Jimmy 32:8ea194f6145b 179
The Other Jimmy 32:8ea194f6145b 180 os.chdir(cwd)
The Other Jimmy 32:8ea194f6145b 181 return not return_code
The Other Jimmy 32:8ea194f6145b 182
The Other Jimmy 32:8ea194f6145b 183 def create_work_directory(path):
The Other Jimmy 32:8ea194f6145b 184 """ Create a new directory specified in 'path', overwrite if the directory already
The Other Jimmy 32:8ea194f6145b 185 exists.
The Other Jimmy 32:8ea194f6145b 186
The Other Jimmy 32:8ea194f6145b 187 Args:
The Other Jimmy 32:8ea194f6145b 188 path - directory path to be created.
The Other Jimmy 32:8ea194f6145b 189
The Other Jimmy 32:8ea194f6145b 190 """
The Other Jimmy 32:8ea194f6145b 191 if os.path.exists(path):
The Other Jimmy 32:8ea194f6145b 192 print("'%s' directory already exists. Deleting..." % path)
The Other Jimmy 32:8ea194f6145b 193 rmtree_readonly(path)
The Other Jimmy 32:8ea194f6145b 194
The Other Jimmy 32:8ea194f6145b 195 os.makedirs(path)
The Other Jimmy 32:8ea194f6145b 196
The Other Jimmy 32:8ea194f6145b 197 def test_compile(config, tag):
The Other Jimmy 32:8ea194f6145b 198 """ For each example repo identified in the config json object, clone, update mbed-os to
The Other Jimmy 32:8ea194f6145b 199 the specified tag and then compile for all supported toolchains.
The Other Jimmy 32:8ea194f6145b 200
The Other Jimmy 32:8ea194f6145b 201 Args:
The Other Jimmy 32:8ea194f6145b 202 config - the json object imported from the file.
The Other Jimmy 32:8ea194f6145b 203 tag - GitHub tag corresponding to a version of mbed-os to upgrade to.
The Other Jimmy 32:8ea194f6145b 204 results - summary of compilation results.
The Other Jimmy 32:8ea194f6145b 205
The Other Jimmy 32:8ea194f6145b 206 """
The Other Jimmy 32:8ea194f6145b 207 # Create work directories
The Other Jimmy 32:8ea194f6145b 208 create_work_directory('test_compile')
The Other Jimmy 32:8ea194f6145b 209
The Other Jimmy 32:8ea194f6145b 210 # Loop through the examples
The Other Jimmy 32:8ea194f6145b 211 results = {}
The Other Jimmy 32:8ea194f6145b 212 os.chdir('test_compile')
The Other Jimmy 32:8ea194f6145b 213
The Other Jimmy 32:8ea194f6145b 214 lib.source_repos(config)
The Other Jimmy 32:8ea194f6145b 215 lib.update_mbedos_version(config, tag)
The Other Jimmy 32:8ea194f6145b 216 results = lib.compile_repos(config, SUPPORTED_TOOLCHAINS)
The Other Jimmy 32:8ea194f6145b 217 os.chdir("..")
The Other Jimmy 32:8ea194f6145b 218
The Other Jimmy 32:8ea194f6145b 219 return results
The Other Jimmy 32:8ea194f6145b 220
The Other Jimmy 32:8ea194f6145b 221
The Other Jimmy 32:8ea194f6145b 222 def main(arguments):
The Other Jimmy 32:8ea194f6145b 223
The Other Jimmy 32:8ea194f6145b 224 parser = argparse.ArgumentParser(description=__doc__,
The Other Jimmy 32:8ea194f6145b 225 formatter_class=argparse.RawDescriptionHelpFormatter)
The Other Jimmy 32:8ea194f6145b 226 parser.add_argument('tag', help="mbed-os tag to which all examples will be updated")
The Other Jimmy 32:8ea194f6145b 227 parser.add_argument('-c', '--config_file', help="Path to the configuration file (default is 'examples.json')", default='examples.json')
The Other Jimmy 32:8ea194f6145b 228
The Other Jimmy 32:8ea194f6145b 229 args = parser.parse_args(arguments)
The Other Jimmy 32:8ea194f6145b 230
The Other Jimmy 32:8ea194f6145b 231 cfg = os.path.join(os.path.dirname(__file__), args.config_file)
The Other Jimmy 32:8ea194f6145b 232
The Other Jimmy 32:8ea194f6145b 233 # Load the config file
The Other Jimmy 32:8ea194f6145b 234 config = json.load(open(os.path.join(os.path.dirname(__file__),
The Other Jimmy 32:8ea194f6145b 235 args.config_file)))
The Other Jimmy 32:8ea194f6145b 236
The Other Jimmy 32:8ea194f6145b 237 if not config:
The Other Jimmy 32:8ea194f6145b 238 print("Failed to load config file '%s'" % args.config_file)
The Other Jimmy 32:8ea194f6145b 239 sys.exit(1)
The Other Jimmy 32:8ea194f6145b 240
The Other Jimmy 32:8ea194f6145b 241 # Create work directories
The Other Jimmy 32:8ea194f6145b 242 create_work_directory('examples')
The Other Jimmy 32:8ea194f6145b 243
The Other Jimmy 32:8ea194f6145b 244 # Loop through the examples
The Other Jimmy 32:8ea194f6145b 245 failures = []
The Other Jimmy 32:8ea194f6145b 246 successes = []
The Other Jimmy 32:8ea194f6145b 247 not_compiled = []
The Other Jimmy 32:8ea194f6145b 248 results = {}
The Other Jimmy 32:8ea194f6145b 249 os.chdir('examples')
The Other Jimmy 32:8ea194f6145b 250
The Other Jimmy 32:8ea194f6145b 251 results = test_compile(config, args.tag)
The Other Jimmy 32:8ea194f6145b 252 lib.print_compilation_summary(results)
The Other Jimmy 32:8ea194f6145b 253
The Other Jimmy 32:8ea194f6145b 254 for example in config['examples']:
The Other Jimmy 32:8ea194f6145b 255 # Determine if this example should be updated
The Other Jimmy 32:8ea194f6145b 256
The Other Jimmy 32:8ea194f6145b 257 # Attempt to update if:
The Other Jimmy 32:8ea194f6145b 258 # group of examples passed compilation and
The Other Jimmy 32:8ea194f6145b 259 # auto update is set to True
The Other Jimmy 32:8ea194f6145b 260 # Note: results fields are [compiled flag, pass flag, successes list, failures list]
The Other Jimmy 32:8ea194f6145b 261 if not results[example['name']][0]:
The Other Jimmy 32:8ea194f6145b 262 # Example was not compiled
The Other Jimmy 32:8ea194f6145b 263 not_compiled += [example['name']]
The Other Jimmy 32:8ea194f6145b 264 else:
The Other Jimmy 32:8ea194f6145b 265 if results[example['name']][1] and example['auto-update']:
The Other Jimmy 32:8ea194f6145b 266 if upgrade_example(example, args.tag):
The Other Jimmy 32:8ea194f6145b 267 successes += [example['name']]
The Other Jimmy 32:8ea194f6145b 268 else:
The Other Jimmy 32:8ea194f6145b 269 failures += [example['name']]
The Other Jimmy 32:8ea194f6145b 270 else:
The Other Jimmy 32:8ea194f6145b 271 failures += [example['name']]
The Other Jimmy 32:8ea194f6145b 272
The Other Jimmy 32:8ea194f6145b 273 os.chdir('../')
The Other Jimmy 32:8ea194f6145b 274
The Other Jimmy 32:8ea194f6145b 275 # Finish the script and report the results
The Other Jimmy 32:8ea194f6145b 276 print(os.linesep + os.linesep +'Finished updating examples!' + os.linesep)
The Other Jimmy 32:8ea194f6145b 277
The Other Jimmy 32:8ea194f6145b 278 if successes:
The Other Jimmy 32:8ea194f6145b 279 print('The following examples updated successfully:')
The Other Jimmy 32:8ea194f6145b 280 for success in successes:
The Other Jimmy 32:8ea194f6145b 281 print(' - %s' % success)
The Other Jimmy 32:8ea194f6145b 282
The Other Jimmy 32:8ea194f6145b 283 if failures:
The Other Jimmy 32:8ea194f6145b 284 print('\nThe following examples were not updated:')
The Other Jimmy 32:8ea194f6145b 285 for fail in failures:
The Other Jimmy 32:8ea194f6145b 286 print(' - %s' % fail)
The Other Jimmy 32:8ea194f6145b 287
The Other Jimmy 32:8ea194f6145b 288 if not_compiled:
The Other Jimmy 32:8ea194f6145b 289 print('The following examples were skipped:')
The Other Jimmy 32:8ea194f6145b 290 for example in not_compiled:
The Other Jimmy 32:8ea194f6145b 291 print(' - %s' % example)
The Other Jimmy 32:8ea194f6145b 292
The Other Jimmy 32:8ea194f6145b 293
The Other Jimmy 32:8ea194f6145b 294 if __name__ == '__main__':
The Other Jimmy 32:8ea194f6145b 295 sys.exit(main(sys.argv[1:]))