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 new dynamic_version option #209

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all 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
25 changes: 25 additions & 0 deletions attribution/__version__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,28 @@
"""

__version__ = "1.8.0"

try:
import re
import subprocess
from pathlib import Path

version_suffix = "+dev"
path = Path(__file__).resolve().parent
while path != path.parent:
if (path / ".git").is_dir():
proc = subprocess.run(
("git", "describe"), text=True, capture_output=True, check=True
)
if match := re.search(r"-(\d+)-(g[a-f0-9]+)$", proc.stdout):
count, ref = match.groups()
version_suffix = f"+dev{count}-{ref}"
break

path = path.parent

except Exception as e:
print(f"version suffix failed: {e}")

finally:
__version__ += version_suffix
39 changes: 39 additions & 0 deletions attribution/generate.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,45 @@ class VersionFile(GeneratedFile):
'''


class DynamicVersionFile(GeneratedFile):
FILENAME = "{project.package}/__version__.py"
TEMPLATE = '''\
"""
This file is automatically generated by attribution.

Do not edit manually. Get more info at https://attribution.omnilib.dev
"""

__version__ = "{{ project.latest.version }}"

try:
import re
import subprocess
from pathlib import Path

version_suffix = "+dev"
path = Path(__file__).resolve().parent
while path != path.parent:
if (path / ".git").is_dir():
proc = subprocess.run(
("git", "describe"), text=True, capture_output=True, check=True
)
if match := re.search(r"-(\\d+)-(g[a-f0-9]+)$", proc.stdout):
count, ref = match.groups()
version_suffix = f"+dev{count}-{ref}"
break

path = path.parent

except Exception as e:
print(f"version suffix failed: {e}")

finally:
__version__ += version_suffix

'''


class CargoFile(GeneratedFile):
EXPECTS = ("package_name", "package_dir")
FILENAME = "{package_dir}/Cargo.toml"
Expand Down
19 changes: 17 additions & 2 deletions attribution/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
import tomlkit

from attribution import __version__
from .generate import CargoFile, Changelog, NpmFile, VersionFile
from .generate import CargoFile, Changelog, DynamicVersionFile, NpmFile, VersionFile
from .helpers import sh
from .project import Project
from .tag import Tag
Expand All @@ -37,6 +37,12 @@ def init() -> None:
version_file = click.confirm(
"Use __version__.py file", default=project.config["version_file"]
)
dynamic_version = False
if version_file:
dynamic_version = click.confirm(
"Use dynamic version suffix (eg. '1.0+git4-gabc123')",
default=project.config["dynamic_version"],
)
signed_tags = click.confirm(
"Use GPG signed tags", default=project.config["signed_tags"]
)
Expand Down Expand Up @@ -66,13 +72,17 @@ def init() -> None:
table["package"] = package
table["signed_tags"] = signed_tags
table["version_file"] = version_file
table["dynamic_version"] = dynamic_version

project.pyproject_path().write_text(tomlkit.dumps(pyproject))

# pick up any changes
project = Project.load()
if version_file:
VersionFile(project).write()
if dynamic_version:
DynamicVersionFile(project).write()
else:
VersionFile(project).write()


@main.command("debug")
Expand Down Expand Up @@ -186,6 +196,11 @@ def tag_release(version: Version, message: Optional[str]) -> None:
sh("git commit --amend --no-edit")
tag.update(message=message, signed=project.config["signed_tags"])

if project.config.get("dynamic_version"):
path = DynamicVersionFile(project).write()
sh(f"git add {path}")
sh("git commit -m 'Dynamic version file'")

except Exception:
mfile = Path(f".attribution-{version}.txt").resolve()
mfile.write_text(message)
Expand Down
1 change: 1 addition & 0 deletions attribution/project.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ def load(cls, path: Optional[Path] = None) -> "Project":
"ignored_authors": [],
"version_file": True,
"signed_tags": True,
"dynamic_version": False,
}

if cls.pyproject_path(path).is_file():
Expand Down
6 changes: 6 additions & 0 deletions attribution/tests/project.py
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@ def test_load(self, cwd_mock):
"cargo_packages": [],
"ignored_authors": [],
"version_file": True,
"dynamic_version": False,
"signed_tags": True,
},
)
Expand All @@ -181,6 +182,7 @@ def test_load(self, cwd_mock):
"cargo_packages": [],
"ignored_authors": [],
"version_file": True,
"dynamic_version": False,
"signed_tags": True,
},
)
Expand All @@ -197,6 +199,7 @@ def test_load(self, cwd_mock):
"cargo_packages": [],
"ignored_authors": [],
"version_file": True,
"dynamic_version": False,
"signed_tags": True,
},
)
Expand All @@ -213,6 +216,7 @@ def test_load(self, cwd_mock):
"cargo_packages": [],
"ignored_authors": [],
"version_file": False,
"dynamic_version": False,
"signed_tags": True,
},
)
Expand All @@ -228,6 +232,7 @@ def test_load(self, cwd_mock):
"cargo_packages": [],
"ignored_authors": [],
"version_file": True,
"dynamic_version": False,
"signed_tags": True,
},
)
Expand All @@ -243,6 +248,7 @@ def test_load(self, cwd_mock):
"cargo_packages": [],
"ignored_authors": [],
"version_file": True,
"dynamic_version": False,
"signed_tags": True,
},
)
16 changes: 16 additions & 0 deletions docs/guide.rst
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,22 @@ Options available are described as follows:
to not have a managed ``__version__.py`` file, this value should be set to
``false``.

.. attribute:: dynamic_version
:type: bool
:value: False

Enables generating a dynamic ``__version__.py`` that generates version
suffixes based on the local repository's revision relative to the last
release. When a release is tagged, a static version file is committed,
without the dynamic suffix logic, before tagging the version bump, and
then the dynamic version file is reinstated after the release is tagged.

If the project's git revision can be queried, then the dynamic version
string will look like ``1.8.0+dev6-g3c61fc2``. Otherwise, the version
string will fall back to the generic form ``1.8.0+dev``.

Requires enabling :attr:`version_file`.


Alternative Packaging
^^^^^^^^^^^^^^^^^^^^^
Expand Down
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ ignored_authors = ["dependabot[bot]", "pyup.io bot"]
version_file = true
signed_tags = true
cargo_packages = ["fake_crate"]
dynamic_version = true

[tool.coverage.run]
branch = true
Expand Down
Loading