Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
with pytest.raises(subprocess.CalledProcessError):
cmd('update unknown-project', cwd=ws)
# Updating a list of projects when some are resolved via project
# imports must fail.
with pytest.raises(subprocess.CalledProcessError):
cmd('update Kconfiglib net-tools', cwd=ws)
# Updates of projects defined in the manifest repository or all
# projects must succeed, and behave the same as if no imports
# existed.
cmd('update net-tools', cwd=ws)
with pytest.raises(ManifestImportFailed):
Manifest.from_file(topdir=ws)
manifest = Manifest.from_file(topdir=ws, import_flags=MIF.IGNORE_PROJECTS)
projects = manifest.get_projects(['net-tools', 'zephyr'])
net_tools_project = projects[0]
zephyr_project = projects[1]
assert net_tools_project.is_cloned()
assert not zephyr_project.is_cloned()
cmd('update zephyr', cwd=ws)
assert zephyr_project.is_cloned()
cmd('update', cwd=ws)
manifest = Manifest.from_file(topdir=ws)
assert manifest.get_projects(['Kconfiglib'])[0].is_cloned()
cmd('update unknown-project', cwd=ws)
# Updating a list of projects when some are resolved via project
# imports must fail.
with pytest.raises(subprocess.CalledProcessError):
cmd('update Kconfiglib net-tools', cwd=ws)
# Updates of projects defined in the manifest repository or all
# projects must succeed, and behave the same as if no imports
# existed.
cmd('update net-tools', cwd=ws)
with pytest.raises(ManifestImportFailed):
Manifest.from_file(topdir=ws)
manifest = Manifest.from_file(topdir=ws, import_flags=MIF.IGNORE_PROJECTS)
projects = manifest.get_projects(['net-tools', 'zephyr'])
net_tools_project = projects[0]
zephyr_project = projects[1]
assert net_tools_project.is_cloned()
assert not zephyr_project.is_cloned()
cmd('update zephyr', cwd=ws)
assert zephyr_project.is_cloned()
cmd('update', cwd=ws)
manifest = Manifest.from_file(topdir=ws)
assert manifest.get_projects(['Kconfiglib'])[0].is_cloned()
def MF(**kwargs):
# A convenience to save typing
return Manifest.from_file(**kwargs)
assert mproj.abspath is None
assert mproj.posixpath is None
p1 = manifest.projects[1]
assert p1.name == 'another-1'
assert p1.url == 'another-url-1'
assert p1.topdir == topdir
assert PurePath(p1.abspath) == topdir / 'another-1'
p2 = manifest.projects[2]
assert p2.name == 'another-2'
assert p2.url == 'another-url-2'
assert p2.topdir == topdir
assert PurePath(p2.abspath) == topdir / 'another' / 'path'
# On the other hand, if the manifest yaml file does specify its
# path, the ManifestProject must also be rooted at topdir.
manifest = Manifest.from_file(source_file=another_yml_with_path)
mproj = manifest.projects[0]
assert mproj.path == 'with-path'
assert PurePath(mproj.topdir) == topdir
assert PurePath(mproj.abspath) == topdir / 'with-path'
with open(another_yml_with_path, 'w') as f:
f.write('''\
manifest:
projects:
- name: foo
url: bar
self:
path: with-path
''')
# manifest_path() should discover west_yml.
assert manifest_path() == west_yml
# Manifest.from_file() should discover west.yml, and
# the project hierarchy should be rooted at topdir.
manifest = Manifest.from_file()
assert PurePath(manifest.topdir) == topdir
assert len(manifest.projects) == 3
assert manifest.projects[1].name == 'project-1'
assert manifest.projects[2].name == 'project-2'
# Manifest.from_file() should be also usable with another_yml.
# The project hierarchy in its return value should still be rooted
# in the topdir, but the resulting ManifestProject does not have a
# path, because it's not set in the file, and we're explicitly not
# comparing its path to manifest.path.
#
# However, the project hierarchy *must* be rooted at topdir.
manifest = Manifest.from_file(source_file=another_yml)
assert len(manifest.projects) == 3
assert manifest.topdir is not None
assert PurePath(manifest.topdir) == PurePath(topdir)
def update_all(self, args):
# Plain 'west update' is the 'easy' case: since the user just
# wants us to update everything, we don't have to keep track
# of projects appearing or disappearing as a result of fetching
# new revisions from projects with imports.
#
# So we just re-parse the manifest, but force west.manifest to
# call our importer whenever it encounters an import statement
# in a project, allowing us to control the recursion so it
# always uses the latest manifest data.
self.updated = set()
self.args = args
manifest = Manifest.from_file(importer=self.update_importer,
import_flags=ImportFlag.FORCE_PROJECTS)
failed = []
for project in manifest.projects:
if (isinstance(project, ManifestProject) or
project.name in self.updated):
continue
try:
self.update(project)
self.updated.add(project.name)
except subprocess.CalledProcessError:
failed.append(project)
self._handle_failed(args, failed)
def load_manifest(self):
# Try to parse the manifest. We'll save it if that works, so
# it doesn't have to be re-parsed.
if not self.topdir:
return
try:
self.manifest = Manifest.from_file(topdir=self.topdir)
except (ManifestVersionError, MalformedManifest, MalformedConfig,
FileNotFoundError, ManifestImportFailed) as e:
# Defer exception handling to WestCommand.run(), which uses
# handle_builtin_manifest_load_err() to decide what to do.
#
# Make sure to update that function if you change the
# exceptions caught here. Unexpected exceptions should
# propagate up and fail fast.
#
# This might be OK, e.g. if we're running 'west config
# manifest.path foo' to fix the MalformedConfig error, but
# there's no way to know until we've parsed the command
# line arguments.
if isinstance(e, _ManifestImportDepth):
log.wrn('recursion depth exceeded during manifest resolution; '
'your manifest likely contains an import loop. '
zb_env = os.environ.get('ZEPHYR_BASE')
if args.zephyr_base:
# The command line --zephyr-base takes precedence over
# everything else.
zb = os.path.abspath(args.zephyr_base)
zb_origin = 'command line'
else:
# If the user doesn't specify it concretely, use the project
# with path 'zephyr' if that exists, or the ZEPHYR_BASE value
# in the calling environment.
#
# At some point, we need a more flexible way to set environment
# variables based on manifest contents, but this is good enough
# to get started with and to ask for wider testing.
manifest = Manifest.from_file()
for project in manifest.projects:
if project.path == 'zephyr':
zb = project.abspath
zb_origin = 'manifest file {}'.format(manifest.path)
break
else:
if zb_env is None:
log.wrn('no --zephyr-base given, ZEPHYR_BASE is unset,',
'and no manifest project has path "zephyr"')
zb = None
zb_origin = None
else:
zb = zb_env
zb_origin = 'environment'
if zb_env and os.path.abspath(zb) != os.path.abspath(zb_env):
def _special_project(args, name):
# Returns a Project instance for one of the special repositories in west/,
# so that we can reuse the project-related functions for them
if name == 'manifest':
url = config.get(name, 'remote', fallback='origin')
revision = config.get(name, 'revision', fallback='master')
return SpecialProject(name, revision=revision,
path=os.path.join('west', name), url=url)
return Manifest.from_file(_manifest_path(args), name).west_project
def toplevel_projects(self, args):
# Return a list of projects from args.projects, or scream and
# die if any projects are either unknown or not defined in the
# manifest repository.
ids = args.projects
assert ids
mr_projects, mr_unknown = projects_unknown(
Manifest.from_file(import_flags=ImportFlag.IGNORE_PROJECTS), ids)
if not mr_unknown:
return mr_projects
try:
manifest = Manifest.from_file()
except ManifestImportFailed:
log.die('one or more projects are unknown or defined via '
'imports; please run plain "west update".')
projects, unknown = projects_unknown(manifest, ids)
if unknown:
die_unknown(unknown)
else:
# All of the ids are known projects, but some of them
# are not defined in the manifest repository.
mr_unknown_set = set(mr_unknown)
from_projects = [p for p in ids if p in mr_unknown_set]
log.die('refusing to update project: ' +
" ".join(from_projects) + '\n' +
' It or they were resolved via project imports.\n'
' Only plain "west update" can currently update them.')