commit:     62c21b1c0ad03f395541a50f439d93d10c289001
Author:     Alfred Wingate <parona <AT> protonmail <DOT> com>
AuthorDate: Wed Feb  4 22:03:33 2026 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Tue Feb 17 00:26:36 2026 +0000
URL:        https://gitweb.gentoo.org/proj/portage.git/commit/?id=62c21b1c

lib: follow PEP440 closer, handle -dirty

If using the live package at a commit that has been tagged it and you
have applied uncommited changes (eg. user patches in portage-9999) it
would lead to a version like 3.0.77-dirty. This would be an invalid
version in the python ecosystem and pip check would complain.

Handle that specific scenario explicitly and while at it use .dev for
the "commit since tag" marker since its strictly more correct.
For example setuptools-scm handles it like this as well.

Example version before change:
3.0.77-dirty
3.0.77-4+g78ec6ee6b

Example versions after change:
3.0.77+dirty
3.0.77.dev5+g0f06e2826

Signed-off-by: Alfred Wingate <parona <AT> protonmail.com>
Part-of: https://github.com/gentoo/portage/pull/1547
Closes: https://github.com/gentoo/portage/pull/1547
Signed-off-by: Sam James <sam <AT> gentoo.org>

 lib/portage/__init__.py | 23 +++++++++++++++++++----
 1 file changed, 19 insertions(+), 4 deletions(-)

diff --git a/lib/portage/__init__.py b/lib/portage/__init__.py
index 1fccfd8c42..831eebf91b 100644
--- a/lib/portage/__init__.py
+++ b/lib/portage/__init__.py
@@ -702,15 +702,30 @@ if installation.TYPE == installation.TYPES.SOURCE:
             if os.path.isdir(os.path.join(PORTAGE_BASE_PATH, ".git")):
                 try:
                     result = subprocess.run(
-                        ["git", "describe", "--dirty", "--match", "portage-*"],
+                        [
+                            "git",
+                            "describe",
+                            "--dirty",
+                            "--long",
+                            "--match",
+                            "portage-*",
+                        ],
                         capture_output=True,
                         cwd=PORTAGE_BASE_PATH,
                         encoding=_encodings["stdio"],
                     )
                     if result.returncode == 0:
-                        VERSION = (
-                            
result.stdout.lstrip("portage-").strip().replace("-g", "+g")
-                        )
+                        # https://peps.python.org/pep-0440/
+                        VERSION, commits_since_tag, commit, dirty = 
re.fullmatch(
+                            "portage-([0-9.]*)-([0-9]*)-(g[0-9a-z]*)(-dirty)?",
+                            result.stdout.strip(),
+                        ).groups()
+                        if commits_since_tag != "0":
+                            VERSION += f".dev{commits_since_tag}+{commit}"
+                            if dirty is not None:
+                                VERSION += "-dirty"
+                        elif dirty is not None:
+                            VERSION += "+dirty"
                 except OSError:
                     pass
             return VERSION

Reply via email to