Example #1
0
def test_init_with_manifest_filename(repos_tmpdir):
    # Test 'west init --mf' on a normal repo

    west_tmpdir = repos_tmpdir / 'workspace'
    manifest = repos_tmpdir / 'repos' / 'zephyr'

    with open(manifest / 'west.yml', 'r') as f:
        manifest_data = f.read()

    # also creates a west.yml with a syntax error to verify west doesn't even
    # try to load the file
    add_commit(str(manifest),
               'rename manifest',
               files={
                   'west.yml': '[',
                   'project.yml': manifest_data
               })

    # syntax error
    with pytest.raises(subprocess.CalledProcessError):
        cmd(f'init -m "{manifest}" "{west_tmpdir}"')
    shutil.move(west_tmpdir, repos_tmpdir / 'workspace-syntaxerror')

    # success
    cmd(f'init -m "{manifest}" --mf project.yml "{west_tmpdir}"')
    west_tmpdir.chdir()
    config.read_config()
    cmd('update')
Example #2
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)
Example #3
0
def update_helper(west_tmpdir, command):
    # Helper command for causing a change in two remote repositories,
    # then running a project command on the west installation.
    #
    # Adds a commit to both of the kconfiglib and net-tools projects
    # remotes, then run `command`.
    #
    # Captures the 'manifest-rev' and HEAD SHAs in both repositories
    # before and after running the command, returning them in a tuple
    # like this:
    #
    # (net-tools-manifest-rev-before,
    #  net-tools-manifest-rev-after,
    #  net-tools-HEAD-before,
    #  net-tools-HEAD-after,
    #  kconfiglib-manifest-rev-before,
    #  kconfiglib-manifest-rev-after,
    #  kconfiglib-HEAD-before,
    #  kconfiglib-HEAD-after)

    nt_remote = str(west_tmpdir.join('..', 'repos', 'net-tools'))
    nt_local = str(west_tmpdir.join('net-tools'))
    kl_remote = str(west_tmpdir.join('..', 'repos', 'Kconfiglib'))
    kl_local = str(west_tmpdir.join('subdir', 'Kconfiglib'))

    nt_mr_0 = check_output([GIT, 'rev-parse', 'manifest-rev'], cwd=nt_local)
    kl_mr_0 = check_output([GIT, 'rev-parse', 'manifest-rev'], cwd=kl_local)
    nt_head_0 = check_output([GIT, 'rev-parse', 'HEAD'], cwd=nt_local)
    kl_head_0 = check_output([GIT, 'rev-parse', 'HEAD'], cwd=kl_local)

    add_commit(nt_remote, 'another net-tools commit')
    add_commit(kl_remote, 'another kconfiglib commit')

    cmd(command)

    nt_mr_1 = check_output([GIT, 'rev-parse', 'manifest-rev'], cwd=nt_local)
    kl_mr_1 = check_output([GIT, 'rev-parse', 'manifest-rev'], cwd=kl_local)
    nt_head_1 = check_output([GIT, 'rev-parse', 'HEAD'], cwd=nt_local)
    kl_head_1 = check_output([GIT, 'rev-parse', 'HEAD'], cwd=kl_local)

    return (nt_mr_0, nt_mr_1,
            nt_head_0, nt_head_1,
            kl_mr_0, kl_mr_1,
            kl_head_0, kl_head_1)
Example #4
0
    def updater(remotes):
        # Create a v2.0 tag on the remote tagged_repo repository.
        add_commit(remotes.tagged_repo, 'another tagged_repo tagged commit')
        add_tag(remotes.tagged_repo, 'v2.0')

        # Update the manifest file to point the project's revision at
        # the new tag.
        manifest = Manifest.from_file(topdir=west_init_tmpdir)
        for p in manifest.projects:
            if p.name == 'tagged_repo':
                p.revision = 'v2.0'
                break
        else:
            assert False, 'no tagged_repo'
        with open(west_init_tmpdir / 'zephyr' / 'west.yml', 'w') as f:
            f.write(manifest.as_yaml())  # NOT as_frozen_yaml().

        # Pull down the v2.0 tag into west_init_tmpdir.
        cmd('update tagged_repo')
Example #5
0
def test_update_west(west_init_tmpdir):
    # Test the 'west selfupdate' command. It calls through to the same backend
    # functions that are used for automatic updates and 'west init'
    # reinitialization.

    # update the net-tools repository
    cmd('update net-tools')

    west_prev = head_subject('.west/west')

    # Add commits to the local repos. We need to reconfigure
    # explicitly as these are clones, and west doesn't handle that for
    # us.
    for path in 'zephyr', '.west/west', 'net-tools':
        add_commit(path, 'test-update-local', reconfigure=True)

    # Check that resetting the west repository removes the local commit
    cmd('selfupdate')
    assert head_subject('zephyr') == 'test-update-local'  # Unaffected
    assert head_subject('.west/west') == west_prev
    assert head_subject('net-tools') == 'test-update-local'  # Unaffected
Example #6
0
def test_update_projects_local_branch_commits(west_init_tmpdir):
    # Test the 'west update' command when working on local branch with local
    # commits and then updating project to upstream commit.
    # It calls through to the same backend functions that are used for
    # automatic updates and 'west init' reinitialization.

    # update all repositories
    cmd('update')

    # Create a local branch and add commits
    checkout_branch('net-tools', 'local_net_tools_test_branch', create=True)
    checkout_branch('subdir/Kconfiglib',
                    'local_kconfig_test_branch',
                    create=True)
    add_commit('net-tools', 'test local branch commit', reconfigure=True)
    add_commit('subdir/Kconfiglib',
               'test local branch commit',
               reconfigure=True)
    net_tools_prev = head_subject('net-tools')
    kconfiglib_prev = head_subject('subdir/Kconfiglib')

    # Add commits to the upstream repos. We need to reconfigure
    # explicitly as these are clones, and west doesn't handle that for
    # us.
    (nt_mr_0, nt_mr_1, nt_head_0, nt_head_1, kl_mr_0, kl_mr_1, kl_head_0,
     kl_head_1) = update_helper(west_init_tmpdir, 'update')

    assert nt_mr_0 != nt_mr_1, 'failed to update net-tools manifest-rev'
    assert nt_head_0 != nt_head_1, 'failed to update net-tools HEAD'
    assert kl_mr_0 != kl_mr_1, 'failed to update kconfiglib manifest-rev'
    assert kl_head_0 != kl_head_1, 'failed to update kconfiglib HEAD'

    # Verify local branch is still present and untouched
    assert net_tools_prev != head_subject('net-tools')
    assert kconfiglib_prev != head_subject('subdir/Kconfiglib')
    checkout_branch('net-tools', 'local_net_tools_test_branch')
    checkout_branch('subdir/Kconfiglib', 'local_kconfig_test_branch')
    assert net_tools_prev == head_subject('net-tools')
    assert kconfiglib_prev == head_subject('subdir/Kconfiglib')
Example #7
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)
Example #8
0
def test_update_projects_local_branch_commits(west_init_tmpdir):
    # Test the 'west update' command when working on local branch with local
    # commits and then updating project to upstream commit.
    # It calls through to the same backend functions that are used for
    # automatic updates and 'west init' reinitialization.

    # update all repositories
    cmd('update')

    # Create a local branch and add commits
    checkout_branch('net-tools', 'local_net_tools_test_branch', create=True)
    checkout_branch('subdir/Kconfiglib',
                    'local_kconfig_test_branch',
                    create=True)
    checkout_branch('tagged_repo',
                    'local_tagged_repo_test_branch',
                    create=True)
    add_commit('net-tools', 'test local branch commit', reconfigure=True)
    add_commit('subdir/Kconfiglib',
               'test local branch commit',
               reconfigure=True)
    add_commit('tagged_repo', 'test local branch commit', reconfigure=True)
    net_tools_prev = head_subject('net-tools')
    kconfiglib_prev = head_subject('subdir/Kconfiglib')
    tagged_repo_prev = head_subject('tagged_repo')

    # Update the upstream repositories, getting an UpdateResults tuple
    # back.
    ur = update_helper(west_init_tmpdir)

    # We updated all the repositories, so all paths and commits should
    # be valid refs (i.e. there shouldn't be a None or empty string
    # value in a ur attribute).
    assert all(ur)

    # Verify each repository has moved to a new manifest-rev,
    # except tagged_repo, which has a manifest-rev locked to a tag.
    # Its HEAD should change, though.
    assert ur.nt_mr_0 != ur.nt_mr_1, 'failed updating net-tools manifest-rev'
    assert ur.kl_mr_0 != ur.kl_mr_1, 'failed updating kconfiglib manifest-rev'
    assert ur.tr_mr_0 == ur.tr_mr_1, 'tagged_repo manifest-rev changed'
    assert ur.nt_head_0 != ur.nt_head_1, 'failed updating net-tools HEAD'
    assert ur.kl_head_0 != ur.kl_head_1, 'failed updating kconfiglib HEAD'
    assert ur.tr_head_0 != ur.tr_head_1, 'failed updating tagged_repo HEAD'

    # Verify local branch is still present and untouched
    assert net_tools_prev != head_subject('net-tools')
    assert kconfiglib_prev != head_subject('subdir/Kconfiglib')
    assert tagged_repo_prev != head_subject('tagged_repo')
    checkout_branch('net-tools', 'local_net_tools_test_branch')
    checkout_branch('subdir/Kconfiglib', 'local_kconfig_test_branch')
    checkout_branch('tagged_repo', 'local_tagged_repo_test_branch')
    assert net_tools_prev == head_subject('net-tools')
    assert kconfiglib_prev == head_subject('subdir/Kconfiglib')
    assert tagged_repo_prev == head_subject('tagged_repo')
Example #9
0
def test_extension_command_multiproject(repos_tmpdir):
    # Test to ensure that multiple projects can define extension commands and
    # that those are correctly presented and executed.
    rr = repos_tmpdir.join('repos')
    remote_kconfiglib = str(rr.join('Kconfiglib'))
    remote_zephyr = str(rr.join('zephyr'))
    remote_west = str(rr.join('west'))

    # Update the manifest to specify extension commands in Kconfiglib.
    add_commit(remote_zephyr,
               'test added extension command',
               files={
                   'west.yml':
                   textwrap.dedent('''\
                      west:
                        url: file://{west}
                      manifest:
                        defaults:
                          remote: test-local

                        remotes:
                          - name: test-local
                            url-base: file://{rr}

                        projects:
                          - name: Kconfiglib
                            revision: zephyr
                            path: subdir/Kconfiglib
                            west-commands: scripts/west-commands.yml
                          - name: net-tools
                            west-commands: scripts/west-commands.yml
                        self:
                          path: zephyr
                      '''.format(west=remote_west, rr=str(rr)))
               })

    # Add an extension command to the Kconfiglib remote.
    add_commit(remote_kconfiglib,
               'add west commands',
               files={
                   'scripts/west-commands.yml':
                   textwrap.dedent('''\
                      west-commands:
                        - file: scripts/test.py
                          commands:
                            - name: kconfigtest
                              class: Test
                      '''),
                   'scripts/test.py':
                   textwrap.dedent('''\
                      from west.commands import WestCommand
                      class Test(WestCommand):
                          def __init__(self):
                              super(Test, self).__init__(
                                  'kconfigtest',
                                  'Kconfig test application',
                                  '')
                          def do_add_parser(self, parser_adder):
                              parser = parser_adder.add_parser(self.name)
                              return parser
                          def do_run(self, args, ignored):
                              print('Testing kconfig test')
                      '''),
               })
    west_tmpdir = repos_tmpdir.join('west_installation')
    cmd('init -m "{}" "{}"'.format(str(repos_tmpdir.join('repos', 'zephyr')),
                                   str(west_tmpdir)))
    west_tmpdir.chdir()
    config.read_config()
    cmd('update')

    help_text = cmd('-h')
    expected = textwrap.dedent('''\
        commands from project at "subdir/Kconfiglib":
          kconfigtest:          (no help provided; try "west kconfigtest -h")

        commands from project at "net-tools":
          test:                 test-help
        ''')

    assert expected in help_text

    actual = cmd('test')
    assert actual == 'Testing test command 1\n'

    actual = cmd('kconfigtest')
    assert actual == 'Testing kconfig test\n'
Example #10
0
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)
Example #11
0
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)
Example #12
0
def default_updater(remotes):
    add_commit(remotes.net_tools, 'another net-tools commit')
    add_commit(remotes.kconfiglib, 'another kconfiglib commit')
    add_commit(remotes.tagged_repo, 'another tagged_repo commit')
    cmd('update')
Example #13
0
def test_update_recovery(tmpdir):
    # Make sure that the final 'west update' can recover from the
    # following turn of events:
    #
    #   1. 'm' is the manifest repository, 'p' is a project
    #   2. m/west.yml imports p at revision 'rbad'; p/west.yml at rbad
    #      contains an invalid manifest
    #   3. user runs 'west update', setting p's manifest-rev to rbad
    #      (and failing the update)
    #   4. user updates m/west.yml to point at p revision 'rgood',
    #      which contains good manifest data
    #   5. user runs 'west update' again
    #
    # The 'west update' in the last step should fix p's manifest-rev,
    # pointing it at rgood, and should succeed.

    # create path objects and string representations
    workspace = Path(tmpdir) / 'workspace'
    workspacestr = os.fspath(workspace)

    m = workspace / 'm'
    p = workspace / 'p'

    # Set up the workspace repositories.
    workspace.mkdir()
    create_repo(m)
    create_repo(p)

    # Create revision rbad, which contains a bogus manifest, in p.
    add_commit(p,
               'rbad commit message',
               files={'west.yml': 'bogus_data'},
               reconfigure=False)
    rbad = rev_parse(p, 'HEAD')

    # Create revision rgood, which contains a good manifest, in p.
    add_commit(p,
               'rgood commit message',
               files={'west.yml': 'manifest:\n  projects: []'},
               reconfigure=False)
    rgood = rev_parse(p, 'HEAD')

    # Set up the initial, 'bad' manifest.
    #
    # Use an invalid local file as the fetch URL: there's no reason
    # west should be fetching from the remote.
    with open(m / 'west.yml', 'w') as m_manifest:
        m_manifest.write(f'''
        manifest:
          projects:
          - name: p
            url: file://{tmpdir}/should-not-be-fetched
            revision: {rbad}
            import: true
        ''')

    # Use west init -l + west update to point p's manifest-rev at rbad.
    cmd(f'init -l {m}', cwd=workspacestr)
    with pytest.raises(subprocess.CalledProcessError):
        cmd('update', cwd=workspacestr)

    # Make sure p's manifest-rev points to the bad revision as expected.
    prev = rev_parse(p, 'refs/heads/manifest-rev')
    assert prev == rbad

    # Fix the main manifest to point at rgood.
    with open(m / 'west.yml', 'w') as m_manifest:
        m_manifest.write(f'''
        manifest:
          projects:
          - name: p
            url: file://{tmpdir}/should-not-be-fetched
            revision: {rgood}
            import: true
        ''')

    # Run the update, making sure it succeeds and p's manifest-rev
    # is fixed.
    cmd('update', cwd=workspacestr)
    prev = rev_parse(p, 'refs/heads/manifest-rev')
    assert prev == rgood
Example #14
0
def test_extension_command_multiproject(repos_tmpdir):
    # Test to ensure that multiple projects can define extension commands and
    # that those are correctly presented and executed.
    rr = repos_tmpdir.join('repos')
    remote_kconfiglib = str(rr.join('Kconfiglib'))
    remote_zephyr = str(rr.join('zephyr'))
    remote_west = str(rr.join('west'))

    # Update the manifest to specify extension commands in Kconfiglib.
    # This removes tagged_repo, but we're not using it, so that's fine.
    add_commit(remote_zephyr,
               'test added extension command',
               files={
                   'west.yml':
                   textwrap.dedent(f'''\
                      west:
                        url: file://{remote_west}
                      manifest:
                        defaults:
                          remote: test-local

                        remotes:
                          - name: test-local
                            url-base: file://{rr}

                        projects:
                          - name: Kconfiglib
                            revision: zephyr
                            path: subdir/Kconfiglib
                            west-commands: scripts/west-commands.yml
                          - name: net-tools
                            west-commands: scripts/west-commands.yml
                        self:
                          path: zephyr
                      ''')
               })

    # Add an extension command to the Kconfiglib remote.
    add_commit(remote_kconfiglib,
               'add west commands',
               files={
                   'scripts/west-commands.yml':
                   textwrap.dedent('''\
                      west-commands:
                        - file: scripts/test.py
                          commands:
                            - name: kconfigtest
                              class: Test
                      '''),
                   'scripts/test.py':
                   textwrap.dedent('''\
                      from west.commands import WestCommand
                      class Test(WestCommand):
                          def __init__(self):
                              super(Test, self).__init__(
                                  'kconfigtest',
                                  'Kconfig test application',
                                  '')
                          def do_add_parser(self, parser_adder):
                              parser = parser_adder.add_parser(self.name)
                              return parser
                          def do_run(self, args, ignored):
                              print('Testing kconfig test')
                      '''),
               })
    west_tmpdir = repos_tmpdir / 'workspace'
    zephyr = repos_tmpdir / 'repos' / 'zephyr'
    cmd(f'init -m "{zephyr}" "{west_tmpdir}"')
    west_tmpdir.chdir()
    config.read_config()
    cmd('update')

    # The newline shenanigans are for Windows.
    help_text = '\n'.join(cmd('-h').splitlines())
    expected = '\n'.join([
        'extension commands from project Kconfiglib (path: subdir/Kconfiglib):',  # noqa: E501
        '  kconfigtest:          (no help provided; try "west kconfigtest -h")',  # noqa: E501
        '',
        'extension commands from project net-tools (path: net-tools):',
        '  test-extension:       test-extension-help'
    ])
    assert expected in help_text, help_text

    actual = cmd('test-extension')
    assert actual.rstrip() == 'Testing test command 1'

    actual = cmd('kconfigtest')
    assert actual.rstrip() == 'Testing kconfig test'
Example #15
0
def test_update_some_with_imports(repos_tmpdir):
    # 'west update project1 project2' should work fine even when
    # imports are used, as long as the relevant projects are all
    # defined in the manifest repository.
    #
    # It currently should fail with a helpful message if the projects
    # are resolved via project imports.

    remotes = repos_tmpdir / 'repos'
    zephyr = remotes / 'zephyr'
    net_tools = remotes / 'net-tools'

    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
                        self:
                          import: foo.yml
                      ''',
            'foo.yml':
            f'''
                      manifest:
                        projects:
                        - name: net-tools
                          url: {net_tools}
                      '''
        })

    cmd(f'init -l {manifest_repo}')

    # Updating unknown projects should fail as always.

    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()
Example #16
0
def test_extension_command_duplicate(repos_tmpdir):
    # Test to ensure that in case to subprojects introduces same command, it
    # will print a warning.
    rr = repos_tmpdir.join('repos')
    remote_kconfiglib = str(rr.join('Kconfiglib'))
    remote_zephyr = str(rr.join('zephyr'))
    remote_west = str(rr.join('west'))

    add_commit(remote_zephyr,
               'test added extension command',
               files={
                   'west.yml':
                   textwrap.dedent('''\
                      west:
                        url: file://{west}
                      manifest:
                        defaults:
                          remote: test-local

                        remotes:
                          - name: test-local
                            url-base: file://{rr}

                        projects:
                          - name: Kconfiglib
                            revision: zephyr
                            path: subdir/Kconfiglib
                            west-commands: scripts/west-commands.yml
                          - name: net-tools
                            west-commands: scripts/west-commands.yml
                        self:
                          path: zephyr
                      '''.format(west=remote_west, rr=str(rr)))
               })

    # Initialize the net-tools repository.
    add_commit(remote_kconfiglib,
               'add west commands',
               files={
                   'scripts/west-commands.yml':
                   textwrap.dedent('''\
                      west-commands:
                        - file: scripts/test.py
                          commands:
                            - name: test
                              class: Test
                      '''),
                   'scripts/test.py':
                   textwrap.dedent('''\
                      from west.commands import WestCommand
                      class Test(WestCommand):
                          def __init__(self):
                              super(Test, self).__init__(
                                  'test',
                                  'test application',
                                  '')
                          def do_add_parser(self, parser_adder):
                              parser = parser_adder.add_parser(self.name)
                              return parser
                          def do_run(self, args, ignored):
                              print('Testing kconfig test command')
                      '''),
               })
    west_tmpdir = repos_tmpdir.join('west_installation')
    cmd('init -m "{}" "{}"'.format(str(repos_tmpdir.join('repos', 'zephyr')),
                                   str(west_tmpdir)))
    west_tmpdir.chdir()
    config.read_config()
    cmd('update')

    actual = cmd('test', stderr=subprocess.STDOUT)
    warning = 'WARNING: ignoring project net-tools extension command "test";'\
              ' command "test" already defined as extension command\n'
    command_out = 'Testing kconfig test command\n'

    assert actual == warning + command_out
Example #17
0
def test_change_remote_conflict(west_update_tmpdir):
    # Test that `west update` will force fetch into local refs space when
    # remote has changed and cannot be fast forwarded.
    wct = west_update_tmpdir
    tmpdir = wct.join('..')

    rrepo = str(tmpdir.join('repos'))
    net_tools = str(tmpdir.join('repos', 'net-tools'))
    rwest = str(tmpdir.join('repos', 'west'))
    alt_repo = str(tmpdir.join('alt_repo'))
    alt_net_tools = str(tmpdir.join('alt_repo', 'net-tools'))
    create_repo(alt_net_tools)
    add_commit(alt_net_tools,
               'test conflicting commit',
               files={'qemu-script.sh': 'echo alternate world net-tools\n'})

    revision = rev_parse(net_tools, 'HEAD')

    west_yml_content = textwrap.dedent('''\
                      west:
                        url: file://{west}
                      manifest:
                        defaults:
                          remote: test-local

                        remotes:
                          - name: test-local
                            url-base: file://{rr}

                        projects:
                          - name: net-tools
                            revision: {rev}
                        self:
                          path: zephyr
                      '''.format(west=rwest, rr=rrepo, rev=revision))
    add_commit(str(wct.join('zephyr')),
               'test update manifest',
               files={'west.yml': west_yml_content})

    cmd('update')

    revision = rev_parse(alt_net_tools, 'HEAD')

    west_yml_content = textwrap.dedent('''\
                      west:
                        url: file://{west}
                      manifest:
                        defaults:
                          remote: test-local

                        remotes:
                          - name: test-local
                            url-base: file://{rr}
                          - name: test-alternate
                            url-base: file://{ar}

                        projects:
                          - name: net-tools
                            remote: test-alternate
                            revision: {rev}
                        self:
                          path: zephyr
                      '''.format(west=rwest,
                                 ar=alt_repo,
                                 rr=rrepo,
                                 rev=revision))

    add_commit(str(wct.join('zephyr')),
               'test update manifest conflict',
               files={'west.yml': west_yml_content})

    cmd('update')
Example #18
0
def test_extension_command_duplicate(repos_tmpdir):
    # Test to ensure that in case to subprojects introduces same command, it
    # will print a warning.
    rr = repos_tmpdir.join('repos')
    remote_kconfiglib = str(rr.join('Kconfiglib'))
    remote_zephyr = str(rr.join('zephyr'))
    remote_west = str(rr.join('west'))

    # This removes tagged_repo, but we're not using it, so that's fine.
    add_commit(remote_zephyr,
               'test added extension command',
               files={
                   'west.yml':
                   textwrap.dedent(f'''\
                      west:
                        url: file://{remote_west}
                      manifest:
                        defaults:
                          remote: test-local

                        remotes:
                          - name: test-local
                            url-base: file://{rr}

                        projects:
                          - name: Kconfiglib
                            revision: zephyr
                            path: subdir/Kconfiglib
                            west-commands: scripts/west-commands.yml
                          - name: net-tools
                            west-commands: scripts/west-commands.yml
                        self:
                          path: zephyr
                      ''')
               })

    # Initialize the net-tools repository.
    add_commit(remote_kconfiglib,
               'add west commands',
               files={
                   'scripts/west-commands.yml':
                   textwrap.dedent('''\
                      west-commands:
                        - file: scripts/test.py
                          commands:
                            - name: test-extension
                              class: Test
                      '''),
                   'scripts/test.py':
                   textwrap.dedent('''\
                      from west.commands import WestCommand
                      class Test(WestCommand):
                          def __init__(self):
                              super(Test, self).__init__(
                                  'test-extension',
                                  'test application',
                                  '')
                          def do_add_parser(self, parser_adder):
                              parser = parser_adder.add_parser(self.name)
                              return parser
                          def do_run(self, args, ignored):
                              print('Testing kconfig test command')
                      '''),
               })
    west_tmpdir = repos_tmpdir / 'workspace'
    zephyr = repos_tmpdir / 'repos' / 'zephyr'
    cmd(f'init -m "{zephyr}" "{west_tmpdir}"')
    west_tmpdir.chdir()
    config.read_config()
    cmd('update')

    actual = cmd('test-extension', stderr=subprocess.STDOUT).splitlines()
    expected = [
        'WARNING: ignoring project net-tools extension command "test-extension"; command "test-extension" is already defined as extension command',  # noqa: E501
        'Testing kconfig test command',
    ]

    assert actual == expected