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>
This commit is contained in:
parent
68f4dcae68
commit
4a32837971
|
@ -5,7 +5,7 @@
|
||||||
# See the help output for details on available commands.
|
# See the help output for details on available commands.
|
||||||
|
|
||||||
# Copyright (C) 2011 Mentor Graphics Corporation
|
# Copyright (C) 2011 Mentor Graphics Corporation
|
||||||
# Copyright (C) 2012 Intel Corporation
|
# Copyright (C) 2011-2015 Intel Corporation
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# This program is free software; you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU General Public License version 2 as
|
# it under the terms of the GNU General Public License version 2 as
|
||||||
|
@ -20,12 +20,12 @@
|
||||||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
|
||||||
import cmd
|
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import fnmatch
|
import fnmatch
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
|
import argparse
|
||||||
import re
|
import re
|
||||||
|
|
||||||
bindir = os.path.dirname(__file__)
|
bindir = os.path.dirname(__file__)
|
||||||
|
@ -42,23 +42,11 @@ import bb.tinfoil
|
||||||
logger = logging.getLogger('BitBake')
|
logger = logging.getLogger('BitBake')
|
||||||
|
|
||||||
|
|
||||||
def main(args):
|
|
||||||
cmds = Commands()
|
|
||||||
if args:
|
|
||||||
# Allow user to specify e.g. show-layers instead of show_layers
|
|
||||||
args = [args[0].replace('-', '_')] + args[1:]
|
|
||||||
cmds.onecmd(' '.join(args))
|
|
||||||
else:
|
|
||||||
cmds.do_help('')
|
|
||||||
return cmds.returncode
|
|
||||||
|
|
||||||
|
class Commands():
|
||||||
class Commands(cmd.Cmd):
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.bbhandler = None
|
self.bbhandler = None
|
||||||
self.returncode = 0
|
|
||||||
self.bblayers = []
|
self.bblayers = []
|
||||||
cmd.Cmd.__init__(self)
|
|
||||||
|
|
||||||
def init_bbhandler(self, config_only = False):
|
def init_bbhandler(self, config_only = False):
|
||||||
if not self.bbhandler:
|
if not self.bbhandler:
|
||||||
|
@ -66,27 +54,6 @@ class Commands(cmd.Cmd):
|
||||||
self.bblayers = (self.bbhandler.config_data.getVar('BBLAYERS', True) or "").split()
|
self.bblayers = (self.bbhandler.config_data.getVar('BBLAYERS', True) or "").split()
|
||||||
self.bbhandler.prepare(config_only)
|
self.bbhandler.prepare(config_only)
|
||||||
|
|
||||||
def default(self, line):
|
|
||||||
"""Handle unrecognised commands"""
|
|
||||||
sys.stderr.write("Unrecognised command or option\n")
|
|
||||||
self.do_help('')
|
|
||||||
|
|
||||||
def do_help(self, topic):
|
|
||||||
"""display general help or help on a specified command"""
|
|
||||||
if topic:
|
|
||||||
sys.stdout.write('%s: ' % topic)
|
|
||||||
cmd.Cmd.do_help(self, topic.replace('-', '_'))
|
|
||||||
else:
|
|
||||||
sys.stdout.write("usage: bitbake-layers <command> [arguments]\n\n")
|
|
||||||
sys.stdout.write("Available commands:\n")
|
|
||||||
procnames = list(set(self.get_names()))
|
|
||||||
for procname in procnames:
|
|
||||||
if procname[:3] == 'do_':
|
|
||||||
sys.stdout.write(" %s\n" % procname[3:].replace('_', '-'))
|
|
||||||
doc = getattr(self, procname).__doc__
|
|
||||||
if doc:
|
|
||||||
sys.stdout.write(" %s\n" % doc.splitlines()[0])
|
|
||||||
|
|
||||||
def do_show_layers(self, args):
|
def do_show_layers(self, args):
|
||||||
"""show current configured layers"""
|
"""show current configured layers"""
|
||||||
self.init_bbhandler(config_only = True)
|
self.init_bbhandler(config_only = True)
|
||||||
|
@ -103,29 +70,25 @@ class Commands(cmd.Cmd):
|
||||||
logger.plain("%s %s %d" % (layername.ljust(20), layerdir.ljust(40), layerpri))
|
logger.plain("%s %s %d" % (layername.ljust(20), layerdir.ljust(40), layerpri))
|
||||||
|
|
||||||
|
|
||||||
def do_add_layer(self, dirname):
|
def do_add_layer(self, args):
|
||||||
"""Add a layer to bblayers.conf
|
"""Add a layer to bblayers.conf
|
||||||
|
|
||||||
usage: add-layer <layerdir>
|
Adds the specified layer to bblayers.conf
|
||||||
"""
|
"""
|
||||||
if not dirname:
|
layerdir = os.path.abspath(args.layerdir)
|
||||||
sys.stderr.write("Please specify the layer directory to add\n")
|
|
||||||
return
|
|
||||||
|
|
||||||
layerdir = os.path.abspath(dirname)
|
|
||||||
if not os.path.exists(layerdir):
|
if not os.path.exists(layerdir):
|
||||||
sys.stderr.write("Specified layer directory doesn't exist\n")
|
sys.stderr.write("Specified layer directory doesn't exist\n")
|
||||||
return
|
return 1
|
||||||
|
|
||||||
layer_conf = os.path.join(layerdir, 'conf', 'layer.conf')
|
layer_conf = os.path.join(layerdir, 'conf', 'layer.conf')
|
||||||
if not os.path.exists(layer_conf):
|
if not os.path.exists(layer_conf):
|
||||||
sys.stderr.write("Specified layer directory doesn't contain a conf/layer.conf file\n")
|
sys.stderr.write("Specified layer directory doesn't contain a conf/layer.conf file\n")
|
||||||
return
|
return 1
|
||||||
|
|
||||||
bblayers_conf = os.path.join('conf', 'bblayers.conf')
|
bblayers_conf = os.path.join('conf', 'bblayers.conf')
|
||||||
if not os.path.exists(bblayers_conf):
|
if not os.path.exists(bblayers_conf):
|
||||||
sys.stderr.write("Unable to find bblayers.conf\n")
|
sys.stderr.write("Unable to find bblayers.conf\n")
|
||||||
return
|
return 1
|
||||||
|
|
||||||
(notadded, _) = bb.utils.edit_bblayers_conf(bblayers_conf, layerdir, None)
|
(notadded, _) = bb.utils.edit_bblayers_conf(bblayers_conf, layerdir, None)
|
||||||
if notadded:
|
if notadded:
|
||||||
|
@ -133,28 +96,25 @@ usage: add-layer <layerdir>
|
||||||
sys.stderr.write("Specified layer %s is already in BBLAYERS\n" % item)
|
sys.stderr.write("Specified layer %s is already in BBLAYERS\n" % item)
|
||||||
|
|
||||||
|
|
||||||
def do_remove_layer(self, dirname):
|
def do_remove_layer(self, args):
|
||||||
"""Remove a layer from bblayers.conf
|
"""Remove a layer from bblayers.conf
|
||||||
|
|
||||||
usage: remove-layer <layerdir>
|
Removes the specified layer from bblayers.conf
|
||||||
"""
|
"""
|
||||||
if not dirname:
|
|
||||||
sys.stderr.write("Please specify the layer directory to remove\n")
|
|
||||||
return
|
|
||||||
|
|
||||||
bblayers_conf = os.path.join('conf', 'bblayers.conf')
|
bblayers_conf = os.path.join('conf', 'bblayers.conf')
|
||||||
if not os.path.exists(bblayers_conf):
|
if not os.path.exists(bblayers_conf):
|
||||||
sys.stderr.write("Unable to find bblayers.conf\n")
|
sys.stderr.write("Unable to find bblayers.conf\n")
|
||||||
return
|
return 1
|
||||||
|
|
||||||
if dirname.startswith('*'):
|
if args.layerdir.startswith('*'):
|
||||||
layerdir = dirname
|
layerdir = dirname
|
||||||
else:
|
else:
|
||||||
layerdir = os.path.abspath(dirname)
|
layerdir = os.path.abspath(args.layerdir)
|
||||||
(_, notremoved) = bb.utils.edit_bblayers_conf(bblayers_conf, None, layerdir)
|
(_, notremoved) = bb.utils.edit_bblayers_conf(bblayers_conf, None, layerdir)
|
||||||
if notremoved:
|
if notremoved:
|
||||||
for item in notremoved:
|
for item in notremoved:
|
||||||
sys.stderr.write("No layers matching %s found in BBLAYERS\n" % item)
|
sys.stderr.write("No layers matching %s found in BBLAYERS\n" % item)
|
||||||
|
return 1
|
||||||
|
|
||||||
|
|
||||||
def version_str(self, pe, pv, pr = None):
|
def version_str(self, pe, pv, pr = None):
|
||||||
|
@ -169,32 +129,13 @@ usage: remove-layer <layerdir>
|
||||||
def do_show_overlayed(self, args):
|
def do_show_overlayed(self, args):
|
||||||
"""list overlayed recipes (where the same recipe exists in another layer)
|
"""list overlayed recipes (where the same recipe exists in another layer)
|
||||||
|
|
||||||
usage: show-overlayed [-f] [-s]
|
|
||||||
|
|
||||||
Lists the names of overlayed recipes and the available versions in each
|
Lists the names of overlayed recipes and the available versions in each
|
||||||
layer, with the preferred version first. Note that skipped recipes that
|
layer, with the preferred version first. Note that skipped recipes that
|
||||||
are overlayed will also be listed, with a " (skipped)" suffix.
|
are overlayed will also be listed, with a " (skipped)" suffix.
|
||||||
|
|
||||||
Options:
|
|
||||||
-f instead of the default formatting, list filenames of higher priority
|
|
||||||
recipes with the ones they overlay indented underneath
|
|
||||||
-s only list overlayed recipes where the version is the same
|
|
||||||
"""
|
"""
|
||||||
self.init_bbhandler()
|
self.init_bbhandler()
|
||||||
|
|
||||||
show_filenames = False
|
items_listed = self.list_recipes('Overlayed recipes', None, True, args.same_version, args.filenames, True)
|
||||||
show_same_ver_only = False
|
|
||||||
for arg in args.split():
|
|
||||||
if arg == '-f':
|
|
||||||
show_filenames = True
|
|
||||||
elif arg == '-s':
|
|
||||||
show_same_ver_only = True
|
|
||||||
else:
|
|
||||||
sys.stderr.write("show-overlayed: invalid option %s\n" % arg)
|
|
||||||
self.do_help('')
|
|
||||||
return
|
|
||||||
|
|
||||||
items_listed = self.list_recipes('Overlayed recipes', None, True, show_same_ver_only, show_filenames, True)
|
|
||||||
|
|
||||||
# Check for overlayed .bbclass files
|
# Check for overlayed .bbclass files
|
||||||
classes = defaultdict(list)
|
classes = defaultdict(list)
|
||||||
|
@ -221,7 +162,7 @@ Options:
|
||||||
overlayed_class_found = True
|
overlayed_class_found = True
|
||||||
|
|
||||||
mainfile = bb.utils.which(bbpath, os.path.join('classes', classfile))
|
mainfile = bb.utils.which(bbpath, os.path.join('classes', classfile))
|
||||||
if show_filenames:
|
if args.filenames:
|
||||||
logger.plain('%s' % mainfile)
|
logger.plain('%s' % mainfile)
|
||||||
else:
|
else:
|
||||||
# We effectively have to guess the layer here
|
# We effectively have to guess the layer here
|
||||||
|
@ -235,7 +176,7 @@ Options:
|
||||||
for classdir in classdirs:
|
for classdir in classdirs:
|
||||||
fullpath = os.path.join(classdir, classfile)
|
fullpath = os.path.join(classdir, classfile)
|
||||||
if fullpath != mainfile:
|
if fullpath != mainfile:
|
||||||
if show_filenames:
|
if args.filenames:
|
||||||
print(' %s' % fullpath)
|
print(' %s' % fullpath)
|
||||||
else:
|
else:
|
||||||
print(' %s' % self.get_layer_name(os.path.dirname(classdir)))
|
print(' %s' % self.get_layer_name(os.path.dirname(classdir)))
|
||||||
|
@ -250,38 +191,15 @@ Options:
|
||||||
def do_show_recipes(self, args):
|
def do_show_recipes(self, args):
|
||||||
"""list available recipes, showing the layer they are provided by
|
"""list available recipes, showing the layer they are provided by
|
||||||
|
|
||||||
usage: show-recipes [-f] [-m] [pnspec]
|
Lists the names of recipes and the available versions in each
|
||||||
|
|
||||||
Lists the names of overlayed recipes and the available versions in each
|
|
||||||
layer, with the preferred version first. Optionally you may specify
|
layer, with the preferred version first. Optionally you may specify
|
||||||
pnspec to match a specified recipe name (supports wildcards). Note that
|
pnspec to match a specified recipe name (supports wildcards). Note that
|
||||||
skipped recipes will also be listed, with a " (skipped)" suffix.
|
skipped recipes will also be listed, with a " (skipped)" suffix.
|
||||||
|
|
||||||
Options:
|
|
||||||
-f instead of the default formatting, list filenames of higher priority
|
|
||||||
recipes with other available recipes indented underneath
|
|
||||||
-m only list where multiple recipes (in the same layer or different
|
|
||||||
layers) exist for the same recipe name
|
|
||||||
"""
|
"""
|
||||||
self.init_bbhandler()
|
self.init_bbhandler()
|
||||||
|
|
||||||
show_filenames = False
|
|
||||||
show_multi_provider_only = False
|
|
||||||
pnspec = None
|
|
||||||
title = 'Available recipes:'
|
title = 'Available recipes:'
|
||||||
for arg in args.split():
|
self.list_recipes(title, args.pnspec, False, False, args.filenames, args.multiple)
|
||||||
if arg == '-f':
|
|
||||||
show_filenames = True
|
|
||||||
elif arg == '-m':
|
|
||||||
show_multi_provider_only = True
|
|
||||||
elif not arg.startswith('-'):
|
|
||||||
pnspec = arg
|
|
||||||
title = 'Available recipes matching %s:' % pnspec
|
|
||||||
else:
|
|
||||||
sys.stderr.write("show-recipes: invalid option %s\n" % arg)
|
|
||||||
self.do_help('')
|
|
||||||
return
|
|
||||||
self.list_recipes(title, pnspec, False, False, show_filenames, show_multi_provider_only)
|
|
||||||
|
|
||||||
|
|
||||||
def list_recipes(self, title, pnspec, show_overlayed_only, show_same_ver_only, show_filenames, show_multi_provider_only):
|
def list_recipes(self, title, pnspec, show_overlayed_only, show_same_ver_only, show_filenames, show_multi_provider_only):
|
||||||
|
@ -361,9 +279,7 @@ Options:
|
||||||
|
|
||||||
|
|
||||||
def do_flatten(self, args):
|
def do_flatten(self, args):
|
||||||
"""flattens layer configuration into a separate output directory.
|
"""flatten layer configuration into a separate output directory.
|
||||||
|
|
||||||
usage: flatten [layer1 layer2 [layer3]...] <outputdir>
|
|
||||||
|
|
||||||
Takes the specified layers (or all layers in the current layer
|
Takes the specified layers (or all layers in the current layer
|
||||||
configuration if none are specified) and builds a "flattened" directory
|
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
|
||||||
layer together with that other layer, you may no longer get the same
|
layer together with that other layer, you may no longer get the same
|
||||||
build results (as the layer priority order has effectively changed).
|
build results (as the layer priority order has effectively changed).
|
||||||
"""
|
"""
|
||||||
arglist = args.split()
|
if len(args.layer) == 1:
|
||||||
if len(arglist) < 1:
|
|
||||||
logger.error('Please specify an output directory')
|
|
||||||
self.do_help('flatten')
|
|
||||||
return
|
|
||||||
|
|
||||||
if len(arglist) == 2:
|
|
||||||
logger.error('If you specify layers to flatten you must specify at least two')
|
logger.error('If you specify layers to flatten you must specify at least two')
|
||||||
self.do_help('flatten')
|
return 1
|
||||||
return
|
|
||||||
|
|
||||||
outputdir = arglist[-1]
|
outputdir = args.outputdir
|
||||||
if os.path.exists(outputdir) and os.listdir(outputdir):
|
if os.path.exists(outputdir) and os.listdir(outputdir):
|
||||||
logger.error('Directory %s exists and is non-empty, please clear it out first' % outputdir)
|
logger.error('Directory %s exists and is non-empty, please clear it out first' % outputdir)
|
||||||
return
|
return 1
|
||||||
|
|
||||||
self.init_bbhandler()
|
self.init_bbhandler()
|
||||||
layers = self.bblayers
|
layers = self.bblayers
|
||||||
if len(arglist) > 2:
|
if len(args.layer) > 2:
|
||||||
layernames = arglist[:-1]
|
layernames = args.layer
|
||||||
found_layernames = []
|
found_layernames = []
|
||||||
found_layerdirs = []
|
found_layerdirs = []
|
||||||
for layerdir in layers:
|
for layerdir in layers:
|
||||||
|
@ -553,14 +462,12 @@ build results (as the layer priority order has effectively changed).
|
||||||
def do_show_appends(self, args):
|
def do_show_appends(self, args):
|
||||||
"""list bbappend files and recipe files they apply to
|
"""list bbappend files and recipe files they apply to
|
||||||
|
|
||||||
usage: show-appends
|
Lists recipes with the bbappends that apply to them as subitems.
|
||||||
|
|
||||||
Recipes are listed with the bbappends that apply to them as subitems.
|
|
||||||
"""
|
"""
|
||||||
self.init_bbhandler()
|
self.init_bbhandler()
|
||||||
if not self.bbhandler.cooker.collection.appendlist:
|
if not self.bbhandler.cooker.collection.appendlist:
|
||||||
logger.plain('No append files found')
|
logger.plain('No append files found')
|
||||||
return
|
return 0
|
||||||
|
|
||||||
logger.plain('=== Appended recipes ===')
|
logger.plain('=== Appended recipes ===')
|
||||||
|
|
||||||
|
@ -599,7 +506,6 @@ Recipes are listed with the bbappends that apply to them as subitems.
|
||||||
if best_filename in missing:
|
if best_filename in missing:
|
||||||
logger.warn('%s: missing append for preferred version',
|
logger.warn('%s: missing append for preferred version',
|
||||||
best_filename)
|
best_filename)
|
||||||
self.returncode |= 1
|
|
||||||
|
|
||||||
|
|
||||||
def get_appends_for_files(self, filenames):
|
def get_appends_for_files(self, filenames):
|
||||||
|
@ -618,29 +524,13 @@ Recipes are listed with the bbappends that apply to them as subitems.
|
||||||
return appended, notappended
|
return appended, notappended
|
||||||
|
|
||||||
def do_show_cross_depends(self, args):
|
def do_show_cross_depends(self, args):
|
||||||
"""figure out the dependency between recipes that crosses a layer boundary.
|
"""Show dependencies between recipes that cross layer boundaries.
|
||||||
|
|
||||||
usage: show-cross-depends [-f] [-i layer1[,layer2[,layer3...]]]
|
Figure out the dependencies between recipes that cross layer boundaries.
|
||||||
|
|
||||||
Figure out the dependency between recipes that crosses a layer boundary.
|
NOTE: .bbappend files can impact the dependencies.
|
||||||
|
|
||||||
Options:
|
|
||||||
-f show full file path
|
|
||||||
-i ignore dependencies on items in the specified layer(s)
|
|
||||||
|
|
||||||
NOTE:
|
|
||||||
The .bbappend file can impact the dependency.
|
|
||||||
"""
|
"""
|
||||||
import optparse
|
ignore_layers = (args.ignore or '').split(',')
|
||||||
|
|
||||||
parser = optparse.OptionParser(usage="show-cross-depends [-f] [-i layer1[,layer2[,layer3...]]]")
|
|
||||||
parser.add_option("-f", "",
|
|
||||||
action="store_true", dest="show_filenames")
|
|
||||||
parser.add_option("-i", "",
|
|
||||||
action="store", dest="ignore_layers", default="")
|
|
||||||
|
|
||||||
options, args = parser.parse_args(sys.argv)
|
|
||||||
ignore_layers = options.ignore_layers.split(',')
|
|
||||||
|
|
||||||
self.init_bbhandler()
|
self.init_bbhandler()
|
||||||
|
|
||||||
|
@ -666,7 +556,7 @@ The .bbappend file can impact the dependency.
|
||||||
self.bbhandler.config_data,
|
self.bbhandler.config_data,
|
||||||
self.bbhandler.cooker_data,
|
self.bbhandler.cooker_data,
|
||||||
self.bbhandler.cooker_data.pkg_pn)
|
self.bbhandler.cooker_data.pkg_pn)
|
||||||
self.check_cross_depends("DEPENDS", layername, f, best[3], options.show_filenames, ignore_layers)
|
self.check_cross_depends("DEPENDS", layername, f, best[3], args.filenames, ignore_layers)
|
||||||
|
|
||||||
# The RDPENDS
|
# The RDPENDS
|
||||||
all_rdeps = self.bbhandler.cooker_data.rundeps[f].values()
|
all_rdeps = self.bbhandler.cooker_data.rundeps[f].values()
|
||||||
|
@ -686,7 +576,7 @@ The .bbappend file can impact the dependency.
|
||||||
best = bb.providers.filterProvidersRunTime(all_p, rdep,
|
best = bb.providers.filterProvidersRunTime(all_p, rdep,
|
||||||
self.bbhandler.config_data,
|
self.bbhandler.config_data,
|
||||||
self.bbhandler.cooker_data)[0][0]
|
self.bbhandler.cooker_data)[0][0]
|
||||||
self.check_cross_depends("RDEPENDS", layername, f, best, options.show_filenames, ignore_layers)
|
self.check_cross_depends("RDEPENDS", layername, f, best, args.filenames, ignore_layers)
|
||||||
|
|
||||||
# The RRECOMMENDS
|
# The RRECOMMENDS
|
||||||
all_rrecs = self.bbhandler.cooker_data.runrecs[f].values()
|
all_rrecs = self.bbhandler.cooker_data.runrecs[f].values()
|
||||||
|
@ -706,7 +596,7 @@ The .bbappend file can impact the dependency.
|
||||||
best = bb.providers.filterProvidersRunTime(all_p, rrec,
|
best = bb.providers.filterProvidersRunTime(all_p, rrec,
|
||||||
self.bbhandler.config_data,
|
self.bbhandler.config_data,
|
||||||
self.bbhandler.cooker_data)[0][0]
|
self.bbhandler.cooker_data)[0][0]
|
||||||
self.check_cross_depends("RRECOMMENDS", layername, f, best, options.show_filenames, ignore_layers)
|
self.check_cross_depends("RRECOMMENDS", layername, f, best, args.filenames, ignore_layers)
|
||||||
|
|
||||||
# The inherit class
|
# The inherit class
|
||||||
cls_re = re.compile('classes/')
|
cls_re = re.compile('classes/')
|
||||||
|
@ -721,7 +611,7 @@ The .bbappend file can impact the dependency.
|
||||||
continue
|
continue
|
||||||
inherit_layername = self.get_file_layer(cls)
|
inherit_layername = self.get_file_layer(cls)
|
||||||
if inherit_layername != layername and not inherit_layername in ignore_layers:
|
if inherit_layername != layername and not inherit_layername in ignore_layers:
|
||||||
if not options.show_filenames:
|
if not args.filenames:
|
||||||
f_short = self.remove_layer_prefix(f)
|
f_short = self.remove_layer_prefix(f)
|
||||||
cls = self.remove_layer_prefix(cls)
|
cls = self.remove_layer_prefix(cls)
|
||||||
else:
|
else:
|
||||||
|
@ -741,7 +631,7 @@ The .bbappend file can impact the dependency.
|
||||||
if pv_re.search(needed_file) and f in self.bbhandler.cooker_data.pkg_pepvpr:
|
if pv_re.search(needed_file) and f in self.bbhandler.cooker_data.pkg_pepvpr:
|
||||||
pv = self.bbhandler.cooker_data.pkg_pepvpr[f][1]
|
pv = self.bbhandler.cooker_data.pkg_pepvpr[f][1]
|
||||||
needed_file = re.sub(r"\${PV}", pv, needed_file)
|
needed_file = re.sub(r"\${PV}", pv, needed_file)
|
||||||
self.print_cross_files(bbpath, keyword, layername, f, needed_file, options.show_filenames, ignore_layers)
|
self.print_cross_files(bbpath, keyword, layername, f, needed_file, args.filenames, ignore_layers)
|
||||||
line = fnfile.readline()
|
line = fnfile.readline()
|
||||||
fnfile.close()
|
fnfile.close()
|
||||||
|
|
||||||
|
@ -768,7 +658,7 @@ The .bbappend file can impact the dependency.
|
||||||
bbclass=".bbclass"
|
bbclass=".bbclass"
|
||||||
# Find a 'require/include xxxx'
|
# Find a 'require/include xxxx'
|
||||||
if m:
|
if m:
|
||||||
self.print_cross_files(bbpath, keyword, layername, f, m.group(1) + bbclass, options.show_filenames, ignore_layers)
|
self.print_cross_files(bbpath, keyword, layername, f, m.group(1) + bbclass, args.filenames, ignore_layers)
|
||||||
line = ffile.readline()
|
line = ffile.readline()
|
||||||
ffile.close()
|
ffile.close()
|
||||||
|
|
||||||
|
@ -808,5 +698,74 @@ The .bbappend file can impact the dependency.
|
||||||
|
|
||||||
logger.plain("%s %s %s" % (f, keyword, best_realfn))
|
logger.plain("%s %s %s" % (f, keyword, best_realfn))
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
sys.exit(main(sys.argv[1:]) or 0)
|
def main():
|
||||||
|
|
||||||
|
cmds = Commands()
|
||||||
|
|
||||||
|
def add_command(cmdname, function, *args, **kwargs):
|
||||||
|
# Convert docstring for function to help (one-liner shown in main --help) and description (shown in subcommand --help)
|
||||||
|
docsplit = function.__doc__.splitlines()
|
||||||
|
help = docsplit[0]
|
||||||
|
if len(docsplit) > 1:
|
||||||
|
desc = '\n'.join(docsplit[1:])
|
||||||
|
else:
|
||||||
|
desc = help
|
||||||
|
subparser = subparsers.add_parser(cmdname, *args, help=help, description=desc, formatter_class=argparse.RawTextHelpFormatter, **kwargs)
|
||||||
|
subparser.set_defaults(func=function)
|
||||||
|
return subparser
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser(description="BitBake layers utility",
|
||||||
|
epilog="Use %(prog)s <subcommand> --help to get help on a specific command")
|
||||||
|
parser.add_argument('-d', '--debug', help='Enable debug output', action='store_true')
|
||||||
|
parser.add_argument('-q', '--quiet', help='Print only errors', action='store_true')
|
||||||
|
subparsers = parser.add_subparsers(title='subcommands', metavar='<subcommand>')
|
||||||
|
|
||||||
|
parser_show_layers = add_command('show-layers', cmds.do_show_layers)
|
||||||
|
|
||||||
|
parser_add_layer = add_command('add-layer', cmds.do_add_layer)
|
||||||
|
parser_add_layer.add_argument('layerdir', help='Layer directory to add')
|
||||||
|
|
||||||
|
parser_remove_layer = add_command('remove-layer', cmds.do_remove_layer)
|
||||||
|
parser_remove_layer.add_argument('layerdir', help='Layer directory to remove (wildcards allowed, enclose in quotes to avoid shell expansion)')
|
||||||
|
parser_remove_layer.set_defaults(func=cmds.do_remove_layer)
|
||||||
|
|
||||||
|
parser_show_overlayed = add_command('show-overlayed', cmds.do_show_overlayed)
|
||||||
|
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')
|
||||||
|
parser_show_overlayed.add_argument('-s', '--same-version', help='only list overlayed recipes where the version is the same', action='store_true')
|
||||||
|
|
||||||
|
parser_show_recipes = add_command('show-recipes', cmds.do_show_recipes)
|
||||||
|
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')
|
||||||
|
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')
|
||||||
|
parser_show_recipes.add_argument('pnspec', nargs='?', help='optional recipe name specification (wildcards allowed, enclose in quotes to avoid shell expansion)')
|
||||||
|
|
||||||
|
parser_show_appends = add_command('show-appends', cmds.do_show_appends)
|
||||||
|
|
||||||
|
parser_flatten = add_command('flatten', cmds.do_flatten)
|
||||||
|
parser_flatten.add_argument('layer', nargs='*', help='Optional layer(s) to flatten (otherwise all are flattened)')
|
||||||
|
parser_flatten.add_argument('outputdir', help='Output directory')
|
||||||
|
|
||||||
|
parser_show_cross_depends = add_command('show-cross-depends', cmds.do_show_cross_depends)
|
||||||
|
parser_show_cross_depends.add_argument('-f', '--filenames', help='show full file path', action='store_true')
|
||||||
|
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')
|
||||||
|
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
if args.debug:
|
||||||
|
logger.setLevel(logging.DEBUG)
|
||||||
|
elif args.quiet:
|
||||||
|
logger.setLevel(logging.ERROR)
|
||||||
|
|
||||||
|
ret = args.func(args)
|
||||||
|
|
||||||
|
return ret
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
try:
|
||||||
|
ret = main()
|
||||||
|
except Exception:
|
||||||
|
ret = 1
|
||||||
|
import traceback
|
||||||
|
traceback.print_exc(5)
|
||||||
|
sys.exit(ret)
|
||||||
|
|
Loading…
Reference in New Issue