gd-tools-cli 0.4.0__tar.gz → 0.6.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.
Files changed (90) hide show
  1. gd_tools_cli-0.6.0/PKG-INFO +447 -0
  2. gd_tools_cli-0.6.0/README.md +406 -0
  3. {gd_tools_cli-0.4.0 → gd_tools_cli-0.6.0}/pyproject.toml +113 -106
  4. {gd_tools_cli-0.4.0 → gd_tools_cli-0.6.0}/src/gd_tools/addons/gd-tools-coverage/coverage.gd +224 -8
  5. {gd_tools_cli-0.4.0 → gd_tools_cli-0.6.0}/src/gd_tools/addons/gd-tools-coverage/post_run_hook.gd +116 -113
  6. gd_tools_cli-0.6.0/src/gd_tools/addons/gd-tools-editor/coverage_overlay.gd +213 -0
  7. gd_tools_cli-0.6.0/src/gd_tools/addons/gd-tools-editor/dock.gd +313 -0
  8. gd_tools_cli-0.6.0/src/gd_tools/addons/gd-tools-editor/plugin.cfg +7 -0
  9. gd_tools_cli-0.6.0/src/gd_tools/addons/gd-tools-editor/plugin.gd +39 -0
  10. gd_tools_cli-0.6.0/src/gd_tools/addons/gd-tools-test/gd_tools_mock.gd +362 -0
  11. gd_tools_cli-0.6.0/src/gd_tools/addons/gd-tools-test/gd_tools_native_coverage.gd +211 -0
  12. gd_tools_cli-0.6.0/src/gd_tools/addons/gd-tools-test/gd_tools_parameter_naming.gd +50 -0
  13. gd_tools_cli-0.6.0/src/gd_tools/addons/gd-tools-test/gd_tools_test.gd +1181 -0
  14. gd_tools_cli-0.6.0/src/gd_tools/addons/gd-tools-test/gd_tools_test_context.gd +298 -0
  15. gd_tools_cli-0.6.0/src/gd_tools/addons/gd-tools-test/gd_tools_test_preflight.gd +948 -0
  16. gd_tools_cli-0.6.0/src/gd_tools/addons/gd-tools-test/gd_tools_test_runner.gd +938 -0
  17. gd_tools_cli-0.6.0/src/gd_tools/changes.py +117 -0
  18. gd_tools_cli-0.6.0/src/gd_tools/clean.py +264 -0
  19. gd_tools_cli-0.6.0/src/gd_tools/cli.py +1436 -0
  20. {gd_tools_cli-0.4.0 → gd_tools_cli-0.6.0}/src/gd_tools/config.py +92 -4
  21. {gd_tools_cli-0.4.0 → gd_tools_cli-0.6.0}/src/gd_tools/coverage/__init__.py +0 -3
  22. gd_tools_cli-0.6.0/src/gd_tools/coverage/diff_reporter.py +729 -0
  23. {gd_tools_cli-0.4.0 → gd_tools_cli-0.6.0}/src/gd_tools/coverage/html_reporter.py +16 -0
  24. gd_tools_cli-0.6.0/src/gd_tools/coverage/omissions.py +162 -0
  25. gd_tools_cli-0.6.0/src/gd_tools/coverage/orchestrator.py +507 -0
  26. gd_tools_cli-0.6.0/src/gd_tools/coverage/plan_generator.py +762 -0
  27. gd_tools_cli-0.6.0/src/gd_tools/coverage/playtest.py +244 -0
  28. {gd_tools_cli-0.4.0 → gd_tools_cli-0.6.0}/src/gd_tools/coverage/reporter.py +245 -2
  29. {gd_tools_cli-0.4.0 → gd_tools_cli-0.6.0}/src/gd_tools/coverage/templates/file.html +5 -1
  30. {gd_tools_cli-0.4.0 → gd_tools_cli-0.6.0}/src/gd_tools/coverage/terminal_reporter.py +13 -0
  31. {gd_tools_cli-0.4.0 → gd_tools_cli-0.6.0}/src/gd_tools/doctor.py +196 -101
  32. {gd_tools_cli-0.4.0 → gd_tools_cli-0.6.0}/src/gd_tools/errors.py +28 -0
  33. {gd_tools_cli-0.4.0 → gd_tools_cli-0.6.0}/src/gd_tools/format_runner.py +7 -0
  34. {gd_tools_cli-0.4.0 → gd_tools_cli-0.6.0}/src/gd_tools/init.py +122 -321
  35. {gd_tools_cli-0.4.0 → gd_tools_cli-0.6.0}/src/gd_tools/lint_runner.py +6 -0
  36. gd_tools_cli-0.6.0/src/gd_tools/migration/__init__.py +1 -0
  37. gd_tools_cli-0.6.0/src/gd_tools/migration/apply.py +143 -0
  38. gd_tools_cli-0.6.0/src/gd_tools/migration/gutconfig.py +138 -0
  39. gd_tools_cli-0.6.0/src/gd_tools/migration/reporter.py +157 -0
  40. gd_tools_cli-0.6.0/src/gd_tools/migration/rewrite.py +104 -0
  41. gd_tools_cli-0.6.0/src/gd_tools/migration/scan.py +135 -0
  42. gd_tools_cli-0.6.0/src/gd_tools/migration/translate.py +97 -0
  43. gd_tools_cli-0.6.0/src/gd_tools/native_test/__init__.py +33 -0
  44. gd_tools_cli-0.6.0/src/gd_tools/native_test/artifacts.py +279 -0
  45. gd_tools_cli-0.6.0/src/gd_tools/native_test/bridge_scan.py +49 -0
  46. gd_tools_cli-0.6.0/src/gd_tools/native_test/command.py +682 -0
  47. gd_tools_cli-0.6.0/src/gd_tools/native_test/discovery.py +185 -0
  48. gd_tools_cli-0.6.0/src/gd_tools/native_test/import_cache.py +185 -0
  49. gd_tools_cli-0.6.0/src/gd_tools/native_test/orchestrator.py +775 -0
  50. gd_tools_cli-0.6.0/src/gd_tools/native_test/preflight.py +228 -0
  51. gd_tools_cli-0.6.0/src/gd_tools/native_test/preflight_cache.py +239 -0
  52. gd_tools_cli-0.6.0/src/gd_tools/native_test/protocol.py +271 -0
  53. {gd_tools_cli-0.4.0 → gd_tools_cli-0.6.0}/src/gd_tools/output.py +24 -0
  54. gd_tools_cli-0.6.0/src/gd_tools/schema.py +59 -0
  55. gd_tools_cli-0.6.0/src/gd_tools/test_runner.py +175 -0
  56. gd_tools_cli-0.6.0/src/gd_tools/verbosity.py +50 -0
  57. gd_tools_cli-0.6.0/src/gd_tools/watch/__init__.py +1 -0
  58. gd_tools_cli-0.6.0/src/gd_tools/watch/coalescer.py +80 -0
  59. gd_tools_cli-0.6.0/src/gd_tools/watch/loop.py +105 -0
  60. gd_tools_cli-0.6.0/src/gd_tools/watch/mapping.py +100 -0
  61. gd_tools_cli-0.6.0/src/gd_tools/watch/observer.py +131 -0
  62. gd_tools_cli-0.6.0/src/gd_tools/watch/scope.py +88 -0
  63. gd_tools_cli-0.6.0/src/gd_tools/watch/session.py +190 -0
  64. gd_tools_cli-0.6.0/src/gd_tools_cli.egg-info/PKG-INFO +447 -0
  65. gd_tools_cli-0.6.0/src/gd_tools_cli.egg-info/SOURCES.txt +80 -0
  66. {gd_tools_cli-0.4.0 → gd_tools_cli-0.6.0}/src/gd_tools_cli.egg-info/requires.txt +2 -2
  67. gd_tools_cli-0.4.0/PKG-INFO +0 -195
  68. gd_tools_cli-0.4.0/README.md +0 -154
  69. gd_tools_cli-0.4.0/src/gd_tools/cli.py +0 -658
  70. gd_tools_cli-0.4.0/src/gd_tools/coverage/orchestrator.py +0 -383
  71. gd_tools_cli-0.4.0/src/gd_tools/coverage/plan_generator.py +0 -384
  72. gd_tools_cli-0.4.0/src/gd_tools/test_runner.py +0 -509
  73. gd_tools_cli-0.4.0/src/gd_tools_cli.egg-info/PKG-INFO +0 -195
  74. gd_tools_cli-0.4.0/src/gd_tools_cli.egg-info/SOURCES.txt +0 -38
  75. {gd_tools_cli-0.4.0 → gd_tools_cli-0.6.0}/setup.cfg +0 -0
  76. {gd_tools_cli-0.4.0 → gd_tools_cli-0.6.0}/src/gd_tools/__init__.py +0 -0
  77. {gd_tools_cli-0.4.0 → gd_tools_cli-0.6.0}/src/gd_tools/__main__.py +0 -0
  78. {gd_tools_cli-0.4.0 → gd_tools_cli-0.6.0}/src/gd_tools/addon_check.py +0 -0
  79. {gd_tools_cli-0.4.0 → gd_tools_cli-0.6.0}/src/gd_tools/addons/__init__.py +0 -0
  80. {gd_tools_cli-0.4.0 → gd_tools_cli-0.6.0}/src/gd_tools/addons/gd-tools-coverage/pre_run_hook.gd +0 -0
  81. {gd_tools_cli-0.4.0 → gd_tools_cli-0.6.0}/src/gd_tools/coverage/cobertura_reporter.py +0 -0
  82. {gd_tools_cli-0.4.0 → gd_tools_cli-0.6.0}/src/gd_tools/coverage/lcov_reporter.py +0 -0
  83. {gd_tools_cli-0.4.0 → gd_tools_cli-0.6.0}/src/gd_tools/coverage/templates/index.html +0 -0
  84. {gd_tools_cli-0.4.0 → gd_tools_cli-0.6.0}/src/gd_tools/file_discovery.py +0 -0
  85. {gd_tools_cli-0.4.0 → gd_tools_cli-0.6.0}/src/gd_tools/godot.py +0 -0
  86. {gd_tools_cli-0.4.0 → gd_tools_cli-0.6.0}/src/gd_tools/update_check.py +0 -0
  87. {gd_tools_cli-0.4.0 → gd_tools_cli-0.6.0}/src/gd_tools/version.py +0 -0
  88. {gd_tools_cli-0.4.0 → gd_tools_cli-0.6.0}/src/gd_tools_cli.egg-info/dependency_links.txt +0 -0
  89. {gd_tools_cli-0.4.0 → gd_tools_cli-0.6.0}/src/gd_tools_cli.egg-info/entry_points.txt +0 -0
  90. {gd_tools_cli-0.4.0 → gd_tools_cli-0.6.0}/src/gd_tools_cli.egg-info/top_level.txt +0 -0
@@ -0,0 +1,447 @@
1
+ Metadata-Version: 2.4
2
+ Name: gd-tools-cli
3
+ Version: 0.6.0
4
+ Summary: A modern development workflow CLI for GDScript projects in Godot 4.5+
5
+ Author-email: mansyar <m.ansyarafi@gmail.com>
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/mansyar/gd-tools
8
+ Project-URL: Repository, https://github.com/mansyar/gd-tools
9
+ Project-URL: Documentation, https://github.com/mansyar/gd-tools#readme
10
+ Project-URL: Bug Tracker, https://github.com/mansyar/gd-tools/issues
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Environment :: Console
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Operating System :: OS Independent
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Topic :: Software Development :: Testing
21
+ Classifier: Topic :: Software Development :: Quality Assurance
22
+ Requires-Python: >=3.10
23
+ Description-Content-Type: text/markdown
24
+ Requires-Dist: gdtoolkit
25
+ Requires-Dist: click
26
+ Requires-Dist: jinja2
27
+ Requires-Dist: rich
28
+ Requires-Dist: pyyaml
29
+ Requires-Dist: tomli; python_version < "3.11"
30
+ Requires-Dist: tomli_w
31
+ Requires-Dist: pydantic>=2.0
32
+ Requires-Dist: requests
33
+ Requires-Dist: packaging
34
+ Requires-Dist: watchdog
35
+ Provides-Extra: dev
36
+ Requires-Dist: pytest; extra == "dev"
37
+ Requires-Dist: pytest-cov; extra == "dev"
38
+ Requires-Dist: ruff==0.15.21; extra == "dev"
39
+ Requires-Dist: black; extra == "dev"
40
+ Requires-Dist: commitizen; extra == "dev"
41
+
42
+ # gd-tools
43
+
44
+ A modern development workflow CLI for GDScript projects in Godot 4.5+.
45
+
46
+ [![CI](https://github.com/mansyar/gd-tools/actions/workflows/ci.yml/badge.svg)](https://github.com/mansyar/gd-tools/actions/workflows/ci.yml)
47
+ [![Coverage](https://codecov.io/gh/mansyar/gd-tools/branch/main/graph/badge.svg)](https://codecov.io/gh/mansyar/gd-tools)
48
+ [![PyPI version](https://img.shields.io/pypi/v/gd-tools-cli.svg)](https://pypi.org/project/gd-tools-cli/)
49
+ [![Python versions](https://img.shields.io/pypi/pyversions/gd-tools-cli.svg)](https://pypi.org/project/gd-tools-cli/)
50
+ [![Godot version](https://img.shields.io/badge/Godot-4.5%2B-blue.svg)](https://godotengine.org)
51
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
52
+
53
+ ---
54
+
55
+ ## 1. Overview
56
+
57
+ `gd-tools` brings professional development tooling to GDScript -- test, lint,
58
+ format, and code coverage in a single CLI. It wraps gdtoolkit for linting and
59
+ formatting, runs its own Godot-native test runtime, and fills the remaining
60
+ gap with a custom hybrid coverage system -- production-quality line and branch
61
+ coverage for GDScript that no existing tool provides.
62
+
63
+ Tests are written against `GdToolsTest`, a native GDScript base class that runs
64
+ inside your Godot project, so a test can touch the real scene tree, await real
65
+ signals, and assert on real engine objects without leaving the engine. Existing
66
+ suites that `extend GutTest` are no longer runnable -- the GUT compatibility
67
+ bridge was removed in v0.6.0; run `gd-tools migrate` to move them onto
68
+ `GdToolsTest`.
69
+
70
+ One install, one config, one mental model.
71
+
72
+ ## 2. Features
73
+
74
+ | Feature | Description |
75
+ |---------|-------------|
76
+ | **Unified workflow** | One install, one config (`gd-tools.toml`), one mental model for test, lint, format, and coverage. Consistent terminal output with colored markers and summary footers across all commands. |
77
+ | **Native test runtime** | Tests extend `GdToolsTest` and run inside Godot itself. Scene and resource integration tests reach the real scene tree through an explicit context object rather than a proxy. |
78
+ | **Zero-friction bootstrap** | `gd-tools init` gets a project fully set up in under a minute -- native test and coverage addons deployed, configs generated. |
79
+ | **Coverage gap-filling** | Production-quality line and branch coverage for GDScript -- HTML, LCOV, and Cobertura reports that integrate with CI and code review tools. `# gd-tools: no cover` annotations exclude debug-only code from the numbers. `coverage run` collects coverage during manual playtest sessions, not just automated tests. |
80
+ | **CI/CD friendly** | Exit codes, `--check` flags, machine-readable output (JSON, JUnit XML, LCOV, Cobertura), no interactive prompts in CI mode. |
81
+ | **Standalone compatibility** | gdlint and gdformat continue to work if invoked directly. `gd-tools` is a layer on top, not a lock-in. |
82
+
83
+ ## 3. Installation
84
+
85
+ ```bash
86
+ pip install gd-tools-cli
87
+ ```
88
+
89
+ `gd-tools` requires Python 3.10+ and a Godot 4.5+ binary on your system.
90
+ The Godot binary is auto-detected from configuration, environment variables
91
+ (`GODOT_BIN`, `GODOT4_BIN`, `GODOT_PATH`), `PATH`, or common install locations.
92
+
93
+ ## 4. Quick Start
94
+
95
+ ```bash
96
+ # 1. Install
97
+ pip install gd-tools-cli
98
+
99
+ # 2. Bootstrap your Godot project
100
+ cd your-godot-project
101
+ gd-tools init
102
+
103
+ # 3. Run your tests
104
+ gd-tools test
105
+
106
+ # 4. Run tests with coverage
107
+ gd-tools test --coverage --min 80
108
+
109
+ # 5. Show uncovered lines and branches when coverage is below 100%
110
+ gd-tools test --coverage --show-uncovered
111
+
112
+ # 6. Force plan regeneration, bypassing the coverage plan cache
113
+ gd-tools test --coverage --no-cache
114
+ ```
115
+
116
+ `gd-tools init` deploys the native test addon and the coverage addon, generates
117
+ `gd-tools.toml`, `gdlintrc`, and `gdformatrc`, and creates the `.gd-tools/`
118
+ directory. The command is idempotent -- safe to re-run. If you've modified
119
+ coverage addon files, they are automatically backed up to
120
+ `addons/gd-tools-coverage/.backups/` before being overwritten.
121
+
122
+ The GUT compatibility bridge was removed in v0.6.0: suites extending `GutTest`
123
+ are no longer runnable -- `gd-tools test` rejects them with exit 2 and
124
+ migration guidance. Run `gd-tools migrate` and see the
125
+ [migration guide](./docs/gut-migration.md) for the steps to move fully onto
126
+ `GdToolsTest`.
127
+
128
+ A test suite is any class extending `GdToolsTest`:
129
+
130
+ ```gdscript
131
+ extends GdToolsTest
132
+
133
+ func test_health_starts_at_full() -> void:
134
+ assert_eq(health.current(), 100)
135
+ ```
136
+
137
+ ## 5. CLI Command Summary
138
+
139
+ | Command | Description |
140
+ |---------|-------------|
141
+ | `gd-tools init` | Bootstrap a Godot project -- deploy the native test and coverage addons, generate configs. |
142
+ | `gd-tools doctor` | Diagnose the development environment -- Godot, native test addon, coverage addon, tooling; reports legacy GUT artifacts as migration advice. |
143
+ | `gd-tools test` | Run tests with optional coverage, thresholds, and JUnit XML output. Suites must extend `GdToolsTest`; `GutTest` suites are rejected with exit 2 and migration guidance. Accepts optional path arguments to override configured test directories. `--parallel N` runs suites through a bounded worker pool. `--changed` runs only the suites mapped from git-changed files. `--watch` re-runs affected suites on `.gd` file changes. Every run publishes a machine-readable artifact index under `.gd-tools/artifacts/<run_id>/`. |
144
+ | `gd-tools migrate` | Guided GUT-to-native migration. Default: read-only report with unsupported-construct inventory and proposed base-class rewrites. `--apply` renames clean suites to `GdToolsTest` and translates `.gutconfig.json` into `gd-tools.toml` (merge, never clobber). `--config-only` translates config only. |
145
+ | `gd-tools lint` | Lint GDScript files using gdlint with text or JSON output. Accepts one or more file or directory paths. |
146
+ | `gd-tools format` | Format GDScript files using gdformat with check and diff modes. Accepts one or more file or directory paths. |
147
+ | `gd-tools coverage` | Coverage subcommands -- `report`, `merge`, `show`, `save-baseline`, `diff` (baseline comparison for CI regression gates), and `run` (collect coverage during a manual playtest session). |
148
+ | `gd-tools config` | Configuration management -- `show` (display resolved config), `validate` (check config validity), `schema` (print or write the JSON Schema for `gd-tools.toml`). |
149
+ | `gd-tools version` | Display versions of all gd-tools components (gd-tools, Godot, gdtoolkit, Python, and GUT when installed) in a table or JSON. |
150
+ | `gd-tools completion` | Generate shell completion scripts for bash, zsh, fish, or PowerShell. |
151
+
152
+ ### Selecting and Filtering Tests
153
+
154
+ ```bash
155
+ gd-tools test # every discovered suite
156
+ gd-tools test --suite PlayerTests # one suite, by class name
157
+ gd-tools test --test test_takes_damage # one test method
158
+ gd-tools test --tag smoke # suites with that class-level tag
159
+ gd-tools test --test-timeout 30 # per-test timeout, in seconds
160
+ gd-tools test --parallel 4 # run suites with 4 concurrent workers
161
+ gd-tools test --changed # only suites mapped from git-changed files
162
+ gd-tools test --changed --base main # PR/CI mode: diff from merge-base with main
163
+ ```
164
+
165
+ `--tag` is repeatable, and `--test-timeout` (per test) is separate from
166
+ `--timeout` (per suite process). `--parallel` dispatches suites to a bounded
167
+ worker pool (1-32 workers; bare `--parallel` means 4) while keeping results,
168
+ JUnit XML, and merged coverage identical to a sequential run. Persist the
169
+ choice with `parallel = 4` under `[test]` in `gd-tools.toml`.
170
+
171
+ `--changed` selects suites from git instead of running everything: uncommitted
172
+ changes (staged, unstaged, and untracked) map to suites by the same
173
+ file→suite convention as `--watch` — `src/enemy.gd` selects
174
+ `tests/test_enemy.gd` or `tests/enemy_test.gd`. A change that maps to no
175
+ suite (e.g. `project.godot` or a scene file) falls back to the full suite
176
+ with an explicit notice, so the selection is safe for CI. The summary line
177
+ reports how many suites were selected; per-file mapping detail prints under
178
+ `--verbose`. Add `--base <ref>` to diff committed changes from
179
+ `merge-base(<ref>, HEAD)` instead of the working tree — the form to use on
180
+ pull-request CI. `--changed` composes with `--parallel`, `--coverage`, and
181
+ the `--suite`/`--test`/`--tag` filters (the active filters bound the
182
+ mapping domain); an empty change set exits 0 without launching Godot.
183
+
184
+ Repeat runs are faster: the `godot --headless --import` step is cached under
185
+ `.gd-tools/native/import-cache/` and skipped when `project.godot`, any
186
+ project source/resource file (scripts, scenes, import sidecars, addons), or
187
+ the Godot version is unchanged. The integration preflight is likewise cached
188
+ under `.gd-tools/native/preflight-cache/` and skipped when the suites, test
189
+ files, `project.godot`, Godot version, and bundled addons are unchanged. Cache
190
+ hit/miss reasons are reported under `--verbose`; `--no-cache` bypasses the
191
+ import, preflight, and coverage plan caches, and `gd-tools clean --cache`
192
+ removes the cache directory.
193
+
194
+ Each run writes a machine-readable artifact index under
195
+ `.gd-tools/artifacts/<run_id>/`, listing the manifest, result, event stream,
196
+ engine log, coverage data, and any failure screenshots the run actually
197
+ produced. Only the latest run is retained. See the
198
+ [User Guide](./docs/USER_GUIDE.md#34-test) for the full artifact tree.
199
+
200
+ ### Watch Mode
201
+
202
+ ```bash
203
+ gd-tools test --watch # watch .gd files, re-run on change
204
+ gd-tools test --watch --coverage # every re-run includes coverage
205
+ gd-tools test --watch --tag smoke # filters apply to every run
206
+ ```
207
+
208
+ `--watch` runs the full suite once, then keeps watching: saving a `.gd` file
209
+ re-runs the tests affected by the change. The changed file is mapped to its
210
+ suite by convention — `src/enemy.gd` re-runs `tests/test_enemy.gd` or
211
+ `tests/enemy_test.gd` — with a full-suite fallback (announced explicitly)
212
+ when no suite matches. Rapid successive saves are coalesced into a single
213
+ re-run, and a save during a running suite queues exactly one follow-up run.
214
+ The same file→suite mapping powers the non-interactive `gd-tools test
215
+ --changed` selection (see [Selecting and Filtering
216
+ Tests](#selecting-and-filtering-tests)).
217
+
218
+ - Native runtime only: the removed legacy GUT runtime (`--runtime gut`) is
219
+ rejected with exit 2; `GutTest` suites must be migrated (`gd-tools migrate`).
220
+ - Interactive only: `--watch` combined with `CI=true` exits 2.
221
+ - The terminal is cleared between runs; the banner shows how many files are
222
+ watched. While idle, `Ctrl+C` exits 0; interrupting an in-flight run kills
223
+ its Godot processes and exits 130.
224
+ - Positional path arguments are not supported with `--watch`; the watched
225
+ scope is the project root minus standard excludes (`.godot/`, `.gd-tools/`,
226
+ `.git/`, and the gd-tools addons).
227
+
228
+ ### Migrating Legacy GUT Suites
229
+
230
+ The GUT compatibility bridge was removed in v0.6.0; the native runtime
231
+ (`GdToolsTest`) is the only supported runtime. Suites extending `GutTest` are
232
+ rejected by `gd-tools test` with exit 2 and migration guidance, and
233
+ `--runtime gut` is rejected the same way. Run `gd-tools migrate` and see the
234
+ [migration guide](./docs/gut-migration.md) to move legacy suites onto the
235
+ native runtime.
236
+
237
+ **Known limitations.** Parallel execution is opt-in and off by default
238
+ (`--parallel N` / `[test].parallel`); suites run sequentially without it. See
239
+ the [User Guide](./docs/USER_GUIDE.md#34-test) for the full flag reference and
240
+ [Roadmap](./docs/ROADMAP.md#native-runtime-transition-completed-foundation)
241
+ for what is planned.
242
+
243
+ ### Verbosity Control
244
+
245
+ `gd-tools` supports two global flags that control output verbosity. Place
246
+ them before the subcommand:
247
+
248
+ | Flag | Short | Description |
249
+ |------|-------|-------------|
250
+ | `--verbose` | `-v` | Show underlying commands and timing information. |
251
+ | `--quiet` | `-q` | Suppress non-essential output (update checks, info messages, detailed tables). |
252
+
253
+ The flags are mutually exclusive -- using both exits with code 2.
254
+
255
+ ```bash
256
+ # Verbose: see the Godot command and elapsed time
257
+ gd-tools --verbose test
258
+
259
+ # Quiet: minimal output for CI pipelines
260
+ gd-tools --quiet lint
261
+ gd-tools --quiet doctor
262
+
263
+ # Default: current behavior (no change)
264
+ gd-tools test
265
+ ```
266
+
267
+ **Always shown** (regardless of flag): test pass/fail summaries, lint
268
+ violations, coverage reports, error messages, and exit codes.
269
+
270
+ See the [User Guide](./docs/USER_GUIDE.md) for full command reference,
271
+ flags, examples, and exit codes.
272
+
273
+ ## 6. Shell Completion
274
+
275
+ `gd-tools` supports tab completion for bash, zsh, fish, and PowerShell.
276
+ Generate a completion script with `gd-tools completion <shell>` and
277
+ source it in your shell configuration.
278
+
279
+ **Bash:**
280
+
281
+ ```bash
282
+ # Add to ~/.bashrc or ~/.bash_profile
283
+ eval "$(gd-tools completion bash)"
284
+ ```
285
+
286
+ **Zsh:**
287
+
288
+ ```bash
289
+ # Add to ~/.zshrc
290
+ eval "$(gd-tools completion zsh)"
291
+ # Or save to a file in your fpath:
292
+ gd-tools completion zsh > ~/.zsh/completions/_gd-tools
293
+ ```
294
+
295
+ **Fish:**
296
+
297
+ ```bash
298
+ gd-tools completion fish > ~/.config/fish/completions/gd-tools.fish
299
+ ```
300
+
301
+ **PowerShell:**
302
+
303
+ ```powershell
304
+ gd-tools completion powershell | Out-String | Add-Content $PROFILE
305
+ ```
306
+
307
+ **Alternative -- Click's environment variable:**
308
+
309
+ Click also supports completion via the `_GD_TOOLS_COMPLETE` environment
310
+ variable. This is useful for advanced users who prefer not to modify
311
+ their shell profile:
312
+
313
+ ```bash
314
+ # Bash example
315
+ export _GD_TOOLS_COMPLETE=bash_source
316
+ eval "$(gd-tools)"
317
+ ```
318
+
319
+ See the [User Guide](./docs/USER_GUIDE.md) for detailed per-shell
320
+ instructions.
321
+
322
+ ## 7. Configuration
323
+
324
+ `gd-tools` uses a single `gd-tools.toml` file as the source of truth for
325
+ all tool configuration. `gd-tools init` generates this file with sensible
326
+ defaults.
327
+
328
+ ```toml
329
+ [godot]
330
+ binary = "" # Optional -- auto-detected if unset
331
+
332
+ [test]
333
+ test_dirs = ["test", "tests"]
334
+ prefix = "test_"
335
+ suffix = ".gd"
336
+ gutconfig = ".gutconfig.json" # legacy; not read by any runtime
337
+ runtime = "native" # native (default); "gut" is no longer a runnable runtime
338
+ timeout_seconds = 5.0 # default per-test timeout for async native tests
339
+ retries = 0 # opt-in retries per native test
340
+ # parallel = 4 # opt-in parallel suite execution (1-32; unset runs sequentially)
341
+ tags = [] # native suite tag filters
342
+
343
+ [lint]
344
+ exclude = ["addons", ".godot", ".gd-tools", ".git"]
345
+
346
+ [format]
347
+ exclude = ["addons", ".godot", ".gd-tools", ".git"]
348
+
349
+ [coverage]
350
+ enabled = false
351
+ min_percent = 0
352
+ format = "html" # html, lcov, cobertura, text
353
+ output_dir = ".gd-tools/coverage"
354
+ exclude = ["addons", ".godot", ".gd-tools", ".git"]
355
+ test_dirs = ["test", "tests"]
356
+ ```
357
+
358
+ ### Editor Autocomplete & Validation
359
+
360
+ `gd-tools` publishes a JSON Schema for `gd-tools.toml` at
361
+ [`docs/gd-tools.schema.json`](./docs/gd-tools.schema.json). Add a
362
+ `"$schema"` key to your config to enable autocomplete and inline
363
+ validation in editors that support TOML schemas:
364
+
365
+ ```toml
366
+ "$schema" = "https://raw.githubusercontent.com/mansyar/gd-tools/main/docs/gd-tools.schema.json"
367
+ ```
368
+
369
+ The key is accepted and ignored by the CLI — it carries no runtime
370
+ meaning.
371
+
372
+ - **VS Code** (with [Even Better TOML](https://marketplace.visualstudio.com/items?itemName=tamasfe.even-better-toml)):
373
+ the `"$schema"` key above is picked up automatically. Alternatively,
374
+ associate the schema by filename in your settings:
375
+ `"even-better-toml.schema.associations": {"gd-tools.toml": "https://raw.githubusercontent.com/mansyar/gd-tools/main/docs/gd-tools.schema.json"}`
376
+ - **taplo** (CLI / LSP): the `"$schema"` key works out of the box, or
377
+ add a `schema` entry to your `taplo.toml` pointing at the URL above.
378
+
379
+ The schema is regenerated with
380
+ `gd-tools config schema --output docs/gd-tools.schema.json`;
381
+ a unit test keeps the checked-in snapshot in sync with the installed
382
+ version's config model.
383
+
384
+ See the [User Guide](./docs/USER_GUIDE.md) for a full configuration reference
385
+ with all keys, defaults, and examples.
386
+
387
+ ## 8. Documentation
388
+
389
+ | Document | Description |
390
+ |----------|-------------|
391
+ | [User Guide](./docs/USER_GUIDE.md) | Complete CLI reference -- all commands, flags, examples, and troubleshooting. |
392
+ | [Contributing Guide](./docs/CONTRIBUTING.md) | Development setup, code style, testing requirements, and PR process. |
393
+ | [Architecture](./docs/ARCHITECTURE.md) | System architecture -- hybrid coverage instrumentation and the native test runtime. |
394
+ | [Product Requirements](./docs/PRD.md) | Full product specification -- features, design decisions, technical detail. |
395
+ | [Roadmap](./docs/ROADMAP.md) | Release phases and milestones. |
396
+ | [Testing Strategy](./docs/TESTING_STRATEGY.md) | Test pyramid, coverage targets, and CI integration. |
397
+
398
+ ## 9. Development
399
+
400
+ ```bash
401
+ # Clone and install in editable mode with dev dependencies
402
+ git clone https://github.com/mansyar/gd-tools.git
403
+ cd gd-tools
404
+ pip install -e ".[dev]"
405
+ ```
406
+
407
+ ### Running Tests
408
+
409
+ Unit tests run without Godot. Integration tests require a Godot 4.5+
410
+ binary -- configure via `.env` (see `.env.example`):
411
+
412
+ ```bash
413
+ cp .env.example .env
414
+ # Edit .env: set GODOT_BIN to your Godot binary path
415
+
416
+ # Run all tests with coverage
417
+ CI=true pytest
418
+ ```
419
+
420
+ `CI=true` is what makes a missing Godot binary a failure rather than a skip.
421
+ Without it, integration and end-to-end tests skip quietly when Godot is
422
+ absent, so a run can report success having executed nothing.
423
+
424
+ See [Testing Strategy](./docs/TESTING_STRATEGY.md) for the full testing
425
+ guide and [Contributing Guide](./docs/CONTRIBUTING.md) for development
426
+ setup details.
427
+
428
+ ## 10. License
429
+
430
+ MIT
431
+
432
+ ## 11. Acknowledgements
433
+
434
+ `gd-tools` stands on the shoulders of two excellent community tools. It
435
+ wraps them; it does not replace them. Full credit to their authors for the
436
+ hard parts.
437
+
438
+ - **[GUT (Godot Unit Test)](https://github.com/bitwes/Gut)** by
439
+ [bitwes](https://github.com/bitwes): the GDScript test framework whose
440
+ core API informed the native runtime's assertion surface.
441
+ - **[gdtoolkit](https://github.com/Scony/godot-gdscript-toolkit)** by
442
+ [Scony](https://github.com/Scony): provides `gdlint` and `gdformat`, which
443
+ `gd-tools lint` and `gd-tools format` wrap.
444
+
445
+ The native test runtime (`GdToolsTest`) and the custom hybrid coverage system
446
+ (plan generation, runtime instrumentation, and reporting) are the original work
447
+ of `gd-tools` and fill the gaps these tools do not cover.