Skip to content

Commit 996f6df

Browse files
authored
Merge pull request #500 from lbedner/v0.6.0-rc2
Deployment
2 parents 81d9d89 + 453f0bc commit 996f6df

10 files changed

Lines changed: 78 additions & 20 deletions

File tree

CLAUDE.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ Each generated project includes:
3232

3333
## Installation
3434

35-
**Current Version**: 0.6.0rc1
35+
**Current Version**: 0.6.0rc2
3636

3737
```bash
3838
pip install aegis-stack

aegis/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22
Aegis Stack CLI - Component generation and project management tools.
33
"""
44

5-
__version__ = "0.6.0rc1"
5+
__version__ = "0.6.0rc2"

aegis/config/defaults.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
a single source of truth.
66
"""
77

8+
import re
89
from pathlib import Path
910

1011

@@ -94,6 +95,26 @@ def _generate_supported_versions(min_version: str, max_version: str) -> list[str
9495
# Supported Python versions (auto-generated from min to max)
9596
SUPPORTED_PYTHON_VERSIONS = _generate_supported_versions(_min_version, _max_version)
9697

98+
99+
def version_to_git_tag(version: str) -> str:
100+
"""
101+
Convert a PEP 440 version string to a git tag.
102+
103+
PEP 440 uses no separator before pre-release identifiers (e.g., 0.6.0rc1),
104+
but our git tags use a dash (e.g., v0.6.0-rc1).
105+
106+
Args:
107+
version: PEP 440 version string (e.g., "0.6.0rc1", "0.5.4")
108+
109+
Returns:
110+
Git tag string (e.g., "v0.6.0-rc1", "v0.5.4")
111+
"""
112+
# Insert dash before pre-release identifiers: rc, alpha, beta, dev
113+
# Negative lookbehind ensures we don't double-dash if already present
114+
normalized = re.sub(r"(?<!-)(rc|alpha|beta|dev)(\d+)", r"-\1\2", version)
115+
return f"v{normalized}"
116+
117+
97118
# GitHub URL for template source (used when installed via pip/uvx)
98119
GITHUB_TEMPLATE_URL = "gh:lbedner/aegis-stack"
99120

aegis/core/copier_manager.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,11 @@
1616

1717
from aegis import __version__
1818

19-
from ..config.defaults import DEFAULT_PYTHON_VERSION, GITHUB_TEMPLATE_URL
19+
from ..config.defaults import (
20+
DEFAULT_PYTHON_VERSION,
21+
GITHUB_TEMPLATE_URL,
22+
version_to_git_tag,
23+
)
2024
from ..constants import AnswerKeys, StorageBackends
2125
from .migration_generator import (
2226
generate_migrations_for_services,
@@ -159,7 +163,7 @@ def generate_with_copier(
159163
# Use GitHub URL for template source with CLI version as default ref
160164
# This ensures CLI v0.4.1 uses template v0.4.1, not HEAD
161165
template_source = GITHUB_TEMPLATE_URL
162-
resolved_ref = vcs_ref if vcs_ref else f"v{__version__}"
166+
resolved_ref = vcs_ref if vcs_ref else version_to_git_tag(__version__)
163167

164168
# Store template version in answers for future reference
165169
# This allows aegis update to show "v0.4.1" instead of commit hash

aegis/core/copier_updater.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
from packaging.version import parse
1414
from pydantic import BaseModel, Field
1515

16-
from aegis.config.defaults import GITHUB_REPO_URL
16+
from aegis.config.defaults import GITHUB_REPO_URL, version_to_git_tag
1717
from aegis.constants import AnswerKeys, ComponentNames, StorageBackends
1818
from aegis.core.copier_manager import load_copier_answers
1919
from aegis.core.post_gen_tasks import cleanup_components, run_post_generation_tasks
@@ -432,7 +432,7 @@ def resolve_version_to_ref(
432432
if not version or version == "latest":
433433
latest = get_latest_version(template_root)
434434
if latest:
435-
return f"v{latest}"
435+
return version_to_git_tag(latest)
436436
return "HEAD"
437437

438438
# Check if it's a commit hash (40 hex characters)
@@ -442,9 +442,9 @@ def resolve_version_to_ref(
442442
# Check if it looks like a version number (add 'v' prefix)
443443
try:
444444
parse(version)
445-
# Valid version number - always use v-prefixed tag format
446-
# (git verification may fail when installed via pip/uvx, but tag format is consistent)
447-
return f"v{version}"
445+
# Valid version number - convert to git tag format
446+
# PEP 440 "0.6.0rc1" → git tag "v0.6.0-rc1"
447+
return version_to_git_tag(version)
448448
except Exception:
449449
pass
450450

@@ -793,7 +793,7 @@ def get_commit_for_version(
793793
template_root = get_template_root()
794794

795795
# Ensure version has 'v' prefix
796-
tag_name = version if version.startswith("v") else f"v{version}"
796+
tag_name = version if version.startswith("v") else version_to_git_tag(version)
797797

798798
try:
799799
result = subprocess.run(

copier.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
# - Update support
77

88
_min_copier_version: "9.0.0"
9-
_version: "0.6.0rc1"
9+
_version: "0.6.0rc2"
1010

1111
# IMPORTANT: Template content is in subdirectory
1212
# This allows the template to be recognized as git-tracked (aegis-stack repo root has .git)

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "aegis-stack"
3-
version = "0.6.0rc1"
3+
version = "0.6.0rc2"
44
description = "A production-ready Python foundation for builders who refuse to wait. Try: uvx aegis-stack init my-project"
55
readme = "README.md"
66
requires-python = ">=3.11,<3.15"

tests/config/test_defaults.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
SUPPORTED_PYTHON_VERSIONS,
1212
_generate_supported_versions,
1313
_parse_python_version_bounds,
14+
version_to_git_tag,
1415
)
1516

1617

@@ -156,6 +157,38 @@ def test_supported_versions_sorted_ascending(self) -> None:
156157
assert versions_as_tuples == sorted(versions_as_tuples)
157158

158159

160+
class TestVersionToGitTag:
161+
"""Test version_to_git_tag() function."""
162+
163+
def test_rc_version(self) -> None:
164+
"""Test release candidate versions get dash inserted."""
165+
assert version_to_git_tag("0.6.0rc1") == "v0.6.0-rc1"
166+
assert version_to_git_tag("0.6.0rc2") == "v0.6.0-rc2"
167+
assert version_to_git_tag("1.0.0rc10") == "v1.0.0-rc10"
168+
169+
def test_stable_version(self) -> None:
170+
"""Test stable versions are unchanged (just prefixed with v)."""
171+
assert version_to_git_tag("0.5.4") == "v0.5.4"
172+
assert version_to_git_tag("1.0.0") == "v1.0.0"
173+
174+
def test_alpha_version(self) -> None:
175+
"""Test alpha pre-release versions."""
176+
assert version_to_git_tag("0.7.0alpha1") == "v0.7.0-alpha1"
177+
178+
def test_beta_version(self) -> None:
179+
"""Test beta pre-release versions."""
180+
assert version_to_git_tag("0.7.0beta2") == "v0.7.0-beta2"
181+
182+
def test_dev_version(self) -> None:
183+
"""Test dev pre-release versions."""
184+
assert version_to_git_tag("0.8.0dev1") == "v0.8.0-dev1"
185+
186+
def test_already_has_dash(self) -> None:
187+
"""Test versions that already contain a dash don't get double-dashed."""
188+
# If someone passes "0.6.0-rc1" it should become "v0.6.0-rc1", not "v0.6.0--rc1"
189+
assert version_to_git_tag("0.6.0-rc1") == "v0.6.0-rc1"
190+
191+
159192
class TestIntegration:
160193
"""Integration tests for configuration system."""
161194

tests/core/test_copier_updater.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -396,17 +396,17 @@ def git_repo_with_tags(tmp_path: Path) -> Path:
396396
["git", "tag", "v0.2.0"], cwd=tmp_path, capture_output=True, check=True
397397
)
398398

399-
# Add a prerelease tag
400-
(tmp_path / "test.txt").write_text("v0.3.0rc1")
399+
# Add a prerelease tag (dash format matches our git tag convention)
400+
(tmp_path / "test.txt").write_text("v0.3.0-rc1")
401401
subprocess.run(["git", "add", "."], cwd=tmp_path, capture_output=True, check=True)
402402
subprocess.run(
403-
["git", "commit", "-m", "v0.3.0rc1"],
403+
["git", "commit", "-m", "v0.3.0-rc1"],
404404
cwd=tmp_path,
405405
capture_output=True,
406406
check=True,
407407
)
408408
subprocess.run(
409-
["git", "tag", "v0.3.0rc1"], cwd=tmp_path, capture_output=True, check=True
409+
["git", "tag", "v0.3.0-rc1"], cwd=tmp_path, capture_output=True, check=True
410410
)
411411

412412
# Add another prerelease
@@ -444,7 +444,7 @@ def test_excludes_prereleases_by_default(self, git_repo_with_tags: Path) -> None
444444
versions = get_available_versions(git_repo_with_tags)
445445

446446
# Should NOT contain rc or alpha versions
447-
assert "0.3.0rc1" not in versions
447+
assert "0.3.0-rc1" not in versions
448448
assert "0.3.0-alpha.1" not in versions
449449

450450
def test_includes_prereleases_when_requested(
@@ -454,7 +454,7 @@ def test_includes_prereleases_when_requested(
454454
versions = get_available_versions(git_repo_with_tags, include_prereleases=True)
455455

456456
# Should contain all versions including prereleases
457-
assert "0.3.0rc1" in versions
457+
assert "0.3.0-rc1" in versions
458458
assert "0.3.0-alpha.1" in versions
459459
assert "0.2.0" in versions
460460
assert "0.1.0" in versions
@@ -484,7 +484,7 @@ def test_returns_latest_non_prerelease_version(
484484
"""Test that latest version is 0.2.0, not a prerelease."""
485485
latest = get_latest_version(git_repo_with_tags)
486486

487-
# Should be 0.2.0, NOT 0.3.0rc1 or 0.3.0-alpha.1
487+
# Should be 0.2.0, NOT 0.3.0-rc1 or 0.3.0-alpha.1
488488
assert latest == "0.2.0"
489489

490490
def test_returns_none_for_no_versions(self, git_repo: Path) -> None:

uv.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)