galaxy-tool-lint 0.2.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,24 @@
1
+ # Machine-local scratch, never committed: the cloned corpus (.local/corpus,
2
+ # seeded from corpus_sources.json) and external source clones for inspection
3
+ # (e.g. .local/galaxy-src = a clone of galaxyproject/galaxy used to verify
4
+ # Galaxy-internal behaviour locally).
5
+ # No trailing slash: `.local/` matches only a directory, so an accidental
6
+ # symlink at this path was committable (it happened once; removed in this branch).
7
+ .local
8
+ .venv/
9
+ __pycache__/
10
+ *.pyc
11
+ *.pyo
12
+ .pytest_cache/
13
+ .mypy_cache/
14
+ .ruff_cache/
15
+ dist/
16
+ *.egg-info/
17
+
18
+ # Local-only draft of the GCC poster abstract.
19
+ gcc2026-abstract.txt
20
+
21
+ # Claude Code session scratch (the tracked .claude/ settings + skills stay; this
22
+ # runtime lock for scheduled wakeups is machine-local).
23
+ .claude/scheduled_tasks.lock
24
+ .claude/worktrees/
@@ -0,0 +1,95 @@
1
+ # CLAUDE.md
2
+
3
+ Guidance for Claude Code working in this repository.
4
+
5
+ ## Project
6
+
7
+ `galaxy-tool-lint` is the **advisory check** tier (tier 3.5) of the Galaxy
8
+ tool refactoring framework: read-only IUC best-practice checks that report but
9
+ never mutate.
10
+
11
+ | Tier | Layer | Package |
12
+ |---|---|---|
13
+ | 0.5 | rule metadata | `galaxy-tool-refactor-rules` |
14
+ | 1 | parsing & validation | `galaxy-tool-source` |
15
+ | 2 | structure | `galaxy-tool-codemod` |
16
+ | 3 | formatting | `galaxy-tool-fmt` |
17
+ | 3.5 | **advisory checks** | `galaxy-tool-lint` *(this repo)* |
18
+ | 3.6 | rule registry / rulesets | `galaxy-tool-refactor-registry` |
19
+ | 4 | app / CLI | `galaxy-tool-refactor-cli` |
20
+
21
+ It owns the GTR-coded **detect-only** rules (`RuleMeta.detect_only=True`): a
22
+ `CheckRule` ABC (`rules.py`), the concrete checks (the `checks/` sub-package,
23
+ split by element/source area into `tool` / `partition` / `outputs` / `inputs` /
24
+ `validators` / `tests` / `help` submodules + cross-module `_shared` helpers), and
25
+ the registry + runner (`detect.py` — `all_checks()` is an explicit list, mirroring
26
+ the codemod tier's `coded_codemods()` and fmt's `all_rules()`; `detect_violations()`).
27
+ Each check is an LBYL tree query over a tier-1 `ToolDocument` that yields the shared
28
+ tier-0.5 `Violation`.
29
+
30
+ **Tier independence.** Depends ONLY on tier 1 + tier 0.5 — never on the mutating
31
+ tiers (codemod/fmt) or the app. The advisory tier is a sibling the app composes,
32
+ not a consumer of the fixers. Findings are advisory: the app's `check` command
33
+ reports them but does not fail on them by default.
34
+
35
+ **Scope.** Covers the mechanically-detectable IUC practices (presence /
36
+ attribute / structure queries). The **flat** IUC advisories are `GTR021`,
37
+ `GTR023`–`GTR029`, `GTR033` (package `<requirement>`s pin a version, D7) plus the
38
+ `GTR032` (`&&`-vs-lone-`&`) — a real detector since D34 (the
39
+ D3 no-op era ended): the `lone_amp.py` classifier flags only the genuine
40
+ *joining* class.
41
+ (unused `<param>`, D11). **Four are the advisory `.2` half of a partition
42
+ practice** (D9/D31; registry D10): `GTR018.2` / `GTR019.2` (the `<command>` / `<help>`
43
+ CDATA mixed-content residual), `GTR020.2` (the non-provable unquoted-`$var`
44
+ residual, via the **read-only `command_text` lexer** in **tier 1**
45
+ `galaxy_tool_source.command_text`), and `GTR089.2` (`HelpRstResidual` — the invalid
46
+ `<help>` RST the repair can't safely fix, via the tier-1 `galaxy_tool_source.rst`
47
+ predicate). Each `.2` reuses the same tier-1 predicate its fixable sibling
48
+ (`GTR018.1` / `GTR019.1` / `GTR020.1` / `GTR089.1`, codemod tier) uses, so the
49
+ partition is sound and the check never depends on the codemod tier.
50
+
51
+ On top of those, the tier hosts the **planemo-parity wave `GTR038`–`GTR091`** (54
52
+ rules) — a reimplementation of every mechanically-reimplementable
53
+ `galaxy.tool_util.lint` linter, grouped by source area (citations/TODO, outputs,
54
+ embedded expressions, the full `inputs.py` correctness surface, `tests.py`, and
55
+ `<help>` RST validity via the tier-1 `galaxy_tool_source.rst` predicate — `GTR089`, now
56
+ split into the `GTR089.1` repair + `GTR089.2` residual partition, so docutils is a
57
+ tier-1 dep, not declared here — plus output reference integrity and data-param
58
+ format, `GTR090`–`GTR091`; the `GTR035.2` name-whitespace residual, D33; and the
59
+ `GTR095` id/name/version missing-or-empty trio — the half tier-1 `validate` can't
60
+ see, D35). The tier is now **70 checks total**. Each
61
+ wave check that a `<macro>` could spoof skips that tool via the tier-1 `has_macros`
62
+ raw-tree guard (`detect()` reads the un-expanded tree). The authoritative
63
+ planemo→GTR map is `../docs/planemo_linter_parity.md`; per-group rationale + corpus
64
+ counts are in `docs/decisions.md` **D12–D32**. See `../docs/iuc_best_practices.md`
65
+ for the IUC coverage map and D3–D11 for the command-text + requirement-pinning +
66
+ partition-residual + unused-param decisions.
67
+
68
+ ## Coding standards
69
+
70
+ Hand-written code follows **dignified-python** (vendored at the workspace root
71
+ `.claude/skills/dignified-python/`): LBYL over try/except; `pathlib` with
72
+ explicit `encoding`; keyword-only args after the first; absolute imports, no
73
+ re-exports, no `__all__`; no import-time side effects (`@cache` for module
74
+ state). `optimized-python` is a secondary reference; **dignified-python governs
75
+ on conflict**. New checks land tests-first.
76
+
77
+ ## Commands
78
+
79
+ Run from the **workspace root** (`galaxy-tool-refactor/`):
80
+
81
+ - `uv sync` — install dependencies
82
+ - `uv run --package galaxy-tool-lint pytest galaxy-tool-lint/tests/` — run tests
83
+ - `uv run ruff check galaxy-tool-lint/src galaxy-tool-lint/tests` — lint
84
+ - `uv run mypy --config-file galaxy-tool-lint/pyproject.toml galaxy-tool-lint/src` — type-check (strict)
85
+
86
+ ## Useful workspace references
87
+
88
+ - `galaxy-tool-refactor-rules/src/galaxy_tool_refactor_rules/violation.py` — the
89
+ shared `Violation` these checks yield; `meta.py` — `RuleMeta` (the
90
+ `detect_only` flag this tier sets).
91
+ - `galaxy-tool-source/README.md` — tier-1 public API (`ToolDocument`,
92
+ `newest_valid_profile`, the typed model) the checks query.
93
+ - `galaxy-tool-refactor-cli/src/galaxy_tool_refactor_cli/cli.py` — the app
94
+ `check` command that runs these alongside the codemod + fmt detect phases.
95
+ - `../docs/iuc_best_practices.md` — the cross-tier IUC coverage map.
@@ -0,0 +1,59 @@
1
+ Metadata-Version: 2.4
2
+ Name: galaxy-tool-lint
3
+ Version: 0.2.0
4
+ Summary: Advisory (detect-only) IUC best-practice checks for Galaxy tool XML — tier 3.5 of the galaxy-tool-source ecosystem.
5
+ Author: Richard Burhans
6
+ License-Expression: MIT
7
+ Requires-Python: >=3.10
8
+ Requires-Dist: galaxy-tool-refactor-rules==0.2.0
9
+ Requires-Dist: galaxy-tool-source==0.2.0
10
+ Requires-Dist: lxml>=5
11
+ Requires-Dist: packaging>=23
12
+ Description-Content-Type: text/markdown
13
+
14
+ # galaxy-tool-lint
15
+
16
+ The **advisory check** tier (tier 3.5) of the Galaxy tool refactoring framework:
17
+ read-only IUC best-practice checks that *report* but never mutate.
18
+
19
+ Where the codemod (tier 2) and fmt (tier 3) tiers *fix* a tool (their detect
20
+ phases report what their fix would change), this tier covers the
21
+ [IUC `tool_xml` best-practices][iuc] that are **not** safely auto-fixable — they
22
+ need a content or semantic decision (add tests, declare requirements, write
23
+ help). Each check is a `RuleMeta`-coded, `detect_only=True` rule that yields the
24
+ shared tier-0.5 `Violation`. The findings are **advisory**: the
25
+ `galaxy-tool-refactor check` command shows them but, by default, does not fail on
26
+ them (use `--strict` to gate on them too).
27
+
28
+ [iuc]: https://galaxy-iuc-standards.readthedocs.io/en/latest/best_practices/tool_xml.html
29
+
30
+ ## Scope
31
+
32
+ Depends only on tier 1 (`galaxy-tool-source`, the parsed `ToolDocument` and
33
+ profile helpers) and tier 0.5 (`galaxy-tool-refactor-rules`, `RuleMeta` /
34
+ `Violation`). It does **not** depend on the mutating tiers — the app
35
+ (`galaxy-tool-refactor-cli`) composes this alongside them.
36
+
37
+ ```python
38
+ from galaxy_tool_source.binding import load_tool
39
+ from galaxy_tool_lint.detect import detect_violations
40
+
41
+ for violation in detect_violations(load_tool("my_tool.xml")):
42
+ print(violation.code, violation.message)
43
+ ```
44
+
45
+ ## Checks
46
+
47
+ See `galaxy_tool_lint.checks` and the IUC coverage map at
48
+ `../docs/iuc_best_practices.md`. **`GTR020.2`** (single-quote Cheetah `$var`) is
49
+ implemented — it reads `<command>` text through the read-only `command_text.py`
50
+ lexer (quote/directive-aware, across newlines; the lexer lives in tier 1,
51
+ `galaxy_tool_source.command_text`, so the GTR020.1 codemod shares it) and reports one
52
+ advisory per fully-unquoted shell-line `$var`. Its *provable* subset is now
53
+ auto-fixed by the GTR020.1 codemod (`docs/decisions.md` D8). **`GTR089.2`**
54
+ (`HelpRstResidual`) is the advisory half of the GTR089 partition: it reports the
55
+ invalid `<help>` reStructuredText the `GTR089.1` repair codemod can't safely fix,
56
+ through the same tier-1 predicate (`galaxy_tool_source.rst`; `docs/decisions.md`
57
+ D31). **`GTR032`** (`&&`-vs-lone-`&`) is a real detector since `docs/decisions.md`
58
+ D34 (the data-backed D3 deferral ended when the CT3 lexer landed): the
59
+ `lone_amp.py` classifier flags only genuine command-joining lone `&`s.
@@ -0,0 +1,46 @@
1
+ # galaxy-tool-lint
2
+
3
+ The **advisory check** tier (tier 3.5) of the Galaxy tool refactoring framework:
4
+ read-only IUC best-practice checks that *report* but never mutate.
5
+
6
+ Where the codemod (tier 2) and fmt (tier 3) tiers *fix* a tool (their detect
7
+ phases report what their fix would change), this tier covers the
8
+ [IUC `tool_xml` best-practices][iuc] that are **not** safely auto-fixable — they
9
+ need a content or semantic decision (add tests, declare requirements, write
10
+ help). Each check is a `RuleMeta`-coded, `detect_only=True` rule that yields the
11
+ shared tier-0.5 `Violation`. The findings are **advisory**: the
12
+ `galaxy-tool-refactor check` command shows them but, by default, does not fail on
13
+ them (use `--strict` to gate on them too).
14
+
15
+ [iuc]: https://galaxy-iuc-standards.readthedocs.io/en/latest/best_practices/tool_xml.html
16
+
17
+ ## Scope
18
+
19
+ Depends only on tier 1 (`galaxy-tool-source`, the parsed `ToolDocument` and
20
+ profile helpers) and tier 0.5 (`galaxy-tool-refactor-rules`, `RuleMeta` /
21
+ `Violation`). It does **not** depend on the mutating tiers — the app
22
+ (`galaxy-tool-refactor-cli`) composes this alongside them.
23
+
24
+ ```python
25
+ from galaxy_tool_source.binding import load_tool
26
+ from galaxy_tool_lint.detect import detect_violations
27
+
28
+ for violation in detect_violations(load_tool("my_tool.xml")):
29
+ print(violation.code, violation.message)
30
+ ```
31
+
32
+ ## Checks
33
+
34
+ See `galaxy_tool_lint.checks` and the IUC coverage map at
35
+ `../docs/iuc_best_practices.md`. **`GTR020.2`** (single-quote Cheetah `$var`) is
36
+ implemented — it reads `<command>` text through the read-only `command_text.py`
37
+ lexer (quote/directive-aware, across newlines; the lexer lives in tier 1,
38
+ `galaxy_tool_source.command_text`, so the GTR020.1 codemod shares it) and reports one
39
+ advisory per fully-unquoted shell-line `$var`. Its *provable* subset is now
40
+ auto-fixed by the GTR020.1 codemod (`docs/decisions.md` D8). **`GTR089.2`**
41
+ (`HelpRstResidual`) is the advisory half of the GTR089 partition: it reports the
42
+ invalid `<help>` reStructuredText the `GTR089.1` repair codemod can't safely fix,
43
+ through the same tier-1 predicate (`galaxy_tool_source.rst`; `docs/decisions.md`
44
+ D31). **`GTR032`** (`&&`-vs-lone-`&`) is a real detector since `docs/decisions.md`
45
+ D34 (the data-backed D3 deferral ended when the CT3 lexer landed): the
46
+ `lone_amp.py` classifier flags only genuine command-joining lone `&`s.