def test_find_changelog_path(tmpdir, format_type, file_name):
    path = Path(tmpdir)
    (path / file_name).write_text("# 1.0.0 Release (YYYY-MM-DD)")
    assert (find_changelog_path(
        ProjectConfig(path=path,
                      changelog_format_type_file=format_type)) == path /
            file_name)
예제 #2
0
def test_project_config_semver_schema_overwrite():
    assert (
        ProjectConfig(
            version_type=VersionTypeEnum.semver, version_schema="XYZ"
        ).version_schema
        == DEFAULT_SEMVER_SCHEMA
    )
def test_update_version_files_with_invalid_version_files(
        tmpdir, invalid_files):
    config = ProjectConfig(path=Path(tmpdir), version_files=invalid_files)

    current_version = Version.from_tag("v20.1.0", config=config)
    next_version = Version.from_tag("v20.1.1", config=config)

    with pytest.raises(ConfigError):
        update_version_files(config, current_version, next_version)
def test_guess_python_version_files_invalid_poetry_config(tmpdir):
    path = Path(tmpdir)
    (path / "pyproject.toml").write_text("""[tool.poetry]
version = "1.0.0"
""")
    assert guess_version_files(
        ProjectConfig(
            path=path,
            project_type=ProjectTypeEnum.python)) == ("pyproject.toml", )
def test_run_post_bump_hook(capsys, monkeypatch, tmpdir, file_name, expected):
    monkeypatch.setattr("subprocess.check_call", Mock())

    path = Path(tmpdir)
    (path / file_name).write_text("")

    run_post_bump_hook(
        ProjectConfig(path=path, project_type=ProjectTypeEnum.javascript),
        is_dry_run=False,
    )
예제 #6
0
def main(argv: Argv = None) -> int:
    args = parse_args(argv or sys.argv[1:])
    # TODO: Fix this by providing required flag on adding subparsers
    if getattr(args, "func", None) is None:
        print(
            "ERROR: Please provide one of available subcommands. Exit...",
            file=sys.stderr,
        )
        return 1

    config = ProjectConfig.from_path(args.path)
    return cast(int, args.func(args, config=config))
def test_run_post_bump_hook_dry_run(capsys, tmpdir, file_name, expected):
    path = Path(tmpdir)
    (path / file_name).write_text("")

    run_post_bump_hook(
        ProjectConfig(path=path, project_type=ProjectTypeEnum.javascript),
        is_dry_run=True,
    )

    captured = capsys.readouterr()
    assert captured.err == ""
    assert expected in captured.out
def test_guess_python_version_files(tmpdir, files, expected):
    path = Path(tmpdir)

    (path / "pyproject.toml").write_text("""[tool.poetry]
name = "project"
version = "1.0.0"
""")

    for item in files:
        item_path = path.joinpath(item)
        ensure_dir(item_path.parent)
        item_path.write_text("")

    assert (guess_version_files(
        ProjectConfig(path=Path(tmpdir),
                      project_type=ProjectTypeEnum.python)) == expected)
def test_guess_javascript_version_files(tmpdir):
    assert guess_version_files(
        ProjectConfig(
            path=Path(tmpdir),
            project_type=ProjectTypeEnum.javascript)) == ("package.json", )
예제 #10
0
def test_find_changelog_path_no_file(tmpdir, format_type, expected):
    path = Path(tmpdir)
    assert (find_changelog_path(
        ProjectConfig(path=path,
                      changelog_format_type_file=format_type)) == path /
            expected)
예제 #11
0
def test_update_version_files_with_version_files(tmpdir):
    config = ProjectConfig(path=Path(tmpdir),
                           version_files=("pyproject.toml", ))
    current_version = Version.from_tag("v20.1.0", config=config)
    next_version = Version.from_tag("v20.1.1", config=config)
    assert update_version_files(config, current_version, next_version) is False
예제 #12
0
def test_update_version_files_no_current_version(tmpdir):
    config = ProjectConfig(path=Path(tmpdir))
    next_version = Version.from_tag("v20.1.0", config=config)
    assert update_version_files(config, None, next_version) is False
예제 #13
0
def test_guess_python_version_files_no_pyproject_toml(tmpdir):
    assert (guess_version_files(
        ProjectConfig(path=Path(tmpdir),
                      project_type=ProjectTypeEnum.python)) == ())
예제 #14
0
def main(argv: Argv = None) -> int:
    # Parse arguments
    args = parse_args(argv or sys.argv[1:])

    # Initialize project config
    project_config = ProjectConfig.from_path(args.path)

    # Read latest git tag and parse current version
    git = Git(path=project_config.path)

    current_tag = git.retrieve_last_tag_or_none()
    echo_value(
        "Current tag: ",
        current_tag or EMPTY,
        is_ci=args.is_ci,
        ci_name="current_tag",
    )

    current_version: Optional[Version] = None
    if current_tag is not None:
        current_version = Version.from_tag(current_tag, config=project_config)

    echo_value(
        "Current version: ",
        (current_version.format(
            config=project_config) if current_version else EMPTY),
        is_ci=args.is_ci,
        ci_name="current_version",
    )

    # Read commits from last tag
    if current_tag is not None and current_version is not None:
        try:
            git_commits = git.list_commits(current_tag)
            if not git_commits and current_version.pre_release is None:
                raise ValueError("No commits found after latest tag")
        except ValueError:
            print(
                f"ERROR: No commits found after: {current_tag!r}. Exit...",
                file=sys.stderr,
            )
            return 1

        # Create changelog using commits from last tag
        changelog = ChangeLog.from_git_commits(
            git_commits, strict=project_config.strict_mode)

        # Supply update config and guess next version
        update_config = create_update_config(changelog, args.is_pre_release)

        # Guess next version
        next_version = current_version.update(update_config)
    # Create initial changelog
    else:
        next_version = Version.guess_initial_version(
            config=project_config, is_pre_release=args.is_pre_release)
        changelog = ChangeLog.from_git_commits(
            (INITIAL_PRE_RELEASE_COMMIT if next_version.pre_release is not None
             else INITIAL_RELEASE_COMMIT, ), )

    git_changelog = changelog.format(
        ChangeLogTypeEnum.git_commit,
        project_config.changelog_format_type_git,
        ignore_footer_urls=project_config.changelog_ignore_footer_urls,
    )
    echo_value(
        "\nChangeLog\n\n",
        git_changelog,
        is_ci=args.is_ci,
        ci_name="changelog",
    )

    next_version_str = next_version.format(config=project_config)
    echo_value(
        "\nNext version: ",
        next_version_str,
        is_ci=args.is_ci,
        ci_name="next_version",
    )

    # Applying changes to version files
    if not args.is_ci and not args.is_dry_run:
        update_message = (
            "Are you sure to update version files and changelog? [y/N] ")
        if input(update_message).lower() != "y":
            print("OK! OK! Exit...")
            return 0

    update_version_files(
        project_config,
        current_version,
        next_version,
        is_dry_run=args.is_dry_run,
    )

    # Run post-bump hook
    run_post_bump_hook(project_config, is_dry_run=args.is_dry_run)

    # Update changelog
    update_changelog_file(project_config,
                          next_version,
                          changelog,
                          is_dry_run=args.is_dry_run)

    # Supply necessary CI output
    if args.is_ci:
        github_actions_output(
            "next_tag",
            project_config.tag_format.format(version=next_version_str),
        )
        github_actions_output(
            "next_tag_message",
            "\n\n".join((
                project_config.tag_subject_format.format(
                    version=next_version_str),
                git_changelog,
            )),
        )
        github_actions_output(
            "pr_branch",
            project_config.pr_branch_format.format(version=next_version_str),
        )
        github_actions_output(
            "pr_title",
            project_config.pr_title_format.format(version=next_version_str),
        )

    print("All OK!")
    return 0