galaxy-tool-source 0.1.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_source-0.1.0/.gitignore +28 -0
- galaxy_tool_source-0.1.0/.python-version +1 -0
- galaxy_tool_source-0.1.0/CLAUDE.md +140 -0
- galaxy_tool_source-0.1.0/LICENSE +21 -0
- galaxy_tool_source-0.1.0/PKG-INFO +126 -0
- galaxy_tool_source-0.1.0/PLAN.md +654 -0
- galaxy_tool_source-0.1.0/README.md +90 -0
- galaxy_tool_source-0.1.0/docs/codemod-architecture.md +314 -0
- galaxy_tool_source-0.1.0/docs/decisions.md +1283 -0
- galaxy_tool_source-0.1.0/docs/per-version-models-plan.md +356 -0
- galaxy_tool_source-0.1.0/hatch_build.py +39 -0
- galaxy_tool_source-0.1.0/pyproject.toml +138 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/__init__.py +6 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/_codegen.py +159 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/binding.py +338 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/boolean_values.py +201 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/bundle.py +186 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/cdata.py +70 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/cheetah_cdm.py +165 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/cheetah_refs.py +290 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/cheetah_rename.py +801 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/cli.py +129 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/command_text.py +151 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/command_vars.py +225 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/corrections.py +245 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/document.py +196 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/macros.py +365 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/models/__init__.py +10 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/models/any_tool.py +32 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/models/registry.py +46 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/models/v16_10/__init__.py +201 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/models/v16_10/galaxy.py +5576 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/models/v17_01/__init__.py +207 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/models/v17_01/galaxy.py +5692 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/models/v17_05/__init__.py +207 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/models/v17_05/galaxy.py +5793 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/models/v17_09/__init__.py +209 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/models/v17_09/galaxy.py +5878 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/models/v18_01/__init__.py +211 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/models/v18_01/galaxy.py +5965 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/models/v18_05/__init__.py +211 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/models/v18_05/galaxy.py +5996 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/models/v18_09/__init__.py +211 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/models/v18_09/galaxy.py +6044 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/models/v19_01/__init__.py +215 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/models/v19_01/galaxy.py +6120 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/models/v19_05/__init__.py +223 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/models/v19_05/galaxy.py +6526 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/models/v19_09/__init__.py +239 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/models/v19_09/galaxy.py +6779 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/models/v20_01/__init__.py +239 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/models/v20_01/galaxy.py +6839 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/models/v20_05/__init__.py +239 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/models/v20_05/galaxy.py +6875 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/models/v20_09/__init__.py +241 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/models/v20_09/galaxy.py +6950 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/models/v21_01/__init__.py +249 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/models/v21_01/galaxy.py +7380 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/models/v21_05/__init__.py +249 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/models/v21_05/galaxy.py +7419 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/models/v21_09/__init__.py +259 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/models/v21_09/galaxy.py +7620 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/models/v22_01/__init__.py +291 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/models/v22_01/galaxy.py +8605 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/models/v22_05/__init__.py +297 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/models/v22_05/galaxy.py +8737 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/models/v23_0/__init__.py +297 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/models/v23_0/galaxy.py +8807 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/models/v23_1/__init__.py +303 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/models/v23_1/galaxy.py +9078 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/models/v23_2/__init__.py +309 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/models/v23_2/galaxy.py +9248 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/models/v24_0/__init__.py +319 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/models/v24_0/galaxy.py +9460 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/models/v24_1/__init__.py +333 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/models/v24_1/galaxy.py +9985 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/models/v24_2/__init__.py +343 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/models/v24_2/galaxy.py +11327 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/models/v25_0/__init__.py +347 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/models/v25_0/galaxy.py +11437 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/models/v25_1/__init__.py +353 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/models/v25_1/galaxy.py +11686 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/models/v26_0/__init__.py +349 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/models/v26_0/galaxy.py +11678 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/models/v26_1/__init__.py +355 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/models/v26_1/galaxy.py +11805 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/profiles.py +190 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/py.typed +0 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/rst.py +222 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/rst_markdown.py +407 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/schema/PROVENANCE.md +55 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/schema/galaxy-16.10.xsd +5125 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/schema/galaxy-17.01.xsd +5214 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/schema/galaxy-17.05.xsd +5336 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/schema/galaxy-17.09.xsd +5389 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/schema/galaxy-18.01.xsd +5431 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/schema/galaxy-18.05.xsd +5452 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/schema/galaxy-18.09.xsd +5470 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/schema/galaxy-19.01.xsd +5507 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/schema/galaxy-19.05.xsd +5594 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/schema/galaxy-19.09.xsd +5773 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/schema/galaxy-20.01.xsd +5793 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/schema/galaxy-20.05.xsd +5807 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/schema/galaxy-20.09.xsd +5855 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/schema/galaxy-21.01.xsd +6250 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/schema/galaxy-21.05.xsd +6289 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/schema/galaxy-21.09.xsd +6407 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/schema/galaxy-22.01.xsd +7045 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/schema/galaxy-22.05.xsd +7151 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/schema/galaxy-23.0.xsd +7230 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/schema/galaxy-23.1.xsd +7353 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/schema/galaxy-23.2.xsd +7494 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/schema/galaxy-24.0.xsd +7704 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/schema/galaxy-24.1.xsd +7966 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/schema/galaxy-24.2.xsd +8249 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/schema/galaxy-25.0.xsd +8351 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/schema/galaxy-25.1.xsd +8569 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/schema/galaxy-26.0.xsd +8565 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/schema/galaxy-26.1.xsd +8637 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/schema/manifest.json +229 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/schema_content.py +103 -0
- galaxy_tool_source-0.1.0/src/galaxy_tool_source/shell_oracle.py +346 -0
- galaxy_tool_source-0.1.0/tests/conftest.py +11 -0
- galaxy_tool_source-0.1.0/tests/data/invalid_tool.xml +6 -0
- galaxy_tool_source-0.1.0/tests/data/macros.xml +5 -0
- galaxy_tool_source-0.1.0/tests/data/malformed_tool.xml +7 -0
- galaxy_tool_source-0.1.0/tests/data/minimal_tool.xml +5 -0
- galaxy_tool_source-0.1.0/tests/data/nested_macros.xml +3 -0
- galaxy_tool_source-0.1.0/tests/data/nested_macros_inner.xml +5 -0
- galaxy_tool_source-0.1.0/tests/data/regressions/PROVENANCE.md +13 -0
- galaxy_tool_source-0.1.0/tests/data/regressions/bedtools/macros.xml +263 -0
- galaxy_tool_source-0.1.0/tests/data/regressions/bedtools/tool.xml +384 -0
- galaxy_tool_source-0.1.0/tests/data/regressions/dazeone__kleborate__kleborate/tool.xml +76 -0
- galaxy_tool_source-0.1.0/tests/data/regressions/nml__hivtrace__hivtrace/tool.xml +303 -0
- galaxy_tool_source-0.1.0/tests/data/regressions/tools-iuc__samtools_consensus/macros.xml +246 -0
- galaxy_tool_source-0.1.0/tests/data/regressions/tools-iuc__samtools_consensus/macros_tool_specific.xml +65 -0
- galaxy_tool_source-0.1.0/tests/data/regressions/tools-iuc__samtools_consensus/tool.xml +615 -0
- galaxy_tool_source-0.1.0/tests/data/representative_tool.xml +14 -0
- galaxy_tool_source-0.1.0/tests/data/token_macros.xml +4 -0
- galaxy_tool_source-0.1.0/tests/data/tool_imported_tokens.xml +8 -0
- galaxy_tool_source-0.1.0/tests/data/tool_inline_tokens.xml +8 -0
- galaxy_tool_source-0.1.0/tests/data/tool_macro_error.xml +10 -0
- galaxy_tool_source-0.1.0/tests/data/tool_nested_macros.xml +10 -0
- galaxy_tool_source-0.1.0/tests/data/tool_no_profile.xml +5 -0
- galaxy_tool_source-0.1.0/tests/data/tool_old_profile.xml +5 -0
- galaxy_tool_source-0.1.0/tests/data/tool_with_macros.xml +10 -0
- galaxy_tool_source-0.1.0/tests/data/tool_with_typos.xml +8 -0
- galaxy_tool_source-0.1.0/tests/test_binding.py +96 -0
- galaxy_tool_source-0.1.0/tests/test_boolean_values.py +89 -0
- galaxy_tool_source-0.1.0/tests/test_bundle.py +176 -0
- galaxy_tool_source-0.1.0/tests/test_cdata.py +63 -0
- galaxy_tool_source-0.1.0/tests/test_cheetah_cdm.py +135 -0
- galaxy_tool_source-0.1.0/tests/test_cheetah_refs.py +160 -0
- galaxy_tool_source-0.1.0/tests/test_cheetah_rename.py +654 -0
- galaxy_tool_source-0.1.0/tests/test_cli.py +75 -0
- galaxy_tool_source-0.1.0/tests/test_codegen.py +26 -0
- galaxy_tool_source-0.1.0/tests/test_command_text.py +87 -0
- galaxy_tool_source-0.1.0/tests/test_command_vars.py +137 -0
- galaxy_tool_source-0.1.0/tests/test_corpus_check.py +574 -0
- galaxy_tool_source-0.1.0/tests/test_corrections.py +70 -0
- galaxy_tool_source-0.1.0/tests/test_macros.py +172 -0
- galaxy_tool_source-0.1.0/tests/test_measure.py +1872 -0
- galaxy_tool_source-0.1.0/tests/test_models.py +47 -0
- galaxy_tool_source-0.1.0/tests/test_pr_impact.py +234 -0
- galaxy_tool_source-0.1.0/tests/test_profiles.py +82 -0
- galaxy_tool_source-0.1.0/tests/test_regressions.py +41 -0
- galaxy_tool_source-0.1.0/tests/test_rst.py +60 -0
- galaxy_tool_source-0.1.0/tests/test_rst_markdown.py +210 -0
- galaxy_tool_source-0.1.0/tests/test_schema_content.py +41 -0
- galaxy_tool_source-0.1.0/tests/test_shared.py +71 -0
- galaxy_tool_source-0.1.0/tests/test_shell_oracle.py +133 -0
- galaxy_tool_source-0.1.0/tests/test_validate.py +149 -0
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Python-generated files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[oc]
|
|
4
|
+
build/
|
|
5
|
+
dist/
|
|
6
|
+
wheels/
|
|
7
|
+
*.egg-info
|
|
8
|
+
|
|
9
|
+
# Virtual environments
|
|
10
|
+
.venv
|
|
11
|
+
|
|
12
|
+
# Tooling caches
|
|
13
|
+
.pytest_cache/
|
|
14
|
+
.mypy_cache/
|
|
15
|
+
.ruff_cache/
|
|
16
|
+
|
|
17
|
+
# Per-version xsdata models — generated at build time by hatch_build.py
|
|
18
|
+
src/galaxy_tool_xml/models/v*/
|
|
19
|
+
src/galaxy_tool_xml/models/any_tool.py
|
|
20
|
+
|
|
21
|
+
# Dev-only corpus checkouts — public Galaxy tool repositories (and any
|
|
22
|
+
# future toolshed snapshots) cloned by scripts/corpus_check.py for deep
|
|
23
|
+
# testing and design decisions; never committed.
|
|
24
|
+
corpus/
|
|
25
|
+
|
|
26
|
+
# Local, per-developer Claude Code settings
|
|
27
|
+
.claude/settings.local.json
|
|
28
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.13
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
This file provides guidance to Claude Code (claude.ai/code) when working with
|
|
4
|
+
code in this repository.
|
|
5
|
+
|
|
6
|
+
## Project
|
|
7
|
+
|
|
8
|
+
`galaxy-tool-source` is a foundation library and CLI for parsing, profile-aware
|
|
9
|
+
validation, and typed inspection of Galaxy tool definition XML. It is the
|
|
10
|
+
foundation for a separate, `black`-like Galaxy tool linter/formatter — it has
|
|
11
|
+
**no serializer**: it exposes the mutable lxml tree and callers serialize it
|
|
12
|
+
themselves.
|
|
13
|
+
|
|
14
|
+
## Commands
|
|
15
|
+
|
|
16
|
+
Run these from the **workspace root** (`galaxy-tool-refactor/`):
|
|
17
|
+
|
|
18
|
+
- `uv sync` — install dependencies; the build hook generates the per-version models.
|
|
19
|
+
- `uv run --package galaxy-tool-source pytest galaxy-tool-source/tests/` — run this package's tests.
|
|
20
|
+
- `uv run --package galaxy-tool-source pytest galaxy-tool-source/tests/test_binding.py::test_load_tool_returns_document` — run a single test.
|
|
21
|
+
- `uv run --package galaxy-tool-source pytest -m slow galaxy-tool-source/tests/` — run the xsdata codegen sweep over every vendored XSD.
|
|
22
|
+
- `uv run ruff check galaxy-tool-source/src` — lint.
|
|
23
|
+
- `uv run mypy --config-file galaxy-tool-source/pyproject.toml galaxy-tool-source/src` — type-check (strict).
|
|
24
|
+
- `uv run python -m scripts.fetch_schemas` — download release XSDs (`--force` re-downloads all).
|
|
25
|
+
- `uv run python -m scripts.regenerate` — regenerate the per-version typed models from every vendored XSD.
|
|
26
|
+
- `uv run python -m scripts.corpus_check validate` — sweep public Galaxy tool repositories for crashes (maintainer QA).
|
|
27
|
+
- `uv run galaxy-tool-source validate <file>` / `suggest <file>` / `profiles` — the CLI.
|
|
28
|
+
- `uv build --package galaxy-tool-source` — build the wheel (the build hook generates the per-version models).
|
|
29
|
+
|
|
30
|
+
## Naming
|
|
31
|
+
|
|
32
|
+
The repo directory, the distribution, and the CLI command are all
|
|
33
|
+
`galaxy-tool-source`; the import package is `galaxy_tool_source`.
|
|
34
|
+
|
|
35
|
+
## Architecture
|
|
36
|
+
|
|
37
|
+
`ToolDocument` (`document.py`) wraps a mutable lxml tree — the **source of
|
|
38
|
+
truth**, faithfully preserving CDATA, comments, and attribute order.
|
|
39
|
+
`binding.py` parses (`load_tool`, `parse_tool`; `load_macros` for a `<macros>`
|
|
40
|
+
file → `MacroDocument`), validates (`validate_tool`), and finds a tool's newest
|
|
41
|
+
valid profile (`newest_valid_profile`). `MacroDocument` (`document.py`) is the
|
|
42
|
+
macro-file counterpart to `ToolDocument` — a mutable tree with no profile/model
|
|
43
|
+
and no standalone XSD validation. `profiles.py`
|
|
44
|
+
resolves a tool's `profile` to one of the ~28 vendored per-release XSDs.
|
|
45
|
+
`macros.py` handles Galaxy macros and is the sole `galaxy-util` adapter; it also
|
|
46
|
+
exposes read-only macro-file resolution (`imported_macro_paths`) and
|
|
47
|
+
token-definition lookup (`token_definitions` / `TokenDefinition`) over a tool and
|
|
48
|
+
its imported macro files. `bundle.py` builds a `ToolBundle` (a tool + its
|
|
49
|
+
transitively-imported macro documents) via `load_bundle` and renames a parameter
|
|
50
|
+
across the whole bundle (`rename_param_in_bundle`) — the cross-file extension of
|
|
51
|
+
`cheetah_rename` (decisions §21).
|
|
52
|
+
`corrections.py` suggests near-miss typo fixes. `schema_content.py` derives
|
|
53
|
+
the text-bearing element-tag set from the vendored XSDs (the fmt tier's
|
|
54
|
+
payload-guard source of truth). `rst.py` / `rst_markdown.py` own
|
|
55
|
+
the `<help>` reStructuredText subsystem: validity + surgical repair (the GTR089
|
|
56
|
+
partition seam, decisions §23) and the render-equivalence-gated RST → Markdown
|
|
57
|
+
conversion (GTR092's engine, §24; markdown-it-py rides the `[markdown]` extra). `models/` holds an
|
|
58
|
+
xsdata-generated read-only typed model per vendored schema version, generated at
|
|
59
|
+
build time by `_codegen.py` and reached via `ToolDocument.model()`;
|
|
60
|
+
`models/registry.py` resolves a version to its model.
|
|
61
|
+
|
|
62
|
+
The public API is the prose-declared list in `README.md`; everything else is
|
|
63
|
+
private and may change. For the rationale behind each architectural choice
|
|
64
|
+
(profile-aware validation, the lxml-as-source-of-truth contract, the macro
|
|
65
|
+
expansion adapter, etc.) plus assumptions about the Galaxy ecosystem and
|
|
66
|
+
testing-derived data, see `docs/decisions.md`.
|
|
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`; exceptions only at
|
|
72
|
+
the click error boundary (chained `from e`); `pathlib` with explicit
|
|
73
|
+
`encoding` for text I/O; no import-time side effects (`@cache` for module
|
|
74
|
+
state); absolute imports, no re-exports, no `__all__`; keyword-only arguments
|
|
75
|
+
after the first. `optimized-python` (`.claude/skills/optimized-python/`) is
|
|
76
|
+
installed as a reference; **dignified-python governs on any conflict**. The
|
|
77
|
+
generated per-version model packages (`models/v*/`, `models/any_tool.py`) are
|
|
78
|
+
exempt — they are not hand-written; `models/__init__.py` and `models/registry.py`
|
|
79
|
+
are hand-written and are not exempt.
|
|
80
|
+
|
|
81
|
+
## Non-obvious conventions
|
|
82
|
+
|
|
83
|
+
- The lxml tree is the source of truth; the typed model is a derived read-only
|
|
84
|
+
view, bound to the tool's own profile. The library does not emit XML.
|
|
85
|
+
- Parsing uses `strip_cdata=False`: CDATA, comments, and attribute order are
|
|
86
|
+
preserved. XML is parsed from `bytes`, never a decoded `str`, so the
|
|
87
|
+
document's own encoding declaration is honoured.
|
|
88
|
+
- The Galaxy XSD is a **post-macro-expansion** schema; `validate_tool`
|
|
89
|
+
transforms the tool per `macro_handling` (default `expand`) into a throwaway
|
|
90
|
+
copy and validates that — the `ToolDocument` tree is never mutated.
|
|
91
|
+
- `galaxy.util` is Galaxy's *internal* API; all use of it is confined to
|
|
92
|
+
`macros.py`, and `galaxy-util` is pinned to a version range.
|
|
93
|
+
- The per-version model packages (`models/v*/`, `models/any_tool.py`) are
|
|
94
|
+
generated — never hand-edit; they are gitignored, regenerated by the build
|
|
95
|
+
hook and by `scripts/regenerate.py`, and excluded from ruff and mypy. Each
|
|
96
|
+
generated `v*/__init__.py` re-exports its module — the one sanctioned
|
|
97
|
+
exception to the no-re-exports rule.
|
|
98
|
+
- `schema/` holds vendored XSDs downloaded once by `scripts/fetch_schemas.py`;
|
|
99
|
+
re-running is additive, `--force` re-downloads. `manifest.json` and
|
|
100
|
+
`PROVENANCE.md` are committed alongside the XSDs.
|
|
101
|
+
- `../docs/corpus_data/` (workspace root) holds the fine-grained per-tool data
|
|
102
|
+
(JSON + TSV) emitted alongside the aggregate `../docs/*_corpus_stats.md`
|
|
103
|
+
artifacts; both regenerate together on a full `corpus_check.py validate` sweep.
|
|
104
|
+
Toolshed row
|
|
105
|
+
versions come from `.local/corpus/galaxy-toolshed/manifest.json`, which
|
|
106
|
+
`fetch_toolshed.py` populates by capturing each clone's tip changeset
|
|
107
|
+
before `.hg/` is removed. The combined stats markdown also carries two
|
|
108
|
+
failure-reason tables (macro-expansion failures, no-valid-profile
|
|
109
|
+
reasons) categorising every tool whose validity vector is empty —
|
|
110
|
+
these answer the "are these our bugs?" question at a glance.
|
|
111
|
+
- Both validation and binding are profile-aware: `validate_tool` uses the
|
|
112
|
+
per-release XSD, and `ToolDocument.model()` binds against the model for the
|
|
113
|
+
tool's resolved profile (overridable via `model(version=...)`).
|
|
114
|
+
- Binding uses a lenient xsdata config: unknown elements/attributes are ignored,
|
|
115
|
+
and schema-required fields the tree omits (an element a macro would supply)
|
|
116
|
+
default to `None`, so binding an un-expanded tool never raises.
|
|
117
|
+
- `corrections.py` is suggest-only and independent of `validate_tool`; its
|
|
118
|
+
vocabulary comes from introspecting the generated model for the tool's own
|
|
119
|
+
profile, with a macro skip-set so an un-expanded tool's macro constructs are
|
|
120
|
+
never flagged.
|
|
121
|
+
- No-profile tools validate against `16.10` (our oldest vendored XSD), matching
|
|
122
|
+
Galaxy's `16.01` legacy default for a missing `profile` (`resolve_profile(None)`
|
|
123
|
+
→ nearest vendored = 16.10). See `docs/decisions.md` §1.5.
|
|
124
|
+
- Failure modes: syntax errors (`load_tool` raises, the others collect them),
|
|
125
|
+
macro-expansion errors, and XSD validation errors. The XSD has no
|
|
126
|
+
`targetNamespace`, so Galaxy tool XML is namespace-free.
|
|
127
|
+
|
|
128
|
+
## Implementation workarounds
|
|
129
|
+
|
|
130
|
+
Two deviations from a naive implementation, both forced by upstream bugs:
|
|
131
|
+
|
|
132
|
+
- **xsdata codegen** (`_codegen.py`): xsdata 26.2's circular-reference detector
|
|
133
|
+
raises `KeyError` on the Galaxy 24.2+ schema when inner classes are nested, so
|
|
134
|
+
codegen sets `output.unnest_classes = True`. Each version is generated in its
|
|
135
|
+
own subprocess — xsdata caches its resolved output path process-wide.
|
|
136
|
+
- **Schema compilation** (`profiles.py`): Galaxy releases 19.05 through 23.0
|
|
137
|
+
shipped an XSD whose `Output` type has a non-deterministic content model that
|
|
138
|
+
libxml2 refuses to compile. `compiled_schema` retries after applying Galaxy's
|
|
139
|
+
own release-23.1 fix (drop the redundant `Output` group) in memory — the
|
|
140
|
+
vendored XSD files on disk remain verbatim.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Richard Burhans
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: galaxy-tool-source
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Foundation library for parsing, profile-aware validation, and typed inspection of Galaxy tool XML
|
|
5
|
+
Project-URL: Homepage, https://github.com/richard-burhans/galaxy-tool-refactor
|
|
6
|
+
Project-URL: Repository, https://github.com/richard-burhans/galaxy-tool-refactor
|
|
7
|
+
Project-URL: Issues, https://github.com/richard-burhans/galaxy-tool-refactor/issues
|
|
8
|
+
Author-email: Richard Burhans <richard.burhans@gmail.com>
|
|
9
|
+
License-Expression: MIT
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Keywords: bioinformatics,cheetah,galaxy,tool-xml,validation,xsd
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
20
|
+
Classifier: Topic :: Scientific/Engineering :: Bio-Informatics
|
|
21
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
22
|
+
Classifier: Topic :: Text Processing :: Markup :: XML
|
|
23
|
+
Classifier: Typing :: Typed
|
|
24
|
+
Requires-Python: >=3.10
|
|
25
|
+
Requires-Dist: click>=8
|
|
26
|
+
Requires-Dist: docutils>=0.21
|
|
27
|
+
Requires-Dist: galaxy-util[template]<27,>=24
|
|
28
|
+
Requires-Dist: lxml>=5
|
|
29
|
+
Requires-Dist: packaging>=23
|
|
30
|
+
Requires-Dist: xsdata[lxml]>=26.2
|
|
31
|
+
Provides-Extra: markdown
|
|
32
|
+
Requires-Dist: markdown-it-py>=4; extra == 'markdown'
|
|
33
|
+
Provides-Extra: shell-oracle
|
|
34
|
+
Requires-Dist: bashlex>=0.18; extra == 'shell-oracle'
|
|
35
|
+
Description-Content-Type: text/markdown
|
|
36
|
+
|
|
37
|
+
# galaxy-tool-source
|
|
38
|
+
|
|
39
|
+
A Python library and small CLI for parsing, profile-aware validation, and typed
|
|
40
|
+
inspection of [Galaxy](https://galaxyproject.org/) tool definition XML — the
|
|
41
|
+
`<tool>` wrapper files that define Galaxy bioinformatics tools.
|
|
42
|
+
|
|
43
|
+
This package is the **foundation** for a separate, `black`-like program for
|
|
44
|
+
Galaxy tool XML (conformance checking, autofixing, reformatting). It provides
|
|
45
|
+
only the foundation — no rules, no formatter, no serializer:
|
|
46
|
+
|
|
47
|
+
1. **Parse** tool XML into a mutable representation that faithfully preserves
|
|
48
|
+
CDATA, comments, attribute data and order, and significant element text.
|
|
49
|
+
2. A **typed read-only view** of a parsed tool — bound to the model for the
|
|
50
|
+
tool's own schema profile — for convenient rule-checking.
|
|
51
|
+
3. **Profile-aware XSD validation**, with configurable macro handling so
|
|
52
|
+
validation is accurate on real-world tools that use Galaxy macros.
|
|
53
|
+
4. **Near-miss typo suggestions** against the schema vocabulary (suggest only).
|
|
54
|
+
|
|
55
|
+
## Install
|
|
56
|
+
|
|
57
|
+
```sh
|
|
58
|
+
uv sync
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Usage
|
|
62
|
+
|
|
63
|
+
```python
|
|
64
|
+
from galaxy_tool_source.binding import load_tool, validate_tool
|
|
65
|
+
|
|
66
|
+
document = load_tool("my_tool.xml")
|
|
67
|
+
print(document.profile)
|
|
68
|
+
|
|
69
|
+
result = validate_tool("my_tool.xml")
|
|
70
|
+
if not result.valid:
|
|
71
|
+
for error in result.errors:
|
|
72
|
+
print(error)
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
From the command line:
|
|
76
|
+
|
|
77
|
+
```sh
|
|
78
|
+
uv run galaxy-tool-source validate my_tool.xml
|
|
79
|
+
uv run galaxy-tool-source suggest my_tool.xml
|
|
80
|
+
uv run galaxy-tool-source profiles
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Public API
|
|
84
|
+
|
|
85
|
+
The downstream formatter project may rely on exactly these symbols. Everything
|
|
86
|
+
else is private and may change without notice.
|
|
87
|
+
|
|
88
|
+
```python
|
|
89
|
+
from galaxy_tool_source.binding import load_tool, parse_tool, validate_tool, newest_valid_profile
|
|
90
|
+
from galaxy_tool_source.binding import load_macros
|
|
91
|
+
from galaxy_tool_source.binding import ParseResult, ValidationResult, XmlError, ToolXmlSyntaxError
|
|
92
|
+
from galaxy_tool_source.document import ToolDocument, MacroDocument
|
|
93
|
+
from galaxy_tool_source.macros import MacroError, imported_macro_paths, token_definitions, TokenDefinition, expanded_detection_root
|
|
94
|
+
from galaxy_tool_source.corrections import suggest_corrections, Correction
|
|
95
|
+
from galaxy_tool_source.boolean_values import suggest_boolean_normalizations, normalize_boolean_token, BooleanNormalization
|
|
96
|
+
from galaxy_tool_source.cheetah_refs import tool_cheetah_references, CheetahRef
|
|
97
|
+
from galaxy_tool_source.cheetah_rename import rename_param, rename_param_plan, RenameOutcome, RenameEdit, RenamePlan
|
|
98
|
+
from galaxy_tool_source.bundle import ToolBundle, load_bundle, rename_param_in_bundle, BundleRenameOutcome
|
|
99
|
+
from galaxy_tool_source.profiles import available_profiles, latest_profile, UnknownProfileError
|
|
100
|
+
from galaxy_tool_source.schema_content import text_bearing_tags
|
|
101
|
+
from galaxy_tool_source.models.registry import model_module, tool_class
|
|
102
|
+
from galaxy_tool_source.models.any_tool import AnyTool
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
## Architecture
|
|
106
|
+
|
|
107
|
+
`ToolDocument` (`document.py`) wraps a mutable lxml tree — the source of truth,
|
|
108
|
+
faithfully preserving CDATA, comments, and attribute order. `binding.py` parses
|
|
109
|
+
and validates; `profiles.py` resolves the per-release vendored XSD; `macros.py`
|
|
110
|
+
handles Galaxy macros (the sole `galaxy-util` adapter); `corrections.py` suggests
|
|
111
|
+
near-miss typo fixes; `boolean_values.py` reports schema-boolean attribute value
|
|
112
|
+
normalizations (`True` → `true`); `cheetah_refs.py` / `cheetah_rename.py` find and
|
|
113
|
+
rename a parameter across a tool's Cheetah sections (the latter renders the rename
|
|
114
|
+
either as a tree mutation, `rename_param`, or as minimal source offsets,
|
|
115
|
+
`rename_param_plan`, for editor / LSP use); `bundle.py` extends the rename across a
|
|
116
|
+
tool *and its imported macro files* (`ToolBundle` / `load_bundle` /
|
|
117
|
+
`rename_param_in_bundle`); `rst.py` / `rst_markdown.py` own the `<help>`
|
|
118
|
+
reStructuredText subsystem — validity + surgical repair (the GTR089 partition seam)
|
|
119
|
+
and the render-equivalence-gated RST → Markdown conversion (GTR092; needs the
|
|
120
|
+
`[markdown]` extra); `models/` holds an xsdata-generated
|
|
121
|
+
read-only typed model for every vendored schema version, reached via
|
|
122
|
+
`ToolDocument.model()`.
|
|
123
|
+
|
|
124
|
+
## License
|
|
125
|
+
|
|
126
|
+
MIT — see [LICENSE](LICENSE).
|