Skip to content

Commit

Permalink
Better support non-semver SCM versions
Browse files Browse the repository at this point in the history
Fall back to using the last git tag starting with `v\d.+` if no valid semver is found.
This is useful when using vendored tag versions such as libcurl's `v1.1.1q`.
  • Loading branch information
bennettgoble committed Aug 10, 2024
1 parent f43ca67 commit a1407c7
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 8 deletions.
4 changes: 2 additions & 2 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.3.0
rev: v4.6.0
hooks:
- id: check-ast
- id: check-yaml
- id: mixed-line-ending
- id: trailing-whitespace
- repo: https://github.com/pycqa/isort
rev: 5.10.1
rev: 5.13.2
hooks:
- id: isort
args: [--line-length=120]
Expand Down
11 changes: 7 additions & 4 deletions autobuild/scm/git.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ class GitMeta(NamedTuple):
dirty: bool
distance: int
commit: str # Short commit hash
version: Semver
version: Semver | str


def _find_repo_dir(start: Path, level: int = 0) -> Path | None:
Expand Down Expand Up @@ -87,7 +87,7 @@ def _parse_describe(describe: str) -> GitMeta:
dirty=dirty,
distance=int(distance),
commit=commit[1:], # omit "g" prefix
version=Semver.parse(raw_tag),
version=Semver.parse(raw_tag) or raw_tag.lstrip("v"),
)


Expand Down Expand Up @@ -131,12 +131,15 @@ def version(self) -> str | None:
return None
meta = _parse_describe(self.describe())

# If the tag is not a valid semver, then use the raw tag as the next version.
next_version = meta.version.next if isinstance(meta.version, Semver) else meta.version

if meta.dirty:
# dirty + distance or no distance
return f"{meta.version.next}-dev{meta.distance}.g{meta.commit}.d{date()}"
return f"{next_version}-dev{meta.distance}.g{meta.commit}.d{date()}"
elif meta.distance:
# clean + distance
return f"{meta.version.next}-dev{meta.distance}.g{meta.commit}"
return f"{next_version}-dev{meta.distance}.g{meta.commit}"
else:
# clean + no distance
return str(meta.version)
Expand Down
4 changes: 2 additions & 2 deletions tests/basetest.py
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@ def envvar(key: str, val: str | None):


@contextmanager
def git_repo():
def git_repo(initial_tag="v1.0.0"):
"""
Initialize a new git repository in a temporary directory, yield its path, clean after context exit.
Expand Down Expand Up @@ -290,7 +290,7 @@ def git_repo():
cmd("git", "remote", "add", "origin", "https://example.com/foo.git")
cmd("git", "add", "-A")
cmd("git", "commit", "-m", "Initial")
cmd("git", "tag", "v1.0.0")
cmd("git", "tag", initial_tag)
yield root
finally:
# Make sure to chdir out of temp_dir before closing it, otherwise windows
Expand Down
16 changes: 16 additions & 0 deletions tests/test_scm_git.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,22 @@
from tests.basetest import chdir, git_repo, needs_git


@needs_git
class InvalidSemverTests(TestCase):
def test_invalid_semver(self):
with git_repo("v1.1.1q") as repo:
version = get_version(repo)
self.assertEqual(version, "1.1.1q")

def test_dirty_invalid_semver(self):
with git_repo("v1.1.1q") as repo:
with open(os.path.join(repo, "file"), "w") as f:
f.write("+1")
cmd("git", "add", "file")
version = get_version(repo)
self.assertRegex(version, fr"^1\.1\.1q\-dev0\.g[a-z0-9]{{7}}.d{date()}$")


@needs_git
class GitTests(TestCase):
repo: str
Expand Down

0 comments on commit a1407c7

Please sign in to comment.