summaryrefslogtreecommitdiffstats
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 23:29:13 +0100
commit0eb40ba0de4c063ac5dcbc71b0de8e8e2cd5aa17 (patch)
tree90a5c8f78c41b0f0dda7bc9d87cc8ecd55ac9dfe
parentda02f483c47ff2a6fe01a878b4b575b50b50c6d3 (diff)
downloadpoky-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-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 fa799f6a06..557a83013a 100755
--- a/scripts/devtool
+++ b/scripts/devtool
@@ -35,7 +35,7 @@ context = None
35scripts_path = os.path.dirname(os.path.realpath(__file__)) 35scripts_path = os.path.dirname(os.path.realpath(__file__))
36lib_path = scripts_path + '/lib' 36lib_path = scripts_path + '/lib'
37sys.path = sys.path + [lib_path] 37sys.path = sys.path + [lib_path]
38from devtool import DevtoolError 38from devtool import DevtoolError, setup_tinfoil
39import scriptutils 39import scriptutils
40logger = scriptutils.logger_create('devtool') 40logger = 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
99def setup_tinfoil(): 99def 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