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.
- galaxy_tool_lint-0.2.0/.gitignore +24 -0
- galaxy_tool_lint-0.2.0/CLAUDE.md +95 -0
- galaxy_tool_lint-0.2.0/PKG-INFO +59 -0
- galaxy_tool_lint-0.2.0/README.md +46 -0
- galaxy_tool_lint-0.2.0/docs/decisions.md +1137 -0
- galaxy_tool_lint-0.2.0/pyproject.toml +56 -0
- galaxy_tool_lint-0.2.0/src/galaxy_tool_lint/__init__.py +8 -0
- galaxy_tool_lint-0.2.0/src/galaxy_tool_lint/checks/__init__.py +5 -0
- galaxy_tool_lint-0.2.0/src/galaxy_tool_lint/checks/_shared.py +72 -0
- galaxy_tool_lint-0.2.0/src/galaxy_tool_lint/checks/help.py +67 -0
- galaxy_tool_lint-0.2.0/src/galaxy_tool_lint/checks/inputs.py +1298 -0
- galaxy_tool_lint-0.2.0/src/galaxy_tool_lint/checks/outputs.py +505 -0
- galaxy_tool_lint-0.2.0/src/galaxy_tool_lint/checks/partition.py +141 -0
- galaxy_tool_lint-0.2.0/src/galaxy_tool_lint/checks/tests.py +554 -0
- galaxy_tool_lint-0.2.0/src/galaxy_tool_lint/checks/tool.py +723 -0
- galaxy_tool_lint-0.2.0/src/galaxy_tool_lint/checks/validators.py +411 -0
- galaxy_tool_lint-0.2.0/src/galaxy_tool_lint/detect.py +211 -0
- galaxy_tool_lint-0.2.0/src/galaxy_tool_lint/lone_amp.py +58 -0
- galaxy_tool_lint-0.2.0/src/galaxy_tool_lint/py.typed +0 -0
- galaxy_tool_lint-0.2.0/src/galaxy_tool_lint/rules.py +31 -0
- galaxy_tool_lint-0.2.0/tests/test_checks.py +1228 -0
- galaxy_tool_lint-0.2.0/tests/test_detect.py +46 -0
|
@@ -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.
|