feat(analyse): add Bash language support - #92
Conversation
ReviewMust fix — the supported-styles table in Test coverage
Otherwise clean. Wiring is complete and consistent: enum + file-type map, query + |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #92 +/- ##
==========================================
+ Coverage 92.34% 92.38% +0.04%
==========================================
Files 43 43
Lines 3721 3743 +22
Branches 380 381 +1
==========================================
+ Hits 3436 3458 +22
Misses 172 172
Partials 113 113 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
Review findings addressed in f604413 and fe82065:
Verified with the full tox suite (267 passed, 34 snapshots), mypy, and the pinned pre-commit hooks on the changed files; CI is green on fe82065. |
…attern - Fix test_source_discover + test_src_trace: add 'markdown' to expected comment_type validation error message list - Add FE_MARKDOWN feature need to docs/source/components/features.rst (fixes docs build warnings for IMPL_MD_1/IMPL_MD_3/IMPL_LANG_1) - Add default_oneliner_markdown fixture to tests/data/extraction/oneline.yaml with end_sequence: " -->" config - Generate snapshot for the markdown extraction fixture - Add init_markdown_tree_sitter fixture + test_extract_comments_markdown + test_init_tree_sitter_markdown to tests/test_analyse_utils.py - Add 'markdown' entry to LANG_MAP in tests/test_extraction_fixtures.py - Update docs: configuration.rst (supported values + table row), analyse.rst (language support list), change_log.rst (Unreleased entry)
Add `bash` as a supported comment-type for marker extraction, discovering `.sh`, `.bash`, `.zsh` and `.ksh` files. Bash has only `#` line comments, so it reuses the existing hash-comment extraction path (BASH_QUERY + `function_definition` scope nodes) via a tree-sitter-bash grammar. A `default_oneliner_bash` case is added to the shared `oneline.yaml` extraction fixture with its captured snapshot, and the feature is documented under `FE_BASH`. Fish shell is intentionally excluded: no tree-sitter-fish grammar is published on PyPI, so it cannot be wired into this Python package. Closes #48
… row The bash row was inserted between the JSONC row's last cell and its continuation line, so the mode-line example rendered inside the bash "discovered file types" cell and the JSONC cell lost it.
…ssociation
- shebang_oneliner_bash extraction fixture: the shebang comment yields no
marker or warning, the marker anchors to line 2, and `function name { }`
definitions parse
- test_find_associated_scope_bash: comments associate with the
function_definition for both definition syntaxes, including the
enclosing-scope fallback for comments inside a body
fe82065 to
f73507f
Compare
Follow-up to #97. Adds the traceability artifacts for the substantial features that landed since 1.3.0 without any. ## Audit Every merged PR in the `1.3.0` → `1.4.0` window, checked against `features.rst` and the `@` markers in `src/`: | PR | Substantial feature? | Traceability | |---|---|---| | #92 Bash language support | yes | ✅ `FE_BASH` + `FAULT_BASH_1/2` + `IMPL_BASH_1/2/3` + added to `IMPL_LANG_1` | | #85 Preprocessor-aware C/C++ engine (libclang) | yes | ❌ **none** — no feature need, no markers | | #89 Marker anchoring fix | no (fix to existing traced code, `IMPL_OLP_1`) | n/a | | #83 Declarative fixture tests | no (test infra, no `src/` change) | n/a | | #84 / #86 Dependency caps | no | n/a | So the libclang engine was the one gap: 4 new modules and 353 lines in `analyse/preproc/`, plus wiring in `analyse.py` / `config.py` / `cmd.py` / `src_trace.py`, with zero traceability. ## Changes **`docs/source/components/features.rst`** — new `FE_PREPROC` feature need, placed after the language-support block, with three `fault` children: - `FAULT_PREPROC_1` — objects in inactive branches are extracted (false positives, the defect the engine exists to prevent) - `FAULT_PREPROC_2` — objects in active branches are dropped (false negatives) - `FAULT_PREPROC_3` — flags resolved from the wrong compilation database entry, so the wrong branches evaluate as active **Six `@` markers**, one per capability listed in the need, so the mapping is 1:1 and reviewable: | Marker | Site | Capability | |---|---|---| | `IMPL_PREPROC_1` | `analyse.py::create_src_objects_libclang` | engine entry / opt-in | | `IMPL_PREPROC_2` | `preproc/libclang_parser.py::extract_active_comments` | drop inactive-branch comments | | `IMPL_PREPROC_3` | `preproc/compile_db.py::find_compile_db` | walk-up database discovery | | `IMPL_PREPROC_4` | `preproc/compile_db.py::load_flags_map` | per-file compiler flags | | `IMPL_PREPROC_5` | `preproc/compile_db.py::defines_to_args` | standalone header parsing | | `IMPL_PREPROC_6` | `preproc/loader.py::load_clang_cindex` | optional-dependency guard | Comments only — no logic touched. ## Verification A green `-nW` build alone would not prove the markers work: a marker that fails to parse produces no need and no error. So the built output was checked directly. ``` $ tox -e docs-clean # sphinx-build -nW --keep-going build succeeded. $ grep -o 'id="IMPL_PREPROC_[0-9]"' docs/_build/html/development/traceability.html | sort -u id="IMPL_PREPROC_1" … id="IMPL_PREPROC_6" # all six needs materialized $ grep -o 'href="[^"]*#FE_PREPROC"[^>]*title="IMPL_PREPROC_[0-9]"' … | sort -u IMPL_PREPROC_1 … IMPL_PREPROC_6 # all six link to the feature ``` - `tox -e py312-sphinx8-needs5` — 345 passed, 1 skipped, 58 snapshots passed - `tox -e mypy` — no issues in 20 source files - `pre-commit run --files …` — all hooks pass ## Deliberately out of scope Pre-existing gaps, all predating the 1.3.0 → 1.4.0 window this PR was scoped to. Flagging rather than fixing, since each is a separate judgment call: - **`FE_CSHARP` is an orphan.** It has no incoming `impl` link — it is missing from the `IMPL_LANG_1` list in `analyse/utils.py:110` even though `init_tree_sitter` handles `CommentType.cs` (utils.py:122). C# is the only supported language whose implementation is untraced. One-word fix if you want it here. - **No feature need for the `src-trace` directive, nor for source-link URL generation** (`local-url` / `remote-url`), while the CLI has three (`FE_CLI_*`). This asymmetry may be intentional — capability-level needs covering *what* is traced regardless of interface — so changing it is a feature-model decision, not a gap fix. - **The test-needs layer is empty.** `docs/ubproject.toml` defines a `test` type and `development/traceability.rst` runs a `src-trace` over the `tests` project, but `tests/` carries no `@` markers, so zero `TEST_` needs exist. ## Note on sequencing No changelog entry here, deliberately: this PR is based on `main`, where the `Unreleased` heading still holds the Bash entry that #97 converts into the dated `1.4.0` section. Editing it would conflict with the open release PR. Since these artifacts document a feature already listed in the 1.4.0 notes, either fold a line into #97 before merging it, or let the next release's notes pick this up — your call on the order.
Prepares the **1.4.0** release. ## Release changes - ⬆️ Bump version `1.3.0` → `1.4.0` in `pyproject.toml`. - 📝 Finalize the changelog: convert the `Unreleased` heading into a dated `1.4.0` section (released 30.07.2026). Only 1 of the 6 PRs merged since 1.3.0 (#92) had added a changelog entry, so this also documents the 5 that were missing one, plus the traceability artifacts from #98. - 🗺️ No roadmap changes — none of the merged PRs completed a listed roadmap item. Minor bump: two new user-facing features, no removals or config-breaking changes. ## Changelog for 1.4.0 **New and Improved** - ✨ Added Bash language support for the `analyse` module (#92) - ✨ Added an opt-in preprocessor-aware C/C++ extraction engine, powered by libclang (#85) - 📚 Traced the preprocessor-aware C/C++ engine in the feature documentation (#98) - 🧪 Added a declarative fixture and snapshot test layer for marker extraction (#83) **Fixes** - 🐛 Anchor newline-terminated one-line markers to the start of the comment (#89, fixes #88) - 🐛 Pinned `typer` and `sphinxcontrib-typer` to keep the documentation build working (#84, #86) ## Behavior change worth calling out #89 is released as a fix, but it does narrow marker matching: a newline-terminated one-line marker (default `@…`) is now only recognized when nothing but comment decoration and whitespace precedes the start sequence. A project that deliberately embedded such markers *after* prose on the same line will stop seeing them — the fix is what stops `@` in prose from producing bogus need IDs and `InvalidNeedException`. Explicitly bounded markers (e.g. `[[ … ]]`) are unaffected. ## Verification Rebased onto `main` at #98, so this branch carries the full 1.4.0 content. - `tox -e py312-sphinx8-needs5` — 345 passed, 1 skipped (58 snapshots passed). - `tox -e docs-clean` (`sphinx-build -nW --keep-going`) — build succeeded, 0 warnings. - `pre-commit run --files docs/source/development/change_log.rst pyproject.toml` — all hooks pass. ## Not included Pre-existing traceability gaps are left for a follow-up, since all predate 1.3.0: `FE_CSHARP` has no incoming `impl` link; the five enum-site markers carrying a trailing `;` (`IMPL_BASH_1`, `IMPL_GO_1`, `IMPL_RUST_1`, `IMPL_RUST_2`, `IMPL_JSONC_1`) are inert and produce no needs, so file-extension discovery is untraced for every language; and `IMPL_C_1` / `IMPL_PY_1` / `IMPL_GO_2` are anchored on `COMMENT_MARKERS`, which has no readers. See the discussion in #98. ## After merge - Tag `1.4.0` on the merge commit (matching the existing `1.0.0`–`1.3.0` tags). The `Release` workflow triggers on that tag pattern and publishes to PyPI.
Adds
bashas a supportedcomment_typefor marker extraction. Closes #48.What
CommentType.bash, discovering.sh,.bash,.zshand.kshfiles.#line comments, so extraction reuses the existing hash-comment path: a(comment) @commenttree-sitter query over thetree-sitter-bashgrammar, withfunction_definitionscope nodes.tree-sitter-bash>=0.25.1dependency.Tests & docs
default_oneliner_bashcase in the sharedoneline.yamlextraction fixture, with its captured snapshot.FE_BASHfeature, with the configuration / analyse / changelog pages updated.Not included
Fish shell — it is not POSIX-compatible and no
tree-sitter-fishgrammar is published on PyPI, so it cannot be wired into this package. Can be revisited if a PyPI grammar becomes available.