feat(release): bump the root crate in Cargo.toml and Cargo.lock
A repo whose Cargo.toml has a [package] section now gets its version set to the release version, and the matching local [[package]] entry in Cargo.lock (same name, no source line) follows in the same release commit, so cargo build --locked keeps passing. Workspaces without [package] and repos without Cargo.toml release as before; a Cargo.lock without the local entry aborts the release before any file is written. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
168d59e1b2
commit
d823a42edc
4 files changed
+194
No files matched your search
@@ -10,6 +10,7 @@ Keep this package stable so existing imports continue to work, e.g.:
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from .cargo import update_cargo_version
|
||||
from .changelog_md import update_changelog
|
||||
from .debian import _get_debian_author, update_debian_changelog
|
||||
from .editor import _open_editor_for_changelog
|
||||
@@ -22,6 +23,7 @@ from .rpm_spec import update_spec_version
|
||||
__all__ = [
|
||||
"_get_debian_author",
|
||||
"_open_editor_for_changelog",
|
||||
"update_cargo_version",
|
||||
"update_changelog",
|
||||
"update_debian_changelog",
|
||||
"update_flake_version",
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
import re
|
||||
|
||||
|
||||
def _read(path: str) -> str:
|
||||
with open(path, encoding="utf-8") as f:
|
||||
return f.read()
|
||||
|
||||
|
||||
def _write(path: str, content: str) -> None:
|
||||
with open(path, "w", encoding="utf-8") as f:
|
||||
f.write(content)
|
||||
|
||||
|
||||
def update_cargo_version(
|
||||
repo_root: str, new_version: str, preview: bool = False
|
||||
) -> list[str]:
|
||||
"""
|
||||
Set the root crate's version in Cargo.toml and its entry in Cargo.lock.
|
||||
|
||||
Args:
|
||||
repo_root: repository root that may hold Cargo.toml and Cargo.lock.
|
||||
new_version: release version without the leading "v".
|
||||
preview: only print what would change.
|
||||
|
||||
Returns:
|
||||
The paths that were (or in preview would be) changed.
|
||||
"""
|
||||
toml_path = os.path.join(repo_root, "Cargo.toml")
|
||||
if not os.path.exists(toml_path):
|
||||
print("[INFO] No Cargo.toml found. Skipping Cargo version update.")
|
||||
return []
|
||||
|
||||
toml = _read(toml_path)
|
||||
block = re.search(r"(?ms)^\[package\]\s*$.*?(?=^\s*\[|\Z)", toml)
|
||||
if not block:
|
||||
print("[INFO] Cargo.toml has no [package] section. Skipping.")
|
||||
return []
|
||||
|
||||
name = re.search(r'(?m)^\s*name\s*=\s*"([^"]+)"', block.group(0))
|
||||
if not name:
|
||||
raise RuntimeError("Missing name key in [package] section of Cargo.toml")
|
||||
new_block, count = re.subn(
|
||||
r'(?m)^(\s*version\s*=\s*")[^"]+(")',
|
||||
lambda m: f"{m.group(1)}{new_version}{m.group(2)}",
|
||||
block.group(0),
|
||||
count=1,
|
||||
)
|
||||
if count == 0:
|
||||
raise RuntimeError("Missing version key in [package] section of Cargo.toml")
|
||||
changes = {toml_path: toml[: block.start()] + new_block + toml[block.end() :]}
|
||||
|
||||
lock_path = os.path.join(repo_root, "Cargo.lock")
|
||||
if os.path.exists(lock_path):
|
||||
lock, count = re.subn(
|
||||
rf'(?m)^(\[\[package\]\]\nname = "{re.escape(name.group(1))}"\n'
|
||||
r'version = ")[^"]+("\n)(?!source = )',
|
||||
lambda m: f"{m.group(1)}{new_version}{m.group(2)}",
|
||||
_read(lock_path),
|
||||
)
|
||||
if count != 1:
|
||||
raise RuntimeError(
|
||||
f"Expected one local {name.group(1)!r} package in Cargo.lock, "
|
||||
f"found {count}"
|
||||
)
|
||||
changes[lock_path] = lock
|
||||
|
||||
for path, content in changes.items():
|
||||
if preview:
|
||||
print(f"[PREVIEW] Would update {path} version to {new_version}")
|
||||
else:
|
||||
_write(path, content)
|
||||
print(f"Updated {path} version to {new_version}")
|
||||
return list(changes)
|
||||
@@ -10,6 +10,7 @@ from pkgmgr.core.git.queries import get_current_branch
|
||||
from pkgmgr.core.repository.paths import resolve_repo_paths
|
||||
|
||||
from .files import (
|
||||
update_cargo_version,
|
||||
update_changelog,
|
||||
update_debian_changelog,
|
||||
update_flake_version,
|
||||
@@ -74,6 +75,8 @@ def _release_impl(
|
||||
|
||||
update_flake_version(paths.flake_nix, new_ver_str, preview=preview)
|
||||
|
||||
cargo_files = update_cargo_version(repo_root, new_ver_str, preview=preview)
|
||||
|
||||
if paths.arch_pkgbuild:
|
||||
update_pkgbuild_version(paths.arch_pkgbuild, new_ver_str, preview=preview)
|
||||
else:
|
||||
@@ -124,6 +127,7 @@ def _release_impl(
|
||||
paths.arch_pkgbuild,
|
||||
paths.rpm_spec,
|
||||
paths.debian_changelog,
|
||||
*cargo_files,
|
||||
]
|
||||
existing_files = [
|
||||
p for p in files_to_add if isinstance(p, str) and p and os.path.exists(p)
|
||||
|
||||
Reference in new issue
Block a user