Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add cli next-version #25

Merged
merged 5 commits into from
Feb 8, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
Anything MAY change at any time. The public API SHOULD NOT be considered stable.").
While in this phase, we will denote breaking changes with a minor increase.

## 0.4.1

### Added

* Introduce `dac next-version` command, that allows to find the next minor release for a given python package and (optionally) a given major version.

## 0.4.0

### Changed
Expand Down
26 changes: 26 additions & 0 deletions src/dac/_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import sys
from importlib.metadata import requires, version
from pathlib import Path
from typing import Optional

import typer
from rich.console import Console
Expand All @@ -11,6 +12,7 @@
from dac._input.config import PackConfig
from dac._input.pyproject import PyProjectConfig
from dac._packing import pack as py_api_pack
from dac._version_management import find_latest_version, increase_minor

app = typer.Typer()
console = Console()
Expand Down Expand Up @@ -69,6 +71,30 @@ def pack(
)


@app.command()
def next_version(
pkg_name: str = typer.Option(
...,
help="Name of the python package",
),
major: Optional[int] = typer.Option(
None,
"--major",
help="Major of the version that should be increased. "
"If not specified just take it from the latest version of the package.",
),
):
"""
Print the next version of the python package.

It assumes that semantic versioning (https://semver.org) is used,
and that the next version corresponds to a minor upgrade.
"""
latest_version = find_latest_version(pkg_name=pkg_name, major=major)
next_version = increase_minor(version=latest_version)
console.print(next_version)


@app.command()
def info():
"""
Expand Down
29 changes: 29 additions & 0 deletions src/dac/_version_management.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import re
import subprocess
from typing import Optional


def find_latest_version(pkg_name: str, major: Optional[int] = None) -> str:
output = subprocess.check_output(
[
"pip",
"install",
"--no-deps",
"--ignore-installed",
"--no-cache-dir",
"--dry-run",
f"{pkg_name}{f'=={major}.*' if major is not None else ''}",
],
stderr=subprocess.DEVNULL,
)
last_line = output.decode("utf-8").splitlines()[-1]
regex_rule = f"{pkg_name.replace('_', '-')}-{major if major is not None else ''}.[^ ]+"
match = re.search(regex_rule, last_line)
assert match is not None
return match[0][len(f"{pkg_name}-") :]


def increase_minor(version: str) -> str:
major, minor, patch = version.split(".")
assert major.isdigit() and minor.isdigit()
return f"{major}.{int(minor) + 1}.0"
14 changes: 12 additions & 2 deletions test/cli_utilities.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,9 @@
from typing import Optional

from click.testing import Result
from typer.testing import CliRunner

from dac._cli import app
from dac._input.config import PackConfig
from typer.testing import CliRunner

runner = CliRunner()

Expand Down Expand Up @@ -66,5 +65,16 @@ def invoke_dac_pack_from_config(config: PackConfig) -> Result:
)


def invoke_dac_next_version(
pkg_name: str,
major: Optional[int] = None,
) -> Result:
major_option = [] if major is None else ["--major", str(major)]
return runner.invoke(
app,
["next-version", "--pkg-name", pkg_name] + major_option,
)


def invoke_dac_info() -> Result:
return runner.invoke(app, ["info"])
27 changes: 27 additions & 0 deletions test/integration_test/version_management_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
from test.cli_utilities import invoke_dac_next_version

import pytest
from dac._version_management import find_latest_version


def test_if_find_latest_version_is_called_then_return_latest_version():
assert "0.5" == find_latest_version(pkg_name="rainbow-server")


def test_if_find_latest_version_is_called_with_major_constraint_then_return_latest_major_version():
assert "0.25.3" == find_latest_version(pkg_name="pandas", major=0)


def test_if_pkg_does_not_exist_then_find_package_raises_exception():
with pytest.raises(Exception):
find_latest_version(pkg_name="non-existing-package")


def test_if_next_version_without_major_spec_then_return_latest_version_with_minor_upgrade():
result = invoke_dac_next_version(pkg_name="rainbow-saddle")
assert result.stdout == "0.5.0\n"


def test_if_next_version_with_major_spec_then_return_minor_upgrade_for_that_major():
result = invoke_dac_next_version(pkg_name="pandas", major=0)
assert result.stdout == "0.26.0\n"
Empty file.
13 changes: 13 additions & 0 deletions test/unit_test/_version_management/increase_minot_test.py
ajuhasz10 marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import pytest
from dac._version_management import increase_minor


def test_increase_minor_then_return_version_with_increased_minor():
assert "0.6.0" == increase_minor(version="0.5.0")
assert "0.6.0" == increase_minor(version="0.5.1rc0")


@pytest.mark.parametrize("version", ["0", "0.5", "guess.what.now", "guess.0.now"])
def test_if_invalid_version_then_increase_minor_raises_exception(version):
with pytest.raises(Exception):
increase_minor(version=version)
Loading