multicz 0.2.0__tar.gz → 0.2.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {multicz-0.2.0 → multicz-0.2.2}/PKG-INFO +1 -1
- {multicz-0.2.0 → multicz-0.2.2}/pyproject.toml +1 -1
- multicz-0.2.2/src/multicz/__main__.py +3 -0
- {multicz-0.2.0 → multicz-0.2.2}/src/multicz/cli.py +36 -9
- {multicz-0.2.0 → multicz-0.2.2}/README.md +0 -0
- {multicz-0.2.0 → multicz-0.2.2}/src/multicz/__init__.py +0 -0
- {multicz-0.2.0 → multicz-0.2.2}/src/multicz/changelog.py +0 -0
- {multicz-0.2.0 → multicz-0.2.2}/src/multicz/commits.py +0 -0
- {multicz-0.2.0 → multicz-0.2.2}/src/multicz/components.py +0 -0
- {multicz-0.2.0 → multicz-0.2.2}/src/multicz/config.py +0 -0
- {multicz-0.2.0 → multicz-0.2.2}/src/multicz/debian.py +0 -0
- {multicz-0.2.0 → multicz-0.2.2}/src/multicz/discovery.py +0 -0
- {multicz-0.2.0 → multicz-0.2.2}/src/multicz/planner.py +0 -0
- {multicz-0.2.0 → multicz-0.2.2}/src/multicz/state.py +0 -0
- {multicz-0.2.0 → multicz-0.2.2}/src/multicz/validation.py +0 -0
- {multicz-0.2.0 → multicz-0.2.2}/src/multicz/writers.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: multicz
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.2
|
|
4
4
|
Summary: Multi-component versioning for monorepos: bump apps, charts, and images independently from conventional commits.
|
|
5
5
|
Keywords: semver,monorepo,helm,conventional-commits,release,versioning
|
|
6
6
|
Author: Chris
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
+
import hashlib
|
|
5
6
|
import shlex
|
|
6
7
|
import subprocess
|
|
7
8
|
import sys
|
|
@@ -1010,9 +1011,11 @@ def _git(repo: Path, *args: str) -> str:
|
|
|
1010
1011
|
def _porcelain_paths(repo: Path) -> set[str]:
|
|
1011
1012
|
"""Repo-relative paths currently dirty in the working tree.
|
|
1012
1013
|
|
|
1013
|
-
Used to
|
|
1014
|
-
hooks
|
|
1015
|
-
|
|
1014
|
+
Used to identify candidate paths to hash before/after running
|
|
1015
|
+
``post_bump`` hooks. A pure set diff would miss a file that's
|
|
1016
|
+
dirty both before and after with different content — the
|
|
1017
|
+
canonical case being ``uv run`` itself silently re-syncing
|
|
1018
|
+
``uv.lock`` before multicz even gets to run.
|
|
1016
1019
|
"""
|
|
1017
1020
|
out = subprocess.run(
|
|
1018
1021
|
["git", "status", "--porcelain"],
|
|
@@ -1032,12 +1035,20 @@ def _porcelain_paths(repo: Path) -> set[str]:
|
|
|
1032
1035
|
return paths
|
|
1033
1036
|
|
|
1034
1037
|
|
|
1038
|
+
def _hash_file(path: Path) -> str | None:
|
|
1039
|
+
try:
|
|
1040
|
+
return hashlib.sha256(path.read_bytes()).hexdigest()
|
|
1041
|
+
except OSError:
|
|
1042
|
+
return None
|
|
1043
|
+
|
|
1044
|
+
|
|
1035
1045
|
def _run_post_bump_hook(repo: Path, command: str) -> None:
|
|
1036
1046
|
"""Execute a single ``post_bump`` shell command in ``repo``."""
|
|
1037
1047
|
args = shlex.split(command)
|
|
1038
1048
|
if not args:
|
|
1039
1049
|
return
|
|
1040
|
-
|
|
1050
|
+
# stderr, so `multicz bump --output json | jq` stays parseable.
|
|
1051
|
+
err.print(f" [dim]post_bump:[/] {command}")
|
|
1041
1052
|
result = subprocess.run(
|
|
1042
1053
|
args, cwd=repo, capture_output=True, text=True
|
|
1043
1054
|
)
|
|
@@ -1424,21 +1435,37 @@ def bump(
|
|
|
1424
1435
|
# changelog, state) so commands like `uv lock`, `npm install
|
|
1425
1436
|
# --package-lock-only`, `cargo update --workspace`, `helm dependency
|
|
1426
1437
|
# update` see the new pyproject.toml / package.json / Chart.yaml /
|
|
1427
|
-
# Cargo.toml. Files modified by hooks are auto-detected
|
|
1428
|
-
#
|
|
1429
|
-
#
|
|
1430
|
-
#
|
|
1438
|
+
# Cargo.toml. Files modified by hooks are auto-detected and folded
|
|
1439
|
+
# into ``written`` so they ride the release commit.
|
|
1440
|
+
#
|
|
1441
|
+
# Detection compares content hashes — not just the dirty-paths set —
|
|
1442
|
+
# because the entry point is typically ``uv run multicz bump``, and
|
|
1443
|
+
# ``uv run`` re-syncs the venv (which can rewrite ``uv.lock``) before
|
|
1444
|
+
# multicz code runs at all. By the time we snapshot, uv.lock is
|
|
1445
|
+
# already in the dirty set; a set diff would miss the *second*
|
|
1446
|
+
# rewrite the post_bump hook performs against the new pyproject. The
|
|
1447
|
+
# hash comparison catches it.
|
|
1431
1448
|
if not dry_run and applied:
|
|
1432
1449
|
hook_components = [
|
|
1433
1450
|
n for n in applied if config.components[n].post_bump
|
|
1434
1451
|
]
|
|
1435
1452
|
if hook_components:
|
|
1436
1453
|
before_dirty = _porcelain_paths(repo)
|
|
1454
|
+
before_hashes: dict[str, str | None] = {
|
|
1455
|
+
relpath: _hash_file(repo / relpath)
|
|
1456
|
+
for relpath in before_dirty
|
|
1457
|
+
}
|
|
1437
1458
|
for name in hook_components:
|
|
1438
1459
|
for command in config.components[name].post_bump:
|
|
1439
1460
|
_run_post_bump_hook(repo, command)
|
|
1440
1461
|
after_dirty = _porcelain_paths(repo)
|
|
1441
|
-
|
|
1462
|
+
hook_modified: set[str] = {
|
|
1463
|
+
relpath
|
|
1464
|
+
for relpath in after_dirty
|
|
1465
|
+
if relpath not in before_dirty
|
|
1466
|
+
or _hash_file(repo / relpath) != before_hashes.get(relpath)
|
|
1467
|
+
}
|
|
1468
|
+
for relpath in sorted(hook_modified):
|
|
1442
1469
|
path = (repo / relpath).resolve()
|
|
1443
1470
|
if path.is_file() and path not in written:
|
|
1444
1471
|
written.append(path)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|