commands: project: use get_projects() internally

Use self.manifest.get_projects() instead of the older implementation
of similar functionality. With the previous modification to west list
in place, no behavioral changes are expected.

Signed-off-by: Marti Bolivar <marti.bolivar@nordicsemi.no>
This commit is contained in:
Marti Bolivar 2019-08-15 13:57:48 -07:00 committed by Carles Cufí
parent 3b3f8842fa
commit d3d69dd3a8
1 changed files with 37 additions and 87 deletions

View File

@ -48,92 +48,44 @@ class _ProjectCommand(WestCommand):
defaults to all projects in the manifest''') defaults to all projects in the manifest''')
def _cloned_projects(self, args): def _cloned_projects(self, args):
# Returns _projects(args, listed_must_be_cloned=True) if a # Returns _projects(args.projects, only_cloned=True) if
# list of projects was given by the user (i.e., listed # args.projects is not empty (i.e., explicitly given projects
# projects are required to be cloned). If no projects were # are required to be cloned). Otherwise, returns all cloned
# listed, returns all cloned projects. # projects.
if args.projects:
return self._projects(args.projects, only_cloned=True)
else:
return [p for p in self.manifest.projects if p.is_cloned()]
# This approach avoids redundant project.is_cloned() checks def _projects(self, ids, only_cloned=False):
return self._projects(args.projects) if args.projects else \ try:
[p for p in self.manifest.projects if p.is_cloned()] return self.manifest.get_projects(ids, only_cloned=only_cloned)
except ValueError as ve:
if len(ve.args) != 2:
raise # not directly raised by get_projects()
def _projects(self, ids, listed_must_be_cloned=True): # Die with an error message on unknown or uncloned projects.
# Returns a list of project instances for the projects unknown, uncloned = ve.args
# requested in *ids* in the same order that they are specified if unknown:
# there. log.die('Unknown project name{s}/path{s}: {unknown} '
# '(use "west list" to list all projects)'
# If *ids* is empty all the manifest's projects will be .format(s='s' if len(unknown) > 1 else '',
# returned. If a non-existent project was listed by the user, unknown=', '.join(unknown)))
# an error is raised. elif only_cloned and uncloned:
# plural = len(uncloned) > 1
# ids: names = [p.name for p in uncloned]
# A sequence of projects, identified by name (at first priority) log.die(textwrap.dedent('''\
# or path (as a fallback). The following project{} not cloned: {}.
# Please clone {} first, with:
# listed_must_be_cloned (default: True): west update {}
# If True, an error is raised if an uncloned project was listed. This then retry.'''.format('s are' if plural else ' is',
# only applies to projects listed explicitly on the command line. ", ".join(names),
'them' if plural else 'it',
projects = list(self.manifest.projects) " ".join(names))))
if not ids:
# No projects specified. Return all projects.
return projects
# Sort the projects by the length of their absolute paths,
# with the longest path first. That way, projects within
# projects (e.g., for submodules) are tried before their
# parent projects, when projects are specified via their path.
projects.sort(key=lambda project: len(project.abspath), reverse=True)
# Listed but missing projects. Used for error reporting.
missing_projects = []
res = []
uncloned = []
for proj_id in ids:
for project in projects:
if project.name == proj_id:
# The argument is a project name
res.append(project)
if listed_must_be_cloned and not project.is_cloned():
uncloned.append(project.name)
break
else: else:
# The argument is not a project name. See if it specifies # Should never happen, but re-raise to fail fast and
# an absolute or relative path to a project. # preserve a stack trace, to encourage a bug report.
proj_arg_norm = util.canon_path(proj_id) raise
for project in projects:
if proj_arg_norm == util.canon_path(project.abspath):
res.append(project)
break
else:
# Neither a project name nor a project path. We
# will report an error below.
missing_projects.append(proj_id)
if missing_projects:
log.die(
'Unknown project name{0}/path{0} {1} (available projects: {2})'
.format('s' if len(missing_projects) > 1 else '',
', '.join(missing_projects),
', '.join(project.name for project in projects)))
# Check that all listed repositories are cloned, if requested.
if listed_must_be_cloned and uncloned:
plural = len(uncloned) > 1
log.die(textwrap.dedent('''\
The following project{} not cloned: {}.
Please clone {} first, with:
west update {}
then retry.'''
.format('s are' if plural else ' is',
", ".join(uncloned),
'them' if plural else 'it',
" ".join(uncloned))))
return res
class Init(_ProjectCommand): class Init(_ProjectCommand):
@ -439,8 +391,7 @@ class List(_ProjectCommand):
def delay(func, project): def delay(func, project):
return DelayFormat(partial(func, project)) return DelayFormat(partial(func, project))
for project in self._projects(args.projects, for project in self._projects(args.projects):
listed_must_be_cloned=False):
# Spelling out the format keys explicitly here gives us # Spelling out the format keys explicitly here gives us
# future-proofing if the internal Project representation # future-proofing if the internal Project representation
# ever changes. # ever changes.
@ -627,8 +578,7 @@ class Update(_ProjectCommand):
failed_rebases = [] failed_rebases = []
for project in self._projects(args.projects, for project in self._projects(args.projects):
listed_must_be_cloned=False):
if isinstance(project, ManifestProject): if isinstance(project, ManifestProject):
continue continue