Beispiel #1
0
async def clone_git(clonespec):
    """Note: we ignore transforming git submodules into fat repository here since we'll rewrite history for the branch if we do that"""
    with asutil.TemporaryDirectory(suffix="git") as clone_dir:

        c = await config.get_configuration()
        git_user = c.get("git_username")

        new_internal_repo = await check_new_internal_repo(
            asutil.add_username_url(clonespec["targetRepoUrl"], git_user)
        )
        logger.info(
            "The internal repository considered new? => " + str(new_internal_repo)
        )

        # NCL-4255: if ref provided and internal repository is not 'new', sync the ref only
        if "ref" in clonespec and clonespec["ref"] and not new_internal_repo:
            await git.clone(clone_dir, clonespec["originRepoUrl"])  # Clone origin
            await git.checkout(clone_dir, clonespec["ref"], force=True)  # Checkout ref
            await git.add_remote(
                clone_dir,
                "target",
                asutil.add_username_url(clonespec["targetRepoUrl"], git_user),
            )  # Add target remote

            ref = clonespec["ref"]
            await push_sync_changes(clone_dir, ref, "target")
        else:
            # Sync everything if ref not specified or internal repository is new
            # From: https://stackoverflow.com/a/7216269/2907906
            logger.info("Syncing everything")
            await git.clone_mirror(
                clone_dir + "/.git", clonespec["originRepoUrl"]
            )  # Clone origin
            await git.disable_bare_repository(clone_dir)
            await git.reset_hard(clone_dir)
            await git.add_remote(
                clone_dir,
                "target",
                asutil.add_username_url(clonespec["targetRepoUrl"], git_user),
            )  # Add target remote
            await git.push_all(clone_dir, "target", tags_also=True)

        return clonespec
Beispiel #2
0
async def adjust(adjustspec, repo_provider):
    """
    This method executes adjust providers as specified in configuration.
    Returns a dictionary corresponding to the HTTP response content.
    """

    c = await config.get_configuration()

    adjust_result = {"adjustType": [], "resultData": {}}

    result = {}

    verify_only_authorized_urls_used(adjustspec, c)

    # By default the buildType is Maven
    build_type = "MVN"

    if "buildType" in adjustspec:
        logger.info("Build Type specified: " + adjustspec["buildType"])
        build_type = adjustspec["buildType"]

    with asutil.TemporaryDirectory(suffix="git") as work_dir:

        repo_url = await repo_provider(adjustspec, create=False)

        process_mdc("BEGIN", "SCM_CLONE")
        sync_enabled = await is_sync_on(adjustspec)
        if sync_enabled:
            await sync_external_repo(adjustspec, repo_provider, work_dir, c)
        else:
            git_user = c.get("git_username")

            await git.clone(work_dir,
                            asutil.add_username_url(repo_url.readwrite,
                                                    git_user))  # Clone origin
            await git.checkout(work_dir, adjustspec["ref"],
                               force=True)  # Checkout ref

        await asgit.setup_commiter(expect_ok, work_dir)
        await asgit.transform_git_submodule_into_fat_repository(work_dir)
        process_mdc("END", "SCM_CLONE")

        process_mdc("BEGIN", "ALIGNMENT_ADJUST")
        ### Adjust Phase ###
        if build_type == "MVN":
            specific_tag_name = await adjust_mvn(work_dir, c, adjustspec,
                                                 adjust_result)
        elif build_type == "GRADLE":
            specific_tag_name = await adjust_gradle(work_dir, c, adjustspec,
                                                    adjust_result)
        elif build_type == "SBT":
            specific_tag_name = await adjust_scala(work_dir, c, adjustspec,
                                                   adjust_result)
        else:
            specific_tag_name = await adjust_project_manip(
                work_dir, c, adjustspec, adjust_result)

        is_pull_request = git.is_ref_a_pull_request(adjustspec["ref"])

        # if we are aligning from a PR, indicate it as such in the tag name
        if is_pull_request:
            specific_tag_name = "Pull_Request-" + specific_tag_name

        result = await commit_adjustments(
            repo_dir=work_dir,
            repo_url=repo_url,
            original_ref=adjustspec["ref"],
            adjust_type=", ".join(adjust_result["adjustType"]),
            force_continue_on_no_changes=True,
            specific_tag_name=specific_tag_name,
        )

        result = result if result is not None else {}

        result["adjustResultData"] = adjust_result["resultData"]
        process_mdc("END", "ALIGNMENT_ADJUST")
    return result
Beispiel #3
0
async def sync_external_repo(adjustspec, repo_provider, work_dir,
                             configuration):
    """Get external repository and its ref into the internal repository"""
    internal_repo_url = await repo_provider(adjustspec, create=False)
    git_user = configuration.get("git_username")

    await git.clone(work_dir, adjustspec["originRepoUrl"])  # Clone origin

    # See NCL-4069: sometimes even with sync on, the upstream repo might not have the ref, but the downstream repo will
    # if ref exists on upstream repository, continue the sync as usual
    # if no, make sure ref exists on downstream repository, and checkout the correct repo
    # if no, then fail completely
    ref_exists = await check_ref_exists(work_dir, adjustspec["ref"])
    if ref_exists:
        is_pull_request = git.is_ref_a_pull_request(adjustspec["ref"])

        if is_pull_request:
            await git.checkout_pr(work_dir, adjustspec["ref"])
        else:
            await git.checkout(work_dir, adjustspec["ref"],
                               force=True)  # Checkout ref

        await git.rename_remote(work_dir, "origin",
                                "origin_remote")  # Rename origin remote
        await git.add_remote(
            work_dir,
            "origin",
            asutil.add_username_url(internal_repo_url.readwrite, git_user),
        )  # Add target remote

        ref = adjustspec["ref"]
        # Sync
        if is_pull_request:
            logger.info(
                "Syncing of Pull Request to downstream repository disabled since the ref is a pull request"
            )
        else:
            await clone.push_sync_changes(work_dir,
                                          ref,
                                          "origin",
                                          origin_remote="origin_remote")

    else:
        logger.warn(
            "Upstream repository does not have the 'ref'. Trying to see if 'ref' present in downstream repository"
        )
        # Delete the upstreamed clone repository
        shutil.rmtree(work_dir)
        os.makedirs(work_dir)

        # Clone the internal repository
        await git.clone(work_dir,
                        asutil.add_username_url(internal_repo_url.readwrite,
                                                git_user))  # Clone origin

        ref_exists = await check_ref_exists(work_dir, adjustspec["ref"])
        if ref_exists:
            logger.info(
                "Downstream repository has the ref, but not the upstream one. No syncing required!"
            )
            await git.checkout(work_dir, adjustspec["ref"],
                               force=True)  # Checkout ref
        else:
            logger.error(
                "Both upstream and downstream repository do not have the 'ref' present. Cannot proceed"
            )
            raise exception.AdjustCommandError(
                "Both upstream and downstream repository do not have the 'ref' present. Cannot proceed",
                [],
                exit_code=10,
            )

    # At this point the target repository might have the ref we want to sync, but the local repository might not have all the tags
    # from the target repository. We need to sync tags because we use it to know if we have tags with existing changes or if we
    # need to create tags of format <version>-<sha> if existing tag with name <version> exists after pme changes
    await git.fetch_tags(work_dir, remote="origin")