Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of mbed-sdk-tools by
Diff: test/examples/update.py
- Revision:
- 31:182518299918
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/examples/update.py Wed Jan 04 11:58:24 2017 -0600 @@ -0,0 +1,295 @@ +#!/usr/bin/env python + +import os +from os.path import dirname, abspath, basename +import sys +import argparse +import json +import subprocess +import shutil +import stat + +ROOT = abspath(dirname(dirname(dirname(dirname(__file__))))) +sys.path.insert(0, ROOT) + +import examples_lib as lib +from examples_lib import SUPPORTED_TOOLCHAINS + +def run_cmd(command, print_warning_on_fail=True): + """ Takes the command specified and runs it in a sub-process, obtaining the return code. + + Args: + command - command to run, provided as a list of individual fields which are combined into a + single command before passing to the sub-process call. + return_code - result of the command. + + """ + print('[Exec] %s' % ' '.join(command)) + return_code = subprocess.call(command) + + if return_code: + print("The command '%s' failed with return code: %s" % (' '.join(command), return_code)) + print("Ignoring and moving on to the next example") + + return return_code + + +def rmtree_readonly(directory): + """ Deletes a readonly directory tree. + + Args: + directory - tree to delete + """ + def remove_readonly(func, path, _): + os.chmod(path, stat.S_IWRITE) + func(path) + + shutil.rmtree(directory, onerror=remove_readonly) + +def find_all_examples(path): + """ Searches the path specified for sub-example folders, ie those containing an + mbed-os.lib file. If found adds the path to the sub-example to a list which is + then returned. + + Args: + path - path to search. + examples - (returned) list of paths to example directories. + + """ + examples = [] + for root, dirs, files in os.walk(path): + if 'mbed-os.lib' in files: + examples += [root] + + return examples + +def upgrade_single_example(example, tag, directory): + """ Updates the mbed-os.lib file in the example specified to correspond to the + version specified by the GitHub tag supplied. Also deals with + multiple sub-examples in the GitHub repo, updating them in the same way. + + Args: + example - json example object containing the GitHub repo to update. + tag - GitHub tag corresponding to a version of mbed-os to upgrade to. + directory - directory path for the example. + returns - True if the upgrade was successful, False otherwise. + + """ + print("Upgrading single example at path '%s'" % directory) + cwd = os.getcwd() + os.chdir(directory) + + return_code = None + + # Change directories to the mbed-os library + if not os.path.exists('mbed-os'): + print("'mbed-os' directory not found in the root of '%s'" % directory) + print("Ignoring and moving on to the next example") + os.chdir(cwd) + return False + + os.chdir('mbed-os') + + # Setup and run the update command + update_cmd = ['mbed', 'update', tag] + return_code = run_cmd(update_cmd) + + if return_code: + os.chdir(cwd) + return False + + os.chdir('../') + + # Setup and run the add command + add_cmd = ['git', 'add', 'mbed-os.lib'] + return_code = run_cmd(add_cmd) + + os.chdir(cwd) + return not return_code + +def upgrade_example(example, tag): + """ Clones the example specified from GitHub and updates the associated mbed-os.lib file + to correspond to the version specified by the GitHub tag supplied. Also deals with + multiple sub-examples in the GitHub repo, updating them in the same way. + + Args: + example - json example object containing the GitHub repo to update. + tag - GitHub tag corresponding to a version of mbed-os to upgrade to. + + """ + print("Updating example '%s'" % example['name']) + cwd = os.getcwd() + + # Setup and run the import command + clone_cmd = ['git', 'clone', example['github']] + return_code = run_cmd(clone_cmd) + + if return_code: + return False + + # Find all examples + example_directories = find_all_examples(example['name']) + + os.chdir(example['name']) + + # Setup and run the update command + import_cmd = ['mbed', 'update'] + return_code = run_cmd(import_cmd) + if return_code: + os.chdir(cwd) + return False + + for example_directory in example_directories: + if not upgrade_single_example(example, tag, os.path.relpath(example_directory, example['name'])): + os.chdir(cwd) + return False + + # Setup the default commit message + commit_message = 'Updating mbed-os to {{' + tag +'}}' + + # Setup and run the commit command + commit_cmd = ['git', 'commit', '-m', commit_message] + return_code = run_cmd(commit_cmd) + if return_code: + if return_code == 1: + print("[WARNING] 'git commit' exited with a return code of 1. " + \ + "This usually inidicates that no update was made. Still " + \ + "attempting to create a tag.") + else: + os.chdir(cwd) + return False + + # Setup and run the tag command + tag_cmd = ['git', 'tag', '-a', tag, '-m', tag] + return_code = run_cmd(tag_cmd) + if return_code: + os.chdir(cwd) + return False + + # Setup and run the push command + push_cmd = ['git', 'push', 'origin', 'master'] + return_code = run_cmd(push_cmd) + + if return_code: + os.chdir(cwd) + return False + + push_cmd = ['git', 'push', 'origin', tag] + return_code = run_cmd(push_cmd) + + os.chdir(cwd) + return not return_code + +def create_work_directory(path): + """ Create a new directory specified in 'path', overwrite if the directory already + exists. + + Args: + path - directory path to be created. + + """ + if os.path.exists(path): + print("'%s' directory already exists. Deleting..." % path) + rmtree_readonly(path) + + os.makedirs(path) + +def test_compile(config, tag): + """ For each example repo identified in the config json object, clone, update mbed-os to + the specified tag and then compile for all supported toolchains. + + Args: + config - the json object imported from the file. + tag - GitHub tag corresponding to a version of mbed-os to upgrade to. + results - summary of compilation results. + + """ + # Create work directories + create_work_directory('test_compile') + + # Loop through the examples + results = {} + os.chdir('test_compile') + + lib.source_repos(config) + lib.update_mbedos_version(config, tag) + results = lib.compile_repos(config, SUPPORTED_TOOLCHAINS) + os.chdir("..") + + return results + + +def main(arguments): + + parser = argparse.ArgumentParser(description=__doc__, + formatter_class=argparse.RawDescriptionHelpFormatter) + parser.add_argument('tag', help="mbed-os tag to which all examples will be updated") + parser.add_argument('-c', '--config_file', help="Path to the configuration file (default is 'examples.json')", default='examples.json') + + args = parser.parse_args(arguments) + + cfg = os.path.join(os.path.dirname(__file__), args.config_file) + + # Load the config file + config = json.load(open(os.path.join(os.path.dirname(__file__), + args.config_file))) + + if not config: + print("Failed to load config file '%s'" % args.config_file) + sys.exit(1) + + # Create work directories + create_work_directory('examples') + + # Loop through the examples + failures = [] + successes = [] + not_compiled = [] + results = {} + os.chdir('examples') + + results = test_compile(config, args.tag) + lib.print_compilation_summary(results) + + for example in config['examples']: + # Determine if this example should be updated + + # Attempt to update if: + # group of examples passed compilation and + # auto update is set to True + # Note: results fields are [compiled flag, pass flag, successes list, failures list] + if not results[example['name']][0]: + # Example was not compiled + not_compiled += [example['name']] + else: + if results[example['name']][1] and example['auto-update']: + if upgrade_example(example, args.tag): + successes += [example['name']] + else: + failures += [example['name']] + else: + failures += [example['name']] + + os.chdir('../') + + # Finish the script and report the results + print(os.linesep + os.linesep +'Finished updating examples!' + os.linesep) + + if successes: + print('The following examples updated successfully:') + for success in successes: + print(' - %s' % success) + + if failures: + print('\nThe following examples were not updated:') + for fail in failures: + print(' - %s' % fail) + + if not_compiled: + print('The following examples were skipped:') + for example in not_compiled: + print(' - %s' % example) + + +if __name__ == '__main__': + sys.exit(main(sys.argv[1:])) \ No newline at end of file