From a366db880356e2bd839bbdc7d2c29050ae20cf96 Mon Sep 17 00:00:00 2001 From: mtkennerly Date: Mon, 29 Apr 2024 18:59:32 -0400 Subject: [PATCH] #82: Add --ignore-untracked --- CHANGELOG.md | 1 + dunamai/__init__.py | 37 ++++++++++++++++++++++++++++--- dunamai/__main__.py | 7 ++++++ tests/integration/test_dunamai.py | 3 +++ tests/unit/test_main.py | 2 ++ 5 files changed, 47 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1f9239e..07859f6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ For example, `--pattern default --pattern-prefix some-package-` would match tags like `some-package-v1.2.3`. This is useful if you just want a custom prefix without writing a whole pattern. +* Added `--ignore-untracked` option to control checking whether the repository is dirty. ## v1.20.0 (2024-04-12) diff --git a/dunamai/__init__.py b/dunamai/__init__.py index fdefa09..1fbb6ef 100644 --- a/dunamai/__init__.py +++ b/dunamai/__init__.py @@ -1015,6 +1015,7 @@ def from_git( strict: bool = False, path: Optional[Path] = None, pattern_prefix: Optional[str] = None, + ignore_untracked: bool = False, ) -> "Version": r""" Determine a version based on Git tags. @@ -1031,6 +1032,8 @@ def from_git( When there are no tags, fail instead of falling back to 0.0.0. :param path: Directory to inspect, if not the current working directory. :param pattern_prefix: Insert this after the pattern's start anchor (`^`). + :param ignore_untracked: + Ignore untracked files when determining whether the repository is dirty. :returns: Detected version. """ vcs = Vcs.Git @@ -1168,7 +1171,7 @@ def from_git( code, msg = _run_cmd("git describe --always --dirty", path) dirty = msg.endswith("-dirty") - if not dirty: + if not dirty and not ignore_untracked: code, msg = _run_cmd("git status --porcelain", path) if msg.strip() != "": dirty = True @@ -2022,6 +2025,7 @@ def from_any_vcs( strict: bool = False, path: Optional[Path] = None, pattern_prefix: Optional[str] = None, + ignore_untracked: bool = False, ) -> "Version": r""" Determine a version based on a detected version control system. @@ -2051,13 +2055,25 @@ def from_any_vcs( When there are no tags, fail instead of falling back to 0.0.0. :param path: Directory to inspect, if not the current working directory. :param pattern_prefix: Insert this after the pattern's start anchor (`^`). + :param ignore_untracked: + Ignore untracked files when determining whether the repository is dirty. + This is only used for Git currently. :returns: Detected version. """ vcs = _detect_vcs_from_archival(path) if vcs is None: vcs = _detect_vcs(None, path) return cls._do_vcs_callback( - vcs, pattern, latest_tag, tag_dir, tag_branch, full_commit, strict, path + vcs, + pattern, + latest_tag, + tag_dir, + tag_branch, + full_commit, + strict, + path, + pattern_prefix, + ignore_untracked, ) @classmethod @@ -2072,6 +2088,7 @@ def from_vcs( strict: bool = False, path: Optional[Path] = None, pattern_prefix: Optional[str] = None, + ignore_untracked: bool = False, ) -> "Version": r""" Determine a version based on a specific VCS setting. @@ -2095,10 +2112,22 @@ def from_vcs( When there are no tags, fail instead of falling back to 0.0.0. :param path: Directory to inspect, if not the current working directory. :param pattern_prefix: Insert this after the pattern's start anchor (`^`). + :param ignore_untracked: + Ignore untracked files when determining whether the repository is dirty. + This is only used for Git currently. :returns: Detected version. """ return cls._do_vcs_callback( - vcs, pattern, latest_tag, tag_dir, tag_branch, full_commit, strict, path, pattern_prefix + vcs, + pattern, + latest_tag, + tag_dir, + tag_branch, + full_commit, + strict, + path, + pattern_prefix, + ignore_untracked, ) @classmethod @@ -2113,6 +2142,7 @@ def _do_vcs_callback( strict: bool, path: Optional[Path], pattern_prefix: Optional[str] = None, + ignore_untracked: bool = False, ) -> "Version": mapping = { Vcs.Any: cls.from_any_vcs, @@ -2135,6 +2165,7 @@ def _do_vcs_callback( ("strict", strict), ("path", path), ("pattern_prefix", pattern_prefix), + ("ignore_untracked", ignore_untracked), ]: if kwarg in inspect.getfullargspec(callback).args: kwargs[kwarg] = value diff --git a/dunamai/__main__.py b/dunamai/__main__.py index 3c271ec..8cbe82e 100644 --- a/dunamai/__main__.py +++ b/dunamai/__main__.py @@ -27,6 +27,13 @@ "dest": "dirty", "help": "Include dirty flag if applicable. Ignored when --format is used", }, + { + "vcs": [Vcs.Git], + "triggers": ["--ignore-untracked"], + "action": "store_true", + "dest": "ignore_untracked", + "help": "Ignore untracked files when determining whether the repository is dirty", + }, { "triggers": ["--tagged-metadata"], "action": "store_true", diff --git a/tests/integration/test_dunamai.py b/tests/integration/test_dunamai.py index 5df8043..45fcbfb 100644 --- a/tests/integration/test_dunamai.py +++ b/tests/integration/test_dunamai.py @@ -124,6 +124,9 @@ def test__version__from_git__with_annotated_tags(tmp_path) -> None: # Detect dirty if untracked files (vcs / "bar.txt").write_text("bye") assert from_vcs() == Version("0.0.0", distance=1, dirty=True, branch=b) + assert from_vcs(ignore_untracked=True) == Version( + "0.0.0", distance=1, dirty=False, branch=b + ) # Once the untracked file is removed we are no longer dirty (vcs / "bar.txt").unlink() diff --git a/tests/unit/test_main.py b/tests/unit/test_main.py index 3701ee7..a4f72d3 100644 --- a/tests/unit/test_main.py +++ b/tests/unit/test_main.py @@ -25,6 +25,7 @@ def test__parse_args__from(): strict=False, path=None, pattern_prefix=None, + ignore_untracked=False, ) assert parse_args(["from", "git"]).vcs == "git" assert parse_args(["from", "git", "--tag-branch", "foo"]).tag_branch == "foo" @@ -53,6 +54,7 @@ def test__parse_args__from(): assert parse_args(["from", "any", "--strict"]).strict is True assert parse_args(["from", "any", "--path", "/tmp"]).path == "/tmp" assert parse_args(["from", "any", "--pattern-prefix", "foo-"]).pattern_prefix == "foo-" + assert parse_args(["from", "any", "--ignore-untracked"]).ignore_untracked is True assert parse_args(["from", "subversion", "--tag-dir", "foo"]).tag_dir == "foo" with pytest.raises(SystemExit):