Skip to content

Commit c896239

Browse files
committed
release: v0.10.0 — coverage push to 85%
Internal quality release. Raises pytest coverage from 74% (the v0.9.0 baseline) to 85% via 397 new tests across 15 new test files, with no source-code changes outside one small `pyproject.toml` lint-config tweak. Every new test targets a previously-uncovered code path in the existing modules — no new tools, no new public APIs, no behavioural changes. The shape of the push: core/ command, platform, menu, host_service, systemd, ui (banner, spinner, quiet mode, color override) cli doctor full run, config show/path/edit/validate, self-update no-update path, per-tool --help java/ manager menu loop + _menu_install/upgrade/switch/ uninstall/remove_oracle branches, scanner (scan + homebrew + sdkman + JAVA_HOME), installer (5 lifecycle methods + verify + reload_env), brew (prefix cache, lifecycle wrappers, outdated_java JSON parse), oracle (safe-roots refusal) ssh/ manager keys_generate/rotate + agent_add + known_hosts + perms + config + run() loop, scanner (parse_agent_keys both formats, parse_known_hosts, prune_known_hosts_duplicates, audit_perms tree walk, _looks_like_private_key, _read_pub_metadata edge cases) adguard/ manager scan / verify / loopback DNS / ports_show / ports_set with API + yaml fallback, service + logs + rollback + config_validate, ports (psutil branch + cgroup unified vs legacy) dns/ manager diagnose + flush + show + test + set + reset + fix dispatcher, fixer (detect_interference, step_detect_vpn, _make_backup_dir safety guard, latest_backup_dir, rollback) db/ _to_status_row helper edges, --on-host JSON paths, Linux + macOS service-name resolution, dump-to-file gpg/ manager keys_generate/export, git_signing_show/ configure, agent_status, run() loop, missing- git remediation path docker_clean/ manager prune dispatch, quick dry-run, nuke token, inspect, compose_down with/without -v, schedule_emit to stdout vs file tls/ revoke dry-run, renew failure exit propagation, status with unparseable cert, cron-install delegation hosts/ _read_source URL + local + missing, _back_up sudo fail/succeed, _atomic_write fallback chain, run() interactive web/nginx/ list empty, apply + remove severe-token gate, generate flavors Two minor non-test changes: - `pyproject.toml` — adds `tests/* = ["RUF012"]` to ruff's per-file-ignores. Test stubs use throwaway classes to mock pydantic models; RUF012 (mutable class-attribute defaults need ClassVar) is real-code advice that doesn't apply to dataclass-style test fakes. Test count: 630 → 1027 (+397). Coverage: 74% → 85% (1,266 lines still uncovered, mostly UI rendering paths in adguard/manager and interactive menu loops that branch on Menu.select choices we can't deterministically enumerate without re-implementing each manager's dispatch table). Gates: pytest 1027 passed, ruff clean, mypy strict clean. No new dependencies, no new optional extras.
1 parent 60e8b85 commit c896239

19 files changed

Lines changed: 6743 additions & 2 deletions

CHANGELOG.md

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,66 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
66

77
## [Unreleased]
88

9+
## [0.10.0] — 2026-05-15
10+
11+
### Tests
12+
13+
- Coverage push from 74% to **85%** (1009 → 1027 tests added across
14+
11 new test files; +397 tests on top of the v0.9.0 baseline).
15+
All new tests target previously-thin code paths in:
16+
- `core/` — command (sudo/has_sudo/CommandResult), platform
17+
(WSL detection, brew-prefix, container probes), menu
18+
(FallbackMenu fallback paths + Menu.prompt_for_change),
19+
host_service (SystemdHost + BrewServicesHost), systemd
20+
(state / lifecycle / journal), ui (banner / spinner / quiet).
21+
- `tools/java/` — manager menu paths (_menu_install /
22+
_menu_upgrade / _menu_switch / _menu_uninstall /
23+
_menu_remove_oracle / run() loop), scanner (scan / homebrew
24+
versions / SDKman / JAVA_HOME), installer (install /
25+
reinstall / uninstall / upgrade / switch / verify /
26+
reload_env), brew (prefix cache / install / outdated / link),
27+
oracle (safe-roots enforcement).
28+
- `tools/ssh/` — manager (keys_generate / keys_rotate / agent
29+
paths / known_hosts audit + prune / perms audit + fix /
30+
config show / run() loop), scanner (parse_agent_keys /
31+
parse_known_hosts / prune_known_hosts / list_keys /
32+
_looks_like_private_key / _read_pub_metadata).
33+
- `tools/adguard/` — manager (scan with/without conflicts /
34+
verify / loopback DNS / ports_show / ports_set / service /
35+
logs / rollback / config_validate), ports (psutil branch +
36+
cgroup parsing).
37+
- `tools/dns/` — manager (diagnose / flush / show / test /
38+
set / reset / fix dispatcher / no-service paths), fixer
39+
(detect_interference / step_detect_vpn / _make_backup_dir
40+
safety / latest_backup_dir / rollback).
41+
- `tools/db/`_to_status_row helper, --on-host JSON output
42+
paths, on-host Linux + macOS service-name resolution, dump
43+
to file, status JSON shape with running container.
44+
- `tools/gpg/` — manager (keys_generate / keys_export /
45+
git_signing_show / git_signing_configure / agent_status /
46+
run() loop), error paths for missing git binary.
47+
- `tools/docker_clean/` — manager (prune dispatch / quick
48+
dry-run / nuke token enforcement / inspect / compose_down
49+
with/without --volumes / schedule_emit stdout vs file).
50+
- `tools/tls/` — revoke dry-run, renew failure exit-code
51+
propagation, status with unparseable expiry, cron-install
52+
delegation.
53+
- `tools/hosts/`_read_source URL + local file paths,
54+
_back_up sudo failure + success, _atomic_write fallback
55+
chain, run() interactive loop.
56+
- `tools/web/nginx/` — list with empty sites-available, apply
57+
+ remove severe-token enforcement, vhost generate flavors.
58+
- `cli.py` — config show/path/edit/validate, doctor full run,
59+
self-update no-update path, per-tool --help registration.
60+
61+
### Changed
62+
63+
- `pyproject.toml` — added `tests/* = ["RUF012"]` to ruff's
64+
`per-file-ignores`. Test stubs use throwaway classes to mock
65+
pydantic models; RUF012 (mutable class-attribute defaults
66+
need ClassVar) is real-code advice that doesn't apply to
67+
dataclass-style test fakes.
68+
969
## [0.9.0] — 2026-05-15
1070

1171
### Added

pyproject.toml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
44

55
[project]
66
name = "shimkit"
7-
version = "0.9.0"
7+
version = "0.10.0"
88
description = "A toolkit of developer utilities — Java version manager, shell upgrader, and more. Python tools, shimmed by bash."
99
readme = "README.md"
1010
license = { file = "LICENSE" }
@@ -117,6 +117,12 @@ ignore = ["E501"]
117117
# B008 would otherwise flag every command we declare.
118118
extend-immutable-calls = ["typer.Argument", "typer.Option"]
119119

120+
[tool.ruff.lint.per-file-ignores]
121+
# Test stubs use throwaway classes to mock pydantic models; RUF012 (mutable
122+
# class-attribute defaults need ClassVar) is real-code advice that doesn't
123+
# apply to dataclass-style test fakes.
124+
"tests/*" = ["RUF012"]
125+
120126
[tool.ruff.lint.isort]
121127
# CI installs shimkit editably via `pip install -e ".[dev]"`, after which
122128
# ruff's first-party heuristic can flip-flop on whether `shimkit` is the

src/shimkit/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,5 @@
33
Python tools, shimmed by bash.
44
"""
55

6-
__version__ = "0.9.0"
6+
__version__ = "0.10.0"
77
__all__ = ["__version__"]

0 commit comments

Comments
 (0)