west list: teach it about project groups
Add '-f {groups}' and '--all' options. Respect active projects by not printing inactive ones by default. This allows printing a project's groups, and hides non-updatable groups by default. Here we rely on the fact that groups may not have commas or whitespace to ensure that the printed-out groups are a single whitespace-free and comma separated string in the 'west list' output. For example, in this manifest: manifest: # ... projects: - name: foo groups: - foo-group-1 - foo-group-2 - name: bar path: path-for-bar - name: baz groups: - baz-group The output for "west list -f '{name} {groups} {path}'" is the following, with <SPC> standing for a space character: foo<SPC>foo-group-1,foo-group-2<SPC>foo bar<SPC><SPC>path-for-bar baz<SPC>baz-group<SPC>baz The empty string in the {groups} field for 'bar' can be picked up by tools like cut(1) to find the entire list of groups. E.g., this command $ west list -f '{name} {groups} {path} | cut -d' ' -f 2 will print: foo-group-1,foo-group-2 baz-group Additionally, we repurpose the old --all command line option (that used to print the location of the bootstrapped west repository back in the 0.5.x days) to print projects that would be skipped by 'west update' by default due to groups or no-groups lists. We're about to do something similar to several other commands, so structure the help in the epilog in a way that we'll take advantage of in subsequent patches. Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
This commit is contained in:
parent
c1d9146d01
commit
018e62885d
|
@ -376,35 +376,38 @@ class List(_ProjectCommand):
|
|||
default_fmt = '{name:12} {path:28} {revision:40} {url}'
|
||||
parser = self._parser(
|
||||
parser_adder,
|
||||
epilog=textwrap.dedent(f'''\
|
||||
FORMAT STRINGS
|
||||
--------------
|
||||
epilog=f'''\
|
||||
{ACTIVE_PROJECTS_HELP}
|
||||
|
||||
Projects are listed using a Python 3 format string. Arguments
|
||||
to the format string are accessed by name.
|
||||
FORMAT STRINGS
|
||||
--------------
|
||||
|
||||
The default format string is:
|
||||
Projects are listed using a Python 3 format string. Arguments
|
||||
to the format string are accessed by name.
|
||||
|
||||
"{default_fmt}"
|
||||
The default format string is:
|
||||
|
||||
The following arguments are available:
|
||||
"{default_fmt}"
|
||||
|
||||
- name: project name in the manifest
|
||||
- url: full remote URL as specified by the manifest
|
||||
- path: the relative path to the project from the top level,
|
||||
as specified in the manifest where applicable
|
||||
- abspath: absolute and normalized path to the project
|
||||
- posixpath: like abspath, but in posix style, that is, with '/'
|
||||
as the separator character instead of '\\'
|
||||
- revision: project's revision as it appears in the manifest
|
||||
- sha: project's revision as a SHA. Note that use of this requires
|
||||
that the project has been cloned.
|
||||
- cloned: "cloned" if the project has been cloned, "not-cloned"
|
||||
otherwise
|
||||
- clone_depth: project clone depth if specified, "None" otherwise
|
||||
'''))
|
||||
The following arguments are available:
|
||||
|
||||
- name: project name in the manifest
|
||||
- url: full remote URL as specified by the manifest
|
||||
- path: the relative path to the project from the top level,
|
||||
as specified in the manifest where applicable
|
||||
- abspath: absolute and normalized path to the project
|
||||
- posixpath: like abspath, but in posix style, that is, with '/'
|
||||
as the separator character instead of '\\'
|
||||
- revision: project's revision as it appears in the manifest
|
||||
- sha: project's revision as a SHA. Note that use of this requires
|
||||
that the project has been cloned.
|
||||
- cloned: "cloned" if the project has been cloned, "not-cloned"
|
||||
otherwise
|
||||
- clone_depth: project clone depth if specified, "None" otherwise
|
||||
- groups: project groups, as a comma-separated list
|
||||
''')
|
||||
parser.add_argument('-a', '--all', action='store_true',
|
||||
help='ignored for backwards compatibility'),
|
||||
help='include inactive projects'),
|
||||
parser.add_argument('--manifest-path-from-yaml', action='store_true',
|
||||
help='''print the manifest repository's path
|
||||
according to the manifest file YAML, which may
|
||||
|
@ -414,7 +417,9 @@ class List(_ProjectCommand):
|
|||
help='''format string to use to list each
|
||||
project; see FORMAT STRINGS below.''')
|
||||
|
||||
self._add_projects_arg(parser)
|
||||
parser.add_argument('projects', metavar='PROJECT', nargs='*',
|
||||
help='''projects (by name or path) to operate on;
|
||||
see ACTIVE PROJECTS below''')
|
||||
|
||||
return parser
|
||||
|
||||
|
@ -441,6 +446,13 @@ class List(_ProjectCommand):
|
|||
self._setup_logging(args)
|
||||
|
||||
for project in self._projects(args.projects):
|
||||
# Skip inactive projects unless the user said
|
||||
# --all or named some projects explicitly.
|
||||
if not (args.all or args.projects or
|
||||
self.manifest.is_active(project)):
|
||||
log.dbg(f'{project.name}: skipping, inactive')
|
||||
continue
|
||||
|
||||
# Spelling out the format keys explicitly here gives us
|
||||
# future-proofing if the internal Project representation
|
||||
# ever changes.
|
||||
|
@ -471,7 +483,8 @@ class List(_ProjectCommand):
|
|||
revision=project.revision or 'N/A',
|
||||
clone_depth=project.clone_depth or "None",
|
||||
cloned=delay(cloned_thunk, project),
|
||||
sha=delay(sha_thunk, project))
|
||||
sha=delay(sha_thunk, project),
|
||||
groups=','.join(project.groups))
|
||||
except KeyError as e:
|
||||
# The raised KeyError seems to just put the first
|
||||
# invalid argument in the args tuple, regardless of
|
||||
|
@ -1421,6 +1434,24 @@ MANIFEST_URL_DEFAULT = 'https://github.com/zephyrproject-rtos/zephyr'
|
|||
# Default revision to check out of the manifest repository.
|
||||
MANIFEST_REV_DEFAULT = 'master'
|
||||
|
||||
#
|
||||
# Other shared globals.
|
||||
#
|
||||
|
||||
ACTIVE_PROJECTS_HELP = '''\
|
||||
ACTIVE PROJECTS
|
||||
---------------
|
||||
|
||||
Default output is limited to "active" projects as determined by the:
|
||||
|
||||
- "groups" manifest file section
|
||||
- "manifest.groups" local configuration option in .west/config
|
||||
|
||||
To include inactive projects as well, use "--all" or give an explicit
|
||||
list of projects (by name or path). See the west documentation for
|
||||
more details on active projects.
|
||||
'''
|
||||
|
||||
#
|
||||
# Helper class for creating format string keys that are expensive or
|
||||
# undesirable to compute if not needed.
|
||||
|
|
|
@ -145,6 +145,59 @@ def test_list_manifest(west_update_tmpdir):
|
|||
assert posixpath == Path(west_update_tmpdir).as_posix() + '/zephyr'
|
||||
|
||||
|
||||
def test_list_groups(west_init_tmpdir):
|
||||
with open('zephyr/west.yml', 'w') as f:
|
||||
f.write("""
|
||||
manifest:
|
||||
defaults:
|
||||
remote: r
|
||||
remotes:
|
||||
- name: r
|
||||
url-base: https://example.com
|
||||
projects:
|
||||
- name: foo
|
||||
groups:
|
||||
- foo-group-1
|
||||
- foo-group-2
|
||||
- name: bar
|
||||
path: path-for-bar
|
||||
- name: baz
|
||||
groups:
|
||||
- baz-group
|
||||
groups: [-foo-group-1,-foo-group-2,-baz-group]
|
||||
""")
|
||||
|
||||
def check(command_string, expected):
|
||||
out_lines = cmd(command_string).splitlines()
|
||||
assert out_lines == expected
|
||||
|
||||
check('list -f "{name} .{groups}. {path}"',
|
||||
['manifest .. zephyr',
|
||||
'bar .. path-for-bar'])
|
||||
|
||||
check('list -f "{name} .{groups}. {path}" foo',
|
||||
['foo .foo-group-1,foo-group-2. foo'])
|
||||
|
||||
check('list -f "{name} .{groups}. {path}" baz',
|
||||
['baz .baz-group. baz'])
|
||||
|
||||
check('list -f "{name} .{groups}. {path}" foo bar baz',
|
||||
['foo .foo-group-1,foo-group-2. foo',
|
||||
'bar .. path-for-bar',
|
||||
'baz .baz-group. baz'])
|
||||
|
||||
check('list --all -f "{name} .{groups}. {path}"',
|
||||
['manifest .. zephyr',
|
||||
'foo .foo-group-1,foo-group-2. foo',
|
||||
'bar .. path-for-bar',
|
||||
'baz .baz-group. baz'])
|
||||
|
||||
cmd('config manifest.groups foo-group-1')
|
||||
check('list -f "{name} .{groups}. {path}"',
|
||||
['manifest .. zephyr',
|
||||
'foo .foo-group-1,foo-group-2. foo',
|
||||
'bar .. path-for-bar'])
|
||||
|
||||
def test_manifest_freeze(west_update_tmpdir):
|
||||
# We should be able to freeze manifests.
|
||||
actual = cmd('manifest --freeze').splitlines()
|
||||
|
|
Loading…
Reference in New Issue