summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Eggleton <paul.eggleton@linux.intel.com>2016-02-19 22:38:53 +1300
committerRichard Purdie <richard.purdie@linuxfoundation.org>2016-02-21 09:32:42 +0000
commit32ef52389833a8b8dfb63444ace6561bb0ac741c (patch)
tree59f597df4ce685609706c7db90ee0eb654b044a5
parent9f7df76eb49eac1ec7627061a8219e5d0b052034 (diff)
downloadpoky-32ef52389833a8b8dfb63444ace6561bb0ac741c.tar.gz
devtool: categorise and order subcommands in help output
The listing of subcommands in the --help output for devtool was starting to get difficult to follow, with commands appearing in no particular order (due to some being in separate modules and the order of those modules being parsed). Logically grouping the subcommands as well as being able to exercise some control over the order of the subcommands and groups would help, if we do so without losing the dynamic nature of the list (i.e. that it comes from the plugins). Argparse provides no built-in way to handle this and really, really makes it a pain to add, but with some subclassing and hacking it's now possible, and can be extended by any plugin as desired. To put a subcommand into a group, all you need to do is specify a group= parameter in the call to subparsers.add_parser(). you can also specify an order= parameter to make the subcommand sort higher or lower in the list (higher order numbers appear first, so use negative numbers to force items to the end if that's what you want). To add a new group, use subparsers.add_subparser_group(), supplying the name, description and optionally an order number for the group itself (again, higher numbers appear first). (From OE-Core rev: e1b9d31e6ea3c254ecfe940fe795af44761e0e69) Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
-rwxr-xr-xscripts/devtool10
-rw-r--r--scripts/lib/argparse_oe.py59
-rw-r--r--scripts/lib/devtool/build-image.py3
-rw-r--r--scripts/lib/devtool/build.py3
-rw-r--r--scripts/lib/devtool/deploy.py8
-rw-r--r--scripts/lib/devtool/package.py5
-rw-r--r--scripts/lib/devtool/runqemu.py3
-rw-r--r--scripts/lib/devtool/sdk.py10
-rw-r--r--scripts/lib/devtool/search.py3
-rw-r--r--scripts/lib/devtool/standard.py21
-rw-r--r--scripts/lib/devtool/upgrade.py3
-rw-r--r--scripts/lib/devtool/utilcmds.py6
12 files changed, 114 insertions, 20 deletions
diff --git a/scripts/devtool b/scripts/devtool
index 23e9b50074..06e91b7591 100755
--- a/scripts/devtool
+++ b/scripts/devtool
@@ -275,10 +275,18 @@ def main():
275 275
276 subparsers = parser.add_subparsers(dest="subparser_name", title='subcommands', metavar='<subcommand>') 276 subparsers = parser.add_subparsers(dest="subparser_name", title='subcommands', metavar='<subcommand>')
277 277
278 subparsers.add_subparser_group('sdk', 'SDK maintenance', -2)
279 subparsers.add_subparser_group('advanced', 'Advanced', -1)
280 subparsers.add_subparser_group('starting', 'Beginning work on a recipe', 100)
281 subparsers.add_subparser_group('info', 'Getting information')
282 subparsers.add_subparser_group('working', 'Working on a recipe in the workspace')
283 subparsers.add_subparser_group('testbuild', 'Testing changes on target')
284
278 if not context.fixed_setup: 285 if not context.fixed_setup:
279 parser_create_workspace = subparsers.add_parser('create-workspace', 286 parser_create_workspace = subparsers.add_parser('create-workspace',
280 help='Set up workspace in an alternative location', 287 help='Set up workspace in an alternative location',
281 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.') 288 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.',
289 group='advanced')
282 parser_create_workspace.add_argument('layerpath', nargs='?', help='Path in which the workspace layer should be created') 290 parser_create_workspace.add_argument('layerpath', nargs='?', help='Path in which the workspace layer should be created')
283 parser_create_workspace.add_argument('--create-only', action="store_true", help='Only create the workspace layer, do not alter configuration') 291 parser_create_workspace.add_argument('--create-only', action="store_true", help='Only create the workspace layer, do not alter configuration')
284 parser_create_workspace.set_defaults(func=create_workspace, no_workspace=True) 292 parser_create_workspace.set_defaults(func=create_workspace, no_workspace=True)
diff --git a/scripts/lib/argparse_oe.py b/scripts/lib/argparse_oe.py
index fd866922bd..744cfe312f 100644
--- a/scripts/lib/argparse_oe.py
+++ b/scripts/lib/argparse_oe.py
@@ -1,5 +1,6 @@
1import sys 1import sys
2import argparse 2import argparse
3from collections import defaultdict, OrderedDict
3 4
4class ArgumentUsageError(Exception): 5class ArgumentUsageError(Exception):
5 """Exception class you can raise (and catch) in order to show the help""" 6 """Exception class you can raise (and catch) in order to show the help"""
@@ -9,6 +10,10 @@ class ArgumentUsageError(Exception):
9 10
10class ArgumentParser(argparse.ArgumentParser): 11class ArgumentParser(argparse.ArgumentParser):
11 """Our own version of argparse's ArgumentParser""" 12 """Our own version of argparse's ArgumentParser"""
13 def __init__(self, *args, **kwargs):
14 kwargs.setdefault('formatter_class', OeHelpFormatter)
15 self._subparser_groups = OrderedDict()
16 super(ArgumentParser, self).__init__(*args, **kwargs)
12 17
13 def error(self, message): 18 def error(self, message):
14 sys.stderr.write('ERROR: %s\n' % message) 19 sys.stderr.write('ERROR: %s\n' % message)
@@ -27,10 +32,26 @@ class ArgumentParser(argparse.ArgumentParser):
27 32
28 def add_subparsers(self, *args, **kwargs): 33 def add_subparsers(self, *args, **kwargs):
29 ret = super(ArgumentParser, self).add_subparsers(*args, **kwargs) 34 ret = super(ArgumentParser, self).add_subparsers(*args, **kwargs)
35 # Need a way of accessing the parent parser
36 ret._parent_parser = self
37 # Ensure our class gets instantiated
30 ret._parser_class = ArgumentSubParser 38 ret._parser_class = ArgumentSubParser
39 # Hacky way of adding a method to the subparsers object
40 ret.add_subparser_group = self.add_subparser_group
31 return ret 41 return ret
32 42
43 def add_subparser_group(self, groupname, groupdesc, order=0):
44 self._subparser_groups[groupname] = (groupdesc, order)
45
46
33class ArgumentSubParser(ArgumentParser): 47class ArgumentSubParser(ArgumentParser):
48 def __init__(self, *args, **kwargs):
49 if 'group' in kwargs:
50 self._group = kwargs.pop('group')
51 if 'order' in kwargs:
52 self._order = kwargs.pop('order')
53 super(ArgumentSubParser, self).__init__(*args, **kwargs)
54
34 def parse_known_args(self, args=None, namespace=None): 55 def parse_known_args(self, args=None, namespace=None):
35 # This works around argparse not handling optional positional arguments being 56 # This works around argparse not handling optional positional arguments being
36 # intermixed with other options. A pretty horrible hack, but we're not left 57 # intermixed with other options. A pretty horrible hack, but we're not left
@@ -64,3 +85,41 @@ class ArgumentSubParser(ArgumentParser):
64 if hasattr(action, 'save_nargs'): 85 if hasattr(action, 'save_nargs'):
65 action.nargs = action.save_nargs 86 action.nargs = action.save_nargs
66 return super(ArgumentParser, self).format_help() 87 return super(ArgumentParser, self).format_help()
88
89
90class OeHelpFormatter(argparse.HelpFormatter):
91 def _format_action(self, action):
92 if hasattr(action, '_get_subactions'):
93 # subcommands list
94 groupmap = defaultdict(list)
95 ordermap = {}
96 subparser_groups = action._parent_parser._subparser_groups
97 groups = sorted(subparser_groups.keys(), key=lambda item: subparser_groups[item][1], reverse=True)
98 for subaction in self._iter_indented_subactions(action):
99 parser = action._name_parser_map[subaction.dest]
100 group = getattr(parser, '_group', None)
101 groupmap[group].append(subaction)
102 if group not in groups:
103 groups.append(group)
104 order = getattr(parser, '_order', 0)
105 ordermap[subaction.dest] = order
106
107 lines = []
108 if len(groupmap) > 1:
109 groupindent = ' '
110 else:
111 groupindent = ''
112 for group in groups:
113 subactions = groupmap[group]
114 if not subactions:
115 continue
116 if groupindent:
117 if not group:
118 group = 'other'
119 groupdesc = subparser_groups.get(group, (group, 0))[0]
120 lines.append(' %s:' % groupdesc)
121 for subaction in sorted(subactions, key=lambda item: ordermap[item.dest], reverse=True):
122 lines.append('%s%s' % (groupindent, self._format_action(subaction).rstrip()))
123 return '\n'.join(lines)
124 else:
125 return super(OeHelpFormatter, self)._format_action(action)
diff --git a/scripts/lib/devtool/build-image.py b/scripts/lib/devtool/build-image.py
index 48c3a1198a..ff764fa833 100644
--- a/scripts/lib/devtool/build-image.py
+++ b/scripts/lib/devtool/build-image.py
@@ -109,7 +109,8 @@ def register_commands(subparsers, context):
109 parser = subparsers.add_parser('build-image', 109 parser = subparsers.add_parser('build-image',
110 help='Build image including workspace recipe packages', 110 help='Build image including workspace recipe packages',
111 description='Builds an image, extending it to include ' 111 description='Builds an image, extending it to include '
112 'packages from recipes in the workspace') 112 'packages from recipes in the workspace',
113 group='testbuild', order=-10)
113 parser.add_argument('imagename', help='Image recipe to build', nargs='?') 114 parser.add_argument('imagename', help='Image recipe to build', nargs='?')
114 parser.add_argument('-p', '--add-packages', help='Instead of adding packages for the ' 115 parser.add_argument('-p', '--add-packages', help='Instead of adding packages for the '
115 'entire workspace, specify packages to be added to the image ' 116 'entire workspace, specify packages to be added to the image '
diff --git a/scripts/lib/devtool/build.py b/scripts/lib/devtool/build.py
index b10a6a903b..48f6fe1be5 100644
--- a/scripts/lib/devtool/build.py
+++ b/scripts/lib/devtool/build.py
@@ -79,7 +79,8 @@ def build(args, config, basepath, workspace):
79def register_commands(subparsers, context): 79def register_commands(subparsers, context):
80 """Register devtool subcommands from this plugin""" 80 """Register devtool subcommands from this plugin"""
81 parser_build = subparsers.add_parser('build', help='Build a recipe', 81 parser_build = subparsers.add_parser('build', help='Build a recipe',
82 description='Builds the specified recipe using bitbake (up to and including %s)' % ', '.join(_get_build_tasks(context.config))) 82 description='Builds the specified recipe using bitbake (up to and including %s)' % ', '.join(_get_build_tasks(context.config)),
83 group='working')
83 parser_build.add_argument('recipename', help='Recipe to build') 84 parser_build.add_argument('recipename', help='Recipe to build')
84 parser_build.add_argument('-s', '--disable-parallel-make', action="store_true", help='Disable make parallelism') 85 parser_build.add_argument('-s', '--disable-parallel-make', action="store_true", help='Disable make parallelism')
85 parser_build.set_defaults(func=build) 86 parser_build.set_defaults(func=build)
diff --git a/scripts/lib/devtool/deploy.py b/scripts/lib/devtool/deploy.py
index c90c6b1f76..0236c53726 100644
--- a/scripts/lib/devtool/deploy.py
+++ b/scripts/lib/devtool/deploy.py
@@ -131,7 +131,9 @@ def undeploy(args, config, basepath, workspace):
131 131
132def register_commands(subparsers, context): 132def register_commands(subparsers, context):
133 """Register devtool subcommands from the deploy plugin""" 133 """Register devtool subcommands from the deploy plugin"""
134 parser_deploy = subparsers.add_parser('deploy-target', help='Deploy recipe output files to live target machine') 134 parser_deploy = subparsers.add_parser('deploy-target',
135 help='Deploy recipe output files to live target machine',
136 group='testbuild')
135 parser_deploy.add_argument('recipename', help='Recipe to deploy') 137 parser_deploy.add_argument('recipename', help='Recipe to deploy')
136 parser_deploy.add_argument('target', help='Live target machine running an ssh server: user@hostname[:destdir]') 138 parser_deploy.add_argument('target', help='Live target machine running an ssh server: user@hostname[:destdir]')
137 parser_deploy.add_argument('-c', '--no-host-check', help='Disable ssh host key checking', action='store_true') 139 parser_deploy.add_argument('-c', '--no-host-check', help='Disable ssh host key checking', action='store_true')
@@ -139,7 +141,9 @@ def register_commands(subparsers, context):
139 parser_deploy.add_argument('-n', '--dry-run', help='List files to be deployed only', action='store_true') 141 parser_deploy.add_argument('-n', '--dry-run', help='List files to be deployed only', action='store_true')
140 parser_deploy.set_defaults(func=deploy) 142 parser_deploy.set_defaults(func=deploy)
141 143
142 parser_undeploy = subparsers.add_parser('undeploy-target', help='Undeploy recipe output files in live target machine') 144 parser_undeploy = subparsers.add_parser('undeploy-target',
145 help='Undeploy recipe output files in live target machine',
146 group='testbuild')
143 parser_undeploy.add_argument('recipename', help='Recipe to undeploy') 147 parser_undeploy.add_argument('recipename', help='Recipe to undeploy')
144 parser_undeploy.add_argument('target', help='Live target machine running an ssh server: user@hostname') 148 parser_undeploy.add_argument('target', help='Live target machine running an ssh server: user@hostname')
145 parser_undeploy.add_argument('-c', '--no-host-check', help='Disable ssh host key checking', action='store_true') 149 parser_undeploy.add_argument('-c', '--no-host-check', help='Disable ssh host key checking', action='store_true')
diff --git a/scripts/lib/devtool/package.py b/scripts/lib/devtool/package.py
index a296fce9b1..afb5809a36 100644
--- a/scripts/lib/devtool/package.py
+++ b/scripts/lib/devtool/package.py
@@ -54,6 +54,9 @@ def package(args, config, basepath, workspace):
54def register_commands(subparsers, context): 54def register_commands(subparsers, context):
55 """Register devtool subcommands from the package plugin""" 55 """Register devtool subcommands from the package plugin"""
56 if context.fixed_setup: 56 if context.fixed_setup:
57 parser_package = subparsers.add_parser('package', help='Build packages for a recipe', description='Builds packages for a recipe\'s output files') 57 parser_package = subparsers.add_parser('package',
58 help='Build packages for a recipe',
59 description='Builds packages for a recipe\'s output files',
60 group='testbuild', order=-5)
58 parser_package.add_argument('recipename', help='Recipe to package') 61 parser_package.add_argument('recipename', help='Recipe to package')
59 parser_package.set_defaults(func=package) 62 parser_package.set_defaults(func=package)
diff --git a/scripts/lib/devtool/runqemu.py b/scripts/lib/devtool/runqemu.py
index 5282afba68..daee7fbbe3 100644
--- a/scripts/lib/devtool/runqemu.py
+++ b/scripts/lib/devtool/runqemu.py
@@ -57,7 +57,8 @@ def register_commands(subparsers, context):
57 """Register devtool subcommands from this plugin""" 57 """Register devtool subcommands from this plugin"""
58 if context.fixed_setup: 58 if context.fixed_setup:
59 parser_runqemu = subparsers.add_parser('runqemu', help='Run QEMU on the specified image', 59 parser_runqemu = subparsers.add_parser('runqemu', help='Run QEMU on the specified image',
60 description='Runs QEMU to boot the specified image') 60 description='Runs QEMU to boot the specified image',
61 group='testbuild', order=-20)
61 parser_runqemu.add_argument('imagename', help='Name of built image to boot within QEMU', nargs='?') 62 parser_runqemu.add_argument('imagename', help='Name of built image to boot within QEMU', nargs='?')
62 parser_runqemu.add_argument('args', help='Any remaining arguments are passed to the runqemu script (pass --help after imagename to see what these are)', 63 parser_runqemu.add_argument('args', help='Any remaining arguments are passed to the runqemu script (pass --help after imagename to see what these are)',
63 nargs=argparse.REMAINDER) 64 nargs=argparse.REMAINDER)
diff --git a/scripts/lib/devtool/sdk.py b/scripts/lib/devtool/sdk.py
index 12de9423e7..f6c5434732 100644
--- a/scripts/lib/devtool/sdk.py
+++ b/scripts/lib/devtool/sdk.py
@@ -296,10 +296,16 @@ def sdk_install(args, config, basepath, workspace):
296def register_commands(subparsers, context): 296def register_commands(subparsers, context):
297 """Register devtool subcommands from the sdk plugin""" 297 """Register devtool subcommands from the sdk plugin"""
298 if context.fixed_setup: 298 if context.fixed_setup:
299 parser_sdk = subparsers.add_parser('sdk-update', help='Update SDK components from a nominated location') 299 parser_sdk = subparsers.add_parser('sdk-update',
300 help='Update SDK components from a nominated location',
301 group='sdk')
300 parser_sdk.add_argument('updateserver', help='The update server to fetch latest SDK components from', nargs='?') 302 parser_sdk.add_argument('updateserver', help='The update server to fetch latest SDK components from', nargs='?')
301 parser_sdk.add_argument('--skip-prepare', action="store_true", help='Skip re-preparing the build system after updating (for debugging only)') 303 parser_sdk.add_argument('--skip-prepare', action="store_true", help='Skip re-preparing the build system after updating (for debugging only)')
302 parser_sdk.set_defaults(func=sdk_update) 304 parser_sdk.set_defaults(func=sdk_update)
303 parser_sdk_install = subparsers.add_parser('sdk-install', help='Install additional SDK components', description='Installs additional recipe development files into the SDK. (You can use "devtool search" to find available recipes.)') 305
306 parser_sdk_install = subparsers.add_parser('sdk-install',
307 help='Install additional SDK components',
308 description='Installs additional recipe development files into the SDK. (You can use "devtool search" to find available recipes.)',
309 group='sdk')
304 parser_sdk_install.add_argument('recipename', help='Name of the recipe to install the development artifacts for', nargs='+') 310 parser_sdk_install.add_argument('recipename', help='Name of the recipe to install the development artifacts for', nargs='+')
305 parser_sdk_install.set_defaults(func=sdk_install) 311 parser_sdk_install.set_defaults(func=sdk_install)
diff --git a/scripts/lib/devtool/search.py b/scripts/lib/devtool/search.py
index 2ea446237e..b44bed7f6f 100644
--- a/scripts/lib/devtool/search.py
+++ b/scripts/lib/devtool/search.py
@@ -82,6 +82,7 @@ def search(args, config, basepath, workspace):
82def register_commands(subparsers, context): 82def register_commands(subparsers, context):
83 """Register devtool subcommands from this plugin""" 83 """Register devtool subcommands from this plugin"""
84 parser_search = subparsers.add_parser('search', help='Search available recipes', 84 parser_search = subparsers.add_parser('search', help='Search available recipes',
85 description='Searches for available target recipes. Matches on recipe name, package name, description and installed files, and prints the recipe name on match.') 85 description='Searches for available target recipes. Matches on recipe name, package name, description and installed files, and prints the recipe name on match.',
86 group='info')
86 parser_search.add_argument('keyword', help='Keyword to search for (regular expression syntax allowed)') 87 parser_search.add_argument('keyword', help='Keyword to search for (regular expression syntax allowed)')
87 parser_search.set_defaults(func=search, no_workspace=True) 88 parser_search.set_defaults(func=search, no_workspace=True)
diff --git a/scripts/lib/devtool/standard.py b/scripts/lib/devtool/standard.py
index 804c127848..084039a855 100644
--- a/scripts/lib/devtool/standard.py
+++ b/scripts/lib/devtool/standard.py
@@ -1303,7 +1303,8 @@ def register_commands(subparsers, context):
1303 1303
1304 defsrctree = get_default_srctree(context.config) 1304 defsrctree = get_default_srctree(context.config)
1305 parser_add = subparsers.add_parser('add', help='Add a new recipe', 1305 parser_add = subparsers.add_parser('add', help='Add a new recipe',
1306 description='Adds a new recipe to the workspace to build a specified source tree. Can optionally fetch a remote URI and unpack it to create the source tree.') 1306 description='Adds a new recipe to the workspace to build a specified source tree. Can optionally fetch a remote URI and unpack it to create the source tree.',
1307 group='starting', order=100)
1307 parser_add.add_argument('recipename', nargs='?', help='Name for new recipe to add (just name - no version, path or extension). If not specified, will attempt to auto-detect it.') 1308 parser_add.add_argument('recipename', nargs='?', help='Name for new recipe to add (just name - no version, path or extension). If not specified, will attempt to auto-detect it.')
1308 parser_add.add_argument('srctree', nargs='?', help='Path to external source tree. If not specified, a subdirectory of %s will be used.' % defsrctree) 1309 parser_add.add_argument('srctree', nargs='?', help='Path to external source tree. If not specified, a subdirectory of %s will be used.' % defsrctree)
1309 parser_add.add_argument('fetchuri', nargs='?', help='Fetch the specified URI and extract it to create the source tree') 1310 parser_add.add_argument('fetchuri', nargs='?', help='Fetch the specified URI and extract it to create the source tree')
@@ -1319,7 +1320,8 @@ def register_commands(subparsers, context):
1319 parser_add.set_defaults(func=add) 1320 parser_add.set_defaults(func=add)
1320 1321
1321 parser_modify = subparsers.add_parser('modify', help='Modify the source for an existing recipe', 1322 parser_modify = subparsers.add_parser('modify', help='Modify the source for an existing recipe',
1322 description='Enables modifying the source for an existing recipe. You can either provide your own pre-prepared source tree, or specify -x/--extract to extract the source being fetched by the recipe.') 1323 description='Enables modifying the source for an existing recipe. You can either provide your own pre-prepared source tree, or specify -x/--extract to extract the source being fetched by the recipe.',
1324 group='starting', order=90)
1323 parser_modify.add_argument('recipename', help='Name of existing recipe to edit (just name - no version, path or extension)') 1325 parser_modify.add_argument('recipename', help='Name of existing recipe to edit (just name - no version, path or extension)')
1324 parser_modify.add_argument('srctree', nargs='?', help='Path to external source tree. If not specified, a subdirectory of %s will be used.' % defsrctree) 1326 parser_modify.add_argument('srctree', nargs='?', help='Path to external source tree. If not specified, a subdirectory of %s will be used.' % defsrctree)
1325 parser_modify.add_argument('--wildcard', '-w', action="store_true", help='Use wildcard for unversioned bbappend') 1327 parser_modify.add_argument('--wildcard', '-w', action="store_true", help='Use wildcard for unversioned bbappend')
@@ -1333,7 +1335,8 @@ def register_commands(subparsers, context):
1333 parser_modify.set_defaults(func=modify) 1335 parser_modify.set_defaults(func=modify)
1334 1336
1335 parser_extract = subparsers.add_parser('extract', help='Extract the source for an existing recipe', 1337 parser_extract = subparsers.add_parser('extract', help='Extract the source for an existing recipe',
1336 description='Extracts the source for an existing recipe') 1338 description='Extracts the source for an existing recipe',
1339 group='advanced')
1337 parser_extract.add_argument('recipename', help='Name of recipe to extract the source for') 1340 parser_extract.add_argument('recipename', help='Name of recipe to extract the source for')
1338 parser_extract.add_argument('srctree', help='Path to where to extract the source tree') 1341 parser_extract.add_argument('srctree', help='Path to where to extract the source tree')
1339 parser_extract.add_argument('--branch', '-b', default="devtool", help='Name for development branch to checkout (default "%(default)s")') 1342 parser_extract.add_argument('--branch', '-b', default="devtool", help='Name for development branch to checkout (default "%(default)s")')
@@ -1342,7 +1345,8 @@ def register_commands(subparsers, context):
1342 1345
1343 parser_sync = subparsers.add_parser('sync', help='Synchronize the source tree for an existing recipe', 1346 parser_sync = subparsers.add_parser('sync', help='Synchronize the source tree for an existing recipe',
1344 description='Synchronize the previously extracted source tree for an existing recipe', 1347 description='Synchronize the previously extracted source tree for an existing recipe',
1345 formatter_class=argparse.ArgumentDefaultsHelpFormatter) 1348 formatter_class=argparse.ArgumentDefaultsHelpFormatter,
1349 group='advanced')
1346 parser_sync.add_argument('recipename', help='Name of recipe to sync the source for') 1350 parser_sync.add_argument('recipename', help='Name of recipe to sync the source for')
1347 parser_sync.add_argument('srctree', help='Path to the source tree') 1351 parser_sync.add_argument('srctree', help='Path to the source tree')
1348 parser_sync.add_argument('--branch', '-b', default="devtool", help='Name for development branch to checkout') 1352 parser_sync.add_argument('--branch', '-b', default="devtool", help='Name for development branch to checkout')
@@ -1350,7 +1354,8 @@ def register_commands(subparsers, context):
1350 parser_sync.set_defaults(func=sync) 1354 parser_sync.set_defaults(func=sync)
1351 1355
1352 parser_update_recipe = subparsers.add_parser('update-recipe', help='Apply changes from external source tree to recipe', 1356 parser_update_recipe = subparsers.add_parser('update-recipe', help='Apply changes from external source tree to recipe',
1353 description='Applies changes from external source tree to a recipe (updating/adding/removing patches as necessary, or by updating SRCREV). Note that these changes need to have been committed to the git repository in order to be recognised.') 1357 description='Applies changes from external source tree to a recipe (updating/adding/removing patches as necessary, or by updating SRCREV). Note that these changes need to have been committed to the git repository in order to be recognised.',
1358 group='working', order=-90)
1354 parser_update_recipe.add_argument('recipename', help='Name of recipe to update') 1359 parser_update_recipe.add_argument('recipename', help='Name of recipe to update')
1355 parser_update_recipe.add_argument('--mode', '-m', choices=['patch', 'srcrev', 'auto'], default='auto', help='Update mode (where %(metavar)s is %(choices)s; default is %(default)s)', metavar='MODE') 1360 parser_update_recipe.add_argument('--mode', '-m', choices=['patch', 'srcrev', 'auto'], default='auto', help='Update mode (where %(metavar)s is %(choices)s; default is %(default)s)', metavar='MODE')
1356 parser_update_recipe.add_argument('--initial-rev', help='Override starting revision for patches') 1361 parser_update_recipe.add_argument('--initial-rev', help='Override starting revision for patches')
@@ -1360,11 +1365,13 @@ def register_commands(subparsers, context):
1360 parser_update_recipe.set_defaults(func=update_recipe) 1365 parser_update_recipe.set_defaults(func=update_recipe)
1361 1366
1362 parser_status = subparsers.add_parser('status', help='Show workspace status', 1367 parser_status = subparsers.add_parser('status', help='Show workspace status',
1363 description='Lists recipes currently in your workspace and the paths to their respective external source trees') 1368 description='Lists recipes currently in your workspace and the paths to their respective external source trees',
1369 group='info', order=100)
1364 parser_status.set_defaults(func=status) 1370 parser_status.set_defaults(func=status)
1365 1371
1366 parser_reset = subparsers.add_parser('reset', help='Remove a recipe from your workspace', 1372 parser_reset = subparsers.add_parser('reset', help='Remove a recipe from your workspace',
1367 description='Removes the specified recipe from your workspace (resetting its state)') 1373 description='Removes the specified recipe from your workspace (resetting its state)',
1374 group='working', order=-100)
1368 parser_reset.add_argument('recipename', nargs='?', help='Recipe to reset') 1375 parser_reset.add_argument('recipename', nargs='?', help='Recipe to reset')
1369 parser_reset.add_argument('--all', '-a', action="store_true", help='Reset all recipes (clear workspace)') 1376 parser_reset.add_argument('--all', '-a', action="store_true", help='Reset all recipes (clear workspace)')
1370 parser_reset.add_argument('--no-clean', '-n', action="store_true", help='Don\'t clean the sysroot to remove recipe output') 1377 parser_reset.add_argument('--no-clean', '-n', action="store_true", help='Don\'t clean the sysroot to remove recipe output')
diff --git a/scripts/lib/devtool/upgrade.py b/scripts/lib/devtool/upgrade.py
index e2be38e7af..0e53c8286e 100644
--- a/scripts/lib/devtool/upgrade.py
+++ b/scripts/lib/devtool/upgrade.py
@@ -339,7 +339,8 @@ def upgrade(args, config, basepath, workspace):
339def register_commands(subparsers, context): 339def register_commands(subparsers, context):
340 """Register devtool subcommands from this plugin""" 340 """Register devtool subcommands from this plugin"""
341 parser_upgrade = subparsers.add_parser('upgrade', help='Upgrade an existing recipe', 341 parser_upgrade = subparsers.add_parser('upgrade', help='Upgrade an existing recipe',
342 description='Upgrades an existing recipe to a new upstream version. Puts the upgraded recipe file into the workspace along with any associated files, and extracts the source tree to a specified location (in case patches need rebasing or adding to as a result of the upgrade).') 342 description='Upgrades an existing recipe to a new upstream version. Puts the upgraded recipe file into the workspace along with any associated files, and extracts the source tree to a specified location (in case patches need rebasing or adding to as a result of the upgrade).',
343 group='starting')
343 parser_upgrade.add_argument('recipename', help='Name of recipe to upgrade (just name - no version, path or extension)') 344 parser_upgrade.add_argument('recipename', help='Name of recipe to upgrade (just name - no version, path or extension)')
344 parser_upgrade.add_argument('srctree', help='Path to where to extract the source tree') 345 parser_upgrade.add_argument('srctree', help='Path to where to extract the source tree')
345 parser_upgrade.add_argument('--version', '-V', help='Version to upgrade to (PV)') 346 parser_upgrade.add_argument('--version', '-V', help='Version to upgrade to (PV)')
diff --git a/scripts/lib/devtool/utilcmds.py b/scripts/lib/devtool/utilcmds.py
index 18eddb78b0..905d6d2b19 100644
--- a/scripts/lib/devtool/utilcmds.py
+++ b/scripts/lib/devtool/utilcmds.py
@@ -214,7 +214,8 @@ The ./configure %s output for %s follows.
214def register_commands(subparsers, context): 214def register_commands(subparsers, context):
215 """Register devtool subcommands from this plugin""" 215 """Register devtool subcommands from this plugin"""
216 parser_edit_recipe = subparsers.add_parser('edit-recipe', help='Edit a recipe file in your workspace', 216 parser_edit_recipe = subparsers.add_parser('edit-recipe', help='Edit a recipe file in your workspace',
217 description='Runs the default editor (as specified by the EDITOR variable) on the specified recipe. Note that the recipe file itself must be in the workspace (i.e. as a result of "devtool add" or "devtool upgrade"); you can override this with the -a/--any-recipe option.') 217 description='Runs the default editor (as specified by the EDITOR variable) on the specified recipe. Note that the recipe file itself must be in the workspace (i.e. as a result of "devtool add" or "devtool upgrade"); you can override this with the -a/--any-recipe option.',
218 group='working')
218 parser_edit_recipe.add_argument('recipename', help='Recipe to edit') 219 parser_edit_recipe.add_argument('recipename', help='Recipe to edit')
219 parser_edit_recipe.add_argument('--any-recipe', '-a', action="store_true", help='Edit any recipe, not just where the recipe file itself is in the workspace') 220 parser_edit_recipe.add_argument('--any-recipe', '-a', action="store_true", help='Edit any recipe, not just where the recipe file itself is in the workspace')
220 parser_edit_recipe.set_defaults(func=edit_recipe) 221 parser_edit_recipe.set_defaults(func=edit_recipe)
@@ -223,7 +224,8 @@ def register_commands(subparsers, context):
223 # gets the order wrong - recipename must come before --arg 224 # gets the order wrong - recipename must come before --arg
224 parser_configure_help = subparsers.add_parser('configure-help', help='Get help on configure script options', 225 parser_configure_help = subparsers.add_parser('configure-help', help='Get help on configure script options',
225 usage='devtool configure-help [options] recipename [--arg ...]', 226 usage='devtool configure-help [options] recipename [--arg ...]',
226 description='Displays the help for the configure script for the specified recipe (i.e. runs ./configure --help) prefaced by a header describing the current options being specified. Output is piped through less (or whatever PAGER is set to, if set) for easy browsing.') 227 description='Displays the help for the configure script for the specified recipe (i.e. runs ./configure --help) prefaced by a header describing the current options being specified. Output is piped through less (or whatever PAGER is set to, if set) for easy browsing.',
228 group='working')
227 parser_configure_help.add_argument('recipename', help='Recipe to show configure help for') 229 parser_configure_help.add_argument('recipename', help='Recipe to show configure help for')
228 parser_configure_help.add_argument('-p', '--no-pager', help='Disable paged output', action="store_true") 230 parser_configure_help.add_argument('-p', '--no-pager', help='Disable paged output', action="store_true")
229 parser_configure_help.add_argument('-n', '--no-header', help='Disable explanatory header text', action="store_true") 231 parser_configure_help.add_argument('-n', '--no-header', help='Disable explanatory header text', action="store_true")