Development mbed library for MAX32630FTHR
Dependents: blinky_max32630fthr
tools/test/examples/update.py
- Committer:
- switches
- Date:
- 2016-11-11
- Revision:
- 0:5c4d7b2438d3
File content as of revision 0:5c4d7b2438d3:
#!/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:]))