{ "intent": "Bring analyze_repo.sh under the 250-line cap by splitting it into a thin entry script plus five sourced libs, leaving the analysis output it produces unchanged.", "scope": [ "linux_configuration/scripts/single_use/utils/analyze_repo.sh (869 -> 231 lines)", "New: lib/analyze_repo_{scan,tools,separate,report,symbols}.sh", "Non-goal: running the script, which installs packages via sudo pacman / cargo / makepkg", "Non-goal: defining the never-defined KEYWORDS_SHELL and KEYWORDS_JAVA tables" ], "changes": [ "Extracted the output/discovery helpers (print_header, print_subheader, is_git_repo, find_files, count_files, fast_count) into lib/analyze_repo_scan.sh.", "Extracted install_missing_tools, the 117-line package-manager dispatch, into lib/analyze_repo_tools.sh.", "Wrapped the STEP 4 language-detection and comment/code-separation blocks as detect_languages and separate_code_and_comments in lib/analyze_repo_separate.sh; the HAS_* flags are set and read entirely within that file.", "Wrapped the per-language keyword/function/import reporting as report_languages in lib/analyze_repo_report.sh, and moved the KEYWORDS_* tables in beside their only consumer.", "Wrapped STEPs 5-7 as analyze_symbols, analyze_cscope and analyze_clang_ast in lib/analyze_repo_symbols.sh.", "Passed the LANG_CODE_FILES map between the two STEP 4 passes explicitly by nameref and COMMENTS_TEMP by parameter, so no mutable state crosses a file boundary.", "Fixed three unquoted $TOP_N expansions (SC2086) and quoted nine assoc-array subscripts that the nameref made shellcheck misread as arithmetic (SC2154). No suppression added." ], "verification": [ { "command": "shellcheck analyze_repo.sh lib/analyze_repo_*.sh", "result": "pass", "evidence": "Zero findings across all six files at the repo's no-severity-filter setting. An earlier boundary produced 23 findings (14 SC2034, 9 SC2154); those were cleared by moving the KEYWORDS_* tables and detect_languages beside their consumers, not by suppressing." }, { "command": "bash -n on the entry and each lib", "result": "pass", "evidence": "All six parse. Run before linting, per the heredoc trap in docs/shell-split-recipes.md." }, { "command": "bash ~/utils/scripts/check_file_length.sh --all", "result": "pass", "evidence": "entry 231, report 228, separate 186, tools 125, symbols 112, scan 86. None of the six appears in the violation list; repo total 69 -> 68." }, { "command": "diff of the function set against a detached worktree at HEAD", "result": "pass", "evidence": "All eight original functions preserved (count_files, fast_count, find_files, install_missing_tools, is_git_repo, is_url, print_header, print_subheader). The six additions are exactly the wrappers named in the contract. Each function is defined exactly once across the six files." }, { "command": "sorted line-set diff of HEAD:analyze_repo.sh against entry+libs concatenated", "result": "pass", "evidence": "After repair, no executable line is lost. The first pass caught a real regression this way: the `find \"$RESULTS_DIR/per_language/\" -maxdepth 1 -type f -printf` call at original line 719 fell into a one-line gap between two extraction ranges and was silently dropped. shellcheck and bash -n both passed on the broken version. Restored to the tail of report_languages." }, { "command": "stubbed run of the entry preamble (source lines only, main flow replaced by declare -F)", "result": "pass", "evidence": "Prints all fourteen function names, proving each source line resolves at runtime. verify_shell_split.sh does not apply here: the script has no main \"$@\", so the by-hand fallback in docs/shell-split-recipes.md was used." }, { "command": "grep -n 'source ' over the five libs", "result": "pass", "evidence": "No lib sources another; the entry sources all five. Only comment-text matches were returned." } ], "risks": [ "The script cannot be executed under decision 6, so verification is static plus a stubbed source. A behaviour change confined to the interior of a moved block would not be caught by the line-set diff, though that diff does prove no line was added, removed or reordered within a function body.", "detect_languages now declares LANG_FILES as local rather than global. Confirmed safe: LANG_FILES was only ever read inside that same block. The HAS_* flags it sets remain global and are read by separate_code_and_comments in the same file.", "The trap that cleans up COMMENTS_TEMP and /tmp/code_*.tmp moved into the entry script, where it is installed before the functions that create those files run. Same coverage as before, set one step earlier." ], "rollback": [ "git revert the commit; analyze_repo.sh returns to its 869-line single-file form and the five libs disappear.", "After rollback, re-run shellcheck on analyze_repo.sh to confirm it still lints clean, and confirm repo_to_study.sh still resolves ANALYZE_SCRIPT at scripts/single_use/utils/analyze_repo.sh, which this split did not move." ] }