tasktree 0.0.18__tar.gz → 0.0.19__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.19/.github/ISSUE_TEMPLATES/bug_report.yml +75 -0
- tasktree-0.0.19/.github/ISSUE_TEMPLATES/feature_request.yml +59 -0
- {tasktree-0.0.18 → tasktree-0.0.19}/.github/workflows/claude-code-review.yml +2 -0
- {tasktree-0.0.18 → tasktree-0.0.19}/PKG-INFO +217 -1
- {tasktree-0.0.18 → tasktree-0.0.19}/README.md +216 -0
- {tasktree-0.0.18 → tasktree-0.0.19}/pyproject.toml +1 -1
- {tasktree-0.0.18 → tasktree-0.0.19}/schema/README.md +6 -2
- {tasktree-0.0.18 → tasktree-0.0.19}/schema/tasktree-schema.json +53 -7
- {tasktree-0.0.18 → tasktree-0.0.19}/src/tasktree/__init__.py +2 -0
- {tasktree-0.0.18 → tasktree-0.0.19}/src/tasktree/cli.py +21 -5
- {tasktree-0.0.18 → tasktree-0.0.19}/src/tasktree/executor.py +28 -2
- {tasktree-0.0.18 → tasktree-0.0.19}/src/tasktree/graph.py +116 -1
- {tasktree-0.0.18 → tasktree-0.0.19}/src/tasktree/hasher.py +32 -3
- {tasktree-0.0.18 → tasktree-0.0.19}/src/tasktree/parser.py +128 -14
- {tasktree-0.0.18 → tasktree-0.0.19}/src/tasktree/substitution.py +82 -0
- {tasktree-0.0.18 → tasktree-0.0.19}/tests/integration/test_builtin_variables.py +0 -8
- tasktree-0.0.19/tests/integration/test_dependency_outputs.py +313 -0
- tasktree-0.0.19/tests/integration/test_private_tasks_execution.py +264 -0
- {tasktree-0.0.18 → tasktree-0.0.19}/tests/unit/test_list_formatting.py +61 -0
- {tasktree-0.0.18 → tasktree-0.0.19}/tests/unit/test_parser.py +269 -0
- tasktree-0.0.19/tests/unit/test_private_tasks.py +141 -0
- {tasktree-0.0.18 → tasktree-0.0.19}/tests/unit/test_substitution.py +203 -0
- {tasktree-0.0.18 → tasktree-0.0.19}/.claude/settings.local.json +0 -0
- {tasktree-0.0.18 → tasktree-0.0.19}/.github/workflows/claude.yml +0 -0
- {tasktree-0.0.18 → tasktree-0.0.19}/.github/workflows/release.yml +0 -0
- {tasktree-0.0.18 → tasktree-0.0.19}/.github/workflows/test.yml +0 -0
- {tasktree-0.0.18 → tasktree-0.0.19}/.github/workflows/validate-pipx-install.yml +0 -0
- {tasktree-0.0.18 → tasktree-0.0.19}/.gitignore +0 -0
- {tasktree-0.0.18 → tasktree-0.0.19}/.python-version +0 -0
- {tasktree-0.0.18 → tasktree-0.0.19}/CLAUDE.md +0 -0
- {tasktree-0.0.18 → tasktree-0.0.19}/example/source.txt +0 -0
- {tasktree-0.0.18 → tasktree-0.0.19}/example/tasktree.yaml +0 -0
- {tasktree-0.0.18 → tasktree-0.0.19}/schema/vscode-settings-snippet.json +0 -0
- {tasktree-0.0.18 → tasktree-0.0.19}/src/__init__.py +0 -0
- {tasktree-0.0.18 → tasktree-0.0.19}/src/tasktree/docker.py +0 -0
- {tasktree-0.0.18 → tasktree-0.0.19}/src/tasktree/state.py +0 -0
- {tasktree-0.0.18 → tasktree-0.0.19}/src/tasktree/types.py +0 -0
- {tasktree-0.0.18 → tasktree-0.0.19}/tasktree.yaml +0 -0
- {tasktree-0.0.18 → tasktree-0.0.19}/tests/e2e/__init__.py +0 -0
- {tasktree-0.0.18 → tasktree-0.0.19}/tests/e2e/test_docker_basic.py +0 -0
- {tasktree-0.0.18 → tasktree-0.0.19}/tests/e2e/test_docker_environment.py +0 -0
- {tasktree-0.0.18 → tasktree-0.0.19}/tests/e2e/test_docker_ownership.py +0 -0
- {tasktree-0.0.18 → tasktree-0.0.19}/tests/e2e/test_docker_volumes.py +0 -0
- {tasktree-0.0.18 → tasktree-0.0.19}/tests/e2e/test_non_docker.py +0 -0
- {tasktree-0.0.18 → tasktree-0.0.19}/tests/integration/test_arg_choices.py +0 -0
- {tasktree-0.0.18 → tasktree-0.0.19}/tests/integration/test_arg_min_max.py +0 -0
- {tasktree-0.0.18 → tasktree-0.0.19}/tests/integration/test_clean_state.py +0 -0
- {tasktree-0.0.18 → tasktree-0.0.19}/tests/integration/test_cli_options.py +0 -0
- {tasktree-0.0.18 → tasktree-0.0.19}/tests/integration/test_dependency_execution.py +0 -0
- {tasktree-0.0.18 → tasktree-0.0.19}/tests/integration/test_docker_build_args.py +0 -0
- {tasktree-0.0.18 → tasktree-0.0.19}/tests/integration/test_end_to_end.py +0 -0
- {tasktree-0.0.18 → tasktree-0.0.19}/tests/integration/test_exported_args.py +0 -0
- {tasktree-0.0.18 → tasktree-0.0.19}/tests/integration/test_input_detection.py +0 -0
- {tasktree-0.0.18 → tasktree-0.0.19}/tests/integration/test_missing_outputs.py +0 -0
- {tasktree-0.0.18 → tasktree-0.0.19}/tests/integration/test_nested_imports.py +0 -0
- {tasktree-0.0.18 → tasktree-0.0.19}/tests/integration/test_parameterized_dependencies.yaml +0 -0
- {tasktree-0.0.18 → tasktree-0.0.19}/tests/integration/test_parameterized_deps_execution.py +0 -0
- {tasktree-0.0.18 → tasktree-0.0.19}/tests/integration/test_parameterized_deps_templates.py +0 -0
- {tasktree-0.0.18 → tasktree-0.0.19}/tests/integration/test_state_persistence.py +0 -0
- {tasktree-0.0.18 → tasktree-0.0.19}/tests/integration/test_variables.py +0 -0
- {tasktree-0.0.18 → tasktree-0.0.19}/tests/integration/test_working_directory.py +0 -0
- {tasktree-0.0.18 → tasktree-0.0.19}/tests/unit/test_cli.py +0 -0
- {tasktree-0.0.18 → tasktree-0.0.19}/tests/unit/test_dependency_parsing.py +0 -0
- {tasktree-0.0.18 → tasktree-0.0.19}/tests/unit/test_docker.py +0 -0
- {tasktree-0.0.18 → tasktree-0.0.19}/tests/unit/test_environment_tracking.py +0 -0
- {tasktree-0.0.18 → tasktree-0.0.19}/tests/unit/test_executor.py +0 -0
- {tasktree-0.0.18 → tasktree-0.0.19}/tests/unit/test_graph.py +0 -0
- {tasktree-0.0.18 → tasktree-0.0.19}/tests/unit/test_hasher.py +0 -0
- {tasktree-0.0.18 → tasktree-0.0.19}/tests/unit/test_parameterized_graph.py +0 -0
- {tasktree-0.0.18 → tasktree-0.0.19}/tests/unit/test_state.py +0 -0
- {tasktree-0.0.18 → tasktree-0.0.19}/tests/unit/test_types.py +0 -0
- {tasktree-0.0.18 → tasktree-0.0.19}/uv.lock +0 -0
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
name: Bug report
|
|
2
|
+
description: Create a report to help us improve
|
|
3
|
+
title: "[BUG] <describe bug>"
|
|
4
|
+
labels: [bug]
|
|
5
|
+
assignees: []
|
|
6
|
+
body:
|
|
7
|
+
- type: markdown
|
|
8
|
+
attributes:
|
|
9
|
+
value: |
|
|
10
|
+
**Please fill out as much of this form as possible. Incomplete reports may slow triage.**
|
|
11
|
+
|
|
12
|
+
- type: input
|
|
13
|
+
id: summary
|
|
14
|
+
attributes:
|
|
15
|
+
label: Bug Summary
|
|
16
|
+
description: Short summary of the bug (1-2 sentences).
|
|
17
|
+
placeholder: "Unexpected crash when saving file"
|
|
18
|
+
|
|
19
|
+
- type: textarea
|
|
20
|
+
id: steps
|
|
21
|
+
attributes:
|
|
22
|
+
label: Steps to Reproduce
|
|
23
|
+
description: Step-by-step description to reproduce the bug.
|
|
24
|
+
placeholder: |
|
|
25
|
+
1. Open the application
|
|
26
|
+
2. Click on "Save"
|
|
27
|
+
3. Observe the error
|
|
28
|
+
|
|
29
|
+
- type: textarea
|
|
30
|
+
id: expected
|
|
31
|
+
attributes:
|
|
32
|
+
label: Expected Behavior
|
|
33
|
+
description: What did you expect to happen?
|
|
34
|
+
placeholder: App should save the file without errors.
|
|
35
|
+
|
|
36
|
+
- type: textarea
|
|
37
|
+
id: actual
|
|
38
|
+
attributes:
|
|
39
|
+
label: Actual Behavior
|
|
40
|
+
description: What actually happens?
|
|
41
|
+
placeholder: "Error dialog appears: 'Failed to save'."
|
|
42
|
+
|
|
43
|
+
- type: dropdown
|
|
44
|
+
id: system
|
|
45
|
+
attributes:
|
|
46
|
+
label: Environment
|
|
47
|
+
multiple: true
|
|
48
|
+
options:
|
|
49
|
+
- Linux (Debian-based)
|
|
50
|
+
- Linux (other)
|
|
51
|
+
- Windows
|
|
52
|
+
- macOS
|
|
53
|
+
- Other (please describe below)
|
|
54
|
+
description: Select all platforms where this bug occurs.
|
|
55
|
+
|
|
56
|
+
- type: input
|
|
57
|
+
id: version
|
|
58
|
+
attributes:
|
|
59
|
+
label: Version(s)
|
|
60
|
+
description: App and/or OS version numbers (paste output, e.g. `git describe`, `uname -a`, etc.)
|
|
61
|
+
placeholder: "v1.2.3, Debian 12.4, kernel 6.1.0..."
|
|
62
|
+
|
|
63
|
+
- type: textarea
|
|
64
|
+
id: logs
|
|
65
|
+
attributes:
|
|
66
|
+
label: Relevant Logs/Backtrace
|
|
67
|
+
description: Paste relevant logs, stack traces, or error messages. Use triple backticks for code.
|
|
68
|
+
render: shell
|
|
69
|
+
|
|
70
|
+
- type: textarea
|
|
71
|
+
id: extra
|
|
72
|
+
attributes:
|
|
73
|
+
label: Additional Context
|
|
74
|
+
description: Anything else useful for diagnosis? (Configurations, screenshots, external resources, etc.)
|
|
75
|
+
placeholder: "N/A"
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
name: Feature request
|
|
2
|
+
description: Suggest a new feature or improvement for this project
|
|
3
|
+
title: "[Feature] <concise feature title>"
|
|
4
|
+
labels: [enhancement]
|
|
5
|
+
assignees: []
|
|
6
|
+
body:
|
|
7
|
+
- type: markdown
|
|
8
|
+
attributes:
|
|
9
|
+
value: |
|
|
10
|
+
**Thanks for suggesting an improvement! Please provide as much context as possible.**
|
|
11
|
+
|
|
12
|
+
- type: input
|
|
13
|
+
id: summary
|
|
14
|
+
attributes:
|
|
15
|
+
label: Feature Summary
|
|
16
|
+
description: Short, high-level summary of the requested feature.
|
|
17
|
+
placeholder: "Add support for IPv6 packet inspection"
|
|
18
|
+
|
|
19
|
+
- type: textarea
|
|
20
|
+
id: motivation
|
|
21
|
+
attributes:
|
|
22
|
+
label: Motivation & Use Case
|
|
23
|
+
description: What problem does this solve? Who benefits? Why is this needed?
|
|
24
|
+
placeholder: |
|
|
25
|
+
Currently, only IPv4 is supported in the firewall module. Many environments use IPv6 and need equivalent inspection features.
|
|
26
|
+
|
|
27
|
+
- type: textarea
|
|
28
|
+
id: description
|
|
29
|
+
attributes:
|
|
30
|
+
label: Feature Description & Requirements
|
|
31
|
+
description: Describe the change or new capability. List any requirements or constraints.
|
|
32
|
+
placeholder: |
|
|
33
|
+
- Support parsing and filtering of IPv6 packets in filter mode.
|
|
34
|
+
- Update UI to allow IPv6 rule specification.
|
|
35
|
+
- Follow current module design patterns.
|
|
36
|
+
|
|
37
|
+
- type: textarea
|
|
38
|
+
id: impact
|
|
39
|
+
attributes:
|
|
40
|
+
label: Impact/Alternatives
|
|
41
|
+
description: How does this improve the project? Are there workarounds or competing solutions?
|
|
42
|
+
placeholder: |
|
|
43
|
+
Improves feature parity with other products; current workaround requires separate external processing.
|
|
44
|
+
|
|
45
|
+
- type: textarea
|
|
46
|
+
id: implementation
|
|
47
|
+
attributes:
|
|
48
|
+
label: Implementation notes (optional)
|
|
49
|
+
description: If you have ideas about implementing this, list them here (API ideas, design notes, related RFCs, etc.)
|
|
50
|
+
placeholder: |
|
|
51
|
+
- May require libc updates (for older distros)
|
|
52
|
+
- Reference: RFC 8200
|
|
53
|
+
|
|
54
|
+
- type: textarea
|
|
55
|
+
id: extra
|
|
56
|
+
attributes:
|
|
57
|
+
label: Additional context
|
|
58
|
+
description: Add any other context, mockups, references, or screenshots here.
|
|
59
|
+
placeholder: "N/A"
|
|
@@ -48,6 +48,8 @@ jobs:
|
|
|
48
48
|
- Test coverage
|
|
49
49
|
|
|
50
50
|
Use the repository's CLAUDE.md for guidance on style and conventions. Be constructive and helpful in your feedback.
|
|
51
|
+
|
|
52
|
+
At the end of the review, create a tickbox list of the actions arising from the review, suitable for pasting into a comment for Claude Code to work on.
|
|
51
53
|
|
|
52
54
|
Use `gh pr comment` with your Bash tool to leave your review as a comment on the PR.
|
|
53
55
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: tasktree
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.19
|
|
4
4
|
Summary: A task automation tool with incremental execution
|
|
5
5
|
Requires-Python: >=3.11
|
|
6
6
|
Requires-Dist: click>=8.1.0
|
|
@@ -248,6 +248,7 @@ tasks:
|
|
|
248
248
|
outputs: [dist/binary] # Output files (glob patterns)
|
|
249
249
|
working_dir: subproject/ # Execution directory (default: project root)
|
|
250
250
|
env: bash-strict # Execution environment (optional)
|
|
251
|
+
private: false # Hide from --list output (default: false)
|
|
251
252
|
args: # Task parameters
|
|
252
253
|
- param1 # Simple argument
|
|
253
254
|
- param2: { type: path, default: "." } # With type and default
|
|
@@ -687,6 +688,185 @@ tasks:
|
|
|
687
688
|
cmd: echo "All tests passed"
|
|
688
689
|
```
|
|
689
690
|
|
|
691
|
+
### Dependency Output References
|
|
692
|
+
|
|
693
|
+
Tasks can reference named outputs from their dependencies, enabling dynamic workflows where build artifacts, generated filenames, and other values are passed between tasks.
|
|
694
|
+
|
|
695
|
+
**Named Outputs:**
|
|
696
|
+
|
|
697
|
+
Tasks can define outputs with names for easy referencing:
|
|
698
|
+
|
|
699
|
+
```yaml
|
|
700
|
+
tasks:
|
|
701
|
+
build:
|
|
702
|
+
outputs:
|
|
703
|
+
- bundle: "dist/app.js" # Named output
|
|
704
|
+
- sourcemap: "dist/app.js.map" # Named output
|
|
705
|
+
cmd: webpack build
|
|
706
|
+
|
|
707
|
+
deploy:
|
|
708
|
+
deps: [build]
|
|
709
|
+
cmd: |
|
|
710
|
+
echo "Deploying {{ dep.build.outputs.bundle }}"
|
|
711
|
+
scp {{ dep.build.outputs.bundle }} server:/var/www/
|
|
712
|
+
scp {{ dep.build.outputs.sourcemap }} server:/var/www/
|
|
713
|
+
```
|
|
714
|
+
|
|
715
|
+
**Syntax:**
|
|
716
|
+
|
|
717
|
+
- **Defining named outputs**: `outputs: [{ name: "path/to/file" }]`
|
|
718
|
+
- **Referencing outputs**: `{{ dep.task_name.outputs.output_name }}`
|
|
719
|
+
- **Mixed format**: Can combine named and anonymous outputs in the same task
|
|
720
|
+
|
|
721
|
+
**Examples:**
|
|
722
|
+
|
|
723
|
+
```yaml
|
|
724
|
+
tasks:
|
|
725
|
+
# Generate a config file
|
|
726
|
+
generate-config:
|
|
727
|
+
outputs:
|
|
728
|
+
- config: "build/config.json"
|
|
729
|
+
cmd: |
|
|
730
|
+
mkdir -p build
|
|
731
|
+
echo '{"version": "1.0.0"}' > build/config.json
|
|
732
|
+
|
|
733
|
+
# Compile using the generated config
|
|
734
|
+
compile:
|
|
735
|
+
deps: [generate-config]
|
|
736
|
+
outputs:
|
|
737
|
+
- binary: "build/app"
|
|
738
|
+
- symbols: "build/app.sym"
|
|
739
|
+
cmd: |
|
|
740
|
+
echo "Using config: {{ dep.generate-config.outputs.config }}"
|
|
741
|
+
gcc -o build/app src/*.c
|
|
742
|
+
|
|
743
|
+
# Package multiple dependency outputs
|
|
744
|
+
package:
|
|
745
|
+
deps: [compile]
|
|
746
|
+
outputs:
|
|
747
|
+
- archive: "dist/app.tar.gz"
|
|
748
|
+
cmd: |
|
|
749
|
+
mkdir -p dist
|
|
750
|
+
tar czf {{ dep.package.outputs.archive }} \
|
|
751
|
+
{{ dep.compile.outputs.binary }} \
|
|
752
|
+
{{ dep.compile.outputs.symbols }}
|
|
753
|
+
```
|
|
754
|
+
|
|
755
|
+
**Mixed Named and Anonymous Outputs:**
|
|
756
|
+
|
|
757
|
+
Tasks can have both named and anonymous outputs:
|
|
758
|
+
|
|
759
|
+
```yaml
|
|
760
|
+
tasks:
|
|
761
|
+
build:
|
|
762
|
+
outputs:
|
|
763
|
+
- binary: "build/app" # Named - can be referenced
|
|
764
|
+
- "build/app.debug" # Anonymous - tracked but not referenceable
|
|
765
|
+
- manifest: "build/manifest.json" # Named - can be referenced
|
|
766
|
+
cmd: make all
|
|
767
|
+
```
|
|
768
|
+
|
|
769
|
+
**Transitive References:**
|
|
770
|
+
|
|
771
|
+
Output references work across multiple levels of dependencies:
|
|
772
|
+
|
|
773
|
+
```yaml
|
|
774
|
+
tasks:
|
|
775
|
+
base:
|
|
776
|
+
outputs:
|
|
777
|
+
- lib: "out/libbase.a"
|
|
778
|
+
cmd: gcc -c base.c -o out/libbase.a
|
|
779
|
+
|
|
780
|
+
middleware:
|
|
781
|
+
deps: [base]
|
|
782
|
+
outputs:
|
|
783
|
+
- lib: "out/libmiddleware.a"
|
|
784
|
+
cmd: |
|
|
785
|
+
# Reference the base library
|
|
786
|
+
gcc -c middleware.c {{ dep.base.outputs.lib }} -o out/libmiddleware.a
|
|
787
|
+
|
|
788
|
+
app:
|
|
789
|
+
deps: [middleware]
|
|
790
|
+
cmd: |
|
|
791
|
+
# Reference middleware, which transitively used base
|
|
792
|
+
gcc main.c {{ dep.middleware.outputs.lib }} -o app
|
|
793
|
+
```
|
|
794
|
+
|
|
795
|
+
**Key Behaviors:**
|
|
796
|
+
|
|
797
|
+
- **Template resolution**: Output references are resolved during dependency graph planning (in topological order)
|
|
798
|
+
- **Fail-fast validation**: Errors are caught before execution begins
|
|
799
|
+
- **Clear error messages**: If an output name doesn't exist, you get a list of available named outputs
|
|
800
|
+
- **Backward compatible**: Existing anonymous outputs (`outputs: ["file.txt"]`) work unchanged
|
|
801
|
+
- **Automatic input tracking**: Named outputs are automatically tracked as implicit inputs for dependent tasks
|
|
802
|
+
|
|
803
|
+
**Error Messages:**
|
|
804
|
+
|
|
805
|
+
If you reference a non-existent output:
|
|
806
|
+
|
|
807
|
+
```yaml
|
|
808
|
+
tasks:
|
|
809
|
+
build:
|
|
810
|
+
outputs:
|
|
811
|
+
- bundle: "dist/app.js"
|
|
812
|
+
cmd: webpack build
|
|
813
|
+
|
|
814
|
+
deploy:
|
|
815
|
+
deps: [build]
|
|
816
|
+
cmd: echo "{{ dep.build.outputs.missing }}" # Error!
|
|
817
|
+
```
|
|
818
|
+
|
|
819
|
+
You'll get a clear error before execution:
|
|
820
|
+
|
|
821
|
+
```
|
|
822
|
+
Task 'deploy' references output 'missing' from task 'build',
|
|
823
|
+
but 'build' has no output named 'missing'.
|
|
824
|
+
Available named outputs in 'build': bundle
|
|
825
|
+
Hint: Define named outputs like: outputs: [{ missing: 'path/to/file' }]
|
|
826
|
+
```
|
|
827
|
+
|
|
828
|
+
**Use Cases:**
|
|
829
|
+
|
|
830
|
+
- **Dynamic artifact names**: Pass generated filenames between tasks
|
|
831
|
+
- **Build metadata**: Reference manifests, checksums, or version files
|
|
832
|
+
- **Multi-stage builds**: Chain compilation steps with specific output references
|
|
833
|
+
- **Deployment pipelines**: Reference exact artifacts to deploy
|
|
834
|
+
- **Configuration propagation**: Pass generated config files through build stages
|
|
835
|
+
|
|
836
|
+
|
|
837
|
+
### Private Tasks
|
|
838
|
+
|
|
839
|
+
Sometimes you may want to define helper tasks that are useful as dependencies but shouldn't be listed when users run `tt --list`. Mark these tasks as private:
|
|
840
|
+
|
|
841
|
+
```yaml
|
|
842
|
+
tasks:
|
|
843
|
+
# Private helper task - hidden from --list
|
|
844
|
+
setup-deps:
|
|
845
|
+
private: true
|
|
846
|
+
cmd: |
|
|
847
|
+
npm install
|
|
848
|
+
pip install -r requirements.txt
|
|
849
|
+
|
|
850
|
+
# Public task that uses the helper
|
|
851
|
+
build:
|
|
852
|
+
deps: [setup-deps]
|
|
853
|
+
cmd: npm run build
|
|
854
|
+
```
|
|
855
|
+
|
|
856
|
+
**Behavior:**
|
|
857
|
+
- `tt --list` shows only public tasks (`build` in this example)
|
|
858
|
+
- Private tasks can still be executed: `tt setup-deps` works
|
|
859
|
+
- Private tasks work normally as dependencies
|
|
860
|
+
- By default, all tasks are public (`private: false`)
|
|
861
|
+
|
|
862
|
+
**Use cases:**
|
|
863
|
+
- Internal helper tasks that shouldn't be run directly
|
|
864
|
+
- Implementation details you want to hide from users
|
|
865
|
+
- Shared setup tasks across multiple public tasks
|
|
866
|
+
|
|
867
|
+
Note that private tasks remain fully functional - they're only hidden from the list view. Users who know the task name can still execute it directly.
|
|
868
|
+
|
|
869
|
+
|
|
690
870
|
## Environment Variables
|
|
691
871
|
|
|
692
872
|
Task Tree supports reading environment variables in two ways:
|
|
@@ -1028,6 +1208,42 @@ At the start of each invocation, state is checked for invalid task hashes and no
|
|
|
1028
1208
|
|
|
1029
1209
|
Task Tree provides several command-line options for controlling task execution:
|
|
1030
1210
|
|
|
1211
|
+
### Recipe File Selection
|
|
1212
|
+
|
|
1213
|
+
Task Tree automatically discovers recipe files in the current directory and parent directories. You can also explicitly specify which file to use.
|
|
1214
|
+
|
|
1215
|
+
**Automatic Discovery:**
|
|
1216
|
+
|
|
1217
|
+
Task Tree searches for recipe files in the following order of preference:
|
|
1218
|
+
|
|
1219
|
+
1. **Standard recipe files** (searched first, in order):
|
|
1220
|
+
- `tasktree.yaml`
|
|
1221
|
+
- `tasktree.yml`
|
|
1222
|
+
- `tt.yaml`
|
|
1223
|
+
|
|
1224
|
+
2. **Import files** (searched only if no standard files found):
|
|
1225
|
+
- `*.tasks` files (e.g., `build.tasks`, `deploy.tasks`)
|
|
1226
|
+
|
|
1227
|
+
If multiple files of the same priority level exist in the same directory, Task Tree will report an error and ask you to specify which file to use with `--tasks`.
|
|
1228
|
+
|
|
1229
|
+
**Manual Selection:**
|
|
1230
|
+
|
|
1231
|
+
```bash
|
|
1232
|
+
# Specify a recipe file explicitly
|
|
1233
|
+
tt --tasks build.tasks build
|
|
1234
|
+
tt -T custom-recipe.yaml test
|
|
1235
|
+
|
|
1236
|
+
# Useful when you have multiple recipe files in the same directory
|
|
1237
|
+
tt --tasks ci.yaml deploy
|
|
1238
|
+
```
|
|
1239
|
+
|
|
1240
|
+
**File Search Behavior:**
|
|
1241
|
+
|
|
1242
|
+
- Task Tree searches **upward** from the current directory to find recipe files
|
|
1243
|
+
- **Standard recipe files** (`.yaml`/`.yml`) are always preferred over `*.tasks` files
|
|
1244
|
+
- `*.tasks` files are typically used for imports and are only used as main recipes if no standard files exist
|
|
1245
|
+
- The `.tasktree-state` file is created in the directory containing the recipe file
|
|
1246
|
+
|
|
1031
1247
|
### Execution Control
|
|
1032
1248
|
|
|
1033
1249
|
```bash
|
|
@@ -233,6 +233,7 @@ tasks:
|
|
|
233
233
|
outputs: [dist/binary] # Output files (glob patterns)
|
|
234
234
|
working_dir: subproject/ # Execution directory (default: project root)
|
|
235
235
|
env: bash-strict # Execution environment (optional)
|
|
236
|
+
private: false # Hide from --list output (default: false)
|
|
236
237
|
args: # Task parameters
|
|
237
238
|
- param1 # Simple argument
|
|
238
239
|
- param2: { type: path, default: "." } # With type and default
|
|
@@ -672,6 +673,185 @@ tasks:
|
|
|
672
673
|
cmd: echo "All tests passed"
|
|
673
674
|
```
|
|
674
675
|
|
|
676
|
+
### Dependency Output References
|
|
677
|
+
|
|
678
|
+
Tasks can reference named outputs from their dependencies, enabling dynamic workflows where build artifacts, generated filenames, and other values are passed between tasks.
|
|
679
|
+
|
|
680
|
+
**Named Outputs:**
|
|
681
|
+
|
|
682
|
+
Tasks can define outputs with names for easy referencing:
|
|
683
|
+
|
|
684
|
+
```yaml
|
|
685
|
+
tasks:
|
|
686
|
+
build:
|
|
687
|
+
outputs:
|
|
688
|
+
- bundle: "dist/app.js" # Named output
|
|
689
|
+
- sourcemap: "dist/app.js.map" # Named output
|
|
690
|
+
cmd: webpack build
|
|
691
|
+
|
|
692
|
+
deploy:
|
|
693
|
+
deps: [build]
|
|
694
|
+
cmd: |
|
|
695
|
+
echo "Deploying {{ dep.build.outputs.bundle }}"
|
|
696
|
+
scp {{ dep.build.outputs.bundle }} server:/var/www/
|
|
697
|
+
scp {{ dep.build.outputs.sourcemap }} server:/var/www/
|
|
698
|
+
```
|
|
699
|
+
|
|
700
|
+
**Syntax:**
|
|
701
|
+
|
|
702
|
+
- **Defining named outputs**: `outputs: [{ name: "path/to/file" }]`
|
|
703
|
+
- **Referencing outputs**: `{{ dep.task_name.outputs.output_name }}`
|
|
704
|
+
- **Mixed format**: Can combine named and anonymous outputs in the same task
|
|
705
|
+
|
|
706
|
+
**Examples:**
|
|
707
|
+
|
|
708
|
+
```yaml
|
|
709
|
+
tasks:
|
|
710
|
+
# Generate a config file
|
|
711
|
+
generate-config:
|
|
712
|
+
outputs:
|
|
713
|
+
- config: "build/config.json"
|
|
714
|
+
cmd: |
|
|
715
|
+
mkdir -p build
|
|
716
|
+
echo '{"version": "1.0.0"}' > build/config.json
|
|
717
|
+
|
|
718
|
+
# Compile using the generated config
|
|
719
|
+
compile:
|
|
720
|
+
deps: [generate-config]
|
|
721
|
+
outputs:
|
|
722
|
+
- binary: "build/app"
|
|
723
|
+
- symbols: "build/app.sym"
|
|
724
|
+
cmd: |
|
|
725
|
+
echo "Using config: {{ dep.generate-config.outputs.config }}"
|
|
726
|
+
gcc -o build/app src/*.c
|
|
727
|
+
|
|
728
|
+
# Package multiple dependency outputs
|
|
729
|
+
package:
|
|
730
|
+
deps: [compile]
|
|
731
|
+
outputs:
|
|
732
|
+
- archive: "dist/app.tar.gz"
|
|
733
|
+
cmd: |
|
|
734
|
+
mkdir -p dist
|
|
735
|
+
tar czf {{ dep.package.outputs.archive }} \
|
|
736
|
+
{{ dep.compile.outputs.binary }} \
|
|
737
|
+
{{ dep.compile.outputs.symbols }}
|
|
738
|
+
```
|
|
739
|
+
|
|
740
|
+
**Mixed Named and Anonymous Outputs:**
|
|
741
|
+
|
|
742
|
+
Tasks can have both named and anonymous outputs:
|
|
743
|
+
|
|
744
|
+
```yaml
|
|
745
|
+
tasks:
|
|
746
|
+
build:
|
|
747
|
+
outputs:
|
|
748
|
+
- binary: "build/app" # Named - can be referenced
|
|
749
|
+
- "build/app.debug" # Anonymous - tracked but not referenceable
|
|
750
|
+
- manifest: "build/manifest.json" # Named - can be referenced
|
|
751
|
+
cmd: make all
|
|
752
|
+
```
|
|
753
|
+
|
|
754
|
+
**Transitive References:**
|
|
755
|
+
|
|
756
|
+
Output references work across multiple levels of dependencies:
|
|
757
|
+
|
|
758
|
+
```yaml
|
|
759
|
+
tasks:
|
|
760
|
+
base:
|
|
761
|
+
outputs:
|
|
762
|
+
- lib: "out/libbase.a"
|
|
763
|
+
cmd: gcc -c base.c -o out/libbase.a
|
|
764
|
+
|
|
765
|
+
middleware:
|
|
766
|
+
deps: [base]
|
|
767
|
+
outputs:
|
|
768
|
+
- lib: "out/libmiddleware.a"
|
|
769
|
+
cmd: |
|
|
770
|
+
# Reference the base library
|
|
771
|
+
gcc -c middleware.c {{ dep.base.outputs.lib }} -o out/libmiddleware.a
|
|
772
|
+
|
|
773
|
+
app:
|
|
774
|
+
deps: [middleware]
|
|
775
|
+
cmd: |
|
|
776
|
+
# Reference middleware, which transitively used base
|
|
777
|
+
gcc main.c {{ dep.middleware.outputs.lib }} -o app
|
|
778
|
+
```
|
|
779
|
+
|
|
780
|
+
**Key Behaviors:**
|
|
781
|
+
|
|
782
|
+
- **Template resolution**: Output references are resolved during dependency graph planning (in topological order)
|
|
783
|
+
- **Fail-fast validation**: Errors are caught before execution begins
|
|
784
|
+
- **Clear error messages**: If an output name doesn't exist, you get a list of available named outputs
|
|
785
|
+
- **Backward compatible**: Existing anonymous outputs (`outputs: ["file.txt"]`) work unchanged
|
|
786
|
+
- **Automatic input tracking**: Named outputs are automatically tracked as implicit inputs for dependent tasks
|
|
787
|
+
|
|
788
|
+
**Error Messages:**
|
|
789
|
+
|
|
790
|
+
If you reference a non-existent output:
|
|
791
|
+
|
|
792
|
+
```yaml
|
|
793
|
+
tasks:
|
|
794
|
+
build:
|
|
795
|
+
outputs:
|
|
796
|
+
- bundle: "dist/app.js"
|
|
797
|
+
cmd: webpack build
|
|
798
|
+
|
|
799
|
+
deploy:
|
|
800
|
+
deps: [build]
|
|
801
|
+
cmd: echo "{{ dep.build.outputs.missing }}" # Error!
|
|
802
|
+
```
|
|
803
|
+
|
|
804
|
+
You'll get a clear error before execution:
|
|
805
|
+
|
|
806
|
+
```
|
|
807
|
+
Task 'deploy' references output 'missing' from task 'build',
|
|
808
|
+
but 'build' has no output named 'missing'.
|
|
809
|
+
Available named outputs in 'build': bundle
|
|
810
|
+
Hint: Define named outputs like: outputs: [{ missing: 'path/to/file' }]
|
|
811
|
+
```
|
|
812
|
+
|
|
813
|
+
**Use Cases:**
|
|
814
|
+
|
|
815
|
+
- **Dynamic artifact names**: Pass generated filenames between tasks
|
|
816
|
+
- **Build metadata**: Reference manifests, checksums, or version files
|
|
817
|
+
- **Multi-stage builds**: Chain compilation steps with specific output references
|
|
818
|
+
- **Deployment pipelines**: Reference exact artifacts to deploy
|
|
819
|
+
- **Configuration propagation**: Pass generated config files through build stages
|
|
820
|
+
|
|
821
|
+
|
|
822
|
+
### Private Tasks
|
|
823
|
+
|
|
824
|
+
Sometimes you may want to define helper tasks that are useful as dependencies but shouldn't be listed when users run `tt --list`. Mark these tasks as private:
|
|
825
|
+
|
|
826
|
+
```yaml
|
|
827
|
+
tasks:
|
|
828
|
+
# Private helper task - hidden from --list
|
|
829
|
+
setup-deps:
|
|
830
|
+
private: true
|
|
831
|
+
cmd: |
|
|
832
|
+
npm install
|
|
833
|
+
pip install -r requirements.txt
|
|
834
|
+
|
|
835
|
+
# Public task that uses the helper
|
|
836
|
+
build:
|
|
837
|
+
deps: [setup-deps]
|
|
838
|
+
cmd: npm run build
|
|
839
|
+
```
|
|
840
|
+
|
|
841
|
+
**Behavior:**
|
|
842
|
+
- `tt --list` shows only public tasks (`build` in this example)
|
|
843
|
+
- Private tasks can still be executed: `tt setup-deps` works
|
|
844
|
+
- Private tasks work normally as dependencies
|
|
845
|
+
- By default, all tasks are public (`private: false`)
|
|
846
|
+
|
|
847
|
+
**Use cases:**
|
|
848
|
+
- Internal helper tasks that shouldn't be run directly
|
|
849
|
+
- Implementation details you want to hide from users
|
|
850
|
+
- Shared setup tasks across multiple public tasks
|
|
851
|
+
|
|
852
|
+
Note that private tasks remain fully functional - they're only hidden from the list view. Users who know the task name can still execute it directly.
|
|
853
|
+
|
|
854
|
+
|
|
675
855
|
## Environment Variables
|
|
676
856
|
|
|
677
857
|
Task Tree supports reading environment variables in two ways:
|
|
@@ -1013,6 +1193,42 @@ At the start of each invocation, state is checked for invalid task hashes and no
|
|
|
1013
1193
|
|
|
1014
1194
|
Task Tree provides several command-line options for controlling task execution:
|
|
1015
1195
|
|
|
1196
|
+
### Recipe File Selection
|
|
1197
|
+
|
|
1198
|
+
Task Tree automatically discovers recipe files in the current directory and parent directories. You can also explicitly specify which file to use.
|
|
1199
|
+
|
|
1200
|
+
**Automatic Discovery:**
|
|
1201
|
+
|
|
1202
|
+
Task Tree searches for recipe files in the following order of preference:
|
|
1203
|
+
|
|
1204
|
+
1. **Standard recipe files** (searched first, in order):
|
|
1205
|
+
- `tasktree.yaml`
|
|
1206
|
+
- `tasktree.yml`
|
|
1207
|
+
- `tt.yaml`
|
|
1208
|
+
|
|
1209
|
+
2. **Import files** (searched only if no standard files found):
|
|
1210
|
+
- `*.tasks` files (e.g., `build.tasks`, `deploy.tasks`)
|
|
1211
|
+
|
|
1212
|
+
If multiple files of the same priority level exist in the same directory, Task Tree will report an error and ask you to specify which file to use with `--tasks`.
|
|
1213
|
+
|
|
1214
|
+
**Manual Selection:**
|
|
1215
|
+
|
|
1216
|
+
```bash
|
|
1217
|
+
# Specify a recipe file explicitly
|
|
1218
|
+
tt --tasks build.tasks build
|
|
1219
|
+
tt -T custom-recipe.yaml test
|
|
1220
|
+
|
|
1221
|
+
# Useful when you have multiple recipe files in the same directory
|
|
1222
|
+
tt --tasks ci.yaml deploy
|
|
1223
|
+
```
|
|
1224
|
+
|
|
1225
|
+
**File Search Behavior:**
|
|
1226
|
+
|
|
1227
|
+
- Task Tree searches **upward** from the current directory to find recipe files
|
|
1228
|
+
- **Standard recipe files** (`.yaml`/`.yml`) are always preferred over `*.tasks` files
|
|
1229
|
+
- `*.tasks` files are typically used for imports and are only used as main recipes if no standard files exist
|
|
1230
|
+
- The `.tasktree-state` file is created in the directory containing the recipe file
|
|
1231
|
+
|
|
1016
1232
|
### Execution Control
|
|
1017
1233
|
|
|
1018
1234
|
```bash
|
|
@@ -44,7 +44,7 @@ tasks:
|
|
|
44
44
|
- **Name**: Task Tree
|
|
45
45
|
- **Schema file**: Point to `schema/tasktree-schema.json`
|
|
46
46
|
- **Schema version**: JSON Schema version 7
|
|
47
|
-
- **File path pattern**: `tasktree.yaml` or `tt.
|
|
47
|
+
- **File path pattern**: `*.tasks`, `tasktree.yaml`, `tt.yaml`, `tasktree.yml` or `tt.yml`
|
|
48
48
|
|
|
49
49
|
### Command Line Validation
|
|
50
50
|
|
|
@@ -86,7 +86,9 @@ tasks:
|
|
|
86
86
|
desc: Build the application
|
|
87
87
|
deps: [base.setup]
|
|
88
88
|
inputs: ["src/**/*.rs"]
|
|
89
|
-
outputs:
|
|
89
|
+
outputs:
|
|
90
|
+
- binary: target/release/bin # Named output - can be referenced
|
|
91
|
+
- target/release/bin.map # Anonymous output
|
|
90
92
|
cmd: cargo build --release
|
|
91
93
|
|
|
92
94
|
test:
|
|
@@ -100,6 +102,8 @@ tasks:
|
|
|
100
102
|
args: [environment, region=us-west-1]
|
|
101
103
|
cmd: |
|
|
102
104
|
echo "Deploying to {{ arg.environment }} in {{ arg.region }}"
|
|
105
|
+
# Reference named output from dependency
|
|
106
|
+
scp {{ dep.build.outputs.binary }} server:/opt/
|
|
103
107
|
./deploy.sh {{ arg.environment }} {{ arg.region }}
|
|
104
108
|
```
|
|
105
109
|
|