Ejemplo n.º 1
0
def test_synthesize_loop_with_realistic_change_history_squash_prs(
    synthesize_loop_fixture: SynthesizeLoopFixture, ):
    pusher = synthesize_loop_fixture.change_pusher
    synthesize_loop_fixture.change_pusher = SquashingChangePusher(pusher)
    synthesize_loop_with_realistic_change_history(
        synthesize_loop_fixture, True, "mock-synth-golden-squash-prs.log")
    calls = pusher.mock_calls
    golden_calls = [
        call.check_if_pr_already_exists("test-source1"),
        call.push_changes(
            1,
            "test-source1",
            "[CHANGE ME] Re-generated to pick up changes from source1.",
            "",
        ),
        call.push_changes().add_labels(["context: partial"]),
        call.check_if_pr_already_exists("test-source2"),
        call.push_changes(
            1,
            "test-source2",
            "[CHANGE ME] Re-generated to pick up changes from source2.",
            "",
        ),
        call.push_changes().add_labels(["context: partial"]),
    ]
    assert golden_calls == calls
Ejemplo n.º 2
0
def _inner_main(temp_dir: str) -> int:
    """
    Returns:
        int -- Number of commits committed to the repo.
    """
    parser = argparse.ArgumentParser()
    parser.add_argument("--github-user", default=os.environ.get("GITHUB_USER"))
    parser.add_argument("--github-email",
                        default=os.environ.get("GITHUB_EMAIL"))
    parser.add_argument("--github-token",
                        default=os.environ.get("GITHUB_TOKEN"))
    parser.add_argument("--repository",
                        default=os.environ.get("REPOSITORY"),
                        required=True)
    parser.add_argument("--synth-path", default=os.environ.get("SYNTH_PATH"))
    parser.add_argument("--metadata-path",
                        default=os.environ.get("METADATA_PATH"))
    parser.add_argument(
        "--deprecated-execution",
        default=False,
        action="store_true",
        help=
        "If specified, execute synth.py directly instead of synthtool. This behavior is deprecated.",
    )
    parser.add_argument("--branch-suffix",
                        default=os.environ.get("BRANCH_SUFFIX", None))
    parser.add_argument("--pr-title", default="")
    parser.add_argument("extra_args", nargs=argparse.REMAINDER)

    args = parser.parse_args()

    gh = github.GitHub(args.github_token)

    branch = "-".join(filter(None, ["autosynth", args.branch_suffix]))

    pr_title = args.pr_title or (
        f"[CHANGE ME] Re-generated {args.synth_path or ''} to pick up changes in "
        f"the API or client library generator.")
    change_pusher: AbstractChangePusher = ChangePusher(args.repository, gh,
                                                       branch)

    # capture logs for later
    base_synth_log_path = pathlib.Path(
        os.path.realpath("./logs")) / args.repository
    if args.synth_path:
        base_synth_log_path /= args.synth_path
    logger.info(f"logs will be written to: {base_synth_log_path}")

    working_repo_path = synthtool_git.clone(
        f"https://github.com/{args.repository}.git")

    try:
        os.chdir(working_repo_path)

        git.configure_git(args.github_user, args.github_email)

        git.setup_branch(branch)

        if args.synth_path:
            os.chdir(args.synth_path)

        metadata_path = os.path.join(args.metadata_path or "",
                                     "synth.metadata")

        flags = autosynth.flags.parse_flags()
        # Override flags specified in synth.py with flags specified in environment vars.
        for key in flags.keys():
            env_value = os.environ.get(key, "")
            if env_value:
                flags[key] = False if env_value.lower(
                ) == "false" else env_value

        metadata = load_metadata(metadata_path)
        multiple_commits = flags[autosynth.flags.AUTOSYNTH_MULTIPLE_COMMITS]
        multiple_prs = flags[autosynth.flags.AUTOSYNTH_MULTIPLE_PRS]
        if (not multiple_commits and not multiple_prs) or not metadata:
            if change_pusher.check_if_pr_already_exists(branch):
                return 0

            synth_log = Synthesizer(
                metadata_path,
                args.extra_args,
                deprecated_execution=args.deprecated_execution,
            ).synthesize(base_synth_log_path)

            if not has_changes():
                logger.info("No changes. :)")
                sys.exit(EXIT_CODE_SKIPPED)

            git.commit_all_changes(pr_title)
            change_pusher.push_changes(1, branch, pr_title, synth_log)
            return 1

        else:
            if not multiple_prs and change_pusher.check_if_pr_already_exists(
                    branch):
                return 0  # There's already an existing PR

            # Enumerate the versions to loop over.
            sources = metadata.get("sources", [])
            source_versions = [
                git_source.enumerate_versions_for_working_repo(
                    metadata_path, sources)
            ]
            # Add supported source version types below:
            source_versions.extend(
                git_source.enumerate_versions(sources, pathlib.Path(temp_dir)))

            # Prepare to call synthesize loop.
            synthesizer = Synthesizer(
                metadata_path,
                args.extra_args,
                args.deprecated_execution,
                "synth.py",
            )
            x = SynthesizeLoopToolbox(
                source_versions,
                branch,
                temp_dir,
                metadata_path,
                args.synth_path,
                base_synth_log_path,
            )
            if not multiple_commits:
                change_pusher = SquashingChangePusher(change_pusher)

            # Call the loop.
            commit_count = synthesize_loop(x, multiple_prs, change_pusher,
                                           synthesizer)

            if commit_count == 0:
                logger.info("No changes. :)")
                sys.exit(EXIT_CODE_SKIPPED)

            return commit_count
    finally:
        if args.synth_path:
            # We're generating code in a mono repo.  The state left behind will
            # probably be useful for generating the next API.
            pass
        else:
            # We're generating a single API in a single repo, and using a different
            # repo to generate the next API.  So the next synth will not be able to
            # use any of this state.  Clean it up to avoid running out of disk space.
            executor.run(["git", "clean", "-fdx"], cwd=working_repo_path)