예제 #1
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)
예제 #2
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)
예제 #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_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)
예제 #5
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)
예제 #6
0
def test_self_tag():
    # Manifests may contain a self section describing their behavior.
    # It should work with multiple projects and remotes as expected.

    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: the-manifest-path
    '''
    r1 = Remote('testremote1', 'https://example1.com')
    r2 = Remote('testremote2', 'https://example2.com')

    manifest = Manifest.from_data(yaml.safe_load(content))

    expected = [
        ManifestProject(path='the-manifest-path'),
        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):
        check_proj_consistency(p, e)
예제 #7
0
def test_no_defaults(config_file_project_setup):
    # Manifests with no defaults should work.
    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
    '''
    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 = [
            SpecialProject('manifestproject', path='manifestproject'),
            Project('testproject1',
                    r1,
                    None,
                    path='testproject1',
                    clone_depth=None,
                    revision='rev1'),
            Project('testproject2',
                    r2,
                    None,
                    path='testproject2',
                    clone_depth=None,
                    revision='master')
        ]

    # 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)
예제 #8
0
def test_remote_url_init(west_topdir):
    # Projects must be initialized with a remote or a URL, but not both.
    # The resulting URLs must behave as documented.

    r1 = Remote('testremote1', 'https://example.com')
    p1 = Project('project1', None, remote=r1)
    assert p1.remote is r1
    assert p1.url == 'https://example.com/project1'

    p2 = Project('project2', None, url='https://example.com/project2')
    assert p2.remote is None
    assert p2.url == 'https://example.com/project2'

    with pytest.raises(ValueError):
        Project('project3', None, remote=r1, url='not-empty')

    with pytest.raises(ValueError):
        Project('project4', None, remote=None, url=None)
예제 #9
0
def test_multiple_remotes():
    # More than one remote may be used, and one of them may be used as
    # the default.

    content = '''\
    manifest:
      defaults:
        remote: testremote2

      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
        - name: testproject3
    '''
    r1 = Remote('testremote1', 'https://example1.com')
    r2 = Remote('testremote2', 'https://example2.com')

    manifest = Manifest.from_data(yaml.safe_load(content))

    expected = [
        Project('testproject1', revision='rev1', remote=r1),
        Project('testproject2', remote=r2),
        Project('testproject3', 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[1:], expected):
        check_proj_consistency(p, e)

    # Throw in an extra check that absolute paths are not available,
    # just for fun.
    assert all(p.abspath is None for p in manifest.projects)
예제 #10
0
파일: project.py 프로젝트: ulfalizer/west
def _special_project(name):
    # Returns a Project instance for one of the special repositories in west/,
    # so that we can reuse the project-related functions for them
    remote = Remote(name=config.get(name, 'remote', fallback='origin'),
                    url='dummy URL for {} repository'.format(name))

    # 'revision' always exists and defaults to 'master'
    return Project(name,
                   remote,
                   None,
                   revision=config.get(name, 'revision', fallback='master'),
                   path=os.path.join('west', name))
예제 #11
0
파일: project.py 프로젝트: rgundi/west
def _special_project(name):
    # Returns a Project instance for one of the special repositories in west/,
    # so that we can reuse the project-related functions for them

    # TODO: Maybe the Remote class could be replaced by a single
    # project.remote_name field, now that we no longer use the Git remote
    # mechanism and fetch directly from URLs

    remote = Remote(name='dummy name for {} repository'.format(name),
                    url='dummy URL for {} repository'.format(name))

    # 'revision' always exists and defaults to 'master'
    project = Project(name, remote, None,
                      revision=config.get(name, 'revision', fallback='master'),
                      path=os.path.join('west', name))

    # This could also be the name of a Git remote. The naming breaks a bit
    # here.
    project.url = config.get(name, 'remote', fallback='origin')

    return project
예제 #12
0
def test_init_with_url(west_topdir):
    # Test the project constructor works as expected with a URL.

    p = Project('p', url='some-url')
    assert p.name == 'p'
    assert p.remote is None
    assert p.url == 'some-url'
    assert p.path == 'p'
    assert p.abspath == os.path.realpath(os.path.join('/west_top', 'p'))
    posixpath = p.posixpath
    if platform.system() == 'Windows':
        posixpath = os.path.splitdrive(posixpath)[1]
    assert posixpath == '/west_top/p'
    assert p.clone_depth is None
    assert p.revision == 'master'
    assert p.west_commands is None
예제 #13
0
def test_init_with_url_and_topdir():
    # Test the project constructor works as expected with a URL
    # and explicit top level directory.

    p = Project('p', url='some-url', topdir='/west_top')
    assert p.name == 'p'
    assert p.remote is None
    assert p.url == 'some-url'
    assert p.path == 'p'
    assert p.topdir == '/west_top'
    if platform.system() == 'Windows':
        posixpath = os.path.splitdrive(p.posixpath)[1]
        assert posixpath == '/west_top/p'
    assert p.clone_depth is None
    assert p.revision == 'master'
    assert p.west_commands is None
예제 #14
0
def test_repo_path(west_topdir):
    # a project's fetch URL may be specified by combining a remote and
    # repo-path. this overrides the default use of the project's name
    # as the repo-path.

    # default remote + repo-path
    content = '''\
    manifest:
      defaults:
        remote: remote1
      remotes:
        - name: remote1
          url-base: https://example.com
      projects:
        - name: testproject
          repo-path: some/path
    '''
    manifest = Manifest.from_data(yaml.safe_load(content))
    assert manifest.projects[1].url == 'https://example.com/some/path'

    # non-default remote + repo-path
    content = '''\
    manifest:
      defaults:
        remote: remote1
      remotes:
        - name: remote1
          url-base: https://url1.com
        - name: remote2
          url-base: https://url2.com
      projects:
        - name: testproject
          remote: remote2
          repo-path: path
    '''
    manifest = Manifest.from_data(yaml.safe_load(content))
    assert manifest.projects[1].url == 'https://url2.com/path'

    # same project checked out under two different names
    content = '''\
    manifest:
      defaults:
        remote: remote1
      remotes:
        - name: remote1
          url-base: https://url1.com
      projects:
        - name: testproject_v1
          revision: v1.0
          repo-path: testproject
        - name: testproject_v2
          revision: v2.0
          repo-path: testproject
    '''
    manifest = Manifest.from_data(yaml.safe_load(content))
    p1, p2 = manifest.projects[1:]
    r = Remote('remote1', 'https://url1.com')
    assert p1.url == 'https://url1.com/testproject'
    assert p1.url == p2.url
    expected1 = Project('testproject_v1',
                        defaults=None,
                        path='testproject_v1',
                        clone_depth=None,
                        revision='v1.0',
                        west_commands=None,
                        remote=r,
                        repo_path='testproject',
                        url=None)
    expected2 = Project('testproject_v2',
                        defaults=None,
                        path='testproject_v2',
                        clone_depth=None,
                        revision='v2.0',
                        west_commands=None,
                        remote=r,
                        repo_path='testproject',
                        url=None)
    deep_eq_check(p1, expected1)
    deep_eq_check(p2, expected2)
예제 #15
0
파일: test_project.py 프로젝트: utzig/west
def test_import_project_release_fork(repos_tmpdir):
    # Like test_import_project_release(), but with a project fork,
    # and using west init -l.

    remotes = repos_tmpdir / 'repos'

    zephyr = remotes / 'zephyr'
    add_tag(zephyr, 'zephyr-tag')

    fork = remotes / 'my-kconfiglib-fork'
    create_repo(fork)
    add_commit(fork, 'fork kconfiglib')
    add_tag(fork, 'fork-tag')

    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',
               files={
                   'west.yml':
                   f'''
                      manifest:
                        projects:
                        - name: zephyr
                          url: {zephyr}
                          revision: zephyr-tag
                          import: true
                        - name: Kconfiglib
                          url: {fork}
                          revision: fork-tag
                      '''
               })

    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='zephyr-tag', topdir=ws),
        Project('Kconfiglib',
                fork,
                revision='fork-tag',
                path='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)

    zephyr_ws = ws / 'zephyr'
    head_before = rev_parse(zephyr_ws, 'HEAD')
    add_commit(zephyr,
               'this better not show up',
               files={'should-not-clone': ''})

    cmd('update', cwd=ws)

    assert head_before == rev_parse(zephyr_ws, 'HEAD')
    actual = Manifest.from_file(topdir=ws).projects
    for a, e in zip(actual, expected):
        check_proj_consistency(a, e)
    assert (zephyr_ws / 'should-not-clone').check(file=0)
예제 #16
0
파일: test_project.py 프로젝트: utzig/west
def test_import_project_release(repos_tmpdir):
    # Tests for a workspace that's based off of importing from a
    # project at a fixed release, with no downstream project forks.

    remotes = repos_tmpdir / 'repos'
    zephyr = remotes / 'zephyr'
    add_tag(zephyr, 'test-tag')

    # For this test, we create a remote manifest repository. This
    # makes sure we can clone a manifest repository which contains
    # imports without issue (and we don't need to clone the imported
    # projects.)
    #
    # On subsequent tests, we won't bother with this step. We will
    # just put the manifest repository directly into the workspace and
    # use west init -l. This also provides coverage for the -l option
    # in the presence of imports.
    manifest_remote = remotes / 'mp'
    create_repo(manifest_remote)
    add_commit(manifest_remote,
               'manifest repo commit',
               files={
                   'west.yml':
                   f'''
                      manifest:
                        projects:
                        - name: zephyr
                          url: {zephyr}
                          revision: test-tag
                          import: true
                      '''
               })

    # Create the workspace and verify we can't load the manifest yet
    # (because some imported data is missing).
    ws = repos_tmpdir / 'ws'
    cmd(f'init -m {manifest_remote} {ws}')
    with pytest.raises(ManifestImportFailed):
        # We can't load this yet, because we haven't cloned zephyr.
        Manifest.from_file(topdir=ws)

    # Run west update and make sure we can load the manifest now.
    cmd('update', cwd=ws)

    actual = Manifest.from_file(topdir=ws).projects
    expected = [
        ManifestProject(path='mp', topdir=ws),
        Project('zephyr', zephyr, revision='test-tag', 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
    # doesn't affect our local workspace, since we've locked it to a
    # tag.
    zephyr_ws = ws / 'zephyr'
    head_before = rev_parse(zephyr_ws, 'HEAD')
    add_commit(zephyr,
               'this better not show up',
               files={'should-not-clone': ''})

    cmd('update', cwd=ws)

    assert head_before == rev_parse(zephyr_ws, 'HEAD')
    actual = Manifest.from_file(topdir=ws).projects
    for a, e in zip(actual, expected):
        check_proj_consistency(a, e)
    assert (zephyr_ws / 'should-not-clone').check(file=0)