예제 #1
0
파일: project.py 프로젝트: mbolivar/west
    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.')
예제 #2
0
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)
예제 #3
0
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)
예제 #4
0
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')
예제 #5
0
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
예제 #6
0
파일: main.py 프로젝트: sylvioalves/west
    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
예제 #7
0
파일: project.py 프로젝트: mbolivar/west
    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)
예제 #8
0
파일: project.py 프로젝트: XIZHAOJUN/west
 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])
예제 #9
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))
예제 #10
0
    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))
예제 #11
0
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)
예제 #12
0
    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)
예제 #13
0
    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")
예제 #14
0
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')
예제 #15
0
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
예제 #16
0
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))
예제 #17
0
    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
예제 #18
0
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'
예제 #19
0
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
예제 #20
0
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)
예제 #21
0
파일: project.py 프로젝트: XIZHAOJUN/west
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])
예제 #22
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'
예제 #23
0
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'
예제 #24
0
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'])
예제 #25
0
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))
예제 #26
0
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)
예제 #27
0
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
예제 #28
0
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'
예제 #29
0
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'])
예제 #30
0
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)