tasktree 0.0.4__tar.gz → 0.0.6__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.
- {tasktree-0.0.4 → tasktree-0.0.6}/CLAUDE.md +9 -8
- {tasktree-0.0.4 → tasktree-0.0.6}/PKG-INFO +198 -111
- {tasktree-0.0.4 → tasktree-0.0.6}/README.md +197 -110
- tasktree-0.0.6/example/tasktree.yaml +16 -0
- {tasktree-0.0.4 → tasktree-0.0.6}/pyproject.toml +1 -1
- {tasktree-0.0.4 → tasktree-0.0.6}/requirements/implemented/shell-environment-requirements.md +37 -36
- tasktree-0.0.6/schema/README.md +118 -0
- tasktree-0.0.6/schema/tasktree-schema.json +163 -0
- tasktree-0.0.6/schema/vscode-settings-snippet.json +10 -0
- {tasktree-0.0.4 → tasktree-0.0.6}/src/tasktree/cli.py +85 -49
- {tasktree-0.0.4 → tasktree-0.0.6}/src/tasktree/parser.py +85 -14
- {tasktree-0.0.4 → tasktree-0.0.6}/tasktree.yaml +2 -0
- {tasktree-0.0.4 → tasktree-0.0.6}/tests/integration/test_clean_state.py +19 -15
- {tasktree-0.0.4 → tasktree-0.0.6}/tests/integration/test_cli_options.py +455 -81
- {tasktree-0.0.4 → tasktree-0.0.6}/tests/integration/test_dependency_execution.py +43 -40
- {tasktree-0.0.4 → tasktree-0.0.6}/tests/integration/test_end_to_end.py +8 -6
- {tasktree-0.0.4 → tasktree-0.0.6}/tests/integration/test_input_detection.py +15 -12
- {tasktree-0.0.4 → tasktree-0.0.6}/tests/integration/test_nested_imports.py +65 -55
- {tasktree-0.0.4 → tasktree-0.0.6}/tests/integration/test_state_persistence.py +14 -11
- {tasktree-0.0.4 → tasktree-0.0.6}/tests/integration/test_working_directory.py +51 -8
- {tasktree-0.0.4 → tasktree-0.0.6}/tests/unit/test_executor.py +13 -9
- {tasktree-0.0.4 → tasktree-0.0.6}/tests/unit/test_parser.py +397 -167
- tasktree-0.0.4/example/tasktree.yaml +0 -15
- {tasktree-0.0.4 → tasktree-0.0.6}/.github/workflows/release.yml +0 -0
- {tasktree-0.0.4 → tasktree-0.0.6}/.github/workflows/test.yml +0 -0
- {tasktree-0.0.4 → tasktree-0.0.6}/.gitignore +0 -0
- {tasktree-0.0.4 → tasktree-0.0.6}/.python-version +0 -0
- {tasktree-0.0.4 → tasktree-0.0.6}/example/source.txt +0 -0
- {tasktree-0.0.4 → tasktree-0.0.6}/requirements/future/docker-task-environments.md +0 -0
- {tasktree-0.0.4 → tasktree-0.0.6}/src/__init__.py +0 -0
- {tasktree-0.0.4 → tasktree-0.0.6}/src/tasktree/__init__.py +0 -0
- {tasktree-0.0.4 → tasktree-0.0.6}/src/tasktree/executor.py +0 -0
- {tasktree-0.0.4 → tasktree-0.0.6}/src/tasktree/graph.py +0 -0
- {tasktree-0.0.4 → tasktree-0.0.6}/src/tasktree/hasher.py +0 -0
- {tasktree-0.0.4 → tasktree-0.0.6}/src/tasktree/state.py +0 -0
- {tasktree-0.0.4 → tasktree-0.0.6}/src/tasktree/tasks.py +0 -0
- {tasktree-0.0.4 → tasktree-0.0.6}/src/tasktree/types.py +0 -0
- {tasktree-0.0.4 → tasktree-0.0.6}/tests/integration/test_missing_outputs.py +0 -0
- {tasktree-0.0.4 → tasktree-0.0.6}/tests/unit/test_cli.py +0 -0
- {tasktree-0.0.4 → tasktree-0.0.6}/tests/unit/test_graph.py +0 -0
- {tasktree-0.0.4 → tasktree-0.0.6}/tests/unit/test_hasher.py +0 -0
- {tasktree-0.0.4 → tasktree-0.0.6}/tests/unit/test_state.py +0 -0
- {tasktree-0.0.4 → tasktree-0.0.6}/tests/unit/test_tasks.py +0 -0
- {tasktree-0.0.4 → tasktree-0.0.6}/tests/unit/test_types.py +0 -0
- {tasktree-0.0.4 → tasktree-0.0.6}/uv.lock +0 -0
|
@@ -58,12 +58,13 @@ The project uses Python's built-in `unittest` framework with mocking via `unitte
|
|
|
58
58
|
|
|
59
59
|
Tasks are defined in YAML with the following structure:
|
|
60
60
|
```yaml
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
61
|
+
tasks:
|
|
62
|
+
task-name:
|
|
63
|
+
desc: Description (optional)
|
|
64
|
+
deps: [dependency-tasks]
|
|
65
|
+
inputs: [glob-patterns]
|
|
66
|
+
outputs: [glob-patterns]
|
|
67
|
+
working_dir: execution-directory
|
|
68
|
+
args: [typed-parameters]
|
|
69
|
+
cmd: shell-command
|
|
69
70
|
```
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: tasktree
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.6
|
|
4
4
|
Summary: A task automation tool with incremental execution
|
|
5
5
|
Requires-Python: >=3.11
|
|
6
6
|
Requires-Dist: click>=8.1.0
|
|
@@ -70,33 +70,34 @@ Is this just whining and moaning? Should we just man up and revel in our own abi
|
|
|
70
70
|
|
|
71
71
|
... No. That's **a dumb idea**.
|
|
72
72
|
|
|
73
|
-
Task Tree allows you to pile all the knowledge of **what** to run, **when** to run it, **where** to run it and **how** to run it into a single, readable place. Then you can delete all the scripts that no-one knows how to use and all the readme docs that lie to the few people that actually waste their time reading them.
|
|
73
|
+
Task Tree allows you to pile all the knowledge of **what** to run, **when** to run it, **where** to run it and **how** to run it into a single, readable place. Then you can delete all the scripts that no-one knows how to use and all the readme docs that lie to the few people that actually waste their time reading them.
|
|
74
74
|
|
|
75
75
|
The tasks you need to perform to deliver your project become summarised in an executable file that looks like:
|
|
76
76
|
```yaml
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
77
|
+
tasks:
|
|
78
|
+
build:
|
|
79
|
+
desc: Compile stuff
|
|
80
|
+
outputs: [target/release/bin]
|
|
81
|
+
cmd: cargo build --release
|
|
82
|
+
|
|
83
|
+
package:
|
|
84
|
+
desc: build installers
|
|
85
|
+
deps: [build]
|
|
86
|
+
outputs: [awesome.deb]
|
|
87
|
+
cmd: |
|
|
88
|
+
for bin in target/release/*; do
|
|
89
|
+
if [[ -x "$bin" && ! -d "$bin" ]]; then
|
|
90
|
+
install -Dm755 "$bin" "debian/awesome/usr/bin/$(basename "$bin")"
|
|
91
|
+
fi
|
|
92
|
+
done
|
|
93
|
+
|
|
94
|
+
dpkg-buildpackage -us -uc
|
|
95
|
+
|
|
96
|
+
test:
|
|
97
|
+
desc: Run tests
|
|
98
|
+
deps: [package]
|
|
99
|
+
inputs: [tests/**/*.py]
|
|
100
|
+
cmd: PYTHONPATH=src python3 -m pytest tests/ -v
|
|
100
101
|
```
|
|
101
102
|
|
|
102
103
|
If you want to run the tests then:
|
|
@@ -107,6 +108,52 @@ Boom! Done. `build` will always run, because there's no sensible way to know wha
|
|
|
107
108
|
|
|
108
109
|
This is a toy example, but you can image how it plays out on a more complex project.
|
|
109
110
|
|
|
111
|
+
## Migrating from v1.x to v2.0
|
|
112
|
+
|
|
113
|
+
Version 2.0 requires all task definitions to be under a top-level `tasks:` key.
|
|
114
|
+
|
|
115
|
+
### Quick Migration
|
|
116
|
+
|
|
117
|
+
Wrap your existing tasks in a `tasks:` block:
|
|
118
|
+
|
|
119
|
+
```yaml
|
|
120
|
+
# Before (v1.x)
|
|
121
|
+
build:
|
|
122
|
+
cmd: cargo build
|
|
123
|
+
|
|
124
|
+
# After (v2.0)
|
|
125
|
+
tasks:
|
|
126
|
+
build:
|
|
127
|
+
cmd: cargo build
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### Why This Change?
|
|
131
|
+
|
|
132
|
+
1. **Clearer structure**: Explicit separation of tasks from configuration
|
|
133
|
+
2. **No naming conflicts**: You can now create tasks named "imports" or "environments"
|
|
134
|
+
3. **Better error messages**: More helpful validation errors
|
|
135
|
+
4. **Consistency**: All recipe files use the same format
|
|
136
|
+
|
|
137
|
+
### Error Messages
|
|
138
|
+
|
|
139
|
+
If you forget to update, you'll see a clear error:
|
|
140
|
+
|
|
141
|
+
```
|
|
142
|
+
Invalid recipe format in tasktree.yaml
|
|
143
|
+
|
|
144
|
+
Task definitions must be under a top-level "tasks:" key.
|
|
145
|
+
|
|
146
|
+
Found these keys at root level: build, test
|
|
147
|
+
|
|
148
|
+
Did you mean:
|
|
149
|
+
|
|
150
|
+
tasks:
|
|
151
|
+
build:
|
|
152
|
+
cmd: ...
|
|
153
|
+
test:
|
|
154
|
+
cmd: ...
|
|
155
|
+
```
|
|
156
|
+
|
|
110
157
|
## Installation
|
|
111
158
|
|
|
112
159
|
### From PyPI (Recommended)
|
|
@@ -141,20 +188,52 @@ cd tasktree
|
|
|
141
188
|
pipx install .
|
|
142
189
|
```
|
|
143
190
|
|
|
191
|
+
## Editor Support
|
|
192
|
+
|
|
193
|
+
Task Tree includes a [JSON Schema](schema/tasktree-schema.json) that provides autocomplete, validation, and documentation in modern editors.
|
|
194
|
+
|
|
195
|
+
### VS Code
|
|
196
|
+
|
|
197
|
+
Install the [YAML extension](https://marketplace.visualstudio.com/items?itemName=redhat.vscode-yaml), then add to your workspace `.vscode/settings.json`:
|
|
198
|
+
|
|
199
|
+
```json
|
|
200
|
+
{
|
|
201
|
+
"yaml.schemas": {
|
|
202
|
+
"https://raw.githubusercontent.com/kevinchannon/tasktree/main/schema/tasktree-schema.json": [
|
|
203
|
+
"tasktree.yaml",
|
|
204
|
+
"tt.yaml"
|
|
205
|
+
]
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
Or add a comment at the top of your `tasktree.yaml`:
|
|
211
|
+
|
|
212
|
+
```yaml
|
|
213
|
+
# yaml-language-server: $schema=https://raw.githubusercontent.com/kevinchannon/tasktree/main/schema/tasktree-schema.json
|
|
214
|
+
|
|
215
|
+
tasks:
|
|
216
|
+
build:
|
|
217
|
+
cmd: cargo build
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
See [schema/README.md](schema/README.md) for IntelliJ/PyCharm and command-line validation.
|
|
221
|
+
|
|
144
222
|
## Quick Start
|
|
145
223
|
|
|
146
224
|
Create a `tasktree.yaml` (or `tt.yaml`) in your project:
|
|
147
225
|
|
|
148
226
|
```yaml
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
227
|
+
tasks:
|
|
228
|
+
build:
|
|
229
|
+
desc: Compile the application
|
|
230
|
+
outputs: [target/release/bin]
|
|
231
|
+
cmd: cargo build --release
|
|
153
232
|
|
|
154
|
-
test:
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
233
|
+
test:
|
|
234
|
+
desc: Run tests
|
|
235
|
+
deps: [build]
|
|
236
|
+
cmd: cargo test
|
|
158
237
|
```
|
|
159
238
|
|
|
160
239
|
Run tasks:
|
|
@@ -185,15 +264,16 @@ Task Tree only runs tasks when necessary. A task executes if:
|
|
|
185
264
|
Tasks automatically inherit inputs from dependencies, eliminating redundant declarations:
|
|
186
265
|
|
|
187
266
|
```yaml
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
267
|
+
tasks:
|
|
268
|
+
build:
|
|
269
|
+
outputs: [dist/app]
|
|
270
|
+
cmd: go build -o dist/app
|
|
271
|
+
|
|
272
|
+
package:
|
|
273
|
+
deps: [build]
|
|
274
|
+
outputs: [dist/app.tar.gz]
|
|
275
|
+
cmd: tar czf dist/app.tar.gz dist/app
|
|
276
|
+
# Automatically tracks dist/app as an input
|
|
197
277
|
```
|
|
198
278
|
|
|
199
279
|
### Single State File
|
|
@@ -205,15 +285,16 @@ All state lives in `.tasktree-state` at your project root. Stale entries are aut
|
|
|
205
285
|
### Basic Structure
|
|
206
286
|
|
|
207
287
|
```yaml
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
288
|
+
tasks:
|
|
289
|
+
task-name:
|
|
290
|
+
desc: Human-readable description (optional)
|
|
291
|
+
deps: [other-task] # Task dependencies
|
|
292
|
+
inputs: [src/**/*.go] # Explicit input files (glob patterns)
|
|
293
|
+
outputs: [dist/binary] # Output files (glob patterns)
|
|
294
|
+
working_dir: subproject/ # Execution directory (default: project root)
|
|
295
|
+
env: bash-strict # Execution environment (optional)
|
|
296
|
+
args: [param1, param2:path=default] # Task parameters
|
|
297
|
+
cmd: go build -o dist/binary # Command to execute
|
|
217
298
|
```
|
|
218
299
|
|
|
219
300
|
### Commands
|
|
@@ -221,18 +302,20 @@ task-name:
|
|
|
221
302
|
**Single-line commands** are executed directly via the configured shell:
|
|
222
303
|
|
|
223
304
|
```yaml
|
|
224
|
-
|
|
225
|
-
|
|
305
|
+
tasks:
|
|
306
|
+
build:
|
|
307
|
+
cmd: cargo build --release
|
|
226
308
|
```
|
|
227
309
|
|
|
228
310
|
**Multi-line commands** are written to temporary script files for proper execution:
|
|
229
311
|
|
|
230
312
|
```yaml
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
313
|
+
tasks:
|
|
314
|
+
deploy:
|
|
315
|
+
cmd: |
|
|
316
|
+
mkdir -p dist
|
|
317
|
+
cp build/* dist/
|
|
318
|
+
rsync -av dist/ server:/opt/app/
|
|
236
319
|
```
|
|
237
320
|
|
|
238
321
|
Multi-line commands preserve shell syntax (line continuations, heredocs, etc.) and support shebangs on Unix/macOS.
|
|
@@ -240,12 +323,13 @@ Multi-line commands preserve shell syntax (line continuations, heredocs, etc.) a
|
|
|
240
323
|
Or use folded blocks for long single-line commands:
|
|
241
324
|
|
|
242
325
|
```yaml
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
326
|
+
tasks:
|
|
327
|
+
compile:
|
|
328
|
+
cmd: >
|
|
329
|
+
gcc -o bin/app
|
|
330
|
+
src/*.c
|
|
331
|
+
-I include
|
|
332
|
+
-L lib -lm
|
|
249
333
|
```
|
|
250
334
|
|
|
251
335
|
### Execution Environments
|
|
@@ -305,12 +389,13 @@ tasks:
|
|
|
305
389
|
Tasks can accept arguments with optional defaults:
|
|
306
390
|
|
|
307
391
|
```yaml
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
392
|
+
tasks:
|
|
393
|
+
deploy:
|
|
394
|
+
args: [environment, region=eu-west-1]
|
|
395
|
+
deps: [build]
|
|
396
|
+
cmd: |
|
|
397
|
+
aws s3 cp dist/app.zip s3://{{environment}}-{{region}}/
|
|
398
|
+
aws lambda update-function-code --function-name app-{{environment}}
|
|
314
399
|
```
|
|
315
400
|
|
|
316
401
|
Invoke with: `tt deploy production` or `tt deploy staging us-east-1` or `tt deploy staging region=us-east-1`.
|
|
@@ -337,18 +422,19 @@ Split task definitions across multiple files for better organisation:
|
|
|
337
422
|
|
|
338
423
|
```yaml
|
|
339
424
|
# tasktree.yaml
|
|
340
|
-
|
|
425
|
+
imports:
|
|
341
426
|
- file: build/tasks.yml
|
|
342
427
|
as: build
|
|
343
428
|
- file: deploy/tasks.yml
|
|
344
429
|
as: deploy
|
|
345
430
|
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
431
|
+
tasks:
|
|
432
|
+
test:
|
|
433
|
+
deps: [build.compile, build.test-compile]
|
|
434
|
+
cmd: ./run-tests.sh
|
|
349
435
|
|
|
350
|
-
ci:
|
|
351
|
-
|
|
436
|
+
ci:
|
|
437
|
+
deps: [build.all, test, deploy.staging]
|
|
352
438
|
```
|
|
353
439
|
|
|
354
440
|
Imported tasks are namespaced and can be referenced as dependencies. Each imported file is self-contained—it cannot depend on tasks in the importing file.
|
|
@@ -466,41 +552,42 @@ imports:
|
|
|
466
552
|
- file: common/docker.yml
|
|
467
553
|
as: docker
|
|
468
554
|
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
555
|
+
tasks:
|
|
556
|
+
compile:
|
|
557
|
+
desc: Build application binaries
|
|
558
|
+
outputs: [target/release/app]
|
|
559
|
+
cmd: cargo build --release
|
|
560
|
+
|
|
561
|
+
test-unit:
|
|
562
|
+
desc: Run unit tests
|
|
563
|
+
deps: [compile]
|
|
564
|
+
cmd: cargo test
|
|
565
|
+
|
|
566
|
+
package:
|
|
567
|
+
desc: Create distribution archive
|
|
568
|
+
deps: [compile]
|
|
569
|
+
outputs: [dist/app-{{version}}.tar.gz]
|
|
570
|
+
args: [version]
|
|
571
|
+
cmd: |
|
|
572
|
+
mkdir -p dist
|
|
573
|
+
tar czf dist/app-{{version}}.tar.gz \
|
|
574
|
+
target/release/app \
|
|
575
|
+
config/ \
|
|
576
|
+
migrations/
|
|
577
|
+
|
|
578
|
+
deploy:
|
|
579
|
+
desc: Deploy to environment
|
|
580
|
+
deps: [package, docker.build-runtime]
|
|
581
|
+
args: [environment, version]
|
|
582
|
+
cmd: |
|
|
583
|
+
scp dist/app-{{version}}.tar.gz {{environment}}:/opt/
|
|
584
|
+
ssh {{environment}} /opt/deploy.sh {{version}}
|
|
585
|
+
|
|
586
|
+
integration-test:
|
|
587
|
+
desc: Run integration tests against deployed environment
|
|
588
|
+
deps: [deploy]
|
|
589
|
+
args: [environment, version]
|
|
590
|
+
cmd: pytest tests/integration/ --env={{environment}}
|
|
504
591
|
```
|
|
505
592
|
|
|
506
593
|
Run the full pipeline:
|