tasktree 0.0.2__tar.gz → 0.0.3__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.2 → tasktree-0.0.3}/.github/workflows/test.yml +1 -1
- {tasktree-0.0.2 → tasktree-0.0.3}/PKG-INFO +148 -12
- {tasktree-0.0.2 → tasktree-0.0.3}/README.md +147 -11
- {tasktree-0.0.2 → tasktree-0.0.3}/pyproject.toml +1 -1
- tasktree-0.0.3/requirements/future/docker-task-environments.md +1002 -0
- tasktree-0.0.3/requirements/future/shell-environment-requirements.md +392 -0
- {tasktree-0.0.2 → tasktree-0.0.3}/src/tasktree/cli.py +35 -89
- {tasktree-0.0.2 → tasktree-0.0.3}/src/tasktree/executor.py +202 -16
- {tasktree-0.0.2 → tasktree-0.0.3}/src/tasktree/hasher.py +4 -1
- {tasktree-0.0.2 → tasktree-0.0.3}/src/tasktree/parser.py +108 -5
- {tasktree-0.0.2 → tasktree-0.0.3}/tests/integration/test_cli_options.py +149 -1
- {tasktree-0.0.2 → tasktree-0.0.3}/tests/integration/test_dependency_execution.py +4 -4
- {tasktree-0.0.2 → tasktree-0.0.3}/tests/integration/test_missing_outputs.py +7 -7
- {tasktree-0.0.2 → tasktree-0.0.3}/tests/integration/test_working_directory.py +1 -1
- {tasktree-0.0.2 → tasktree-0.0.3}/tests/unit/test_executor.py +375 -5
- {tasktree-0.0.2 → tasktree-0.0.3}/tests/unit/test_parser.py +90 -0
- {tasktree-0.0.2 → tasktree-0.0.3}/.github/workflows/release.yml +0 -0
- {tasktree-0.0.2 → tasktree-0.0.3}/.gitignore +0 -0
- {tasktree-0.0.2 → tasktree-0.0.3}/CLAUDE.md +0 -0
- {tasktree-0.0.2 → tasktree-0.0.3}/example/source.txt +0 -0
- {tasktree-0.0.2 → tasktree-0.0.3}/example/tasktree.yaml +0 -0
- {tasktree-0.0.2 → tasktree-0.0.3}/src/__init__.py +0 -0
- {tasktree-0.0.2 → tasktree-0.0.3}/src/tasktree/__init__.py +0 -0
- {tasktree-0.0.2 → tasktree-0.0.3}/src/tasktree/graph.py +0 -0
- {tasktree-0.0.2 → tasktree-0.0.3}/src/tasktree/state.py +0 -0
- {tasktree-0.0.2 → tasktree-0.0.3}/src/tasktree/tasks.py +0 -0
- {tasktree-0.0.2 → tasktree-0.0.3}/src/tasktree/types.py +0 -0
- {tasktree-0.0.2 → tasktree-0.0.3}/tasktree.yaml +0 -0
- {tasktree-0.0.2 → tasktree-0.0.3}/tests/integration/test_clean_state.py +0 -0
- {tasktree-0.0.2 → tasktree-0.0.3}/tests/integration/test_end_to_end.py +0 -0
- {tasktree-0.0.2 → tasktree-0.0.3}/tests/integration/test_input_detection.py +0 -0
- {tasktree-0.0.2 → tasktree-0.0.3}/tests/integration/test_nested_imports.py +0 -0
- {tasktree-0.0.2 → tasktree-0.0.3}/tests/integration/test_state_persistence.py +0 -0
- {tasktree-0.0.2 → tasktree-0.0.3}/tests/unit/test_cli.py +0 -0
- {tasktree-0.0.2 → tasktree-0.0.3}/tests/unit/test_graph.py +0 -0
- {tasktree-0.0.2 → tasktree-0.0.3}/tests/unit/test_hasher.py +0 -0
- {tasktree-0.0.2 → tasktree-0.0.3}/tests/unit/test_state.py +0 -0
- {tasktree-0.0.2 → tasktree-0.0.3}/tests/unit/test_tasks.py +0 -0
- {tasktree-0.0.2 → tasktree-0.0.3}/tests/unit/test_types.py +0 -0
- {tasktree-0.0.2 → tasktree-0.0.3}/uv.lock +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: tasktree
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.3
|
|
4
4
|
Summary: A task automation tool with incremental execution
|
|
5
5
|
Requires-Python: >=3.11
|
|
6
6
|
Requires-Dist: click>=8.1.0
|
|
@@ -72,11 +72,12 @@ tt --list # Show all available tasks
|
|
|
72
72
|
|
|
73
73
|
Task Tree only runs tasks when necessary. A task executes if:
|
|
74
74
|
|
|
75
|
-
- Its definition (command, outputs, working directory) has changed
|
|
75
|
+
- Its definition (command, outputs, working directory, environment) has changed
|
|
76
76
|
- Any input files have changed since the last run
|
|
77
77
|
- Any dependencies have re-run
|
|
78
78
|
- It has never been executed before
|
|
79
79
|
- It has no inputs or outputs (always runs)
|
|
80
|
+
- The execution environment has changed (CLI override or environment config change)
|
|
80
81
|
|
|
81
82
|
### Automatic Input Inheritance
|
|
82
83
|
|
|
@@ -105,17 +106,25 @@ All state lives in `.tasktree-state` at your project root. Stale entries are aut
|
|
|
105
106
|
```yaml
|
|
106
107
|
task-name:
|
|
107
108
|
desc: Human-readable description (optional)
|
|
108
|
-
deps: [other-task]
|
|
109
|
-
inputs: [src/**/*.go]
|
|
110
|
-
outputs: [dist/binary]
|
|
111
|
-
working_dir: subproject/
|
|
112
|
-
|
|
113
|
-
|
|
109
|
+
deps: [other-task] # Task dependencies
|
|
110
|
+
inputs: [src/**/*.go] # Explicit input files (glob patterns)
|
|
111
|
+
outputs: [dist/binary] # Output files (glob patterns)
|
|
112
|
+
working_dir: subproject/ # Execution directory (default: project root)
|
|
113
|
+
env: bash-strict # Execution environment (optional)
|
|
114
|
+
args: [param1, param2:path=default] # Task parameters
|
|
115
|
+
cmd: go build -o dist/binary # Command to execute
|
|
114
116
|
```
|
|
115
117
|
|
|
116
118
|
### Commands
|
|
117
119
|
|
|
118
|
-
|
|
120
|
+
**Single-line commands** are executed directly via the configured shell:
|
|
121
|
+
|
|
122
|
+
```yaml
|
|
123
|
+
build:
|
|
124
|
+
cmd: cargo build --release
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
**Multi-line commands** are written to temporary script files for proper execution:
|
|
119
128
|
|
|
120
129
|
```yaml
|
|
121
130
|
deploy:
|
|
@@ -125,7 +134,9 @@ deploy:
|
|
|
125
134
|
rsync -av dist/ server:/opt/app/
|
|
126
135
|
```
|
|
127
136
|
|
|
128
|
-
|
|
137
|
+
Multi-line commands preserve shell syntax (line continuations, heredocs, etc.) and support shebangs on Unix/macOS.
|
|
138
|
+
|
|
139
|
+
Or use folded blocks for long single-line commands:
|
|
129
140
|
|
|
130
141
|
```yaml
|
|
131
142
|
compile:
|
|
@@ -136,6 +147,58 @@ compile:
|
|
|
136
147
|
-L lib -lm
|
|
137
148
|
```
|
|
138
149
|
|
|
150
|
+
### Execution Environments
|
|
151
|
+
|
|
152
|
+
Configure custom shell environments for task execution:
|
|
153
|
+
|
|
154
|
+
```yaml
|
|
155
|
+
environments:
|
|
156
|
+
default: bash-strict
|
|
157
|
+
|
|
158
|
+
bash-strict:
|
|
159
|
+
shell: bash
|
|
160
|
+
args: ['-c'] # For single-line: bash -c "command"
|
|
161
|
+
preamble: | # For multi-line: prepended to script
|
|
162
|
+
set -euo pipefail
|
|
163
|
+
|
|
164
|
+
python:
|
|
165
|
+
shell: python
|
|
166
|
+
args: ['-c']
|
|
167
|
+
|
|
168
|
+
powershell:
|
|
169
|
+
shell: powershell
|
|
170
|
+
args: ['-ExecutionPolicy', 'Bypass', '-Command']
|
|
171
|
+
preamble: |
|
|
172
|
+
$ErrorActionPreference = 'Stop'
|
|
173
|
+
|
|
174
|
+
tasks:
|
|
175
|
+
build:
|
|
176
|
+
# Uses 'default' environment (bash-strict)
|
|
177
|
+
cmd: cargo build --release
|
|
178
|
+
|
|
179
|
+
analyze:
|
|
180
|
+
env: python
|
|
181
|
+
cmd: |
|
|
182
|
+
import sys
|
|
183
|
+
print(f"Analyzing with Python {sys.version}")
|
|
184
|
+
# ... analysis code ...
|
|
185
|
+
|
|
186
|
+
windows-task:
|
|
187
|
+
env: powershell
|
|
188
|
+
cmd: |
|
|
189
|
+
Compress-Archive -Path dist/* -DestinationPath package.zip
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
**Environment resolution priority:**
|
|
193
|
+
1. CLI override: `tt --env python build`
|
|
194
|
+
2. Task's `env` field
|
|
195
|
+
3. Recipe's `default` environment
|
|
196
|
+
4. Platform default (bash on Unix, cmd on Windows)
|
|
197
|
+
|
|
198
|
+
**Platform defaults** when no environments are configured:
|
|
199
|
+
- **Unix/macOS**: bash with `-c` args
|
|
200
|
+
- **Windows**: cmd with `/c` args
|
|
201
|
+
|
|
139
202
|
### Parameterised Tasks
|
|
140
203
|
|
|
141
204
|
Tasks can accept arguments with optional defaults:
|
|
@@ -202,12 +265,19 @@ Input and output patterns support standard glob syntax:
|
|
|
202
265
|
|
|
203
266
|
### How State Works
|
|
204
267
|
|
|
205
|
-
Each task is identified by a hash of its definition
|
|
268
|
+
Each task is identified by a hash of its definition. The hash includes:
|
|
206
269
|
|
|
270
|
+
- Command to execute
|
|
271
|
+
- Output patterns
|
|
272
|
+
- Working directory
|
|
273
|
+
- Argument definitions
|
|
274
|
+
- Execution environment
|
|
275
|
+
|
|
276
|
+
State tracks:
|
|
207
277
|
- When the task last ran
|
|
208
278
|
- Timestamps of input files at that time
|
|
209
279
|
|
|
210
|
-
Tasks are re-run when their definition changes
|
|
280
|
+
Tasks are re-run when their definition changes, inputs are newer than the last run, or the environment changes.
|
|
211
281
|
|
|
212
282
|
### What's Not In The Hash
|
|
213
283
|
|
|
@@ -222,6 +292,72 @@ Changes to these don't invalidate cached state:
|
|
|
222
292
|
|
|
223
293
|
At the start of each invocation, state is checked for invalid task hashes and non-existent ones are automatically removed. Delete a task from your recipe file and its state disappears the next time you run `tt <cmd>`
|
|
224
294
|
|
|
295
|
+
## Command-Line Options
|
|
296
|
+
|
|
297
|
+
Task Tree provides several command-line options for controlling task execution:
|
|
298
|
+
|
|
299
|
+
### Execution Control
|
|
300
|
+
|
|
301
|
+
```bash
|
|
302
|
+
# Force re-run (ignore freshness checks)
|
|
303
|
+
tt --force build
|
|
304
|
+
tt -f build
|
|
305
|
+
|
|
306
|
+
# Run only the specified task, skip dependencies (implies --force)
|
|
307
|
+
tt --only deploy
|
|
308
|
+
tt -o deploy
|
|
309
|
+
|
|
310
|
+
# Override environment for all tasks
|
|
311
|
+
tt --env python analyze
|
|
312
|
+
tt -e powershell build
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
### Information Commands
|
|
316
|
+
|
|
317
|
+
```bash
|
|
318
|
+
# List all available tasks
|
|
319
|
+
tt --list
|
|
320
|
+
tt -l
|
|
321
|
+
|
|
322
|
+
# Show detailed task definition
|
|
323
|
+
tt --show build
|
|
324
|
+
|
|
325
|
+
# Show dependency tree (without execution)
|
|
326
|
+
tt --tree deploy
|
|
327
|
+
|
|
328
|
+
# Show version
|
|
329
|
+
tt --version
|
|
330
|
+
tt -v
|
|
331
|
+
|
|
332
|
+
# Create a blank recipe file
|
|
333
|
+
tt --init
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
### State Management
|
|
337
|
+
|
|
338
|
+
```bash
|
|
339
|
+
# Remove state file (reset task cache)
|
|
340
|
+
tt --clean
|
|
341
|
+
tt --clean-state
|
|
342
|
+
tt --reset
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
### Common Workflows
|
|
346
|
+
|
|
347
|
+
```bash
|
|
348
|
+
# Fresh build of everything
|
|
349
|
+
tt --force build
|
|
350
|
+
|
|
351
|
+
# Run a task without rebuilding dependencies
|
|
352
|
+
tt --only test
|
|
353
|
+
|
|
354
|
+
# Test with a different shell/environment
|
|
355
|
+
tt --env python test
|
|
356
|
+
|
|
357
|
+
# Force rebuild and deploy
|
|
358
|
+
tt --force deploy production
|
|
359
|
+
```
|
|
360
|
+
|
|
225
361
|
## Example: Full Build Pipeline
|
|
226
362
|
|
|
227
363
|
```yaml
|
|
@@ -58,11 +58,12 @@ tt --list # Show all available tasks
|
|
|
58
58
|
|
|
59
59
|
Task Tree only runs tasks when necessary. A task executes if:
|
|
60
60
|
|
|
61
|
-
- Its definition (command, outputs, working directory) has changed
|
|
61
|
+
- Its definition (command, outputs, working directory, environment) has changed
|
|
62
62
|
- Any input files have changed since the last run
|
|
63
63
|
- Any dependencies have re-run
|
|
64
64
|
- It has never been executed before
|
|
65
65
|
- It has no inputs or outputs (always runs)
|
|
66
|
+
- The execution environment has changed (CLI override or environment config change)
|
|
66
67
|
|
|
67
68
|
### Automatic Input Inheritance
|
|
68
69
|
|
|
@@ -91,17 +92,25 @@ All state lives in `.tasktree-state` at your project root. Stale entries are aut
|
|
|
91
92
|
```yaml
|
|
92
93
|
task-name:
|
|
93
94
|
desc: Human-readable description (optional)
|
|
94
|
-
deps: [other-task]
|
|
95
|
-
inputs: [src/**/*.go]
|
|
96
|
-
outputs: [dist/binary]
|
|
97
|
-
working_dir: subproject/
|
|
98
|
-
|
|
99
|
-
|
|
95
|
+
deps: [other-task] # Task dependencies
|
|
96
|
+
inputs: [src/**/*.go] # Explicit input files (glob patterns)
|
|
97
|
+
outputs: [dist/binary] # Output files (glob patterns)
|
|
98
|
+
working_dir: subproject/ # Execution directory (default: project root)
|
|
99
|
+
env: bash-strict # Execution environment (optional)
|
|
100
|
+
args: [param1, param2:path=default] # Task parameters
|
|
101
|
+
cmd: go build -o dist/binary # Command to execute
|
|
100
102
|
```
|
|
101
103
|
|
|
102
104
|
### Commands
|
|
103
105
|
|
|
104
|
-
|
|
106
|
+
**Single-line commands** are executed directly via the configured shell:
|
|
107
|
+
|
|
108
|
+
```yaml
|
|
109
|
+
build:
|
|
110
|
+
cmd: cargo build --release
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
**Multi-line commands** are written to temporary script files for proper execution:
|
|
105
114
|
|
|
106
115
|
```yaml
|
|
107
116
|
deploy:
|
|
@@ -111,7 +120,9 @@ deploy:
|
|
|
111
120
|
rsync -av dist/ server:/opt/app/
|
|
112
121
|
```
|
|
113
122
|
|
|
114
|
-
|
|
123
|
+
Multi-line commands preserve shell syntax (line continuations, heredocs, etc.) and support shebangs on Unix/macOS.
|
|
124
|
+
|
|
125
|
+
Or use folded blocks for long single-line commands:
|
|
115
126
|
|
|
116
127
|
```yaml
|
|
117
128
|
compile:
|
|
@@ -122,6 +133,58 @@ compile:
|
|
|
122
133
|
-L lib -lm
|
|
123
134
|
```
|
|
124
135
|
|
|
136
|
+
### Execution Environments
|
|
137
|
+
|
|
138
|
+
Configure custom shell environments for task execution:
|
|
139
|
+
|
|
140
|
+
```yaml
|
|
141
|
+
environments:
|
|
142
|
+
default: bash-strict
|
|
143
|
+
|
|
144
|
+
bash-strict:
|
|
145
|
+
shell: bash
|
|
146
|
+
args: ['-c'] # For single-line: bash -c "command"
|
|
147
|
+
preamble: | # For multi-line: prepended to script
|
|
148
|
+
set -euo pipefail
|
|
149
|
+
|
|
150
|
+
python:
|
|
151
|
+
shell: python
|
|
152
|
+
args: ['-c']
|
|
153
|
+
|
|
154
|
+
powershell:
|
|
155
|
+
shell: powershell
|
|
156
|
+
args: ['-ExecutionPolicy', 'Bypass', '-Command']
|
|
157
|
+
preamble: |
|
|
158
|
+
$ErrorActionPreference = 'Stop'
|
|
159
|
+
|
|
160
|
+
tasks:
|
|
161
|
+
build:
|
|
162
|
+
# Uses 'default' environment (bash-strict)
|
|
163
|
+
cmd: cargo build --release
|
|
164
|
+
|
|
165
|
+
analyze:
|
|
166
|
+
env: python
|
|
167
|
+
cmd: |
|
|
168
|
+
import sys
|
|
169
|
+
print(f"Analyzing with Python {sys.version}")
|
|
170
|
+
# ... analysis code ...
|
|
171
|
+
|
|
172
|
+
windows-task:
|
|
173
|
+
env: powershell
|
|
174
|
+
cmd: |
|
|
175
|
+
Compress-Archive -Path dist/* -DestinationPath package.zip
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
**Environment resolution priority:**
|
|
179
|
+
1. CLI override: `tt --env python build`
|
|
180
|
+
2. Task's `env` field
|
|
181
|
+
3. Recipe's `default` environment
|
|
182
|
+
4. Platform default (bash on Unix, cmd on Windows)
|
|
183
|
+
|
|
184
|
+
**Platform defaults** when no environments are configured:
|
|
185
|
+
- **Unix/macOS**: bash with `-c` args
|
|
186
|
+
- **Windows**: cmd with `/c` args
|
|
187
|
+
|
|
125
188
|
### Parameterised Tasks
|
|
126
189
|
|
|
127
190
|
Tasks can accept arguments with optional defaults:
|
|
@@ -188,12 +251,19 @@ Input and output patterns support standard glob syntax:
|
|
|
188
251
|
|
|
189
252
|
### How State Works
|
|
190
253
|
|
|
191
|
-
Each task is identified by a hash of its definition
|
|
254
|
+
Each task is identified by a hash of its definition. The hash includes:
|
|
192
255
|
|
|
256
|
+
- Command to execute
|
|
257
|
+
- Output patterns
|
|
258
|
+
- Working directory
|
|
259
|
+
- Argument definitions
|
|
260
|
+
- Execution environment
|
|
261
|
+
|
|
262
|
+
State tracks:
|
|
193
263
|
- When the task last ran
|
|
194
264
|
- Timestamps of input files at that time
|
|
195
265
|
|
|
196
|
-
Tasks are re-run when their definition changes
|
|
266
|
+
Tasks are re-run when their definition changes, inputs are newer than the last run, or the environment changes.
|
|
197
267
|
|
|
198
268
|
### What's Not In The Hash
|
|
199
269
|
|
|
@@ -208,6 +278,72 @@ Changes to these don't invalidate cached state:
|
|
|
208
278
|
|
|
209
279
|
At the start of each invocation, state is checked for invalid task hashes and non-existent ones are automatically removed. Delete a task from your recipe file and its state disappears the next time you run `tt <cmd>`
|
|
210
280
|
|
|
281
|
+
## Command-Line Options
|
|
282
|
+
|
|
283
|
+
Task Tree provides several command-line options for controlling task execution:
|
|
284
|
+
|
|
285
|
+
### Execution Control
|
|
286
|
+
|
|
287
|
+
```bash
|
|
288
|
+
# Force re-run (ignore freshness checks)
|
|
289
|
+
tt --force build
|
|
290
|
+
tt -f build
|
|
291
|
+
|
|
292
|
+
# Run only the specified task, skip dependencies (implies --force)
|
|
293
|
+
tt --only deploy
|
|
294
|
+
tt -o deploy
|
|
295
|
+
|
|
296
|
+
# Override environment for all tasks
|
|
297
|
+
tt --env python analyze
|
|
298
|
+
tt -e powershell build
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
### Information Commands
|
|
302
|
+
|
|
303
|
+
```bash
|
|
304
|
+
# List all available tasks
|
|
305
|
+
tt --list
|
|
306
|
+
tt -l
|
|
307
|
+
|
|
308
|
+
# Show detailed task definition
|
|
309
|
+
tt --show build
|
|
310
|
+
|
|
311
|
+
# Show dependency tree (without execution)
|
|
312
|
+
tt --tree deploy
|
|
313
|
+
|
|
314
|
+
# Show version
|
|
315
|
+
tt --version
|
|
316
|
+
tt -v
|
|
317
|
+
|
|
318
|
+
# Create a blank recipe file
|
|
319
|
+
tt --init
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
### State Management
|
|
323
|
+
|
|
324
|
+
```bash
|
|
325
|
+
# Remove state file (reset task cache)
|
|
326
|
+
tt --clean
|
|
327
|
+
tt --clean-state
|
|
328
|
+
tt --reset
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
### Common Workflows
|
|
332
|
+
|
|
333
|
+
```bash
|
|
334
|
+
# Fresh build of everything
|
|
335
|
+
tt --force build
|
|
336
|
+
|
|
337
|
+
# Run a task without rebuilding dependencies
|
|
338
|
+
tt --only test
|
|
339
|
+
|
|
340
|
+
# Test with a different shell/environment
|
|
341
|
+
tt --env python test
|
|
342
|
+
|
|
343
|
+
# Force rebuild and deploy
|
|
344
|
+
tt --force deploy production
|
|
345
|
+
```
|
|
346
|
+
|
|
211
347
|
## Example: Full Build Pipeline
|
|
212
348
|
|
|
213
349
|
```yaml
|