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(f'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.')
def test_import_project_release_dir(tmpdir): # Tests for a workspace that imports a directory from a project # at a fixed release. remotes = tmpdir / 'remotes' empty_project = remotes / 'empty_project' create_repo(empty_project) add_commit(empty_project, 'empty-project empty commit') imported = remotes / 'imported' create_repo(imported) add_commit(imported, 'add directory of imports', files={'test.d/1.yml': f'''\ manifest: projects: - name: west.d/1.yml-p1 url: {empty_project} - name: west.d/1.yml-p2 url: {empty_project} ''', 'test.d/2.yml': f'''\ manifest: projects: - name: west.d/2.yml-p1 url: {empty_project} '''}) add_tag(imported, 'import-tag') ws = tmpdir / 'ws' create_workspace(ws, and_git=True) manifest_repo = ws / 'mp' add_commit(manifest_repo, 'manifest repo commit', files={'west.yml': f''' manifest: projects: - name: imported url: {imported} revision: import-tag import: test.d '''}) cmd(f'init -l {manifest_repo}') with pytest.raises(ManifestImportFailed): Manifest.from_file(topdir=ws) cmd('update', cwd=ws) actual = Manifest.from_file(topdir=ws).projects expected = [ManifestProject(path='mp', topdir=ws), Project('imported', imported, revision='import-tag', topdir=ws), Project('west.d/1.yml-p1', empty_project, topdir=ws), Project('west.d/1.yml-p2', empty_project, topdir=ws), Project('west.d/2.yml-p1', empty_project, topdir=ws)] for a, e in zip(actual, expected): check_proj_consistency(a, e)
def test_import_project_rolling(repos_tmpdir): # Like test_import_project_release, but with a rolling downstream # that pulls master. We also use west init -l. remotes = repos_tmpdir / 'repos' zephyr = remotes / 'zephyr' ws = repos_tmpdir / 'ws' create_workspace(ws, and_git=True) manifest_repo = ws / 'mp' create_repo(manifest_repo) add_commit(manifest_repo, 'manifest repo commit', # zephyr revision is implicitly master: files={'west.yml': f''' manifest: projects: - name: zephyr url: {zephyr} import: true '''}) cmd(f'init -l {manifest_repo}') with pytest.raises(ManifestImportFailed): Manifest.from_file(topdir=ws) cmd('update', cwd=ws) actual = Manifest.from_file(topdir=ws).projects expected = [ManifestProject(path='mp', topdir=ws), Project('zephyr', zephyr, revision='master', topdir=ws), Project('Kconfiglib', remotes / 'Kconfiglib', revision='zephyr', path='subdir/Kconfiglib', topdir=ws), Project('tagged_repo', remotes / 'tagged_repo', revision='v1.0', topdir=ws), Project('net-tools', remotes / 'net-tools', clone_depth=1, topdir=ws, west_commands='scripts/west-commands.yml')] for a, e in zip(actual, expected): check_proj_consistency(a, e) # Add a commit in the remote zephyr repository and make sure it # *does* affect our local workspace, since we're rolling with its # master branch. zephyr_ws = ws / 'zephyr' head_before = rev_parse(zephyr_ws, 'HEAD') add_commit(zephyr, 'this better show up', files={'should-clone': ''}) cmd('update', cwd=ws) assert head_before != rev_parse(zephyr_ws, 'HEAD') assert (zephyr_ws / 'should-clone').check(file=1)
def test_ignore_west_section(): # We no longer validate the west section, so things that would # once have been schema errors shouldn't be anymore. Projects # should still work as expected regardless of what's in there. content_wrong_west = '''\ west: url: https://example.com revision: abranch wrongfield: avalue manifest: remotes: - name: testremote url-base: https://example.com projects: - name: testproject remote: testremote path: sub/directory ''' # Parsing manifest only, no exception raised manifest = Manifest.from_data(yaml.safe_load(content_wrong_west), topdir='/west_top') p1 = manifest.projects[1] assert PurePath(p1.path) == PurePath('sub', 'directory') assert PurePath(p1.abspath) == PurePath('/west_top/sub/directory')
def extension_commands(manifest=None): '''Get descriptions of available extension commands. The return value is an ordered map from project paths to lists of WestExtCommandSpec objects, for projects which define extension commands. The map's iteration order matches the manifest.projects order. The return value is empty if configuration option ``commands.allow_extensions`` is false. :param manifest: a parsed ``west.manifest.Manifest`` object, or None to reload a new one. ''' allow_extensions = config.getboolean('commands', 'allow_extensions', fallback=True) if not allow_extensions: return {} if manifest is None: manifest = Manifest.from_file() specs = OrderedDict() for project in manifest.projects: if project.west_commands: specs[project.path] = _ext_specs(project) return specs
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. ' 'Run "west -v manifest --resolve" to debug.') self.mle = e
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() 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 projects(self, manifest_file): try: return Manifest.from_file(manifest_file).projects except MalformedManifest as mm: log.die(mm.args[0]) except MalformedConfig as mc: log.die(mc.args[0])
def do_run(self, args, unknown_args): env = Manifest.from_file() try: kafl_path = env.get_projects(['kafl'])[0].abspath except ValueError as e: kafl_path = env.get_projects(['manifest'])[0].abspath capstone_path = env.get_projects(['capstone'])[0].abspath libxdc_path = env.get_projects(['libxdc'])[0].abspath qemu_path = env.get_projects(['qemu'])[0].abspath kafl_bin_path = os.path.join(kafl_path, 'kafl_fuzz.py') if not os.path.exists(kafl_bin_path): log.wrn("Could not find kAFL-Fuzzer in %s" % kafl_path) kafl_bin_path = "" qemu_bin_path = os.path.join(qemu_path, 'x86_64-softmmu/qemu-system-x86_64') if not os.path.exists(qemu_bin_path): log.wrn("Could not find kAFL Qemu binary in %s" % qemu_path) qemu_bin_path = "" # project executables print("KAFL_BIN_PATH=%s" % kafl_bin_path) print("KAFL_QEMU_PATH=%s" % qemu_bin_path) # project libraries/includes print("C_INCLUDE_PATH=%s/include:%s" % (capstone_path, libxdc_path)) print("LIBRARY_PATH=%s:%s" % (capstone_path, libxdc_path)) print("LD_LIBRARY_PATH=%s:%s" % (capstone_path, libxdc_path))
def do_run(self, args, extra_args): env = Manifest.from_file() for query in extra_args: try: prj = env.get_projects([query]) print(prj[0].abspath) except ValueError as e: # check if `manifest` is the kAFL repo.. if query != 'kafl': log.err( "Could not find %s in west projects. Try `west list`." % query) return try: # check if manifest repo is kAFL kafl_path = env.get_projects(['manifest'])[0].abspath if os.path.exists(kafl_path + '/kafl_fuzz.py'): log.wrn( "Returning `manifest` repo path for query `%s`.." % query) print(kafl_path) except ValueError as e: log.err( "Could not find %s in west projects. Try `west list`." % query) except Exception as e: log.err(str(e))
def main(args) -> None: """Entry point. Args: args: CLI arguments. """ config = yaml.load(open(args.config).read(), Loader=Loader) manifest = Manifest.from_file(args.manifest) ids = get_docset_ids(config, manifest, args.only) output = Path(args.output) output.mkdir(exist_ok=True) for docset, id in ids.items(): log.info(f"Creating cache files for {docset}...") with open(output / f"{docset}-{id}.zip", "wb") as f: with zipfile.ZipFile(f, "w", zipfile.ZIP_DEFLATED) as zf: docset_files = chain( args.build_dir.glob(f"{docset}/**/*"), args.build_dir.glob(f"html/{docset}/**/*"), ) for file in docset_files: if file.name == ENV_CACHE_PICKLE_FILENAME: continue if file.name == ENV_PICKLE_FILENAME: file_cache = file.parent / ENV_CACHE_PICKLE_FILENAME shutil.copy(file, file_cache) patch_environment(file_cache, Path(manifest.topdir)) file = file_cache arcname = file.relative_to(args.build_dir) zf.write(file, arcname)
def do_run(self, args, user_args): # manifest.path is not supposed to be set during init, thus clear it # for the session and update it to correct location when complete. if config.get('manifest', 'path', fallback=None) is not None: config.remove_option('manifest', 'path') manifest_file = os.path.join(args.local or args.cache, 'west.yml') projects = Manifest.from_file(manifest_file).projects manifest_project = projects[MANIFEST_PROJECT_INDEX] if args.local is not None: rel_manifest = os.path.relpath(args.local, util.west_topdir()) update_config('manifest', 'path', rel_manifest) else: if manifest_project.path == '': url_path = urlparse(args.manifest_url).path manifest_project.path = posixpath.basename(url_path) manifest_project.abspath = os.path.realpath( os.path.join(util.west_topdir(), manifest_project.path)) manifest_project.name = manifest_project.path shutil.move(args.cache, manifest_project.abspath) update_config('manifest', 'path', manifest_project.path) for project in projects: if project.path == 'zephyr': update_config('zephyr', 'base', project.path)
def zephyr_manifest(self): # load the upstream manifest. the west.manifest APIs guarantee # in this case that its project hierarchy is rooted in the NCS # directory. z_project = self.manifest.get_projects(['zephyr'], allow_paths=False, only_cloned=True)[0] cp = z_project.git(f'show {self.zephyr_rev}:west.yml', capture_stdout=True, check=True) z_west_yml = cp.stdout.decode('utf-8') try: # The topdir kwarg was added in a pre-release west, which # is required to use this file. The latest stable (0.6.3) # doesn't have it, so pylint is failing with a false error # report here. Turn it off for now; this can be removed # when west 0.7 is out. # # pylint: disable=unexpected-keyword-arg return Manifest.from_data(source_data=yaml.safe_load(z_west_yml), topdir=self.topdir) except MalformedManifest: log.die(f"can't load zephyr manifest; file {z_west_yml} " "is malformed")
def test_sections(): # We no longer validate the west section, so things that would # once have been schema errors shouldn't matter. content_wrong_west = '''\ west: url: https://example.com revision: abranch wrongfield: avalue manifest: remotes: - name: testremote url-base: https://example.com projects: - name: testproject remote: testremote path: sub/directory ''' with patch('west.util.west_topdir', return_value=os.path.realpath('/west_top')): # Parsing manifest only, no exception raised manifest = Manifest.from_data(yaml.safe_load(content_wrong_west)) assert manifest.projects[1].path == 'sub' + os.path.sep + 'directory' assert manifest.projects[1].abspath == \ os.path.realpath('/west_top/sub/directory')
def west_projects(): manifest_file = None projects = [] # West is imported here, as it is optional # (and thus maybe not installed) # if user is providing a specific modules list. from west.manifest import Manifest from west.util import WestNotFound from west.version import __version__ as WestVersion from packaging import version try: manifest = Manifest.from_file() if version.parse(WestVersion) >= version.parse('0.9.0'): projects = [ p for p in manifest.get_projects([]) if manifest.is_active(p) ] else: projects = manifest.get_projects([]) manifest_file = manifest.path return {'manifest': manifest_file, 'projects': projects} except WestNotFound: # Only accept WestNotFound, meaning we are not in a west # workspace. Such setup is allowed, as west may be installed # but the project is not required to use west. pass return None
def test_fs_topdir(fs_topdir): # The API should be able to find a manifest file based on the file # system and west configuration. The resulting topdir and abspath # attributes should work as specified. content = '''\ manifest: projects: - name: project-from-manifest-dir url: from-manifest-dir ''' west_yml = str(fs_topdir / 'mp' / 'west.yml') with open(west_yml, 'w') as f: f.write(content) # manifest_path() should discover west_yml. assert manifest_path() == west_yml # Manifest.from_file() should as well. # The project hierarchy should be rooted in the topdir. manifest = Manifest.from_file() assert manifest.topdir is not None assert manifest.topdir == str(fs_topdir) assert len(manifest.projects) == 2 p = manifest.projects[1] assert p.name == 'project-from-manifest-dir' assert p.url == 'from-manifest-dir' assert p.topdir is not None assert PurePath(p.topdir) == PurePath(str(fs_topdir))
def bootstrap(self, args): manifest_url = args.manifest_url or MANIFEST_URL_DEFAULT manifest_rev = args.manifest_rev or MANIFEST_REV_DEFAULT topdir = util.canon_path(args.directory or os.getcwd()) west_dir = join(topdir, WEST_DIR) try: already = util.west_topdir(topdir, fall_back=False) self.die_already(already) except util.WestNotFound: pass log.banner('Initializing in', topdir) if not isdir(topdir): self.create(topdir, exist_ok=False) # Clone the manifest repository into a temporary directory. tempdir = join(west_dir, 'manifest-tmp') if exists(tempdir): log.dbg('removing existing temporary manifest directory', tempdir) shutil.rmtree(tempdir) try: self.clone_manifest(manifest_url, manifest_rev, tempdir) except subprocess.CalledProcessError: shutil.rmtree(tempdir, ignore_errors=True) raise # Verify the manifest file exists. temp_manifest = join(tempdir, 'west.yml') if not exists(temp_manifest): log.die(f'can\'t init: no "west.yml" found in {tempdir}\n' f' Hint: check --manifest-url={manifest_url} and ' '--manifest-rev={manifest_rev}\n' f' You may need to remove {west_dir} before retrying.') # Parse the manifest to get the manifest path, if it declares one. # Otherwise, use the URL. Ignore imports -- all we really # want to know is if there's a "self: path:" or not. projects = Manifest.from_file(temp_manifest, import_flags=ImportFlag.IGNORE, topdir=topdir).projects manifest_project = projects[MANIFEST_PROJECT_INDEX] if manifest_project.path: manifest_path = manifest_project.path else: manifest_path = posixpath.basename(urlparse(manifest_url).path) manifest_abspath = join(topdir, manifest_path) log.dbg('moving', tempdir, 'to', manifest_abspath, level=log.VERBOSE_EXTREME) try: shutil.move(tempdir, manifest_abspath) except shutil.Error as e: log.die(e) log.small_banner('setting manifest.path to', manifest_path) update_config('manifest', 'path', manifest_path, topdir=topdir) return topdir
def test_sections(): # Projects must be able to override their default paths. content_wrong_west = '''\ west: url: https://example.com revision: abranch wrongfield: avalue manifest: remotes: - name: testremote url-base: https://example.com projects: - name: testproject remote: testremote path: sub/directory ''' with patch('west.util.west_topdir', return_value=os.path.realpath('/west_top')): # Parsing manifest only, no exception raised manifest = Manifest.from_data(yaml.safe_load(content_wrong_west), sections=['manifest']) assert manifest.projects[1].path == 'sub' + os.path.sep + 'directory' assert manifest.projects[1].abspath == \ os.path.realpath('/west_top/sub/directory') content_wrong_manifest = '''\ west: url: https://example.com revision: abranch manifest: remotes: - name: testremote url-base: https://example.com projects: - name: testproject remote: testremote path: sub/directory ''' with patch('west.util.west_topdir', return_value=os.path.realpath('/west_top')): # Parsing west section only, no exception raised manifest = Manifest.from_data(yaml.safe_load(content_wrong_manifest), sections=['west']) assert manifest.west_project.url == 'https://example.com' assert manifest.west_project.revision == 'abranch'
def test_fs_topdir_freestanding_manifest(tmpdir, fs_topdir): # The API should be able to parse a random manifest file # in a location that has nothing to do with the current topdir. # # The resulting Manifest will have projects rooted at topdir. # # If it has a self path, that's its path, and the ManifestProject # is rooted at topdir. Otherwise, its path and abspath are None. topdir = str(fs_topdir) # Case 1: self path is present. ManifestProject is rooted # within the same topdir as the projects. content = '''\ manifest: projects: - name: name url: url self: path: my-path ''' yml = str(tmpdir / 'random.yml') with open(yml, 'w') as f: f.write(content) manifest = Manifest.from_file(source_file=yml, topdir=topdir) assert PurePath(manifest.topdir) == PurePath(topdir) mproj = manifest.projects[0] assert mproj.path == 'my-path' assert PurePath(mproj.abspath) == PurePath(str(fs_topdir / 'my-path')) # Case 1: self path is missing content = '''\ manifest: projects: - name: name url: url ''' yml = str(tmpdir / 'random.yml') with open(yml, 'w') as f: f.write(content) manifest = Manifest.from_file(source_file=yml, topdir=topdir) assert PurePath(manifest.topdir) == PurePath(topdir) mproj = manifest.projects[0] assert mproj.path is None assert mproj.abspath is None
def test_default_clone_depth(config_file_project_setup): # Defaults and clone depth should work as in this example. content = '''\ manifest: defaults: remote: testremote1 revision: defaultrev remotes: - name: testremote1 url-base: https://example1.com - name: testremote2 url-base: https://example2.com projects: - name: testproject1 - name: testproject2 remote: testremote2 revision: rev clone-depth: 1 ''' r1 = Remote('testremote1', 'https://example1.com') r2 = Remote('testremote2', 'https://example2.com') d = Defaults(remote=r1, revision='defaultrev') with patch('west.util.west_topdir', return_value='/west_top'): manifest = Manifest.from_data(yaml.safe_load(content)) expected = [ ManifestProject(path='manifestproject'), Project('testproject1', d, path='testproject1', clone_depth=None, revision=d.revision, remote=r1), Project('testproject2', d, path='testproject2', clone_depth=1, revision='rev', remote=r2) ] # Check that default attributes match. assert manifest.defaults.remote == d.remote assert manifest.defaults.revision == d.revision # Check the remotes are as expected. assert list(manifest.remotes) == [r1, r2] # Check that the projects are as expected. for p, e in zip(manifest.projects, expected): deep_eq_check(p, e) assert all(p.abspath == os.path.realpath(os.path.join('/west_top', p.path)) for p in manifest.projects)
def _all_projects(): # Get a list of project objects from the manifest. # # If the manifest is malformed, a fatal error occurs and the # command aborts. try: return list(Manifest.from_file().projects) except MalformedManifest as m: log.die(m.args[0])
def test_project_named_west(): # A project named west is allowed now, even though it was once an error. content = '''\ manifest: projects: - name: west url: https://foo.com ''' manifest = Manifest.from_data(yaml.safe_load(content)) assert manifest.projects[1].name == 'west'
def test_no_remote_ok(west_topdir): # remotes isn't required if projects are specified by URL. content = '''\ manifest: projects: - name: testproject url: https://example.com/my-project ''' manifest = Manifest.from_data(yaml.safe_load(content)) assert manifest.projects[1].url == 'https://example.com/my-project'
def test_get_projects_unknown(): content = '''\ manifest: projects: - name: foo url: https://foo.com ''' with patch('west.util.west_topdir', return_value='/west_top'): manifest = Manifest.from_data(yaml.safe_load(content)) with pytest.raises(ValueError): manifest.get_projects(['unknown'])
def set_zephyr_base(args): '''Ensure ZEPHYR_BASE is set, emitting warnings if that's not possible, or if the user is pointing it somewhere different than what the manifest expects.''' 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. try: manifest = Manifest.from_file() except MalformedConfig as e: log.die('Parsing of manifest file failed during command', args.command, ':', *e.args) 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): # The environment ZEPHYR_BASE takes precedence over either the # command line or the manifest, but in normal multi-repo # operation we shouldn't expect to need to set ZEPHYR_BASE to # point to some random place. In practice, this is probably # happening because zephyr-env.sh/cmd was run in some other # zephyr installation, and the user forgot about that. log.wrn('ZEPHYR_BASE={}'.format(zb_env), 'in the calling environment, but has been set to', zb, 'instead by the', zb_origin) os.environ['ZEPHYR_BASE'] = zb log.dbg('ZEPHYR_BASE={} (origin: {})'.format(zb, zb_origin))
def test_default_clone_depth(): # Defaults and clone depth should work as in this example. content = '''\ manifest: defaults: remote: testremote1 revision: defaultrev remotes: - name: testremote1 url-base: https://example1.com - name: testremote2 url-base: https://example2.com projects: - name: testproject1 - name: testproject2 remote: testremote2 revision: rev clone-depth: 1 ''' r1 = Remote('testremote1', 'https://example1.com') r2 = Remote('testremote2', 'https://example2.com') d = Defaults(remote=r1, revision='defaultrev') manifest = Manifest.from_data(yaml.safe_load(content)) expected = [ Project('testproject1', d, path='testproject1', clone_depth=None, revision=d.revision, remote=r1), Project('testproject2', d, path='testproject2', clone_depth=1, revision='rev', remote=r2) ] # Check that default attributes match. assert manifest.defaults.remote == d.remote assert manifest.defaults.revision == d.revision # Check the remotes are as expected. assert list(manifest.remotes) == [r1, r2] # Check that the projects are as expected. for p, e in zip(manifest.projects[1:], expected): check_proj_consistency(p, e)
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 test_project_west_commands(): # Projects may specify subdirectories containing west commands. content = '''\ manifest: projects: - name: zephyr url: https://foo.com west-commands: some-path/west-commands.yml ''' manifest = Manifest.from_data(yaml.safe_load(content)) assert len(manifest.projects) == 2 assert manifest.projects[1].west_commands == 'some-path/west-commands.yml'
def test_get_projects_unknown(): # Attempting to get an unknown project is an error. # TODO: add more testing for get_projects(). content = '''\ manifest: projects: - name: foo url: https://foo.com ''' manifest = Manifest.from_data(yaml.safe_load(content)) with pytest.raises(ValueError): manifest.get_projects(['unknown'])
def test_self_tag(project_setup): # Manifests with self tag reference. content = '''\ manifest: remotes: - name: testremote1 url-base: https://example1.com - name: testremote2 url-base: https://example2.com projects: - name: testproject1 remote: testremote1 revision: rev1 - name: testproject2 remote: testremote2 self: path: mainproject ''' r1 = Remote('testremote1', 'https://example1.com') r2 = Remote('testremote2', 'https://example2.com') with patch('west.util.west_topdir', return_value='/west_top'): manifest = Manifest.from_data(yaml.safe_load(content)) expected = [ ManifestProject(path='mainproject'), Project('testproject1', None, path='testproject1', clone_depth=None, revision='rev1', remote=r1), Project('testproject2', None, path='testproject2', clone_depth=None, revision='master', remote=r2) ] # Check the remotes are as expected. assert list(manifest.remotes) == [r1, r2] # Check the projects are as expected. for p, e in zip(manifest.projects, expected): deep_eq_check(p, e) assert all(p.abspath == os.path.realpath(os.path.join('/west_top', p.path)) for p in manifest.projects)