aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristopher Larson <chris_larson@mentor.com>2015-07-13 11:43:40 -0700
committerRichard Purdie <richard.purdie@linuxfoundation.org>2015-07-27 12:28:12 +0100
commitf9bc3b27244a141ec7273445d3ea139a047e0ddf (patch)
tree6e8208081c0bc2a0924dfea7404020fbbcda1888
parent899288a1b255052a6ee0f97d42f8c4f0ec3c3140 (diff)
downloadopenembedded-core-contrib-f9bc3b27244a141ec7273445d3ea139a047e0ddf.tar.gz
openembedded-core-contrib-f9bc3b27244a141ec7273445d3ea139a047e0ddf.tar.bz2
openembedded-core-contrib-f9bc3b27244a141ec7273445d3ea139a047e0ddf.zip
devtool: also load plugins from BBPATH
This makes it easier to extend, as a layer can add its own sub-commands. Argument parsing is also separated into two steps, the same way it's done in recipetool, as we need access to the global command-line arguments early, before plugins are loaded, both for debugging arguments and for the bitbake path (we need to load the bitbake module to get tinfoil, which is now needed to load the plugins). Rather than constructing tinfoil once and passing it through into sub-commands for their use, we have to construct it for configuration metadata, use it, and then shut it down, as some sub-commands call out to recipetool, which needs its own tinfoil instance, and therefore needs to acquire the bitbake lock. If we're still holding the lock at that point, that's clearly a problem. [YOCTO #7625] Signed-off-by: Christopher Larson <chris_larson@mentor.com> Signed-off-by: Ross Burton <ross.burton@intel.com>
-rwxr-xr-xscripts/devtool57
-rw-r--r--scripts/lib/devtool/__init__.py4
2 files changed, 38 insertions, 23 deletions
diff --git a/scripts/devtool b/scripts/devtool
index fa799f6a06a..557a83013a8 100755
--- a/scripts/devtool
+++ b/scripts/devtool
@@ -35,7 +35,7 @@ context = None
scripts_path = os.path.dirname(os.path.realpath(__file__))
lib_path = scripts_path + '/lib'
sys.path = sys.path + [lib_path]
-from devtool import DevtoolError
+from devtool import DevtoolError, setup_tinfoil
import scriptutils
logger = scriptutils.logger_create('devtool')
@@ -186,37 +186,28 @@ def main():
pth = os.path.dirname(pth)
parser = argparse.ArgumentParser(description="OpenEmbedded development tool",
+ add_help=False,
epilog="Use %(prog)s <subcommand> --help to get help on a specific command")
parser.add_argument('--basepath', help='Base directory of SDK / build directory')
parser.add_argument('-d', '--debug', help='Enable debug output', action='store_true')
parser.add_argument('-q', '--quiet', help='Print only errors', action='store_true')
parser.add_argument('--color', choices=['auto', 'always', 'never'], default='auto', help='Colorize output (where %(metavar)s is %(choices)s)', metavar='COLOR')
- subparsers = parser.add_subparsers(dest="subparser_name", title='subcommands', metavar='<subcommand>')
+ global_args, unparsed_args = parser.parse_known_args()
- if not context.fixed_setup:
- parser_create_workspace = subparsers.add_parser('create-workspace',
- help='Set up a workspace',
- description='Sets up a new workspace. NOTE: other devtool subcommands will create a workspace automatically as needed, so you only need to use %(prog)s if you want to specify where the workspace should be located.')
- parser_create_workspace.add_argument('layerpath', nargs='?', help='Path in which the workspace layer should be created')
- parser_create_workspace.add_argument('--create-only', action="store_true", help='Only create the workspace layer, do not alter configuration')
- parser_create_workspace.set_defaults(func=create_workspace)
+ # Help is added here rather than via add_help=True, as we don't want it to
+ # be handled by parse_known_args()
+ parser.add_argument('-h', '--help', action='help', default=argparse.SUPPRESS,
+ help='show this help message and exit')
- scriptutils.load_plugins(logger, plugins, os.path.join(scripts_path, 'lib', 'devtool'))
- for plugin in plugins:
- if hasattr(plugin, 'register_commands'):
- plugin.register_commands(subparsers, context)
-
- args = parser.parse_args()
-
- if args.debug:
+ if global_args.debug:
logger.setLevel(logging.DEBUG)
- elif args.quiet:
+ elif global_args.quiet:
logger.setLevel(logging.ERROR)
- if args.basepath:
+ if global_args.basepath:
# Override
- basepath = args.basepath
+ basepath = global_args.basepath
elif not context.fixed_setup:
basepath = os.environ.get('BUILDDIR')
if not basepath:
@@ -246,7 +237,31 @@ def main():
logger.debug('Using standard bitbake path %s' % bitbakepath)
scriptpath.add_oe_lib_path()
- scriptutils.logger_setup_color(logger, args.color)
+ scriptutils.logger_setup_color(logger, global_args.color)
+
+ tinfoil = setup_tinfoil(config_only=True)
+ for path in ([scripts_path] +
+ tinfoil.config_data.getVar('BBPATH', True).split(':')):
+ pluginpath = os.path.join(path, 'lib', 'devtool')
+ scriptutils.load_plugins(logger, plugins, pluginpath)
+ tinfoil.cooker.shutdown(force=True)
+ tinfoil.cooker.unlockBitbake()
+
+ subparsers = parser.add_subparsers(dest="subparser_name", title='subcommands', metavar='<subcommand>')
+
+ if not context.fixed_setup:
+ parser_create_workspace = subparsers.add_parser('create-workspace',
+ help='Set up a workspace',
+ description='Sets up a new workspace. NOTE: other devtool subcommands will create a workspace automatically as needed, so you only need to use %(prog)s if you want to specify where the workspace should be located.')
+ parser_create_workspace.add_argument('layerpath', nargs='?', help='Path in which the workspace layer should be created')
+ parser_create_workspace.add_argument('--create-only', action="store_true", help='Only create the workspace layer, do not alter configuration')
+ parser_create_workspace.set_defaults(func=create_workspace)
+
+ for plugin in plugins:
+ if hasattr(plugin, 'register_commands'):
+ plugin.register_commands(subparsers, context)
+
+ args = parser.parse_args(unparsed_args, namespace=global_args)
if args.subparser_name != 'create-workspace':
read_workspace()
diff --git a/scripts/lib/devtool/__init__.py b/scripts/lib/devtool/__init__.py
index 61b810c9382..b54ddf5ff49 100644
--- a/scripts/lib/devtool/__init__.py
+++ b/scripts/lib/devtool/__init__.py
@@ -96,7 +96,7 @@ def exec_fakeroot(d, cmd, **kwargs):
newenv[splitval[0]] = splitval[1]
return subprocess.call("%s %s" % (fakerootcmd, cmd), env=newenv, **kwargs)
-def setup_tinfoil():
+def setup_tinfoil(config_only=False):
"""Initialize tinfoil api from bitbake"""
import scriptpath
bitbakepath = scriptpath.add_bitbake_lib_path()
@@ -106,7 +106,7 @@ def setup_tinfoil():
import bb.tinfoil
tinfoil = bb.tinfoil.Tinfoil()
- tinfoil.prepare(False)
+ tinfoil.prepare(config_only)
tinfoil.logger.setLevel(logger.getEffectiveLevel())
return tinfoil