multicz 0.2.0__tar.gz → 0.2.1__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.1}/PKG-INFO +1 -1
- {multicz-0.2.0 → multicz-0.2.1}/pyproject.toml +1 -1
- {multicz-0.2.0 → multicz-0.2.1}/src/multicz/cli.py +34 -8
- {multicz-0.2.0 → multicz-0.2.1}/README.md +0 -0
- {multicz-0.2.0 → multicz-0.2.1}/src/multicz/__init__.py +0 -0
- {multicz-0.2.0 → multicz-0.2.1}/src/multicz/changelog.py +0 -0
- {multicz-0.2.0 → multicz-0.2.1}/src/multicz/commits.py +0 -0
- {multicz-0.2.0 → multicz-0.2.1}/src/multicz/components.py +0 -0
- {multicz-0.2.0 → multicz-0.2.1}/src/multicz/config.py +0 -0
- {multicz-0.2.0 → multicz-0.2.1}/src/multicz/debian.py +0 -0
- {multicz-0.2.0 → multicz-0.2.1}/src/multicz/discovery.py +0 -0
- {multicz-0.2.0 → multicz-0.2.1}/src/multicz/planner.py +0 -0
- {multicz-0.2.0 → multicz-0.2.1}/src/multicz/state.py +0 -0
- {multicz-0.2.0 → multicz-0.2.1}/src/multicz/validation.py +0 -0
- {multicz-0.2.0 → multicz-0.2.1}/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.1
|
|
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,6 +1035,13 @@ 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)
|
|
@@ -1424,21 +1434,37 @@ def bump(
|
|
|
1424
1434
|
# changelog, state) so commands like `uv lock`, `npm install
|
|
1425
1435
|
# --package-lock-only`, `cargo update --workspace`, `helm dependency
|
|
1426
1436
|
# update` see the new pyproject.toml / package.json / Chart.yaml /
|
|
1427
|
-
# Cargo.toml. Files modified by hooks are auto-detected
|
|
1428
|
-
#
|
|
1429
|
-
#
|
|
1430
|
-
#
|
|
1437
|
+
# Cargo.toml. Files modified by hooks are auto-detected and folded
|
|
1438
|
+
# into ``written`` so they ride the release commit.
|
|
1439
|
+
#
|
|
1440
|
+
# Detection compares content hashes — not just the dirty-paths set —
|
|
1441
|
+
# because the entry point is typically ``uv run multicz bump``, and
|
|
1442
|
+
# ``uv run`` re-syncs the venv (which can rewrite ``uv.lock``) before
|
|
1443
|
+
# multicz code runs at all. By the time we snapshot, uv.lock is
|
|
1444
|
+
# already in the dirty set; a set diff would miss the *second*
|
|
1445
|
+
# rewrite the post_bump hook performs against the new pyproject. The
|
|
1446
|
+
# hash comparison catches it.
|
|
1431
1447
|
if not dry_run and applied:
|
|
1432
1448
|
hook_components = [
|
|
1433
1449
|
n for n in applied if config.components[n].post_bump
|
|
1434
1450
|
]
|
|
1435
1451
|
if hook_components:
|
|
1436
1452
|
before_dirty = _porcelain_paths(repo)
|
|
1453
|
+
before_hashes: dict[str, str | None] = {
|
|
1454
|
+
relpath: _hash_file(repo / relpath)
|
|
1455
|
+
for relpath in before_dirty
|
|
1456
|
+
}
|
|
1437
1457
|
for name in hook_components:
|
|
1438
1458
|
for command in config.components[name].post_bump:
|
|
1439
1459
|
_run_post_bump_hook(repo, command)
|
|
1440
1460
|
after_dirty = _porcelain_paths(repo)
|
|
1441
|
-
|
|
1461
|
+
hook_modified: set[str] = {
|
|
1462
|
+
relpath
|
|
1463
|
+
for relpath in after_dirty
|
|
1464
|
+
if relpath not in before_dirty
|
|
1465
|
+
or _hash_file(repo / relpath) != before_hashes.get(relpath)
|
|
1466
|
+
}
|
|
1467
|
+
for relpath in sorted(hook_modified):
|
|
1442
1468
|
path = (repo / relpath).resolve()
|
|
1443
1469
|
if path.is_file() and path not in written:
|
|
1444
1470
|
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
|