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
arm_pack_manager/pack_manager.py@32:8ea194f6145b, 2017-01-04 (annotated)
- 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?
User | Revision | Line number | New contents of line |
---|---|---|---|
The Other Jimmy |
32:8ea194f6145b | 1 | import argparse |
The Other Jimmy |
32:8ea194f6145b | 2 | from os.path import basename |
The Other Jimmy |
32:8ea194f6145b | 3 | from tools.arm_pack_manager import Cache |
The Other Jimmy |
32:8ea194f6145b | 4 | from os.path import basename, join, dirname, exists |
The Other Jimmy |
32:8ea194f6145b | 5 | from os import makedirs |
The Other Jimmy |
32:8ea194f6145b | 6 | from itertools import takewhile |
The Other Jimmy |
32:8ea194f6145b | 7 | from fuzzywuzzy import process |
The Other Jimmy |
32:8ea194f6145b | 8 | from tools.arm_pack_manager import Cache |
The Other Jimmy |
32:8ea194f6145b | 9 | |
The Other Jimmy |
32:8ea194f6145b | 10 | parser = argparse.ArgumentParser(description='A Handy little utility for keeping your cache of pack files up to date.') |
The Other Jimmy |
32:8ea194f6145b | 11 | subparsers = parser.add_subparsers(title="Commands") |
The Other Jimmy |
32:8ea194f6145b | 12 | |
The Other Jimmy |
32:8ea194f6145b | 13 | def subcommand(name, *args, **kwargs): |
The Other Jimmy |
32:8ea194f6145b | 14 | def subcommand(command): |
The Other Jimmy |
32:8ea194f6145b | 15 | subparser = subparsers.add_parser(name, **kwargs) |
The Other Jimmy |
32:8ea194f6145b | 16 | |
The Other Jimmy |
32:8ea194f6145b | 17 | for arg in args: |
The Other Jimmy |
32:8ea194f6145b | 18 | arg = dict(arg) |
The Other Jimmy |
32:8ea194f6145b | 19 | opt = arg['name'] |
The Other Jimmy |
32:8ea194f6145b | 20 | del arg['name'] |
The Other Jimmy |
32:8ea194f6145b | 21 | |
The Other Jimmy |
32:8ea194f6145b | 22 | if isinstance(opt, basestring): |
The Other Jimmy |
32:8ea194f6145b | 23 | subparser.add_argument(opt, **arg) |
The Other Jimmy |
32:8ea194f6145b | 24 | else: |
The Other Jimmy |
32:8ea194f6145b | 25 | subparser.add_argument(*opt, **arg) |
The Other Jimmy |
32:8ea194f6145b | 26 | |
The Other Jimmy |
32:8ea194f6145b | 27 | subparser.add_argument("-v", "--verbose", action="store_true", dest="verbose", help="Verbose diagnostic output") |
The Other Jimmy |
32:8ea194f6145b | 28 | subparser.add_argument("-vv", "--very_verbose", action="store_true", dest="very_verbose", help="Very verbose diagnostic output") |
The Other Jimmy |
32:8ea194f6145b | 29 | subparser.add_argument("--no-timeouts", action="store_true", help="Remove all timeouts and try to download unconditionally") |
The Other Jimmy |
32:8ea194f6145b | 30 | subparser.add_argument("--and", action="store_true", dest="intersection", help="combine search terms as if with an and") |
The Other Jimmy |
32:8ea194f6145b | 31 | subparser.add_argument("--or", action="store_false", dest="intersection", help="combine search terms as if with an or") |
The Other Jimmy |
32:8ea194f6145b | 32 | subparser.add_argument("--union", action="store_false", dest="intersection", help="combine search terms as if with a set union") |
The Other Jimmy |
32:8ea194f6145b | 33 | subparser.add_argument("--intersection", action="store_true", dest="intersection", help="combine search terms as if with a set intersection") |
The Other Jimmy |
32:8ea194f6145b | 34 | |
The Other Jimmy |
32:8ea194f6145b | 35 | def thunk(parsed_args): |
The Other Jimmy |
32:8ea194f6145b | 36 | cache = Cache(not parsed_args.verbose, parsed_args.no_timeouts) |
The Other Jimmy |
32:8ea194f6145b | 37 | argv = [arg['dest'] if 'dest' in arg else arg['name'] for arg in args] |
The Other Jimmy |
32:8ea194f6145b | 38 | argv = [(arg if isinstance(arg, basestring) else arg[-1]).strip('-') |
The Other Jimmy |
32:8ea194f6145b | 39 | for arg in argv] |
The Other Jimmy |
32:8ea194f6145b | 40 | argv = {arg: vars(parsed_args)[arg] for arg in argv |
The Other Jimmy |
32:8ea194f6145b | 41 | if vars(parsed_args)[arg] is not None} |
The Other Jimmy |
32:8ea194f6145b | 42 | |
The Other Jimmy |
32:8ea194f6145b | 43 | return command(cache, **argv) |
The Other Jimmy |
32:8ea194f6145b | 44 | |
The Other Jimmy |
32:8ea194f6145b | 45 | subparser.set_defaults(command=thunk) |
The Other Jimmy |
32:8ea194f6145b | 46 | return command |
The Other Jimmy |
32:8ea194f6145b | 47 | return subcommand |
The Other Jimmy |
32:8ea194f6145b | 48 | |
The Other Jimmy |
32:8ea194f6145b | 49 | def user_selection (message, options) : |
The Other Jimmy |
32:8ea194f6145b | 50 | print(message) |
The Other Jimmy |
32:8ea194f6145b | 51 | for choice, index in zip(options, range(len(options))) : |
The Other Jimmy |
32:8ea194f6145b | 52 | print("({}) {}".format(index, choice)) |
The Other Jimmy |
32:8ea194f6145b | 53 | pick = None |
The Other Jimmy |
32:8ea194f6145b | 54 | while pick is None : |
The Other Jimmy |
32:8ea194f6145b | 55 | stdout.write("please select an integer from 0 to {} or \"all\"".format(len(options)-1)) |
The Other Jimmy |
32:8ea194f6145b | 56 | input = raw_input() |
The Other Jimmy |
32:8ea194f6145b | 57 | try : |
The Other Jimmy |
32:8ea194f6145b | 58 | if input == "all" : |
The Other Jimmy |
32:8ea194f6145b | 59 | pick = options |
The Other Jimmy |
32:8ea194f6145b | 60 | else : |
The Other Jimmy |
32:8ea194f6145b | 61 | pick = [options[int(input)]] |
The Other Jimmy |
32:8ea194f6145b | 62 | except ValueError : |
The Other Jimmy |
32:8ea194f6145b | 63 | print("I did not understand your input") |
The Other Jimmy |
32:8ea194f6145b | 64 | return pick |
The Other Jimmy |
32:8ea194f6145b | 65 | |
The Other Jimmy |
32:8ea194f6145b | 66 | def fuzzy_find(matches, urls) : |
The Other Jimmy |
32:8ea194f6145b | 67 | choices = {} |
The Other Jimmy |
32:8ea194f6145b | 68 | for match in matches : |
The Other Jimmy |
32:8ea194f6145b | 69 | for key, value in process.extract(match, urls, limit=None) : |
The Other Jimmy |
32:8ea194f6145b | 70 | choices.setdefault(key, 0) |
The Other Jimmy |
32:8ea194f6145b | 71 | choices[key] += value |
The Other Jimmy |
32:8ea194f6145b | 72 | choices = sorted([(v, k) for k, v in choices.iteritems()], reverse=True) |
The Other Jimmy |
32:8ea194f6145b | 73 | if not choices : return [] |
The Other Jimmy |
32:8ea194f6145b | 74 | elif len(choices) == 1 : return [choices[0][1]] |
The Other Jimmy |
32:8ea194f6145b | 75 | elif choices[0][0] > choices[1][0] : choices = choices[:1] |
The Other Jimmy |
32:8ea194f6145b | 76 | else : choices = list(takewhile(lambda t: t[0] == choices[0][0], choices)) |
The Other Jimmy |
32:8ea194f6145b | 77 | return [v for k,v in choices] |
The Other Jimmy |
32:8ea194f6145b | 78 | |
The Other Jimmy |
32:8ea194f6145b | 79 | @subcommand('cache', |
The Other Jimmy |
32:8ea194f6145b | 80 | dict(name='matches', nargs="*", |
The Other Jimmy |
32:8ea194f6145b | 81 | help="a bunch of things to search for in part names"), |
The Other Jimmy |
32:8ea194f6145b | 82 | dict(name=['-e','--everything'], action="store_true", |
The Other Jimmy |
32:8ea194f6145b | 83 | help="download everything possible"), |
The Other Jimmy |
32:8ea194f6145b | 84 | dict(name=['-d','--descriptors'], action="store_true", |
The Other Jimmy |
32:8ea194f6145b | 85 | help="download all descriptors"), |
The Other Jimmy |
32:8ea194f6145b | 86 | dict(name=["-b","--batch"], action="store_true", |
The Other Jimmy |
32:8ea194f6145b | 87 | help="don't ask for user input and assume download all"), |
The Other Jimmy |
32:8ea194f6145b | 88 | help="Cache a group of PACK or PDSC files") |
The Other Jimmy |
32:8ea194f6145b | 89 | def command_cache (cache, matches, everything=False, descriptors=False, batch=False, verbose= False, intersection=True) : |
The Other Jimmy |
32:8ea194f6145b | 90 | if everything : |
The Other Jimmy |
32:8ea194f6145b | 91 | cache.cache_everything() |
The Other Jimmy |
32:8ea194f6145b | 92 | return True |
The Other Jimmy |
32:8ea194f6145b | 93 | if descriptors : |
The Other Jimmy |
32:8ea194f6145b | 94 | cache.cache_descriptors() |
The Other Jimmy |
32:8ea194f6145b | 95 | return True |
The Other Jimmy |
32:8ea194f6145b | 96 | if not matches : |
The Other Jimmy |
32:8ea194f6145b | 97 | print("No action specified nothing to do") |
The Other Jimmy |
32:8ea194f6145b | 98 | else : |
The Other Jimmy |
32:8ea194f6145b | 99 | urls = cache.get_urls() |
The Other Jimmy |
32:8ea194f6145b | 100 | if intersection : |
The Other Jimmy |
32:8ea194f6145b | 101 | choices = fuzzy_find(matches, map(basename, urls)) |
The Other Jimmy |
32:8ea194f6145b | 102 | else : |
The Other Jimmy |
32:8ea194f6145b | 103 | choices = sum([fuzzy_find([m], map(basename, urls)) for m in matches], []) |
The Other Jimmy |
32:8ea194f6145b | 104 | if not batch and len(choices) > 1 : |
The Other Jimmy |
32:8ea194f6145b | 105 | choices = user_selection("Please select a file to cache", choices) |
The Other Jimmy |
32:8ea194f6145b | 106 | to_download = [] |
The Other Jimmy |
32:8ea194f6145b | 107 | for choice in choices : |
The Other Jimmy |
32:8ea194f6145b | 108 | for url in urls : |
The Other Jimmy |
32:8ea194f6145b | 109 | if choice in url : |
The Other Jimmy |
32:8ea194f6145b | 110 | to_download.append(url) |
The Other Jimmy |
32:8ea194f6145b | 111 | cache.cache_pack_list(to_download) |
The Other Jimmy |
32:8ea194f6145b | 112 | return True |
The Other Jimmy |
32:8ea194f6145b | 113 | |
The Other Jimmy |
32:8ea194f6145b | 114 | |
The Other Jimmy |
32:8ea194f6145b | 115 | @subcommand('find-part', |
The Other Jimmy |
32:8ea194f6145b | 116 | dict(name='matches', nargs="+", help="words to match to processors"), |
The Other Jimmy |
32:8ea194f6145b | 117 | dict(name=['-l',"--long"], action="store_true", |
The Other Jimmy |
32:8ea194f6145b | 118 | help="print out part details with part"), |
The Other Jimmy |
32:8ea194f6145b | 119 | dict(name=['-p', '--parts-only'], action="store_false", dest="print_aliases"), |
The Other Jimmy |
32:8ea194f6145b | 120 | dict(name=['-a', '--aliases-only'], action="store_false", dest="print_parts"), |
The Other Jimmy |
32:8ea194f6145b | 121 | help="Find a Part and it's description within the cache") |
The Other Jimmy |
32:8ea194f6145b | 122 | def command_find_part (cache, matches, long=False, intersection=True, |
The Other Jimmy |
32:8ea194f6145b | 123 | print_aliases=True, print_parts=True) : |
The Other Jimmy |
32:8ea194f6145b | 124 | if long : |
The Other Jimmy |
32:8ea194f6145b | 125 | import pprint |
The Other Jimmy |
32:8ea194f6145b | 126 | pp = pprint.PrettyPrinter() |
The Other Jimmy |
32:8ea194f6145b | 127 | parts = cache.index |
The Other Jimmy |
32:8ea194f6145b | 128 | if intersection : |
The Other Jimmy |
32:8ea194f6145b | 129 | choices = fuzzy_find(matches, parts.keys()) |
The Other Jimmy |
32:8ea194f6145b | 130 | aliases = fuzzy_find(matches, cache.aliases.keys()) |
The Other Jimmy |
32:8ea194f6145b | 131 | else : |
The Other Jimmy |
32:8ea194f6145b | 132 | choices = sum([fuzzy_find([m], parts.keys()) for m in matches], []) |
The Other Jimmy |
32:8ea194f6145b | 133 | aliases = sum([fuzzy_find([m], cache.aliases.keys()) for m in matches], []) |
The Other Jimmy |
32:8ea194f6145b | 134 | if print_parts: |
The Other Jimmy |
32:8ea194f6145b | 135 | for part in choices : |
The Other Jimmy |
32:8ea194f6145b | 136 | print part |
The Other Jimmy |
32:8ea194f6145b | 137 | if long : |
The Other Jimmy |
32:8ea194f6145b | 138 | pp.pprint(cache.index[part]) |
The Other Jimmy |
32:8ea194f6145b | 139 | if print_aliases: |
The Other Jimmy |
32:8ea194f6145b | 140 | for alias in aliases : |
The Other Jimmy |
32:8ea194f6145b | 141 | print alias |
The Other Jimmy |
32:8ea194f6145b | 142 | if long : |
The Other Jimmy |
32:8ea194f6145b | 143 | pp.pprint(cache.index[cache.aliases[alias]]) |
The Other Jimmy |
32:8ea194f6145b | 144 | |
The Other Jimmy |
32:8ea194f6145b | 145 | @subcommand('dump-parts', |
The Other Jimmy |
32:8ea194f6145b | 146 | dict(name='out', help='directory to dump to'), |
The Other Jimmy |
32:8ea194f6145b | 147 | dict(name='parts', nargs='+', help='parts to dump'), |
The Other Jimmy |
32:8ea194f6145b | 148 | help='Create a directory with an index.json describing the part and all of their associated flashing algorithms.' |
The Other Jimmy |
32:8ea194f6145b | 149 | ) |
The Other Jimmy |
32:8ea194f6145b | 150 | def command_dump_parts (cache, out, parts, intersection=False) : |
The Other Jimmy |
32:8ea194f6145b | 151 | index = {} |
The Other Jimmy |
32:8ea194f6145b | 152 | if intersection : |
The Other Jimmy |
32:8ea194f6145b | 153 | for part in fuzzy_find(parts, cache.index): |
The Other Jimmy |
32:8ea194f6145b | 154 | index.update(cache.index[part]) |
The Other Jimmy |
32:8ea194f6145b | 155 | else : |
The Other Jimmy |
32:8ea194f6145b | 156 | for part in parts : |
The Other Jimmy |
32:8ea194f6145b | 157 | index.update(dict(cache.find_device(part))) |
The Other Jimmy |
32:8ea194f6145b | 158 | for n, p in index.iteritems() : |
The Other Jimmy |
32:8ea194f6145b | 159 | try : |
The Other Jimmy |
32:8ea194f6145b | 160 | if not exists(join(out, dirname(p['algorithm']['file']))) : |
The Other Jimmy |
32:8ea194f6145b | 161 | makedirs(join(out, dirname(p['algorithm']['file']))) |
The Other Jimmy |
32:8ea194f6145b | 162 | with open(join(out, p['algorithm']['file']), "wb+") as fd : |
The Other Jimmy |
32:8ea194f6145b | 163 | fd.write(cache.get_flash_algorthim_binary(n).read()) |
The Other Jimmy |
32:8ea194f6145b | 164 | except KeyError: |
The Other Jimmy |
32:8ea194f6145b | 165 | print("[Warning] {} does not have an associated flashing algorithm".format(n)) |
The Other Jimmy |
32:8ea194f6145b | 166 | with open(join(out, "index.json"), "wb+") as fd : |
The Other Jimmy |
32:8ea194f6145b | 167 | dump(index,fd) |
The Other Jimmy |
32:8ea194f6145b | 168 | |
The Other Jimmy |
32:8ea194f6145b | 169 | |
The Other Jimmy |
32:8ea194f6145b | 170 | @subcommand('cache-part', |
The Other Jimmy |
32:8ea194f6145b | 171 | dict(name='matches', nargs="+", help="words to match to devices"), |
The Other Jimmy |
32:8ea194f6145b | 172 | help='Cache PACK files associated with the parts matching the provided words') |
The Other Jimmy |
32:8ea194f6145b | 173 | def command_cache_part (cache, matches, intersection=True) : |
The Other Jimmy |
32:8ea194f6145b | 174 | index = cache.index |
The Other Jimmy |
32:8ea194f6145b | 175 | if intersection : |
The Other Jimmy |
32:8ea194f6145b | 176 | choices = fuzzy_find(matches, index.keys()) |
The Other Jimmy |
32:8ea194f6145b | 177 | aliases = fuzzy_find(matches, cache.aliases.keys()) |
The Other Jimmy |
32:8ea194f6145b | 178 | else : |
The Other Jimmy |
32:8ea194f6145b | 179 | choices = sum([fuzzy_find([m], index.keys()) for m in matches], []) |
The Other Jimmy |
32:8ea194f6145b | 180 | aliases = sum([fuzzy_find([m], cache.aliases.keys()) for m in matches], []) |
The Other Jimmy |
32:8ea194f6145b | 181 | urls = set([index[c]['pdsc_file'] for c in choices]) |
The Other Jimmy |
32:8ea194f6145b | 182 | urls += set([index[cache.aliasse[a]] for a in aliases]) |
The Other Jimmy |
32:8ea194f6145b | 183 | cache.cache_pack_list(list(urls)) |
The Other Jimmy |
32:8ea194f6145b | 184 | |
The Other Jimmy |
32:8ea194f6145b | 185 | def get_argparse() : |
The Other Jimmy |
32:8ea194f6145b | 186 | return parser |
The Other Jimmy |
32:8ea194f6145b | 187 | |
The Other Jimmy |
32:8ea194f6145b | 188 | def main() : |
The Other Jimmy |
32:8ea194f6145b | 189 | args = parser.parse_args() |
The Other Jimmy |
32:8ea194f6145b | 190 | args.command(args) |
The Other Jimmy |
32:8ea194f6145b | 191 |