diff options
author | Christopher Larson <chris_larson@mentor.com> | 2015-07-13 11:43:40 -0700 |
---|---|---|
committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2015-07-27 23:29:13 +0100 |
commit | 0eb40ba0de4c063ac5dcbc71b0de8e8e2cd5aa17 (patch) | |
tree | 90a5c8f78c41b0f0dda7bc9d87cc8ecd55ac9dfe | |
parent | da02f483c47ff2a6fe01a878b4b575b50b50c6d3 (diff) | |
download | poky-0eb40ba0de4c063ac5dcbc71b0de8e8e2cd5aa17.tar.gz |
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]
(From OE-Core rev: f9bc3b27244a141ec7273445d3ea139a047e0ddf)
Signed-off-by: Christopher Larson <chris_larson@mentor.com>
Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
-rwxr-xr-x | scripts/devtool | 57 | ||||
-rw-r--r-- | scripts/lib/devtool/__init__.py | 4 |
2 files changed, 38 insertions, 23 deletions
diff --git a/scripts/devtool b/scripts/devtool index fa799f6a06..557a83013a 100755 --- a/scripts/devtool +++ b/scripts/devtool | |||
@@ -35,7 +35,7 @@ context = None | |||
35 | scripts_path = os.path.dirname(os.path.realpath(__file__)) | 35 | scripts_path = os.path.dirname(os.path.realpath(__file__)) |
36 | lib_path = scripts_path + '/lib' | 36 | lib_path = scripts_path + '/lib' |
37 | sys.path = sys.path + [lib_path] | 37 | sys.path = sys.path + [lib_path] |
38 | from devtool import DevtoolError | 38 | from devtool import DevtoolError, setup_tinfoil |
39 | import scriptutils | 39 | import scriptutils |
40 | logger = scriptutils.logger_create('devtool') | 40 | logger = scriptutils.logger_create('devtool') |
41 | 41 | ||
@@ -186,37 +186,28 @@ def main(): | |||
186 | pth = os.path.dirname(pth) | 186 | pth = os.path.dirname(pth) |
187 | 187 | ||
188 | parser = argparse.ArgumentParser(description="OpenEmbedded development tool", | 188 | parser = argparse.ArgumentParser(description="OpenEmbedded development tool", |
189 | add_help=False, | ||
189 | epilog="Use %(prog)s <subcommand> --help to get help on a specific command") | 190 | epilog="Use %(prog)s <subcommand> --help to get help on a specific command") |
190 | parser.add_argument('--basepath', help='Base directory of SDK / build directory') | 191 | parser.add_argument('--basepath', help='Base directory of SDK / build directory') |
191 | parser.add_argument('-d', '--debug', help='Enable debug output', action='store_true') | 192 | parser.add_argument('-d', '--debug', help='Enable debug output', action='store_true') |
192 | parser.add_argument('-q', '--quiet', help='Print only errors', action='store_true') | 193 | parser.add_argument('-q', '--quiet', help='Print only errors', action='store_true') |
193 | parser.add_argument('--color', choices=['auto', 'always', 'never'], default='auto', help='Colorize output (where %(metavar)s is %(choices)s)', metavar='COLOR') | 194 | parser.add_argument('--color', choices=['auto', 'always', 'never'], default='auto', help='Colorize output (where %(metavar)s is %(choices)s)', metavar='COLOR') |
194 | 195 | ||
195 | subparsers = parser.add_subparsers(dest="subparser_name", title='subcommands', metavar='<subcommand>') | 196 | global_args, unparsed_args = parser.parse_known_args() |
196 | 197 | ||
197 | if not context.fixed_setup: | 198 | # Help is added here rather than via add_help=True, as we don't want it to |
198 | parser_create_workspace = subparsers.add_parser('create-workspace', | 199 | # be handled by parse_known_args() |
199 | help='Set up a workspace', | 200 | parser.add_argument('-h', '--help', action='help', default=argparse.SUPPRESS, |
200 | 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.') | 201 | help='show this help message and exit') |
201 | parser_create_workspace.add_argument('layerpath', nargs='?', help='Path in which the workspace layer should be created') | ||
202 | parser_create_workspace.add_argument('--create-only', action="store_true", help='Only create the workspace layer, do not alter configuration') | ||
203 | parser_create_workspace.set_defaults(func=create_workspace) | ||
204 | 202 | ||
205 | scriptutils.load_plugins(logger, plugins, os.path.join(scripts_path, 'lib', 'devtool')) | 203 | if global_args.debug: |
206 | for plugin in plugins: | ||
207 | if hasattr(plugin, 'register_commands'): | ||
208 | plugin.register_commands(subparsers, context) | ||
209 | |||
210 | args = parser.parse_args() | ||
211 | |||
212 | if args.debug: | ||
213 | logger.setLevel(logging.DEBUG) | 204 | logger.setLevel(logging.DEBUG) |
214 | elif args.quiet: | 205 | elif global_args.quiet: |
215 | logger.setLevel(logging.ERROR) | 206 | logger.setLevel(logging.ERROR) |
216 | 207 | ||
217 | if args.basepath: | 208 | if global_args.basepath: |
218 | # Override | 209 | # Override |
219 | basepath = args.basepath | 210 | basepath = global_args.basepath |
220 | elif not context.fixed_setup: | 211 | elif not context.fixed_setup: |
221 | basepath = os.environ.get('BUILDDIR') | 212 | basepath = os.environ.get('BUILDDIR') |
222 | if not basepath: | 213 | if not basepath: |
@@ -246,7 +237,31 @@ def main(): | |||
246 | logger.debug('Using standard bitbake path %s' % bitbakepath) | 237 | logger.debug('Using standard bitbake path %s' % bitbakepath) |
247 | scriptpath.add_oe_lib_path() | 238 | scriptpath.add_oe_lib_path() |
248 | 239 | ||
249 | scriptutils.logger_setup_color(logger, args.color) | 240 | scriptutils.logger_setup_color(logger, global_args.color) |
241 | |||
242 | tinfoil = setup_tinfoil(config_only=True) | ||
243 | for path in ([scripts_path] + | ||
244 | tinfoil.config_data.getVar('BBPATH', True).split(':')): | ||
245 | pluginpath = os.path.join(path, 'lib', 'devtool') | ||
246 | scriptutils.load_plugins(logger, plugins, pluginpath) | ||
247 | tinfoil.cooker.shutdown(force=True) | ||
248 | tinfoil.cooker.unlockBitbake() | ||
249 | |||
250 | subparsers = parser.add_subparsers(dest="subparser_name", title='subcommands', metavar='<subcommand>') | ||
251 | |||
252 | if not context.fixed_setup: | ||
253 | parser_create_workspace = subparsers.add_parser('create-workspace', | ||
254 | help='Set up a workspace', | ||
255 | 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.') | ||
256 | parser_create_workspace.add_argument('layerpath', nargs='?', help='Path in which the workspace layer should be created') | ||
257 | parser_create_workspace.add_argument('--create-only', action="store_true", help='Only create the workspace layer, do not alter configuration') | ||
258 | parser_create_workspace.set_defaults(func=create_workspace) | ||
259 | |||
260 | for plugin in plugins: | ||
261 | if hasattr(plugin, 'register_commands'): | ||
262 | plugin.register_commands(subparsers, context) | ||
263 | |||
264 | args = parser.parse_args(unparsed_args, namespace=global_args) | ||
250 | 265 | ||
251 | if args.subparser_name != 'create-workspace': | 266 | if args.subparser_name != 'create-workspace': |
252 | read_workspace() | 267 | read_workspace() |
diff --git a/scripts/lib/devtool/__init__.py b/scripts/lib/devtool/__init__.py index 61b810c938..b54ddf5ff4 100644 --- a/scripts/lib/devtool/__init__.py +++ b/scripts/lib/devtool/__init__.py | |||
@@ -96,7 +96,7 @@ def exec_fakeroot(d, cmd, **kwargs): | |||
96 | newenv[splitval[0]] = splitval[1] | 96 | newenv[splitval[0]] = splitval[1] |
97 | return subprocess.call("%s %s" % (fakerootcmd, cmd), env=newenv, **kwargs) | 97 | return subprocess.call("%s %s" % (fakerootcmd, cmd), env=newenv, **kwargs) |
98 | 98 | ||
99 | def setup_tinfoil(): | 99 | def setup_tinfoil(config_only=False): |
100 | """Initialize tinfoil api from bitbake""" | 100 | """Initialize tinfoil api from bitbake""" |
101 | import scriptpath | 101 | import scriptpath |
102 | bitbakepath = scriptpath.add_bitbake_lib_path() | 102 | bitbakepath = scriptpath.add_bitbake_lib_path() |
@@ -106,7 +106,7 @@ def setup_tinfoil(): | |||
106 | 106 | ||
107 | import bb.tinfoil | 107 | import bb.tinfoil |
108 | tinfoil = bb.tinfoil.Tinfoil() | 108 | tinfoil = bb.tinfoil.Tinfoil() |
109 | tinfoil.prepare(False) | 109 | tinfoil.prepare(config_only) |
110 | tinfoil.logger.setLevel(logger.getEffectiveLevel()) | 110 | tinfoil.logger.setLevel(logger.getEffectiveLevel()) |
111 | return tinfoil | 111 | return tinfoil |
112 | 112 | ||