tasktree 0.0.4__tar.gz → 0.0.5__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.5}/CLAUDE.md +9 -8
- {tasktree-0.0.4 → tasktree-0.0.5}/PKG-INFO +167 -111
- {tasktree-0.0.4 → tasktree-0.0.5}/README.md +166 -110
- tasktree-0.0.5/example/tasktree.yaml +16 -0
- {tasktree-0.0.4 → tasktree-0.0.5}/pyproject.toml +1 -1
- {tasktree-0.0.4 → tasktree-0.0.5}/requirements/implemented/shell-environment-requirements.md +37 -36
- {tasktree-0.0.4 → tasktree-0.0.5}/src/tasktree/cli.py +19 -18
- {tasktree-0.0.4 → tasktree-0.0.5}/src/tasktree/parser.py +41 -7
- {tasktree-0.0.4 → tasktree-0.0.5}/tests/integration/test_clean_state.py +19 -15
- {tasktree-0.0.4 → tasktree-0.0.5}/tests/integration/test_cli_options.py +233 -81
- {tasktree-0.0.4 → tasktree-0.0.5}/tests/integration/test_dependency_execution.py +43 -40
- {tasktree-0.0.4 → tasktree-0.0.5}/tests/integration/test_end_to_end.py +8 -6
- {tasktree-0.0.4 → tasktree-0.0.5}/tests/integration/test_input_detection.py +15 -12
- {tasktree-0.0.4 → tasktree-0.0.5}/tests/integration/test_nested_imports.py +65 -55
- {tasktree-0.0.4 → tasktree-0.0.5}/tests/integration/test_state_persistence.py +14 -11
- {tasktree-0.0.4 → tasktree-0.0.5}/tests/integration/test_working_directory.py +10 -8
- {tasktree-0.0.4 → tasktree-0.0.5}/tests/unit/test_executor.py +13 -9
- {tasktree-0.0.4 → tasktree-0.0.5}/tests/unit/test_parser.py +349 -164
- tasktree-0.0.4/example/tasktree.yaml +0 -15
- {tasktree-0.0.4 → tasktree-0.0.5}/.github/workflows/release.yml +0 -0
- {tasktree-0.0.4 → tasktree-0.0.5}/.github/workflows/test.yml +0 -0
- {tasktree-0.0.4 → tasktree-0.0.5}/.gitignore +0 -0
- {tasktree-0.0.4 → tasktree-0.0.5}/.python-version +0 -0
- {tasktree-0.0.4 → tasktree-0.0.5}/example/source.txt +0 -0
- {tasktree-0.0.4 → tasktree-0.0.5}/requirements/future/docker-task-environments.md +0 -0
- {tasktree-0.0.4 → tasktree-0.0.5}/src/__init__.py +0 -0
- {tasktree-0.0.4 → tasktree-0.0.5}/src/tasktree/__init__.py +0 -0
- {tasktree-0.0.4 → tasktree-0.0.5}/src/tasktree/executor.py +0 -0
- {tasktree-0.0.4 → tasktree-0.0.5}/src/tasktree/graph.py +0 -0
- {tasktree-0.0.4 → tasktree-0.0.5}/src/tasktree/hasher.py +0 -0
- {tasktree-0.0.4 → tasktree-0.0.5}/src/tasktree/state.py +0 -0
- {tasktree-0.0.4 → tasktree-0.0.5}/src/tasktree/tasks.py +0 -0
- {tasktree-0.0.4 → tasktree-0.0.5}/src/tasktree/types.py +0 -0
- {tasktree-0.0.4 → tasktree-0.0.5}/tasktree.yaml +0 -0
- {tasktree-0.0.4 → tasktree-0.0.5}/tests/integration/test_missing_outputs.py +0 -0
- {tasktree-0.0.4 → tasktree-0.0.5}/tests/unit/test_cli.py +0 -0
- {tasktree-0.0.4 → tasktree-0.0.5}/tests/unit/test_graph.py +0 -0
- {tasktree-0.0.4 → tasktree-0.0.5}/tests/unit/test_hasher.py +0 -0
- {tasktree-0.0.4 → tasktree-0.0.5}/tests/unit/test_state.py +0 -0
- {tasktree-0.0.4 → tasktree-0.0.5}/tests/unit/test_tasks.py +0 -0
- {tasktree-0.0.4 → tasktree-0.0.5}/tests/unit/test_types.py +0 -0
- {tasktree-0.0.4 → tasktree-0.0.5}/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.5
|
|
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)
|
|
@@ -146,15 +193,16 @@ pipx install .
|
|
|
146
193
|
Create a `tasktree.yaml` (or `tt.yaml`) in your project:
|
|
147
194
|
|
|
148
195
|
```yaml
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
196
|
+
tasks:
|
|
197
|
+
build:
|
|
198
|
+
desc: Compile the application
|
|
199
|
+
outputs: [target/release/bin]
|
|
200
|
+
cmd: cargo build --release
|
|
153
201
|
|
|
154
|
-
test:
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
202
|
+
test:
|
|
203
|
+
desc: Run tests
|
|
204
|
+
deps: [build]
|
|
205
|
+
cmd: cargo test
|
|
158
206
|
```
|
|
159
207
|
|
|
160
208
|
Run tasks:
|
|
@@ -185,15 +233,16 @@ Task Tree only runs tasks when necessary. A task executes if:
|
|
|
185
233
|
Tasks automatically inherit inputs from dependencies, eliminating redundant declarations:
|
|
186
234
|
|
|
187
235
|
```yaml
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
236
|
+
tasks:
|
|
237
|
+
build:
|
|
238
|
+
outputs: [dist/app]
|
|
239
|
+
cmd: go build -o dist/app
|
|
240
|
+
|
|
241
|
+
package:
|
|
242
|
+
deps: [build]
|
|
243
|
+
outputs: [dist/app.tar.gz]
|
|
244
|
+
cmd: tar czf dist/app.tar.gz dist/app
|
|
245
|
+
# Automatically tracks dist/app as an input
|
|
197
246
|
```
|
|
198
247
|
|
|
199
248
|
### Single State File
|
|
@@ -205,15 +254,16 @@ All state lives in `.tasktree-state` at your project root. Stale entries are aut
|
|
|
205
254
|
### Basic Structure
|
|
206
255
|
|
|
207
256
|
```yaml
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
257
|
+
tasks:
|
|
258
|
+
task-name:
|
|
259
|
+
desc: Human-readable description (optional)
|
|
260
|
+
deps: [other-task] # Task dependencies
|
|
261
|
+
inputs: [src/**/*.go] # Explicit input files (glob patterns)
|
|
262
|
+
outputs: [dist/binary] # Output files (glob patterns)
|
|
263
|
+
working_dir: subproject/ # Execution directory (default: project root)
|
|
264
|
+
env: bash-strict # Execution environment (optional)
|
|
265
|
+
args: [param1, param2:path=default] # Task parameters
|
|
266
|
+
cmd: go build -o dist/binary # Command to execute
|
|
217
267
|
```
|
|
218
268
|
|
|
219
269
|
### Commands
|
|
@@ -221,18 +271,20 @@ task-name:
|
|
|
221
271
|
**Single-line commands** are executed directly via the configured shell:
|
|
222
272
|
|
|
223
273
|
```yaml
|
|
224
|
-
|
|
225
|
-
|
|
274
|
+
tasks:
|
|
275
|
+
build:
|
|
276
|
+
cmd: cargo build --release
|
|
226
277
|
```
|
|
227
278
|
|
|
228
279
|
**Multi-line commands** are written to temporary script files for proper execution:
|
|
229
280
|
|
|
230
281
|
```yaml
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
282
|
+
tasks:
|
|
283
|
+
deploy:
|
|
284
|
+
cmd: |
|
|
285
|
+
mkdir -p dist
|
|
286
|
+
cp build/* dist/
|
|
287
|
+
rsync -av dist/ server:/opt/app/
|
|
236
288
|
```
|
|
237
289
|
|
|
238
290
|
Multi-line commands preserve shell syntax (line continuations, heredocs, etc.) and support shebangs on Unix/macOS.
|
|
@@ -240,12 +292,13 @@ Multi-line commands preserve shell syntax (line continuations, heredocs, etc.) a
|
|
|
240
292
|
Or use folded blocks for long single-line commands:
|
|
241
293
|
|
|
242
294
|
```yaml
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
295
|
+
tasks:
|
|
296
|
+
compile:
|
|
297
|
+
cmd: >
|
|
298
|
+
gcc -o bin/app
|
|
299
|
+
src/*.c
|
|
300
|
+
-I include
|
|
301
|
+
-L lib -lm
|
|
249
302
|
```
|
|
250
303
|
|
|
251
304
|
### Execution Environments
|
|
@@ -305,12 +358,13 @@ tasks:
|
|
|
305
358
|
Tasks can accept arguments with optional defaults:
|
|
306
359
|
|
|
307
360
|
```yaml
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
361
|
+
tasks:
|
|
362
|
+
deploy:
|
|
363
|
+
args: [environment, region=eu-west-1]
|
|
364
|
+
deps: [build]
|
|
365
|
+
cmd: |
|
|
366
|
+
aws s3 cp dist/app.zip s3://{{environment}}-{{region}}/
|
|
367
|
+
aws lambda update-function-code --function-name app-{{environment}}
|
|
314
368
|
```
|
|
315
369
|
|
|
316
370
|
Invoke with: `tt deploy production` or `tt deploy staging us-east-1` or `tt deploy staging region=us-east-1`.
|
|
@@ -337,18 +391,19 @@ Split task definitions across multiple files for better organisation:
|
|
|
337
391
|
|
|
338
392
|
```yaml
|
|
339
393
|
# tasktree.yaml
|
|
340
|
-
|
|
394
|
+
imports:
|
|
341
395
|
- file: build/tasks.yml
|
|
342
396
|
as: build
|
|
343
397
|
- file: deploy/tasks.yml
|
|
344
398
|
as: deploy
|
|
345
399
|
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
400
|
+
tasks:
|
|
401
|
+
test:
|
|
402
|
+
deps: [build.compile, build.test-compile]
|
|
403
|
+
cmd: ./run-tests.sh
|
|
349
404
|
|
|
350
|
-
ci:
|
|
351
|
-
|
|
405
|
+
ci:
|
|
406
|
+
deps: [build.all, test, deploy.staging]
|
|
352
407
|
```
|
|
353
408
|
|
|
354
409
|
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 +521,42 @@ imports:
|
|
|
466
521
|
- file: common/docker.yml
|
|
467
522
|
as: docker
|
|
468
523
|
|
|
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
|
-
|
|
524
|
+
tasks:
|
|
525
|
+
compile:
|
|
526
|
+
desc: Build application binaries
|
|
527
|
+
outputs: [target/release/app]
|
|
528
|
+
cmd: cargo build --release
|
|
529
|
+
|
|
530
|
+
test-unit:
|
|
531
|
+
desc: Run unit tests
|
|
532
|
+
deps: [compile]
|
|
533
|
+
cmd: cargo test
|
|
534
|
+
|
|
535
|
+
package:
|
|
536
|
+
desc: Create distribution archive
|
|
537
|
+
deps: [compile]
|
|
538
|
+
outputs: [dist/app-{{version}}.tar.gz]
|
|
539
|
+
args: [version]
|
|
540
|
+
cmd: |
|
|
541
|
+
mkdir -p dist
|
|
542
|
+
tar czf dist/app-{{version}}.tar.gz \
|
|
543
|
+
target/release/app \
|
|
544
|
+
config/ \
|
|
545
|
+
migrations/
|
|
546
|
+
|
|
547
|
+
deploy:
|
|
548
|
+
desc: Deploy to environment
|
|
549
|
+
deps: [package, docker.build-runtime]
|
|
550
|
+
args: [environment, version]
|
|
551
|
+
cmd: |
|
|
552
|
+
scp dist/app-{{version}}.tar.gz {{environment}}:/opt/
|
|
553
|
+
ssh {{environment}} /opt/deploy.sh {{version}}
|
|
554
|
+
|
|
555
|
+
integration-test:
|
|
556
|
+
desc: Run integration tests against deployed environment
|
|
557
|
+
deps: [deploy]
|
|
558
|
+
args: [environment, version]
|
|
559
|
+
cmd: pytest tests/integration/ --env={{environment}}
|
|
504
560
|
```
|
|
505
561
|
|
|
506
562
|
Run the full pipeline:
|