diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index c0d9f21..36a8a77 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -24,7 +24,7 @@ repos: exclude: ^test/data - repo: https://github.com/PyCQA/flake8 - rev: 6.0.0 + rev: 7.0.0 hooks: - id: flake8 additional_dependencies: diff --git a/CHANGELOG.md b/CHANGELOG.md index 0b16a07..fe2d3f2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +v3.1.0 (in development) +----------------------- +- When `git describe` fails to retrieve a tag, the resulting log/error message + now includes all options passed to the command (based on contribution by + [@jenshnielsen](https://github.com/jenshnielsen)) + v3.0.0 (2023-12-13) ------------------- - Migrated from setuptools to hatch diff --git a/docs/changelog.rst b/docs/changelog.rst index 1f42052..77b0714 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -3,6 +3,13 @@ Changelog ========= +v3.1.0 (in development) +----------------------- +- When :command:`git describe` fails to retrieve a tag, the resulting log/error + message now includes all options passed to the command (based on contribution + by `@jenshnielsen `_) + + v3.0.0 (2023-12-13) ------------------- - Migrated from setuptools to hatch diff --git a/src/versioningit/__init__.py b/src/versioningit/__init__.py index c908432..1e092fa 100644 --- a/src/versioningit/__init__.py +++ b/src/versioningit/__init__.py @@ -43,7 +43,7 @@ for more information. """ -__version__ = "3.0.0" +__version__ = "3.1.0.dev1" __author__ = "John Thorvald Wodder II" __author_email__ = "versioningit@varonathe.org" __license__ = "MIT" diff --git a/src/versioningit/git.py b/src/versioningit/git.py index 75de4c1..125396a 100644 --- a/src/versioningit/git.py +++ b/src/versioningit/git.py @@ -3,6 +3,7 @@ from datetime import datetime from pathlib import Path import re +import shlex import subprocess from typing import Any, NamedTuple, Optional from .core import VCSDescription @@ -128,6 +129,11 @@ def as_args(self) -> list[str]: args.append(f"--exclude={pat}") return args + def as_cmdline_str(self) -> str: + return "git describe --long --dirty --always" + "".join( + " " + shlex.quote(a) for a in self.as_args() + ) + @dataclass class GitRepo: @@ -194,7 +200,9 @@ def describe(self, opts: DescribeOpts) -> str: except subprocess.CalledProcessError as e: # As far as I'm aware, this only happens in a repo without any # commits or a corrupted repo. - raise NoTagError(f"`git describe` command failed: {e.stderr.strip()}") + raise NoTagError( + f"`{opts.as_cmdline_str()}` command failed: {e.stderr.strip()}" + ) def get_branch(self) -> Optional[str]: """ @@ -338,15 +346,16 @@ def describe_git_core( except ValueError: if default_tag is not None: log.info( - "`git describe` returned a hash instead of a tag; falling back to" - " default tag %r", + "`%s` returned a hash instead of a tag; falling back to default" + " tag %r", + opts.as_cmdline_str(), default_tag, ) tag = default_tag distance = int(repo.read("rev-list", "--count", "HEAD")) - 1 rev = description else: - raise NoTagError("`git describe` could not find a tag") + raise NoTagError(f"`{opts.as_cmdline_str()}` could not find a tag") if distance and dirty: state = "distance-dirty" elif distance: diff --git a/test/data/repos/errors/archive-no-tag.json b/test/data/repos/errors/archive-no-tag.json new file mode 100644 index 0000000..a59a9f0 --- /dev/null +++ b/test/data/repos/errors/archive-no-tag.json @@ -0,0 +1,4 @@ +{ + "type": "NoTagError", + "message": "`git describe --long --dirty --always '--exclude=v*'` could not find a tag" +} diff --git a/test/data/repos/errors/archive-no-tag.marks b/test/data/repos/errors/archive-no-tag.marks new file mode 100644 index 0000000..40e6dd3 --- /dev/null +++ b/test/data/repos/errors/archive-no-tag.marks @@ -0,0 +1 @@ +describe_exclude diff --git a/test/data/repos/errors/archive-no-tag.zip b/test/data/repos/errors/archive-no-tag.zip new file mode 100644 index 0000000..85e135f Binary files /dev/null and b/test/data/repos/errors/archive-no-tag.zip differ diff --git a/test/data/repos/errors/hatch-no-tag.json b/test/data/repos/errors/hatch-no-tag.json index 26fd050..8cb1d08 100644 --- a/test/data/repos/errors/hatch-no-tag.json +++ b/test/data/repos/errors/hatch-no-tag.json @@ -1,4 +1,4 @@ { "type": "NoTagError", - "message": "`git describe` could not find a tag" + "message": "`git describe --long --dirty --always --tags '--exclude=*'` could not find a tag" } diff --git a/test/data/repos/errors/no-tag.json b/test/data/repos/errors/no-tag.json index 26fd050..8cb1d08 100644 --- a/test/data/repos/errors/no-tag.json +++ b/test/data/repos/errors/no-tag.json @@ -1,4 +1,4 @@ { "type": "NoTagError", - "message": "`git describe` could not find a tag" + "message": "`git describe --long --dirty --always --tags '--exclude=*'` could not find a tag" } diff --git a/test/data/repos/git/added-no-commits-default-tag.json b/test/data/repos/git/added-no-commits-default-tag.json index 780dea1..2bfffba 100644 --- a/test/data/repos/git/added-no-commits-default-tag.json +++ b/test/data/repos/git/added-no-commits-default-tag.json @@ -1,4 +1,14 @@ { "version": "0.0.0+d20380119", - "next_version": "0.1.0" + "next_version": "0.1.0", + "logmsgs": [ + { + "level": "ERROR", + "message": "`git describe --long --dirty --always --tags` command failed: fatal: bad revision 'HEAD'" + }, + { + "level": "INFO", + "message": "Falling back to default tag 'v0.0.0'" + } + ] } diff --git a/test/data/repos/git/default-tag.json b/test/data/repos/git/default-tag.json index 7a15df2..2f694bb 100644 --- a/test/data/repos/git/default-tag.json +++ b/test/data/repos/git/default-tag.json @@ -1,4 +1,10 @@ { "version": "0.0.0.post2+gb4461bd", - "next_version": "0.1.0" + "next_version": "0.1.0", + "logmsgs": [ + { + "level": "INFO", + "message": "`git describe --long --dirty --always --tags` returned a hash instead of a tag; falling back to default tag 'v0.0.0'" + } + ] } diff --git a/test/data/repos/git/default-version-bad.json b/test/data/repos/git/default-version-bad.json index 66d81b8..9c3299a 100644 --- a/test/data/repos/git/default-version-bad.json +++ b/test/data/repos/git/default-version-bad.json @@ -2,12 +2,12 @@ "version": "1.1.1m", "next_version": { "type": "NoTagError", - "message": "`git describe` could not find a tag" + "message": "`git describe --long --dirty --always --tags` could not find a tag" }, "logmsgs": [ { "level": "ERROR", - "message": "NoTagError: `git describe` could not find a tag" + "message": "NoTagError: `git describe --long --dirty --always --tags` could not find a tag" }, { "level": "INFO", diff --git a/test/data/repos/git/default-version-onbuild-write.json b/test/data/repos/git/default-version-onbuild-write.json index e923fe8..f79911b 100644 --- a/test/data/repos/git/default-version-onbuild-write.json +++ b/test/data/repos/git/default-version-onbuild-write.json @@ -2,12 +2,12 @@ "version": "0.0.0+error", "next_version": { "type": "NoTagError", - "message": "`git describe` could not find a tag" + "message": "`git describe --long --dirty --always --tags '--match=v*'` could not find a tag" }, "logmsgs": [ { "level": "ERROR", - "message": "NoTagError: `git describe` could not find a tag" + "message": "NoTagError: `git describe --long --dirty --always --tags '--match=v*'` could not find a tag" }, { "level": "INFO", diff --git a/test/data/repos/git/default-version.json b/test/data/repos/git/default-version.json index 0f3e8d3..26ee5e8 100644 --- a/test/data/repos/git/default-version.json +++ b/test/data/repos/git/default-version.json @@ -2,12 +2,12 @@ "version": "0.0.0+error", "next_version": { "type": "NoTagError", - "message": "`git describe` could not find a tag" + "message": "`git describe --long --dirty --always --tags` could not find a tag" }, "logmsgs": [ { "level": "ERROR", - "message": "NoTagError: `git describe` could not find a tag" + "message": "NoTagError: `git describe --long --dirty --always --tags` could not find a tag" }, { "level": "INFO", diff --git a/test/test_methods/test_git.py b/test/test_methods/test_git.py index 7fa25d2..cb7a422 100644 --- a/test/test_methods/test_git.py +++ b/test/test_methods/test_git.py @@ -81,7 +81,10 @@ def test_describe_git_no_tag(tmp_path: Path) -> None: shutil.unpack_archive(DATA_DIR / "repos" / "git" / "default-tag.zip", tmp_path) with pytest.raises(NoTagError) as excinfo: describe_git(project_dir=tmp_path, params={}) - assert str(excinfo.value) == "`git describe` could not find a tag" + assert ( + str(excinfo.value) + == "`git describe --long --dirty --always --tags` could not find a tag" + ) @needs_git @@ -105,7 +108,10 @@ def test_describe_git_added_no_commits(tmp_path: Path) -> None: shutil.unpack_archive( DATA_DIR / "repos" / "git" / "added-no-commits-default-tag.zip", tmp_path ) - with pytest.raises(NoTagError, match=r"^`git describe` command failed: "): + with pytest.raises( + NoTagError, + match=r"^`git describe --long --dirty --always --tags` command failed: ", + ): describe_git(project_dir=tmp_path, params={}) @@ -226,7 +232,7 @@ def test_describe_git_archive_added_no_commits_default_tag( assert any( logger == "versioningit" and level == logging.ERROR - and re.match("^`git describe` command failed: ", msg) + and re.match("^`git describe --long --dirty --always` command failed: ", msg) for logger, level, msg in caplog.record_tuples ) assert ( @@ -244,7 +250,10 @@ def test_describe_git_archive_lightweight_only(tmp_path: Path) -> None: project_dir=tmp_path, params={"describe-subst": "$Format:%(describe)$"}, ) - assert str(excinfo.value) == "`git describe` could not find a tag" + assert ( + str(excinfo.value) + == "`git describe --long --dirty --always` could not find a tag" + ) @needs_git @@ -274,8 +283,8 @@ def test_describe_git_archive_lightweight_only_default_tag( assert ( "versioningit", logging.INFO, - "`git describe` returned a hash instead of a tag; falling back to" - " default tag '0.0.0'", + "`git describe --long --dirty --always` returned a hash instead of a" + " tag; falling back to default tag '0.0.0'", ) in caplog.record_tuples