{ "intent": "Bring meta/lint_python.sh (353 lines) under the 250-line cap by extracting the output helpers and the full-mode linter block into sourced libs.", "scope": [ "meta/lint_python.sh", "meta/lib/lint_output.sh (new)", "meta/lib/lint_full_tools.sh (new)", "Non-goal: no linter added, removed or reconfigured; no flag behaviour changed" ], "changes": [ "Move print_header/print_subheader/print_success/print_warning/print_error/print_info/run_tool/check_tool into lib/lint_output.sh, plus the --help text as usage().", "Move the post-quick-mode linters (pylint, bandit, vulture, flake8, pycodestyle, pydocstyle, radon, interrogate, pyright, autoflake, pyupgrade, codespell) into lib/lint_full_tools.sh as run_full_mode_linters().", "Source lint_output.sh immediately after SCRIPT_DIR, before argument parsing, because --help now calls usage() from it." ], "verification": [ { "command": "bash meta/lint_python.sh --quick scripts/check_requirements_sync.py, before and after, full output diffed", "result": "pass", "evidence": "exit 0 both times, output identical. Note this path exits before the extracted full-mode block, so on its own it does NOT cover the biggest part of the change." }, { "command": "bash meta/lint_python.sh scripts/check_requirements_sync.py (full mode), against a detached worktree at the pre-split commit, paths normalised", "result": "pass", "evidence": "FULL OUTPUT IDENTICAL. Six tools ran and passed -- ruff-lint, ruff-format-check, mypy, pylint, flake8, pycodestyle -- so the run genuinely entered run_full_mode_linters rather than skipping it." }, { "command": "bash meta/lint_python.sh (failure path)", "result": "pass", "evidence": "exit 1, with ruff-format-check, pylint, flake8 and pycodestyle all reporting issues. Confirms OVERALL_STATUS still propagates out of the extracted function; the temp file was removed afterwards." }, { "command": "bash -n on all three; shellcheck -x on the entry; shellcheck on both libs; shfmt -d on all three", "result": "pass", "evidence": "All exit 0. SC2034 (OVERALL_STATUS appears unused, because shellcheck analyses the lib standalone) was fixed by declaring the cross-seam variables at the top of the lib with a comment, not suppressed. lint_python.sh was shfmt-clean at HEAD and is still clean; the one dirty new lib was formatted, banner count 2 before and after, and the full run re-diffed identical afterwards." }, { "command": "bash ~/utils/scripts/check_file_length.sh on all three", "result": "pass", "evidence": "353 -> 175 (entry) + 116 (full tools) + 96 (output helpers), all under 250." } ], "risks": [ "Both libs depend on caller state (TARGET_FILES, FIX_MODE, REPORT_MODE, PROJECT_ROOT, FAILED_TOOLS, OVERALL_STATUS and the colour variables). Documented in each header; the full-mode lib also declares them so the dependency is visible to shellcheck.", "Optional linters (bandit, vulture, pydocstyle, radon, interrogate, pyright) are not installed here, so their check_tool branches were skipped in both baseline and post-split runs. The identical-output comparison therefore does not exercise them -- but it does not exercise them before the split either, and the blocks moved verbatim." ], "rollback": [ "git revert the commit; both libs disappear and lint_python.sh returns to 353 lines.", "Run `bash meta/lint_python.sh scripts/check_requirements_sync.py` and confirm exit 0 with 'All linting checks passed!'." ] }