mirror of
https://github.com/kuhyx/utils.git
synced 2026-11-10 19:07:17 +01:00
Some checks failed
dependency freshness / dependencies on newest stable (push) Waiting to run
file length / file-length (push) Waiting to run
md-naming / markdown naming convention (push) Waiting to run
palette drift / palette (push) Waiting to run
shared gate tests / gate unit tests (push) Waiting to run
crdt_sync_dart tests / test (push) Has been cancelled
crdt_sync_flutter tests / test (push) Has been cancelled
design_system tests / test (push) Has been cancelled
sync_settings_ui tests / test (push) Has been cancelled
The gate is three files per repo -- a delegate, a pre-commit hook entry and a CI workflow -- and Phase 3 needs them in sixteen more repos. Hand-replication is precisely how the 250-line cap ended up shipping under four different hook ids, two of which were independent reimplementations rather than delegates, so the copy is now a script and the templates have exactly one home. scripts/install_dependency_freshness_gate.sh <repo> [--check] [--fvm] Idempotent, and it rewrites a copy that has drifted from the template rather than leaving it. `--check` reports without writing. `--fvm` pins the Flutter SDK, and only in a repo that actually holds a pubspec.yaml -- an .fvmrc in a Python repo declares a toolchain nothing there builds with. An unresolvable SDK version leaves the pin alone and exits 1: guessing would pin every repo to a number nobody chose. The pre-commit block is APPENDED rather than parsed and re-emitted. Every one of these configs carries comments explaining why its hooks exist, and a YAML round-trip through the standard library drops all of them. 306 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
58 lines
1.6 KiB
Python
58 lines
1.6 KiB
Python
"""Command line for `install`: which repo, check-only, and the SDK pin."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import argparse
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
from dep_freshness.install import install, plan, write_fvmrc
|
|
from dep_freshness.registries.toolchain import flutter_latest
|
|
|
|
|
|
def build_parser() -> argparse.ArgumentParser:
|
|
parser = argparse.ArgumentParser(
|
|
description="Install the dependency-freshness gate into a repo."
|
|
)
|
|
parser.add_argument("repo", type=Path)
|
|
parser.add_argument(
|
|
"--check",
|
|
action="store_true",
|
|
help="report what would be written, change nothing",
|
|
)
|
|
parser.add_argument(
|
|
"--fvm", action="store_true", help="also pin the Flutter SDK in <repo>/.fvmrc"
|
|
)
|
|
return parser
|
|
|
|
|
|
def main(argv: list[str] | None = None) -> int:
|
|
args = build_parser().parse_args(argv)
|
|
repo = args.repo.resolve()
|
|
|
|
if args.check:
|
|
todo = plan(repo)
|
|
for piece in todo:
|
|
print(f"would write: {piece}")
|
|
if not todo:
|
|
print("gate already current")
|
|
return 0
|
|
|
|
for piece in install(repo):
|
|
print(f"wrote: {piece}")
|
|
|
|
if args.fvm:
|
|
version, _dart = flutter_latest()
|
|
if version is None:
|
|
# Guessing a version here would pin every repo to a number nobody
|
|
# chose, and the gate would then compare against it forever.
|
|
print(
|
|
"could not resolve latest stable Flutter; .fvmrc left alone",
|
|
file=sys.stderr,
|
|
)
|
|
return 1
|
|
if write_fvmrc(repo, version):
|
|
print(f"wrote: .fvmrc (flutter {version})")
|
|
|
|
return 0
|