From 733e75c964b3632e0d0831aa75dcb4086fa77657 Mon Sep 17 00:00:00 2001 From: "helen@cloud" Date: Wed, 6 May 2026 21:06:09 +0800 Subject: [PATCH] refactor: split doctor fix, verify, and package phases --- scripts/README.md | 3 +- scripts/doctor.sh | 73 ++++++++++++++++---- tests/scripts/test_script_health_contract.py | 10 +++ 3 files changed, 71 insertions(+), 15 deletions(-) diff --git a/scripts/README.md b/scripts/README.md index b09f6f5..a48431d 100644 --- a/scripts/README.md +++ b/scripts/README.md @@ -11,7 +11,7 @@ Executable scripts live in this directory. This file is the entry index for the ## Other Scripts -- [`doctor.sh`](./doctor.sh): primary local development regression entrypoint (uv sync + dependency compatibility + lint + mypy + tests + coverage + built-wheel smoke test) +- [`doctor.sh`](./doctor.sh): primary local development regression entrypoint with explicit fix/verify/package phases (uv sync + dependency compatibility + lint + mypy + tests + coverage + built-wheel smoke test) - [`conformance.sh`](./conformance.sh): local/manual external A2A conformance experiment entrypoint; caches the official TCK, can launch a dummy-backed local SUT, and preserves raw artifacts under `run/conformance/` - [`dependency_health.sh`](./dependency_health.sh): development dependency review entrypoint (`sync`/`pip check` + outdated + dev audit), while blocking CI/publish audits focus on runtime dependencies - [`check_coverage.py`](./check_coverage.py): enforces the overall coverage floor and per-file minimums for critical modules @@ -23,5 +23,6 @@ Executable scripts live in this directory. This file is the entry index for the - `doctor.sh` and `dependency_health.sh` intentionally remain separate entrypoints and share common prerequisites through [`health_common.sh`](./health_common.sh). - `doctor.sh` covers the default local validation baseline, while `dependency_health.sh` remains focused on standalone dependency review and audit flow. +- `doctor.sh` stops early when `pre-commit` rewrites files so you can review the changes and rerun `doctor.sh` from the updated worktree. - [`.github/dependabot.yml`](../.github/dependabot.yml) prefers a single weekly grouped Dependabot PR for `uv`, while `dependency_health.sh` remains the explicit review/audit entrypoint. - External conformance experiments remain intentionally separate from the default regression path. See [`../docs/conformance.md`](../docs/conformance.md). diff --git a/scripts/doctor.sh b/scripts/doctor.sh index f1e254d..1332b99 100755 --- a/scripts/doctor.sh +++ b/scripts/doctor.sh @@ -4,23 +4,68 @@ set -euo pipefail # shellcheck source=./health_common.sh source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/health_common.sh" -run_shared_repo_health_prerequisites "doctor" +doctor_repo_state_fingerprint() { + { + git diff --no-ext-diff --binary --cached -- . + git diff --no-ext-diff --binary -- . + while IFS= read -r -d '' path; do + printf 'untracked %s\n' "$path" + cat "$path" + printf '\n' + done < <(git ls-files --others --exclude-standard -z) + } | git hash-object --stdin +} + +run_doctor_fix_phase() { + local pre_commit_exit_code=0 + local repo_state_before + local repo_state_after + + echo "[doctor] run fix phase" + repo_state_before="$(doctor_repo_state_fingerprint)" + + if uv run pre-commit run --all-files; then + pre_commit_exit_code=0 + else + pre_commit_exit_code=$? + fi + + repo_state_after="$(doctor_repo_state_fingerprint)" + if [[ "$repo_state_before" != "$repo_state_after" ]]; then + echo "[doctor] pre-commit modified files; review the changes and rerun doctor" >&2 + exit 1 + fi -echo "[doctor] run lint" -uv run pre-commit run --all-files + if (( pre_commit_exit_code != 0 )); then + exit "$pre_commit_exit_code" + fi +} -echo "[doctor] run type checks" -uv run mypy src/opencode_a2a +run_doctor_verify_phase() { + echo "[doctor] run verify phase" -echo "[doctor] run tests" -uv run pytest + echo "[doctor] run type checks" + uv run mypy src/opencode_a2a -echo "[doctor] enforce coverage policy" -uv run python ./scripts/check_coverage.py + echo "[doctor] run tests" + uv run pytest -echo "[doctor] build release artifacts" -rm -f dist/opencode_a2a-*.whl dist/opencode_a2a-*.tar.gz -uv build --no-sources + echo "[doctor] enforce coverage policy" + uv run python ./scripts/check_coverage.py +} -echo "[doctor] smoke test built wheel" -bash ./scripts/smoke_test_built_cli.sh dist/opencode_a2a-*.whl +run_doctor_package_phase() { + echo "[doctor] run package phase" + + echo "[doctor] build release artifacts" + rm -f dist/opencode_a2a-*.whl dist/opencode_a2a-*.tar.gz + uv build --no-sources + + echo "[doctor] smoke test built wheel" + bash ./scripts/smoke_test_built_cli.sh dist/opencode_a2a-*.whl +} + +run_shared_repo_health_prerequisites "doctor" +run_doctor_fix_phase +run_doctor_verify_phase +run_doctor_package_phase diff --git a/tests/scripts/test_script_health_contract.py b/tests/scripts/test_script_health_contract.py index 4b96e34..38ba170 100644 --- a/tests/scripts/test_script_health_contract.py +++ b/tests/scripts/test_script_health_contract.py @@ -23,7 +23,15 @@ def test_shared_repo_health_prerequisites_live_in_common_helper() -> None: def test_doctor_keeps_local_regression_scope() -> None: assert 'source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/health_common.sh"' in DOCTOR_TEXT assert 'run_shared_repo_health_prerequisites "doctor"' in DOCTOR_TEXT + assert "doctor_repo_state_fingerprint()" in DOCTOR_TEXT + assert "run_doctor_fix_phase()" in DOCTOR_TEXT + assert "run_doctor_verify_phase()" in DOCTOR_TEXT + assert "run_doctor_package_phase()" in DOCTOR_TEXT + assert 'echo "[doctor] run fix phase"' in DOCTOR_TEXT + assert 'echo "[doctor] run verify phase"' in DOCTOR_TEXT + assert 'echo "[doctor] run package phase"' in DOCTOR_TEXT assert "uv run pre-commit run --all-files" in DOCTOR_TEXT + assert "pre-commit modified files; review the changes and rerun doctor" in DOCTOR_TEXT assert "uv run mypy src/opencode_a2a" in DOCTOR_TEXT assert "uv run pytest" in DOCTOR_TEXT assert "uv run python ./scripts/check_coverage.py" in DOCTOR_TEXT @@ -52,6 +60,8 @@ def test_scripts_index_documents_split_health_entrypoints() -> None: assert "thin forwarding wrappers" in SCRIPTS_INDEX_TEXT assert "health_common.sh" in SCRIPTS_INDEX_TEXT assert "built-wheel smoke test" in SCRIPTS_INDEX_TEXT + assert "fix/verify/package phases" in SCRIPTS_INDEX_TEXT + assert "review the changes and rerun `doctor.sh`" in SCRIPTS_INDEX_TEXT assert "single weekly grouped Dependabot PR for `uv`" in SCRIPTS_INDEX_TEXT