mac-upkeep 3.0.2__tar.gz → 3.0.3__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.
- mac_upkeep-3.0.3/.release-please-manifest.json +3 -0
- {mac_upkeep-3.0.2 → mac_upkeep-3.0.3}/CHANGELOG.md +7 -0
- {mac_upkeep-3.0.2 → mac_upkeep-3.0.3}/PKG-INFO +1 -1
- {mac_upkeep-3.0.2 → mac_upkeep-3.0.3}/pyproject.toml +1 -1
- {mac_upkeep-3.0.2 → mac_upkeep-3.0.3}/src/mac_upkeep/output.py +11 -4
- {mac_upkeep-3.0.2 → mac_upkeep-3.0.3}/tests/test_output.py +43 -0
- {mac_upkeep-3.0.2 → mac_upkeep-3.0.3}/uv.lock +1 -1
- mac_upkeep-3.0.2/.release-please-manifest.json +0 -3
- {mac_upkeep-3.0.2 → mac_upkeep-3.0.3}/.github/workflows/release.yml +0 -0
- {mac_upkeep-3.0.2 → mac_upkeep-3.0.3}/.github/workflows/test.yml +0 -0
- {mac_upkeep-3.0.2 → mac_upkeep-3.0.3}/.gitignore +0 -0
- {mac_upkeep-3.0.2 → mac_upkeep-3.0.3}/CLAUDE.md +0 -0
- {mac_upkeep-3.0.2 → mac_upkeep-3.0.3}/CONTRIBUTING.md +0 -0
- {mac_upkeep-3.0.2 → mac_upkeep-3.0.3}/LICENSE +0 -0
- {mac_upkeep-3.0.2 → mac_upkeep-3.0.3}/README.md +0 -0
- {mac_upkeep-3.0.2 → mac_upkeep-3.0.3}/demo/demo.gif +0 -0
- {mac_upkeep-3.0.2 → mac_upkeep-3.0.3}/demo/record.sh +0 -0
- {mac_upkeep-3.0.2 → mac_upkeep-3.0.3}/docs/reusable-patterns.md +0 -0
- {mac_upkeep-3.0.2 → mac_upkeep-3.0.3}/llms.txt +0 -0
- {mac_upkeep-3.0.2 → mac_upkeep-3.0.3}/release-please-config.json +0 -0
- {mac_upkeep-3.0.2 → mac_upkeep-3.0.3}/src/mac_upkeep/__init__.py +0 -0
- {mac_upkeep-3.0.2 → mac_upkeep-3.0.3}/src/mac_upkeep/cli.py +0 -0
- {mac_upkeep-3.0.2 → mac_upkeep-3.0.3}/src/mac_upkeep/config.py +0 -0
- {mac_upkeep-3.0.2 → mac_upkeep-3.0.3}/src/mac_upkeep/defaults.toml +0 -0
- {mac_upkeep-3.0.2 → mac_upkeep-3.0.3}/src/mac_upkeep/editor_cache.py +0 -0
- {mac_upkeep-3.0.2 → mac_upkeep-3.0.3}/src/mac_upkeep/git_sync.py +0 -0
- {mac_upkeep-3.0.2 → mac_upkeep-3.0.3}/src/mac_upkeep/notify.py +0 -0
- {mac_upkeep-3.0.2 → mac_upkeep-3.0.3}/src/mac_upkeep/py.typed +0 -0
- {mac_upkeep-3.0.2 → mac_upkeep-3.0.3}/src/mac_upkeep/tasks.py +0 -0
- {mac_upkeep-3.0.2 → mac_upkeep-3.0.3}/tests/__init__.py +0 -0
- {mac_upkeep-3.0.2 → mac_upkeep-3.0.3}/tests/conftest.py +0 -0
- {mac_upkeep-3.0.2 → mac_upkeep-3.0.3}/tests/test_cli.py +0 -0
- {mac_upkeep-3.0.2 → mac_upkeep-3.0.3}/tests/test_config.py +0 -0
- {mac_upkeep-3.0.2 → mac_upkeep-3.0.3}/tests/test_editor_cache.py +0 -0
- {mac_upkeep-3.0.2 → mac_upkeep-3.0.3}/tests/test_git_sync.py +0 -0
- {mac_upkeep-3.0.2 → mac_upkeep-3.0.3}/tests/test_isolation.py +0 -0
- {mac_upkeep-3.0.2 → mac_upkeep-3.0.3}/tests/test_notify.py +0 -0
- {mac_upkeep-3.0.2 → mac_upkeep-3.0.3}/tests/test_retry_backoff.py +0 -0
- {mac_upkeep-3.0.2 → mac_upkeep-3.0.3}/tests/test_tasks.py +0 -0
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [3.0.3](https://github.com/calvindotsg/mac-upkeep/compare/v3.0.2...v3.0.3) (2026-08-17)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Bug Fixes
|
|
7
|
+
|
|
8
|
+
* report handler tasks as dry-run instead of as having executed ([#51](https://github.com/calvindotsg/mac-upkeep/issues/51)) ([1db8054](https://github.com/calvindotsg/mac-upkeep/commit/1db8054d65da313f6fe4d51f00932d126fc59c79))
|
|
9
|
+
|
|
3
10
|
## [3.0.2](https://github.com/calvindotsg/mac-upkeep/compare/v3.0.1...v3.0.2) (2026-08-16)
|
|
4
11
|
|
|
5
12
|
|
|
@@ -97,9 +97,9 @@ class Output:
|
|
|
97
97
|
if t.status == "running":
|
|
98
98
|
icon = Spinner("dots", style="yellow")
|
|
99
99
|
detail = Text("running", style="yellow")
|
|
100
|
-
elif t.status == "ok" and t.reason
|
|
100
|
+
elif t.status == "ok" and t.reason.startswith("dry-run"):
|
|
101
101
|
icon = Text(_DRY, style="cyan")
|
|
102
|
-
detail = Text(
|
|
102
|
+
detail = Text(t.reason, style="dim")
|
|
103
103
|
elif t.status == "ok":
|
|
104
104
|
icon = Text(_OK, style="green")
|
|
105
105
|
detail = Text(f"{t.duration:.1f}s", style="dim") if t.duration else Text("")
|
|
@@ -138,8 +138,15 @@ class Output:
|
|
|
138
138
|
else:
|
|
139
139
|
if result.status == "skipped":
|
|
140
140
|
logger.info("SKIP: %s (%s)", result.name, result.reason)
|
|
141
|
-
elif result.status == "ok" and result.reason
|
|
142
|
-
|
|
141
|
+
elif result.status == "ok" and result.reason.startswith("dry-run"):
|
|
142
|
+
# Handlers return a richer reason ("dry-run: 17 repos"); command
|
|
143
|
+
# tasks return the bare "dry-run". Surface the extra detail when
|
|
144
|
+
# there is any, so a handler preview is not reduced to a stub.
|
|
145
|
+
detail = result.reason[len("dry-run") :].lstrip(": ")
|
|
146
|
+
if detail:
|
|
147
|
+
logger.info("DRY-RUN: would run %s (%s)", result.name, detail)
|
|
148
|
+
else:
|
|
149
|
+
logger.info("DRY-RUN: would run %s", result.name)
|
|
143
150
|
elif result.status == "ok":
|
|
144
151
|
logger.info("Running %s... done", result.name)
|
|
145
152
|
elif result.status == "failed":
|
|
@@ -69,6 +69,49 @@ def test_output_non_interactive_task_done_dry_run(caplog):
|
|
|
69
69
|
assert "DRY-RUN" in caplog.text
|
|
70
70
|
|
|
71
71
|
|
|
72
|
+
def test_output_non_interactive_task_done_dry_run_handler_reason(caplog):
|
|
73
|
+
"""Handler tasks return 'dry-run: <detail>', not the bare 'dry-run'.
|
|
74
|
+
|
|
75
|
+
An exact-equality check fell through to the 'Running X... done' branch, so a
|
|
76
|
+
dry run reported handler tasks as if they had executed.
|
|
77
|
+
"""
|
|
78
|
+
import logging
|
|
79
|
+
|
|
80
|
+
output = _non_interactive()
|
|
81
|
+
result = TaskResult("git_sync", "ok", reason="dry-run: 17 repos")
|
|
82
|
+
with caplog.at_level(logging.INFO, logger="mac_upkeep"):
|
|
83
|
+
output.task_done(result)
|
|
84
|
+
assert "DRY-RUN: would run git_sync (17 repos)" in caplog.text
|
|
85
|
+
assert "done" not in caplog.text
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def test_output_non_interactive_task_done_dry_run_bare_has_no_empty_detail(caplog):
|
|
89
|
+
"""The bare 'dry-run' reason must not render an empty '()' suffix."""
|
|
90
|
+
import logging
|
|
91
|
+
|
|
92
|
+
output = _non_interactive()
|
|
93
|
+
result = TaskResult("gcloud", "ok", reason="dry-run")
|
|
94
|
+
with caplog.at_level(logging.INFO, logger="mac_upkeep"):
|
|
95
|
+
output.task_done(result)
|
|
96
|
+
assert "DRY-RUN: would run gcloud" in caplog.text
|
|
97
|
+
assert "()" not in caplog.text
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
def test_output_non_interactive_ok_reason_is_not_treated_as_dry_run(caplog):
|
|
101
|
+
"""A successful handler reason must still read as a real run.
|
|
102
|
+
|
|
103
|
+
Guards the prefix check against over-matching: only 'dry-run...' is a preview.
|
|
104
|
+
"""
|
|
105
|
+
import logging
|
|
106
|
+
|
|
107
|
+
output = _non_interactive()
|
|
108
|
+
result = TaskResult("editor_cache", "ok", reason="nothing to clean")
|
|
109
|
+
with caplog.at_level(logging.INFO, logger="mac_upkeep"):
|
|
110
|
+
output.task_done(result)
|
|
111
|
+
assert "Running editor_cache... done" in caplog.text
|
|
112
|
+
assert "DRY-RUN" not in caplog.text
|
|
113
|
+
|
|
114
|
+
|
|
72
115
|
def test_output_non_interactive_task_done_skipped(caplog):
|
|
73
116
|
import logging
|
|
74
117
|
|
|
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
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|