Exemplo n.º 1
0
def test_changelog_incremental_keep_a_changelog_sample(mocker, capsys,
                                                       changelog_path):
    with open(changelog_path, "w") as f:
        f.write(KEEP_A_CHANGELOG)
    create_file_and_commit("irrelevant commit")
    git.tag("1.0.0")

    create_file_and_commit("feat: add new output")
    create_file_and_commit("fix: output glitch")
    create_file_and_commit("fix: mama gotta work")
    create_file_and_commit("feat: add more stuff")
    create_file_and_commit("Merge into master")

    testargs = ["cz", "changelog", "--incremental"]

    mocker.patch.object(sys, "argv", testargs)
    cli.main()

    with open(changelog_path, "r") as f:
        out = f.read()

    assert (
        out ==
        """# Changelog\nAll notable changes to this project will be documented in this file.\n\nThe format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),\nand this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).\n\n## Unreleased\n\n### Feat\n\n- add more stuff\n- add new output\n\n### Fix\n\n- mama gotta work\n- output glitch\n\n## [1.0.0] - 2017-06-20\n### Added\n- New visual identity by [@tylerfortune8](https://github.com/tylerfortune8).\n- Version navigation.\n\n### Changed\n- Start using "changelog" over "change log" since it\'s the common usage.\n\n### Removed\n- Section about "changelog" vs "CHANGELOG".\n\n## [0.3.0] - 2015-12-03\n### Added\n- RU translation from [@aishek](https://github.com/aishek).\n"""
    )
Exemplo n.º 2
0
def test_changelog_incremental_angular_sample(mocker, capsys, changelog_path):
    with open(changelog_path, "w") as f:
        f.write(
            "# [10.0.0-next.3](https://github.com/angular/angular/compare/10.0.0-next.2...10.0.0-next.3) (2020-04-22)\n"
            "\n"
            "### Bug Fixes"
            "\n"
            "* **common:** format day-periods that cross midnight ([#36611](https://github.com/angular/angular/issues/36611)) ([c6e5fc4](https://github.com/angular/angular/commit/c6e5fc4)), closes [#36566](https://github.com/angular/angular/issues/36566)\n"
        )
    create_file_and_commit("irrelevant commit")
    git.tag("10.0.0-next.3")

    create_file_and_commit("feat: add new output")
    create_file_and_commit("fix: output glitch")
    create_file_and_commit("fix: mama gotta work")
    create_file_and_commit("feat: add more stuff")
    create_file_and_commit("Merge into master")

    testargs = ["cz", "changelog", "--incremental"]

    mocker.patch.object(sys, "argv", testargs)
    cli.main()

    with open(changelog_path, "r") as f:
        out = f.read()

    assert (
        out
        == "## Unreleased\n\n### Feat\n\n- add more stuff\n- add new output\n\n### Fix\n\n- mama gotta work\n- output glitch\n\n# [10.0.0-next.3](https://github.com/angular/angular/compare/10.0.0-next.2...10.0.0-next.3) (2020-04-22)\n\n### Bug Fixes\n* **common:** format day-periods that cross midnight ([#36611](https://github.com/angular/angular/issues/36611)) ([c6e5fc4](https://github.com/angular/angular/commit/c6e5fc4)), closes [#36566](https://github.com/angular/angular/issues/36566)\n"
    )
Exemplo n.º 3
0
def test_changelog_incremental_with_release_candidate_version(
        mocker, changelog_path, file_regression, test_input):
    """Fix #357"""
    with open(changelog_path, "w") as f:
        f.write(KEEP_A_CHANGELOG)
    create_file_and_commit("irrelevant commit")
    git.tag("1.0.0", annotated=True)

    create_file_and_commit("feat: add new output")
    create_file_and_commit("fix: output glitch")

    testargs = [
        "cz", "bump", "--changelog", "--prerelease", test_input, "--yes"
    ]
    mocker.patch.object(sys, "argv", testargs)
    cli.main()

    create_file_and_commit("fix: mama gotta work")
    create_file_and_commit("feat: add more stuff")
    create_file_and_commit("Merge into master")

    testargs = ["cz", "changelog", "--incremental"]

    mocker.patch.object(sys, "argv", testargs)
    cli.main()

    with open(changelog_path, "r") as f:
        out = f.read()

    file_regression.check(out, extension=".md")
Exemplo n.º 4
0
def test_bump_tag_exists_raises_exception(mocker):
    cmd.run("mkdir .git/hooks")
    with open(".git/hooks/post-commit", "w") as f:
        f.write("#!/usr/bin/env bash\n" "exit 9")
    cmd.run("chmod +x .git/hooks/post-commit")

    # MINOR
    create_file_and_commit("feat: new file")
    git.tag("0.2.0")

    testargs = ["cz", "bump", "--yes"]
    mocker.patch.object(sys, "argv", testargs)

    with pytest.raises(BumpTagFailedError) as excinfo:
        cli.main()
    assert "0.2.0" in str(excinfo.value)  # This should be a fatal error
Exemplo n.º 5
0
def test_changelog_with_different_tag_name_and_changelog_content(
        mocker, tmp_commitizen_project):
    changelog_file = tmp_commitizen_project.join("CHANGELOG.md")
    changelog_file.write("""
        # Unreleased

        ## v1.0.0
        """)
    create_file_and_commit("feat: new file")
    git.tag("2.0.0")

    # create_file_and_commit("feat: new file")
    testargs = ["cz", "changelog", "--incremental"]
    mocker.patch.object(sys, "argv", testargs)

    with pytest.raises(NoRevisionError):
        cli.main()
def test_none_increment_should_not_call_git_tag(mocker, tmp_commitizen_project):
    create_file_and_commit("test(test_get_all_droplets): fix bad comparison test")
    testargs = ["cz", "bump", "--yes"]
    mocker.patch.object(sys, "argv", testargs)

    # stash git.tag for later restore
    stashed_git_tag = git.tag
    dummy_value = git.tag("0.0.2")
    git.tag = MagicMock(return_value=dummy_value)

    with pytest.raises(NoneIncrementExit):
        cli.main()
        git.tag.assert_not_called()

    # restore pop stashed
    git.tag = stashed_git_tag
Exemplo n.º 7
0
    def __call__(self):
        """Steps executed to bump."""
        try:
            current_version_instance: Version = Version(self.parameters["version"])
        except TypeError:
            out.error("[NO_VERSION_SPECIFIED]")
            out.error("Check if current version is specified in config file, like:")
            out.error("version = 0.4.3")
            raise SystemExit(NO_VERSION_SPECIFIED)

        # Initialize values from sources (conf)
        current_version: str = self.config["version"]
        tag_format: str = self.parameters["tag_format"]
        bump_commit_message: str = self.parameters["bump_message"]
        current_tag_version: str = bump.create_tag(
            current_version, tag_format=tag_format
        )
        files: list = self.parameters["files"]
        dry_run: bool = self.parameters["dry_run"]

        is_yes: bool = self.arguments["yes"]
        prerelease: str = self.arguments["prerelease"]
        increment: Optional[str] = self.arguments["increment"]

        is_initial = self.is_initial_tag(current_tag_version, is_yes)
        commits = git.get_commits(current_tag_version, from_beginning=is_initial)

        # No commits, there is no need to create an empty tag.
        # Unless we previously had a prerelease.
        if not commits and not current_version_instance.is_prerelease:
            out.error("[NO_COMMITS_FOUND]")
            out.error("No new commits found.")
            raise SystemExit(NO_COMMITS_FOUND)

        if increment is None:
            bump_pattern = self.cz.bump_pattern
            bump_map = self.cz.bump_map
            if not bump_map or not bump_pattern:
                out.error(f"'{self.config['name']}' rule does not support bump")
                raise SystemExit(NO_PATTERN_MAP)
            increment = bump.find_increment(
                commits, regex=bump_pattern, increments_map=bump_map
            )

        # Increment is removed when current and next version
        # are expected to be prereleases.
        if prerelease and current_version_instance.is_prerelease:
            increment = None

        new_version = bump.generate_version(
            current_version, increment, prerelease=prerelease
        )
        new_tag_version = bump.create_tag(new_version, tag_format=tag_format)
        message = bump.create_commit_message(
            current_version, new_version, bump_commit_message
        )

        # Report found information
        out.write(message)
        out.write(f"tag to create: {new_tag_version}")
        out.write(f"increment detected: {increment}")

        # Do not perform operations over files or git.
        if dry_run:
            raise SystemExit()

        config.set_key("version", new_version.public)
        bump.update_version_in_files(current_version, new_version.public, files)
        c = git.commit(message, args="-a")
        if c.err:
            out.error(c.err)
            raise SystemExit(COMMIT_FAILED)
        c = git.tag(new_tag_version)
        if c.err:
            out.error(c.err)
            raise SystemExit(TAG_FAILED)
        out.success("Done!")
Exemplo n.º 8
0
    def __call__(self):  # noqa: C901
        """Steps executed to bump."""
        try:
            current_version_instance: Version = Version(self.bump_settings["version"])
        except TypeError:
            raise NoVersionSpecifiedError()

        # Initialize values from sources (conf)
        current_version: str = self.config.settings["version"]

        tag_format: str = self.bump_settings["tag_format"]
        bump_commit_message: str = self.bump_settings["bump_message"]
        version_files: List[str] = self.bump_settings["version_files"]

        dry_run: bool = self.arguments["dry_run"]
        is_yes: bool = self.arguments["yes"]
        increment: Optional[str] = self.arguments["increment"]
        prerelease: str = self.arguments["prerelease"]
        is_files_only: Optional[bool] = self.arguments["files_only"]
        is_local_version: Optional[bool] = self.arguments["local_version"]

        current_tag_version: str = bump.create_tag(
            current_version, tag_format=tag_format
        )

        is_initial = self.is_initial_tag(current_tag_version, is_yes)
        if is_initial:
            commits = git.get_commits()
        else:
            commits = git.get_commits(current_tag_version)

        # No commits, there is no need to create an empty tag.
        # Unless we previously had a prerelease.
        if not commits and not current_version_instance.is_prerelease:
            raise NoCommitsFoundError("[NO_COMMITS_FOUND]\n" "No new commits found.")

        if increment is None:
            increment = self.find_increment(commits)

        # Increment is removed when current and next version
        # are expected to be prereleases.
        if prerelease and current_version_instance.is_prerelease:
            increment = None

        new_version = bump.generate_version(
            current_version,
            increment,
            prerelease=prerelease,
            is_local_version=is_local_version,
        )
        new_tag_version = bump.create_tag(new_version, tag_format=tag_format)
        message = bump.create_commit_message(
            current_version, new_version, bump_commit_message
        )

        # Report found information
        out.write(
            f"{message}\n"
            f"tag to create: {new_tag_version}\n"
            f"increment detected: {increment}\n"
        )

        if increment is None and new_tag_version == current_tag_version:
            raise NoneIncrementExit()

        # Do not perform operations over files or git.
        if dry_run:
            raise DryRunExit()

        bump.update_version_in_files(
            current_version,
            str(new_version),
            version_files,
            check_consistency=self.check_consistency,
        )

        if self.changelog:
            changelog_cmd = Changelog(
                self.config,
                {
                    "unreleased_version": new_tag_version,
                    "incremental": True,
                    "dry_run": dry_run,
                },
            )
            changelog_cmd()
            c = cmd.run(f"git add {changelog_cmd.file_name}")

        self.config.set_key("version", str(new_version))

        if is_files_only:
            raise ExpectedExit()

        c = git.commit(message, args=self._get_commit_args())
        if c.return_code != 0:
            raise BumpCommitFailedError(f'git.commit error: "{c.err.strip()}"')
        c = git.tag(new_tag_version)
        if c.return_code != 0:
            raise BumpTagFailedError(c.err)
        out.success("Done!")
Exemplo n.º 9
0
    def __call__(self):  # noqa: C901
        """Steps executed to bump."""
        try:
            current_version_instance: Version = Version(
                self.bump_settings["version"])
        except TypeError:
            raise NoVersionSpecifiedError()

        # Initialize values from sources (conf)
        current_version: str = self.config.settings["version"]

        tag_format: str = self.bump_settings["tag_format"]
        bump_commit_message: str = self.bump_settings["bump_message"]
        version_files: List[str] = self.bump_settings["version_files"]

        dry_run: bool = self.arguments["dry_run"]
        is_yes: bool = self.arguments["yes"]
        increment: Optional[str] = self.arguments["increment"]
        prerelease: str = self.arguments["prerelease"]
        is_files_only: Optional[bool] = self.arguments["files_only"]
        is_local_version: Optional[bool] = self.arguments["local_version"]

        current_tag_version: str = bump.normalize_tag(current_version,
                                                      tag_format=tag_format)

        is_initial = self.is_initial_tag(current_tag_version, is_yes)
        if is_initial:
            commits = git.get_commits()
        else:
            commits = git.get_commits(current_tag_version)

        # If user specified changelog_to_stdout, they probably want the
        # changelog to be generated as well, this is the most intuitive solution
        if not self.changelog and self.changelog_to_stdout:
            self.changelog = True

        # No commits, there is no need to create an empty tag.
        # Unless we previously had a prerelease.
        if not commits and not current_version_instance.is_prerelease:
            raise NoCommitsFoundError("[NO_COMMITS_FOUND]\n"
                                      "No new commits found.")

        if increment is None:
            increment = self.find_increment(commits)

        # It may happen that there are commits, but they are not elegible
        # for an increment, this generates a problem when using prerelease (#281)
        if (prerelease and increment is None
                and not current_version_instance.is_prerelease):
            raise NoCommitsFoundError(
                "[NO_COMMITS_FOUND]\n"
                "No commits found to generate a pre-release.\n"
                "To avoid this error, manually specify the type of increment with `--increment`"
            )

        # Increment is removed when current and next version
        # are expected to be prereleases.
        if prerelease and current_version_instance.is_prerelease:
            increment = None

        new_version = bump.generate_version(
            current_version,
            increment,
            prerelease=prerelease,
            is_local_version=is_local_version,
        )

        new_tag_version = bump.normalize_tag(new_version,
                                             tag_format=tag_format)
        message = bump.create_commit_message(current_version, new_version,
                                             bump_commit_message)

        # Report found information
        information = (f"{message}\n"
                       f"tag to create: {new_tag_version}\n"
                       f"increment detected: {increment}\n")

        if self.changelog_to_stdout:
            # When the changelog goes to stdout, we want to send
            # the bump information to stderr, this way the
            # changelog output can be captured
            out.diagnostic(information)
        else:
            out.write(information)

        if increment is None and new_tag_version == current_tag_version:
            raise NoneIncrementExit(
                "[NO_COMMITS_TO_BUMP]\n"
                "The commits found are not elegible to be bumped")

        # Do not perform operations over files or git.
        if dry_run:
            raise DryRunExit()

        bump.update_version_in_files(
            current_version,
            str(new_version),
            version_files,
            check_consistency=self.check_consistency,
        )

        if self.changelog:
            if self.changelog_to_stdout:
                changelog_cmd = Changelog(
                    self.config,
                    {
                        "unreleased_version": new_tag_version,
                        "incremental": True,
                        "dry_run": True,
                    },
                )
                try:
                    changelog_cmd()
                except DryRunExit:
                    pass
            changelog_cmd = Changelog(
                self.config,
                {
                    "unreleased_version": new_tag_version,
                    "incremental": True,
                    "dry_run": dry_run,
                },
            )
            changelog_cmd()
            c = cmd.run(
                f"git add {changelog_cmd.file_name} {' '.join(version_files)}")

        self.config.set_key("version", str(new_version))

        if is_files_only:
            raise ExpectedExit()

        c = git.commit(message, args=self._get_commit_args())
        if self.retry and c.return_code != 0 and self.changelog:
            # Maybe pre-commit reformatted some files? Retry once
            logger.debug("1st git.commit error: %s", c.err)
            logger.info("1st commit attempt failed; retrying once")
            cmd.run(
                f"git add {changelog_cmd.file_name} {' '.join(version_files)}")
            c = git.commit(message, args=self._get_commit_args())
        if c.return_code != 0:
            raise BumpCommitFailedError(
                f'2nd git.commit error: "{c.err.strip()}"')
        c = git.tag(
            new_tag_version,
            annotated=self.bump_settings.get("annotated_tag", False)
            or bool(self.config.settings.get("annotated_tag", False)),
        )
        if c.return_code != 0:
            raise BumpTagFailedError(c.err)

        # TODO: For v3 output this only as diagnostic and remove this if
        if self.changelog_to_stdout:
            out.diagnostic("Done!")
        else:
            out.success("Done!")
Exemplo n.º 10
0
    def __call__(self):  # noqa: C901
        """Steps executed to bump."""
        try:
            current_version_instance: Version = Version(self.bump_settings["version"])
        except TypeError:
            out.error(
                "[NO_VERSION_SPECIFIED]\n"
                "Check if current version is specified in config file, like:\n"
                "version = 0.4.3\n"
            )
            raise SystemExit(NO_VERSION_SPECIFIED)

        # Initialize values from sources (conf)
        current_version: str = self.config.settings["version"]

        tag_format: str = self.bump_settings["tag_format"]
        bump_commit_message: str = self.bump_settings["bump_message"]
        version_files: List[str] = self.bump_settings["version_files"]

        dry_run: bool = self.arguments["dry_run"]
        is_yes: bool = self.arguments["yes"]
        increment: Optional[str] = self.arguments["increment"]
        prerelease: str = self.arguments["prerelease"]
        is_files_only: Optional[bool] = self.arguments["files_only"]

        current_tag_version: str = bump.create_tag(
            current_version, tag_format=tag_format
        )

        is_initial = self.is_initial_tag(current_tag_version, is_yes)
        if is_initial:
            commits = git.get_commits()
        else:
            commits = git.get_commits(current_tag_version)

        # No commits, there is no need to create an empty tag.
        # Unless we previously had a prerelease.
        if not commits and not current_version_instance.is_prerelease:
            out.error("[NO_COMMITS_FOUND]\n" "No new commits found.")
            raise SystemExit(NO_COMMITS_FOUND)

        if increment is None:
            increment = self.find_increment(commits)

        # Increment is removed when current and next version
        # are expected to be prereleases.
        if prerelease and current_version_instance.is_prerelease:
            increment = None

        new_version = bump.generate_version(
            current_version, increment, prerelease=prerelease
        )
        new_tag_version = bump.create_tag(new_version, tag_format=tag_format)
        message = bump.create_commit_message(
            current_version, new_version, bump_commit_message
        )

        # Report found information
        out.write(
            f"message\n"
            f"tag to create: {new_tag_version}\n"
            f"increment detected: {increment}\n"
        )

        # Do not perform operations over files or git.
        if dry_run:
            raise SystemExit()

        bump.update_version_in_files(
            current_version,
            new_version.public,
            version_files,
            check_consistency=self.check_consistency,
        )
        if is_files_only:
            raise SystemExit()

        if self.changelog:
            changelog = Changelog(
                self.config,
                {
                    "unreleased_version": new_tag_version,
                    "incremental": True,
                    "dry_run": dry_run,
                },
            )
            changelog()

        self.config.set_key("version", new_version.public)
        c = git.commit(message, args=self._get_commit_args())
        if c.err:
            out.error('git.commit error: "{}"'.format(c.err.strip()))
            raise SystemExit(COMMIT_FAILED)
        c = git.tag(new_tag_version)
        if c.err:
            out.error(c.err)
            raise SystemExit(TAG_FAILED)
        out.success("Done!")