mirror of
https://github.com/kuhyx/utils.git
synced 2026-11-11 15:08:19 +01:00
Two things, because the first is what blocked the second from committing. **The rot check was scope-blind.** pre-commit passes only the staged manifests, so a run that sees no package.json cannot learn anything about whether the fleet-wide typescript hold is still needed -- yet it concluded the entry was dead and exited 2. Staging two pubspec.yaml files in utils was enough to make the repo uncommittable. The dead-entry check now runs only under --all, which is CI and the manual whole-repo run; a subset scan has seen a subset by construction. **crdt_sync_dart 0.11.1 and design_system 0.2.1.** Both had dependency upgrades land after their newest tag, so a consumer moving to "latest tag" would pick up the pre-upgrade constraints (crdt_sync_dart-v0.11.0 still carries `crypto: ^3.0.7`, `http: ^1.6.0`, `lints: ^5.0.0`) while carrying its own new exact pins -- the unsatisfiable-resolution case exact pins create. Version bump only; the dependency work is already in922fb36and704c67e. The allowlist end-to-end tests moved to their own file for the 250-line cap, and `run`/`canned` moved to conftest so both files share one definition. `canned` is no longer autouse: the resolver tests patch `_fetch` themselves. 293 tests, 100% branch coverage on every production module. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CRykabMwPgDzFHcARoqpaK
132 lines
3.9 KiB
Python
132 lines
3.9 KiB
Python
"""Allowlist behaviour, end to end: what an exception excuses, and when it rots.
|
|
|
|
Split out of test_check.py for the 250-line cap. The fixtures (`run`,
|
|
`canned`, `repo`, and the `no_shared_allowlist` redirect) live in conftest.py
|
|
so both files see one definition.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from datetime import date, timedelta
|
|
|
|
from dep_freshness.tests.conftest import (
|
|
ALLOWLIST,
|
|
CURRENT_PUBSPEC,
|
|
STALE_PUBSPEC,
|
|
write,
|
|
)
|
|
|
|
SHARED = """\
|
|
exceptions:
|
|
- ecosystem: pub
|
|
package: some_other_package
|
|
pinned: "1.0.0"
|
|
reason: "a fleet-wide hold on something this repo does not use"
|
|
blocked_by: "transitive:whatever@1.0.0"
|
|
"""
|
|
|
|
|
|
def test_a_transitive_exception_excuses_the_finding(repo, run):
|
|
write(repo, "pubspec.yaml", STALE_PUBSPEC)
|
|
write(repo, ALLOWLIST, """\
|
|
exceptions:
|
|
- ecosystem: pub
|
|
package: http
|
|
pinned: "1.5.0"
|
|
reason: "something upstream holds it"
|
|
blocked_by: "transitive:some_pkg@1.0.0"
|
|
""")
|
|
assert run("--all") == 0
|
|
|
|
|
|
def test_an_exception_prints_loudly_even_on_success(repo, run, capsys):
|
|
test_a_transitive_exception_excuses_the_finding(repo, run)
|
|
err = capsys.readouterr().err
|
|
assert "DEPENDENCY EXCEPTION IN USE" in err
|
|
assert "still blocking" in err
|
|
|
|
|
|
def test_an_exception_with_nothing_left_to_excuse_is_an_error(repo, run, capsys):
|
|
write(repo, "pubspec.yaml", CURRENT_PUBSPEC)
|
|
write(repo, ALLOWLIST, """\
|
|
exceptions:
|
|
- ecosystem: pub
|
|
package: http
|
|
pinned: "1.5.0"
|
|
reason: "stale entry nobody removed"
|
|
blocked_by: "transitive:some_pkg@1.0.0"
|
|
""")
|
|
assert run("--all") == 2
|
|
assert "no longer stale" in capsys.readouterr().err
|
|
|
|
|
|
def test_a_file_scoped_run_never_judges_an_entry_dead(repo, run, capsys):
|
|
"""pre-commit passes staged files, so it only ever sees a subset.
|
|
|
|
The entry below excuses a dependency that lives in a manifest outside the
|
|
scoped path. `--all` would find it stale and mark the entry used; a scoped
|
|
run cannot, and must not conclude the entry is rot -- that failed a commit
|
|
in utils over the fleet-wide typescript hold when the staged files were
|
|
two pubspec.yaml.
|
|
"""
|
|
write(repo, "pubspec.yaml", STALE_PUBSPEC)
|
|
write(repo, "sub/pubspec.yaml", CURRENT_PUBSPEC)
|
|
write(repo, ALLOWLIST, """\
|
|
exceptions:
|
|
- ecosystem: pub
|
|
package: http
|
|
pinned: "1.5.0"
|
|
reason: "held by something upstream"
|
|
blocked_by: "transitive:some_pkg@1.0.0"
|
|
""")
|
|
assert run("sub/pubspec.yaml") == 0
|
|
assert "no longer stale" not in capsys.readouterr().err
|
|
# The same allowlist over the whole repo still excuses, not rots.
|
|
assert run("--all") == 0
|
|
|
|
|
|
def test_an_expired_allowlist_exits_two(repo, run, capsys):
|
|
write(repo, "pubspec.yaml", STALE_PUBSPEC)
|
|
yesterday = (date.today() - timedelta(days=1)).isoformat()
|
|
write(repo, ALLOWLIST, f"""\
|
|
exceptions:
|
|
- ecosystem: pub
|
|
package: http
|
|
pinned: "1.5.0"
|
|
reason: "held"
|
|
blocked_by: "discretionary"
|
|
expires: "{yesterday}"
|
|
""")
|
|
assert run("--all") == 2
|
|
assert "Allowlist ERROR" in capsys.readouterr().err
|
|
|
|
|
|
def test_an_inherited_entry_this_repo_does_not_need_is_not_rot(
|
|
repo, run, no_shared_allowlist
|
|
):
|
|
"""A fleet-wide hold on typescript excuses nothing in a Flutter app.
|
|
|
|
Treating that as a dead entry would make every repo without the dependency
|
|
uncommittable -- the shared allowlist would be unusable for the exact case
|
|
it exists for.
|
|
"""
|
|
no_shared_allowlist.write_text(SHARED, encoding="utf-8")
|
|
write(repo, "pubspec.yaml", CURRENT_PUBSPEC)
|
|
assert run("--all") == 0
|
|
|
|
|
|
def test_a_repo_local_entry_with_nothing_to_excuse_is_still_rot(
|
|
repo, run, no_shared_allowlist
|
|
):
|
|
no_shared_allowlist.write_text(SHARED, encoding="utf-8")
|
|
write(repo, "pubspec.yaml", CURRENT_PUBSPEC)
|
|
write(repo, ALLOWLIST, """\
|
|
exceptions:
|
|
- ecosystem: pub
|
|
package: http
|
|
pinned: "1.5.0"
|
|
reason: "this repo's own stale entry"
|
|
blocked_by: "transitive:x@1.0.0"
|
|
""")
|
|
assert run("--all") == 2
|