def _find_target_path(taskcluster_path, artifact_map):
    target_path = None
    for map_ in artifact_map:
        if taskcluster_path in map_["paths"]:
            destinations = map_["paths"][taskcluster_path]["destinations"]
            candidate_destination = get_single_item_from_sequence(
                sequence=destinations,
                condition=lambda _: True,
                ErrorClass=TaskVerificationError,
                no_item_error_message=
                f'Path "{taskcluster_path}" has no destination defined',
                too_many_item_error_message=
                f'Path "{taskcluster_path}" has too many destinations',
            )

            if target_path is not None:
                raise TaskVerificationError(
                    f'Path "{taskcluster_path}" was already defined elsewhere in `artifactMap`. '
                    "Previous value: {target_path}. New value: {candidate_destination}"
                )

            target_path = candidate_destination

    if target_path is None:
        raise TaskVerificationError(
            f'Path "{taskcluster_path}" is not present in artifactMap')

    return target_path
Beispiel #2
0
async def checkout_repo(config, task, repo_path):
    """Perform a git clone at ${directory}/src.

    This function will perform a git clone. It will also checkout to the right branch,
    if provided in the task definition.

    Args:
        config (dict): the running config.
        task (dict): the running task.
        repo_path (str): The directory to place the resulting clone.

    Raises:
        TaskVerificationError: if the branch does not exist upstream.

    """
    source_repo = get_source_repo(task)
    if os.path.exists(repo_path):
        log.info("Reusing existing repo_path: {}".format(repo_path))
        repo = Repo(repo_path)
    else:
        log.info('Cloning source_repo "{}" to repo_path: {}'.format(
            source_repo, repo_path))
        repo = Repo.clone_from(
            source_repo,
            repo_path,
        )

    branch = get_branch(task)
    if branch:
        # GitPython cannot simply `git checkout` to right upstream branch. We have to manually
        # create a new branch and manually set the upstream branch
        log.info('Checking out branch "{}"'.format(branch))
        remote_branches = repo.remotes.origin.fetch()
        remote_branches_names = [
            fetch_info.name for fetch_info in remote_branches
        ]
        remote_branch = get_single_item_from_sequence(
            remote_branches_names,
            condition=lambda remote_branch_name: remote_branch_name ==
            _get_upstream_branch_name(branch),
            ErrorClass=TaskVerificationError,
            no_item_error_message="Branch does not exist on remote repo",
            too_many_item_error_message="Too many branches with that name",
        )

        repo.create_head(branch, remote_branch)
        repo.branches[branch].checkout()
    else:
        log.warn(
            "No branch provided in the task payload. Staying on the default one"
        )
Beispiel #3
0
def _extract_last_chunk_of_scope(task, prefix):
    scope = get_single_item_from_sequence(
        sequence=task["scopes"],
        condition=lambda scope: scope.startswith(prefix),
        ErrorClass=TaskVerificationError,
        no_item_error_message=
        f'No scope starting with any of this prefix "{prefix}" found',
        too_many_item_error_message=
        f'Too many scopes with this prefix "{prefix}" found',
    )

    last_chunk = scope.split(":")[prefix.count(
        ":"):]  # the chunk after the prefix is the product name
    return ":".join(last_chunk)
Beispiel #4
0
def test_fail_get_single_item_from_sequence(
    list_,
    condition,
    ErrorClass,
    no_item_error_message,
    too_many_item_error_message,
    append_list_to_error_message,
    has_all_params,
    expected_message,
):
    with pytest.raises(ErrorClass) as exec_info:
        if has_all_params:
            utils.get_single_item_from_sequence(
                list_,
                condition,
                ErrorClass,
                no_item_error_message,
                too_many_item_error_message,
                append_list_to_error_message,
            )
        else:
            utils.get_single_item_from_sequence(list_, condition)

    assert str(exec_info.value) == expected_message
Beispiel #5
0
def extract_common_scope_prefix(config, task):
    prefixes = _get_allowed_scope_prefixes(config)
    scopes = task["scopes"]

    found_prefixes = set((prefix for prefix in prefixes for scope in scopes
                          if scope.startswith(prefix)))

    return get_single_item_from_sequence(
        sequence=found_prefixes,
        condition=lambda _: True,
        ErrorClass=TaskVerificationError,
        no_item_error_message=
        f"No scope starting with any of these prefixes {prefixes} found",
        too_many_item_error_message="Too many prefixes found",
    )
Beispiel #6
0
def _get_existing_artifact(existing_artifacts, target_artifact):
    return get_single_item_from_sequence(sequence=existing_artifacts, condition=lambda github_asset: github_asset.name == target_artifact["name"])
Beispiel #7
0
def test_get_single_item_from_sequence(sequence, condition, expected):
    assert utils.get_single_item_from_sequence(sequence, condition) == expected