diff options
author | Paul Eggleton <paul.eggleton@linux.intel.com> | 2015-02-20 17:52:41 +0000 |
---|---|---|
committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2015-02-21 22:05:37 +0000 |
commit | 4a32837971100fdaf62a544ba9fc651837a6dbcc (patch) | |
tree | 5d42f5e639ccb44d619acb7b2f99543508ee5f3c /bitbake/bin | |
parent | 68f4dcae68f0f99625f9de019eadc4e22d88777e (diff) | |
download | poky-4a32837971100fdaf62a544ba9fc651837a6dbcc.tar.gz |
bitbake: bitbake-layers: refactor to use argparse instead of cmd
This makes help formatting and option handling a lot more standardised
and allows us to drop a bunch of code. We also gain slightly more
straightforward error handling.
One side-effect however is that the old subcommand syntax using
underscores is no longer supported. The dashed form has been supported
(and displayed in the help text) for quite a while now so I wouldn't
imagine that will be much of an issue.
(Bitbake rev: 6e2f09b58882d3949026b9dd545f789ad3fe6fab)
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'bitbake/bin')
-rwxr-xr-x | bitbake/bin/bitbake-layers | 261 |
1 files changed, 110 insertions, 151 deletions
diff --git a/bitbake/bin/bitbake-layers b/bitbake/bin/bitbake-layers index 98794981a0..2622bc0927 100755 --- a/bitbake/bin/bitbake-layers +++ b/bitbake/bin/bitbake-layers | |||
@@ -5,7 +5,7 @@ | |||
5 | # See the help output for details on available commands. | 5 | # See the help output for details on available commands. |
6 | 6 | ||
7 | # Copyright (C) 2011 Mentor Graphics Corporation | 7 | # Copyright (C) 2011 Mentor Graphics Corporation |
8 | # Copyright (C) 2012 Intel Corporation | 8 | # Copyright (C) 2011-2015 Intel Corporation |
9 | # | 9 | # |
10 | # This program is free software; you can redistribute it and/or modify | 10 | # This program is free software; you can redistribute it and/or modify |
11 | # it under the terms of the GNU General Public License version 2 as | 11 | # it under the terms of the GNU General Public License version 2 as |
@@ -20,12 +20,12 @@ | |||
20 | # with this program; if not, write to the Free Software Foundation, Inc., | 20 | # with this program; if not, write to the Free Software Foundation, Inc., |
21 | # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | 21 | # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
22 | 22 | ||
23 | import cmd | ||
24 | import logging | 23 | import logging |
25 | import os | 24 | import os |
26 | import sys | 25 | import sys |
27 | import fnmatch | 26 | import fnmatch |
28 | from collections import defaultdict | 27 | from collections import defaultdict |
28 | import argparse | ||
29 | import re | 29 | import re |
30 | 30 | ||
31 | bindir = os.path.dirname(__file__) | 31 | bindir = os.path.dirname(__file__) |
@@ -42,23 +42,11 @@ import bb.tinfoil | |||
42 | logger = logging.getLogger('BitBake') | 42 | logger = logging.getLogger('BitBake') |
43 | 43 | ||
44 | 44 | ||
45 | def main(args): | ||
46 | cmds = Commands() | ||
47 | if args: | ||
48 | # Allow user to specify e.g. show-layers instead of show_layers | ||
49 | args = [args[0].replace('-', '_')] + args[1:] | ||
50 | cmds.onecmd(' '.join(args)) | ||
51 | else: | ||
52 | cmds.do_help('') | ||
53 | return cmds.returncode | ||
54 | |||
55 | 45 | ||
56 | class Commands(cmd.Cmd): | 46 | class Commands(): |
57 | def __init__(self): | 47 | def __init__(self): |
58 | self.bbhandler = None | 48 | self.bbhandler = None |
59 | self.returncode = 0 | ||
60 | self.bblayers = [] | 49 | self.bblayers = [] |
61 | cmd.Cmd.__init__(self) | ||
62 | 50 | ||
63 | def init_bbhandler(self, config_only = False): | 51 | def init_bbhandler(self, config_only = False): |
64 | if not self.bbhandler: | 52 | if not self.bbhandler: |
@@ -66,27 +54,6 @@ class Commands(cmd.Cmd): | |||
66 | self.bblayers = (self.bbhandler.config_data.getVar('BBLAYERS', True) or "").split() | 54 | self.bblayers = (self.bbhandler.config_data.getVar('BBLAYERS', True) or "").split() |
67 | self.bbhandler.prepare(config_only) | 55 | self.bbhandler.prepare(config_only) |
68 | 56 | ||
69 | def default(self, line): | ||
70 | """Handle unrecognised commands""" | ||
71 | sys.stderr.write("Unrecognised command or option\n") | ||
72 | self.do_help('') | ||
73 | |||
74 | def do_help(self, topic): | ||
75 | """display general help or help on a specified command""" | ||
76 | if topic: | ||
77 | sys.stdout.write('%s: ' % topic) | ||
78 | cmd.Cmd.do_help(self, topic.replace('-', '_')) | ||
79 | else: | ||
80 | sys.stdout.write("usage: bitbake-layers <command> [arguments]\n\n") | ||
81 | sys.stdout.write("Available commands:\n") | ||
82 | procnames = list(set(self.get_names())) | ||
83 | for procname in procnames: | ||
84 | if procname[:3] == 'do_': | ||
85 | sys.stdout.write(" %s\n" % procname[3:].replace('_', '-')) | ||
86 | doc = getattr(self, procname).__doc__ | ||
87 | if doc: | ||
88 | sys.stdout.write(" %s\n" % doc.splitlines()[0]) | ||
89 | |||
90 | def do_show_layers(self, args): | 57 | def do_show_layers(self, args): |
91 | """show current configured layers""" | 58 | """show current configured layers""" |
92 | self.init_bbhandler(config_only = True) | 59 | self.init_bbhandler(config_only = True) |
@@ -103,29 +70,25 @@ class Commands(cmd.Cmd): | |||
103 | logger.plain("%s %s %d" % (layername.ljust(20), layerdir.ljust(40), layerpri)) | 70 | logger.plain("%s %s %d" % (layername.ljust(20), layerdir.ljust(40), layerpri)) |
104 | 71 | ||
105 | 72 | ||
106 | def do_add_layer(self, dirname): | 73 | def do_add_layer(self, args): |
107 | """Add a layer to bblayers.conf | 74 | """Add a layer to bblayers.conf |
108 | 75 | ||
109 | usage: add-layer <layerdir> | 76 | Adds the specified layer to bblayers.conf |
110 | """ | 77 | """ |
111 | if not dirname: | 78 | layerdir = os.path.abspath(args.layerdir) |
112 | sys.stderr.write("Please specify the layer directory to add\n") | ||
113 | return | ||
114 | |||
115 | layerdir = os.path.abspath(dirname) | ||
116 | if not os.path.exists(layerdir): | 79 | if not os.path.exists(layerdir): |
117 | sys.stderr.write("Specified layer directory doesn't exist\n") | 80 | sys.stderr.write("Specified layer directory doesn't exist\n") |
118 | return | 81 | return 1 |
119 | 82 | ||
120 | layer_conf = os.path.join(layerdir, 'conf', 'layer.conf') | 83 | layer_conf = os.path.join(layerdir, 'conf', 'layer.conf') |
121 | if not os.path.exists(layer_conf): | 84 | if not os.path.exists(layer_conf): |
122 | sys.stderr.write("Specified layer directory doesn't contain a conf/layer.conf file\n") | 85 | sys.stderr.write("Specified layer directory doesn't contain a conf/layer.conf file\n") |
123 | return | 86 | return 1 |
124 | 87 | ||
125 | bblayers_conf = os.path.join('conf', 'bblayers.conf') | 88 | bblayers_conf = os.path.join('conf', 'bblayers.conf') |
126 | if not os.path.exists(bblayers_conf): | 89 | if not os.path.exists(bblayers_conf): |
127 | sys.stderr.write("Unable to find bblayers.conf\n") | 90 | sys.stderr.write("Unable to find bblayers.conf\n") |
128 | return | 91 | return 1 |
129 | 92 | ||
130 | (notadded, _) = bb.utils.edit_bblayers_conf(bblayers_conf, layerdir, None) | 93 | (notadded, _) = bb.utils.edit_bblayers_conf(bblayers_conf, layerdir, None) |
131 | if notadded: | 94 | if notadded: |
@@ -133,28 +96,25 @@ usage: add-layer <layerdir> | |||
133 | sys.stderr.write("Specified layer %s is already in BBLAYERS\n" % item) | 96 | sys.stderr.write("Specified layer %s is already in BBLAYERS\n" % item) |
134 | 97 | ||
135 | 98 | ||
136 | def do_remove_layer(self, dirname): | 99 | def do_remove_layer(self, args): |
137 | """Remove a layer from bblayers.conf | 100 | """Remove a layer from bblayers.conf |
138 | 101 | ||
139 | usage: remove-layer <layerdir> | 102 | Removes the specified layer from bblayers.conf |
140 | """ | 103 | """ |
141 | if not dirname: | ||
142 | sys.stderr.write("Please specify the layer directory to remove\n") | ||
143 | return | ||
144 | |||
145 | bblayers_conf = os.path.join('conf', 'bblayers.conf') | 104 | bblayers_conf = os.path.join('conf', 'bblayers.conf') |
146 | if not os.path.exists(bblayers_conf): | 105 | if not os.path.exists(bblayers_conf): |
147 | sys.stderr.write("Unable to find bblayers.conf\n") | 106 | sys.stderr.write("Unable to find bblayers.conf\n") |
148 | return | 107 | return 1 |
149 | 108 | ||
150 | if dirname.startswith('*'): | 109 | if args.layerdir.startswith('*'): |
151 | layerdir = dirname | 110 | layerdir = dirname |
152 | else: | 111 | else: |
153 | layerdir = os.path.abspath(dirname) | 112 | layerdir = os.path.abspath(args.layerdir) |
154 | (_, notremoved) = bb.utils.edit_bblayers_conf(bblayers_conf, None, layerdir) | 113 | (_, notremoved) = bb.utils.edit_bblayers_conf(bblayers_conf, None, layerdir) |
155 | if notremoved: | 114 | if notremoved: |
156 | for item in notremoved: | 115 | for item in notremoved: |
157 | sys.stderr.write("No layers matching %s found in BBLAYERS\n" % item) | 116 | sys.stderr.write("No layers matching %s found in BBLAYERS\n" % item) |
117 | return 1 | ||
158 | 118 | ||
159 | 119 | ||
160 | def version_str(self, pe, pv, pr = None): | 120 | def version_str(self, pe, pv, pr = None): |
@@ -169,32 +129,13 @@ usage: remove-layer <layerdir> | |||
169 | def do_show_overlayed(self, args): | 129 | def do_show_overlayed(self, args): |
170 | """list overlayed recipes (where the same recipe exists in another layer) | 130 | """list overlayed recipes (where the same recipe exists in another layer) |
171 | 131 | ||
172 | usage: show-overlayed [-f] [-s] | ||
173 | |||
174 | Lists the names of overlayed recipes and the available versions in each | 132 | Lists the names of overlayed recipes and the available versions in each |
175 | layer, with the preferred version first. Note that skipped recipes that | 133 | layer, with the preferred version first. Note that skipped recipes that |
176 | are overlayed will also be listed, with a " (skipped)" suffix. | 134 | are overlayed will also be listed, with a " (skipped)" suffix. |
177 | |||
178 | Options: | ||
179 | -f instead of the default formatting, list filenames of higher priority | ||
180 | recipes with the ones they overlay indented underneath | ||
181 | -s only list overlayed recipes where the version is the same | ||
182 | """ | 135 | """ |
183 | self.init_bbhandler() | 136 | self.init_bbhandler() |
184 | 137 | ||
185 | show_filenames = False | 138 | items_listed = self.list_recipes('Overlayed recipes', None, True, args.same_version, args.filenames, True) |
186 | show_same_ver_only = False | ||
187 | for arg in args.split(): | ||
188 | if arg == '-f': | ||
189 | show_filenames = True | ||
190 | elif arg == '-s': | ||
191 | show_same_ver_only = True | ||
192 | else: | ||
193 | sys.stderr.write("show-overlayed: invalid option %s\n" % arg) | ||
194 | self.do_help('') | ||
195 | return | ||
196 | |||
197 | items_listed = self.list_recipes('Overlayed recipes', None, True, show_same_ver_only, show_filenames, True) | ||
198 | 139 | ||
199 | # Check for overlayed .bbclass files | 140 | # Check for overlayed .bbclass files |
200 | classes = defaultdict(list) | 141 | classes = defaultdict(list) |
@@ -221,7 +162,7 @@ Options: | |||
221 | overlayed_class_found = True | 162 | overlayed_class_found = True |
222 | 163 | ||
223 | mainfile = bb.utils.which(bbpath, os.path.join('classes', classfile)) | 164 | mainfile = bb.utils.which(bbpath, os.path.join('classes', classfile)) |
224 | if show_filenames: | 165 | if args.filenames: |
225 | logger.plain('%s' % mainfile) | 166 | logger.plain('%s' % mainfile) |
226 | else: | 167 | else: |
227 | # We effectively have to guess the layer here | 168 | # We effectively have to guess the layer here |
@@ -235,7 +176,7 @@ Options: | |||
235 | for classdir in classdirs: | 176 | for classdir in classdirs: |
236 | fullpath = os.path.join(classdir, classfile) | 177 | fullpath = os.path.join(classdir, classfile) |
237 | if fullpath != mainfile: | 178 | if fullpath != mainfile: |
238 | if show_filenames: | 179 | if args.filenames: |
239 | print(' %s' % fullpath) | 180 | print(' %s' % fullpath) |
240 | else: | 181 | else: |
241 | print(' %s' % self.get_layer_name(os.path.dirname(classdir))) | 182 | print(' %s' % self.get_layer_name(os.path.dirname(classdir))) |
@@ -250,38 +191,15 @@ Options: | |||
250 | def do_show_recipes(self, args): | 191 | def do_show_recipes(self, args): |
251 | """list available recipes, showing the layer they are provided by | 192 | """list available recipes, showing the layer they are provided by |
252 | 193 | ||
253 | usage: show-recipes [-f] [-m] [pnspec] | 194 | Lists the names of recipes and the available versions in each |
254 | |||
255 | Lists the names of overlayed recipes and the available versions in each | ||
256 | layer, with the preferred version first. Optionally you may specify | 195 | layer, with the preferred version first. Optionally you may specify |
257 | pnspec to match a specified recipe name (supports wildcards). Note that | 196 | pnspec to match a specified recipe name (supports wildcards). Note that |
258 | skipped recipes will also be listed, with a " (skipped)" suffix. | 197 | skipped recipes will also be listed, with a " (skipped)" suffix. |
259 | |||
260 | Options: | ||
261 | -f instead of the default formatting, list filenames of higher priority | ||
262 | recipes with other available recipes indented underneath | ||
263 | -m only list where multiple recipes (in the same layer or different | ||
264 | layers) exist for the same recipe name | ||
265 | """ | 198 | """ |
266 | self.init_bbhandler() | 199 | self.init_bbhandler() |
267 | 200 | ||
268 | show_filenames = False | ||
269 | show_multi_provider_only = False | ||
270 | pnspec = None | ||
271 | title = 'Available recipes:' | 201 | title = 'Available recipes:' |
272 | for arg in args.split(): | 202 | self.list_recipes(title, args.pnspec, False, False, args.filenames, args.multiple) |
273 | if arg == '-f': | ||
274 | show_filenames = True | ||
275 | elif arg == '-m': | ||
276 | show_multi_provider_only = True | ||
277 | elif not arg.startswith('-'): | ||
278 | pnspec = arg | ||
279 | title = 'Available recipes matching %s:' % pnspec | ||
280 | else: | ||
281 | sys.stderr.write("show-recipes: invalid option %s\n" % arg) | ||
282 | self.do_help('') | ||
283 | return | ||
284 | self.list_recipes(title, pnspec, False, False, show_filenames, show_multi_provider_only) | ||
285 | 203 | ||
286 | 204 | ||
287 | def list_recipes(self, title, pnspec, show_overlayed_only, show_same_ver_only, show_filenames, show_multi_provider_only): | 205 | def list_recipes(self, title, pnspec, show_overlayed_only, show_same_ver_only, show_filenames, show_multi_provider_only): |
@@ -361,9 +279,7 @@ Options: | |||
361 | 279 | ||
362 | 280 | ||
363 | def do_flatten(self, args): | 281 | def do_flatten(self, args): |
364 | """flattens layer configuration into a separate output directory. | 282 | """flatten layer configuration into a separate output directory. |
365 | |||
366 | usage: flatten [layer1 layer2 [layer3]...] <outputdir> | ||
367 | 283 | ||
368 | Takes the specified layers (or all layers in the current layer | 284 | Takes the specified layers (or all layers in the current layer |
369 | configuration if none are specified) and builds a "flattened" directory | 285 | configuration if none are specified) and builds a "flattened" directory |
@@ -385,26 +301,19 @@ bbappends in the layers interact, and then attempt to use the new output | |||
385 | layer together with that other layer, you may no longer get the same | 301 | layer together with that other layer, you may no longer get the same |
386 | build results (as the layer priority order has effectively changed). | 302 | build results (as the layer priority order has effectively changed). |
387 | """ | 303 | """ |
388 | arglist = args.split() | 304 | if len(args.layer) == 1: |
389 | if len(arglist) < 1: | ||
390 | logger.error('Please specify an output directory') | ||
391 | self.do_help('flatten') | ||
392 | return | ||
393 | |||
394 | if len(arglist) == 2: | ||
395 | logger.error('If you specify layers to flatten you must specify at least two') | 305 | logger.error('If you specify layers to flatten you must specify at least two') |
396 | self.do_help('flatten') | 306 | return 1 |
397 | return | ||
398 | 307 | ||
399 | outputdir = arglist[-1] | 308 | outputdir = args.outputdir |
400 | if os.path.exists(outputdir) and os.listdir(outputdir): | 309 | if os.path.exists(outputdir) and os.listdir(outputdir): |
401 | logger.error('Directory %s exists and is non-empty, please clear it out first' % outputdir) | 310 | logger.error('Directory %s exists and is non-empty, please clear it out first' % outputdir) |
402 | return | 311 | return 1 |
403 | 312 | ||
404 | self.init_bbhandler() | 313 | self.init_bbhandler() |
405 | layers = self.bblayers | 314 | layers = self.bblayers |
406 | if len(arglist) > 2: | 315 | if len(args.layer) > 2: |
407 | layernames = arglist[:-1] | 316 | layernames = args.layer |
408 | found_layernames = [] | 317 | found_layernames = [] |
409 | found_layerdirs = [] | 318 | found_layerdirs = [] |
410 | for layerdir in layers: | 319 | for layerdir in layers: |
@@ -553,14 +462,12 @@ build results (as the layer priority order has effectively changed). | |||
553 | def do_show_appends(self, args): | 462 | def do_show_appends(self, args): |
554 | """list bbappend files and recipe files they apply to | 463 | """list bbappend files and recipe files they apply to |
555 | 464 | ||
556 | usage: show-appends | 465 | Lists recipes with the bbappends that apply to them as subitems. |
557 | |||
558 | Recipes are listed with the bbappends that apply to them as subitems. | ||
559 | """ | 466 | """ |
560 | self.init_bbhandler() | 467 | self.init_bbhandler() |
561 | if not self.bbhandler.cooker.collection.appendlist: | 468 | if not self.bbhandler.cooker.collection.appendlist: |
562 | logger.plain('No append files found') | 469 | logger.plain('No append files found') |
563 | return | 470 | return 0 |
564 | 471 | ||
565 | logger.plain('=== Appended recipes ===') | 472 | logger.plain('=== Appended recipes ===') |
566 | 473 | ||
@@ -599,7 +506,6 @@ Recipes are listed with the bbappends that apply to them as subitems. | |||
599 | if best_filename in missing: | 506 | if best_filename in missing: |
600 | logger.warn('%s: missing append for preferred version', | 507 | logger.warn('%s: missing append for preferred version', |
601 | best_filename) | 508 | best_filename) |
602 | self.returncode |= 1 | ||
603 | 509 | ||
604 | 510 | ||
605 | def get_appends_for_files(self, filenames): | 511 | def get_appends_for_files(self, filenames): |
@@ -618,29 +524,13 @@ Recipes are listed with the bbappends that apply to them as subitems. | |||
618 | return appended, notappended | 524 | return appended, notappended |
619 | 525 | ||
620 | def do_show_cross_depends(self, args): | 526 | def do_show_cross_depends(self, args): |
621 | """figure out the dependency between recipes that crosses a layer boundary. | 527 | """Show dependencies between recipes that cross layer boundaries. |
622 | |||
623 | usage: show-cross-depends [-f] [-i layer1[,layer2[,layer3...]]] | ||
624 | 528 | ||
625 | Figure out the dependency between recipes that crosses a layer boundary. | 529 | Figure out the dependencies between recipes that cross layer boundaries. |
626 | 530 | ||
627 | Options: | 531 | NOTE: .bbappend files can impact the dependencies. |
628 | -f show full file path | ||
629 | -i ignore dependencies on items in the specified layer(s) | ||
630 | |||
631 | NOTE: | ||
632 | The .bbappend file can impact the dependency. | ||
633 | """ | 532 | """ |
634 | import optparse | 533 | ignore_layers = (args.ignore or '').split(',') |
635 | |||
636 | parser = optparse.OptionParser(usage="show-cross-depends [-f] [-i layer1[,layer2[,layer3...]]]") | ||
637 | parser.add_option("-f", "", | ||
638 | action="store_true", dest="show_filenames") | ||
639 | parser.add_option("-i", "", | ||
640 | action="store", dest="ignore_layers", default="") | ||
641 | |||
642 | options, args = parser.parse_args(sys.argv) | ||
643 | ignore_layers = options.ignore_layers.split(',') | ||
644 | 534 | ||
645 | self.init_bbhandler() | 535 | self.init_bbhandler() |
646 | 536 | ||
@@ -666,7 +556,7 @@ The .bbappend file can impact the dependency. | |||
666 | self.bbhandler.config_data, | 556 | self.bbhandler.config_data, |
667 | self.bbhandler.cooker_data, | 557 | self.bbhandler.cooker_data, |
668 | self.bbhandler.cooker_data.pkg_pn) | 558 | self.bbhandler.cooker_data.pkg_pn) |
669 | self.check_cross_depends("DEPENDS", layername, f, best[3], options.show_filenames, ignore_layers) | 559 | self.check_cross_depends("DEPENDS", layername, f, best[3], args.filenames, ignore_layers) |
670 | 560 | ||
671 | # The RDPENDS | 561 | # The RDPENDS |
672 | all_rdeps = self.bbhandler.cooker_data.rundeps[f].values() | 562 | all_rdeps = self.bbhandler.cooker_data.rundeps[f].values() |
@@ -686,7 +576,7 @@ The .bbappend file can impact the dependency. | |||
686 | best = bb.providers.filterProvidersRunTime(all_p, rdep, | 576 | best = bb.providers.filterProvidersRunTime(all_p, rdep, |
687 | self.bbhandler.config_data, | 577 | self.bbhandler.config_data, |
688 | self.bbhandler.cooker_data)[0][0] | 578 | self.bbhandler.cooker_data)[0][0] |
689 | self.check_cross_depends("RDEPENDS", layername, f, best, options.show_filenames, ignore_layers) | 579 | self.check_cross_depends("RDEPENDS", layername, f, best, args.filenames, ignore_layers) |
690 | 580 | ||
691 | # The RRECOMMENDS | 581 | # The RRECOMMENDS |
692 | all_rrecs = self.bbhandler.cooker_data.runrecs[f].values() | 582 | all_rrecs = self.bbhandler.cooker_data.runrecs[f].values() |
@@ -706,7 +596,7 @@ The .bbappend file can impact the dependency. | |||
706 | best = bb.providers.filterProvidersRunTime(all_p, rrec, | 596 | best = bb.providers.filterProvidersRunTime(all_p, rrec, |
707 | self.bbhandler.config_data, | 597 | self.bbhandler.config_data, |
708 | self.bbhandler.cooker_data)[0][0] | 598 | self.bbhandler.cooker_data)[0][0] |
709 | self.check_cross_depends("RRECOMMENDS", layername, f, best, options.show_filenames, ignore_layers) | 599 | self.check_cross_depends("RRECOMMENDS", layername, f, best, args.filenames, ignore_layers) |
710 | 600 | ||
711 | # The inherit class | 601 | # The inherit class |
712 | cls_re = re.compile('classes/') | 602 | cls_re = re.compile('classes/') |
@@ -721,7 +611,7 @@ The .bbappend file can impact the dependency. | |||
721 | continue | 611 | continue |
722 | inherit_layername = self.get_file_layer(cls) | 612 | inherit_layername = self.get_file_layer(cls) |
723 | if inherit_layername != layername and not inherit_layername in ignore_layers: | 613 | if inherit_layername != layername and not inherit_layername in ignore_layers: |
724 | if not options.show_filenames: | 614 | if not args.filenames: |
725 | f_short = self.remove_layer_prefix(f) | 615 | f_short = self.remove_layer_prefix(f) |
726 | cls = self.remove_layer_prefix(cls) | 616 | cls = self.remove_layer_prefix(cls) |
727 | else: | 617 | else: |
@@ -741,7 +631,7 @@ The .bbappend file can impact the dependency. | |||
741 | if pv_re.search(needed_file) and f in self.bbhandler.cooker_data.pkg_pepvpr: | 631 | if pv_re.search(needed_file) and f in self.bbhandler.cooker_data.pkg_pepvpr: |
742 | pv = self.bbhandler.cooker_data.pkg_pepvpr[f][1] | 632 | pv = self.bbhandler.cooker_data.pkg_pepvpr[f][1] |
743 | needed_file = re.sub(r"\${PV}", pv, needed_file) | 633 | needed_file = re.sub(r"\${PV}", pv, needed_file) |
744 | self.print_cross_files(bbpath, keyword, layername, f, needed_file, options.show_filenames, ignore_layers) | 634 | self.print_cross_files(bbpath, keyword, layername, f, needed_file, args.filenames, ignore_layers) |
745 | line = fnfile.readline() | 635 | line = fnfile.readline() |
746 | fnfile.close() | 636 | fnfile.close() |
747 | 637 | ||
@@ -768,7 +658,7 @@ The .bbappend file can impact the dependency. | |||
768 | bbclass=".bbclass" | 658 | bbclass=".bbclass" |
769 | # Find a 'require/include xxxx' | 659 | # Find a 'require/include xxxx' |
770 | if m: | 660 | if m: |
771 | self.print_cross_files(bbpath, keyword, layername, f, m.group(1) + bbclass, options.show_filenames, ignore_layers) | 661 | self.print_cross_files(bbpath, keyword, layername, f, m.group(1) + bbclass, args.filenames, ignore_layers) |
772 | line = ffile.readline() | 662 | line = ffile.readline() |
773 | ffile.close() | 663 | ffile.close() |
774 | 664 | ||
@@ -808,5 +698,74 @@ The .bbappend file can impact the dependency. | |||
808 | 698 | ||
809 | logger.plain("%s %s %s" % (f, keyword, best_realfn)) | 699 | logger.plain("%s %s %s" % (f, keyword, best_realfn)) |
810 | 700 | ||
811 | if __name__ == '__main__': | 701 | |
812 | sys.exit(main(sys.argv[1:]) or 0) | 702 | def main(): |
703 | |||
704 | cmds = Commands() | ||
705 | |||
706 | def add_command(cmdname, function, *args, **kwargs): | ||
707 | # Convert docstring for function to help (one-liner shown in main --help) and description (shown in subcommand --help) | ||
708 | docsplit = function.__doc__.splitlines() | ||
709 | help = docsplit[0] | ||
710 | if len(docsplit) > 1: | ||
711 | desc = '\n'.join(docsplit[1:]) | ||
712 | else: | ||
713 | desc = help | ||
714 | subparser = subparsers.add_parser(cmdname, *args, help=help, description=desc, formatter_class=argparse.RawTextHelpFormatter, **kwargs) | ||
715 | subparser.set_defaults(func=function) | ||
716 | return subparser | ||
717 | |||
718 | parser = argparse.ArgumentParser(description="BitBake layers utility", | ||
719 | epilog="Use %(prog)s <subcommand> --help to get help on a specific command") | ||
720 | parser.add_argument('-d', '--debug', help='Enable debug output', action='store_true') | ||
721 | parser.add_argument('-q', '--quiet', help='Print only errors', action='store_true') | ||
722 | subparsers = parser.add_subparsers(title='subcommands', metavar='<subcommand>') | ||
723 | |||
724 | parser_show_layers = add_command('show-layers', cmds.do_show_layers) | ||
725 | |||
726 | parser_add_layer = add_command('add-layer', cmds.do_add_layer) | ||
727 | parser_add_layer.add_argument('layerdir', help='Layer directory to add') | ||
728 | |||
729 | parser_remove_layer = add_command('remove-layer', cmds.do_remove_layer) | ||
730 | parser_remove_layer.add_argument('layerdir', help='Layer directory to remove (wildcards allowed, enclose in quotes to avoid shell expansion)') | ||
731 | parser_remove_layer.set_defaults(func=cmds.do_remove_layer) | ||
732 | |||
733 | parser_show_overlayed = add_command('show-overlayed', cmds.do_show_overlayed) | ||
734 | parser_show_overlayed.add_argument('-f', '--filenames', help='instead of the default formatting, list filenames of higher priority recipes with the ones they overlay indented underneath', action='store_true') | ||
735 | parser_show_overlayed.add_argument('-s', '--same-version', help='only list overlayed recipes where the version is the same', action='store_true') | ||
736 | |||
737 | parser_show_recipes = add_command('show-recipes', cmds.do_show_recipes) | ||
738 | parser_show_recipes.add_argument('-f', '--filenames', help='instead of the default formatting, list filenames of higher priority recipes with the ones they overlay indented underneath', action='store_true') | ||
739 | parser_show_recipes.add_argument('-m', '--multiple', help='only list where multiple recipes (in the same layer or different layers) exist for the same recipe name', action='store_true') | ||
740 | parser_show_recipes.add_argument('pnspec', nargs='?', help='optional recipe name specification (wildcards allowed, enclose in quotes to avoid shell expansion)') | ||
741 | |||
742 | parser_show_appends = add_command('show-appends', cmds.do_show_appends) | ||
743 | |||
744 | parser_flatten = add_command('flatten', cmds.do_flatten) | ||
745 | parser_flatten.add_argument('layer', nargs='*', help='Optional layer(s) to flatten (otherwise all are flattened)') | ||
746 | parser_flatten.add_argument('outputdir', help='Output directory') | ||
747 | |||
748 | parser_show_cross_depends = add_command('show-cross-depends', cmds.do_show_cross_depends) | ||
749 | parser_show_cross_depends.add_argument('-f', '--filenames', help='show full file path', action='store_true') | ||
750 | parser_show_cross_depends.add_argument('-i', '--ignore', help='ignore dependencies on items in the specified layer(s) (split multiple layer names with commas, no spaces)', metavar='LAYERNAME') | ||
751 | |||
752 | args = parser.parse_args() | ||
753 | |||
754 | if args.debug: | ||
755 | logger.setLevel(logging.DEBUG) | ||
756 | elif args.quiet: | ||
757 | logger.setLevel(logging.ERROR) | ||
758 | |||
759 | ret = args.func(args) | ||
760 | |||
761 | return ret | ||
762 | |||
763 | |||
764 | if __name__ == "__main__": | ||
765 | try: | ||
766 | ret = main() | ||
767 | except Exception: | ||
768 | ret = 1 | ||
769 | import traceback | ||
770 | traceback.print_exc(5) | ||
771 | sys.exit(ret) | ||