tasktree 0.0.1__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.1/.github/workflows/release.yml +62 -0
- tasktree-0.0.1/.github/workflows/test.yml +61 -0
- tasktree-0.0.1/.gitignore +161 -0
- tasktree-0.0.1/CLAUDE.md +69 -0
- tasktree-0.0.1/PKG-INFO +387 -0
- tasktree-0.0.1/README.md +373 -0
- tasktree-0.0.1/example/source.txt +1 -0
- tasktree-0.0.1/example/tasktree.yaml +15 -0
- tasktree-0.0.1/pyproject.toml +29 -0
- tasktree-0.0.1/src/__init__.py +0 -0
- tasktree-0.0.1/src/tasktree/__init__.py +42 -0
- tasktree-0.0.1/src/tasktree/cli.py +502 -0
- tasktree-0.0.1/src/tasktree/executor.py +365 -0
- tasktree-0.0.1/src/tasktree/graph.py +139 -0
- tasktree-0.0.1/src/tasktree/hasher.py +74 -0
- tasktree-0.0.1/src/tasktree/parser.py +300 -0
- tasktree-0.0.1/src/tasktree/state.py +119 -0
- tasktree-0.0.1/src/tasktree/tasks.py +8 -0
- tasktree-0.0.1/src/tasktree/types.py +130 -0
- tasktree-0.0.1/tasktree.yaml +48 -0
- tasktree-0.0.1/tests/integration/test_clean_state.py +162 -0
- tasktree-0.0.1/tests/integration/test_cli_options.py +210 -0
- tasktree-0.0.1/tests/integration/test_missing_outputs.py +65 -0
- tasktree-0.0.1/tests/integration/test_nested_imports.py +246 -0
- tasktree-0.0.1/tests/unit/test_executor.py +358 -0
- tasktree-0.0.1/tests/unit/test_graph.py +99 -0
- tasktree-0.0.1/tests/unit/test_hasher.py +76 -0
- tasktree-0.0.1/tests/unit/test_parser.py +763 -0
- tasktree-0.0.1/tests/unit/test_state.py +85 -0
- tasktree-0.0.1/tests/unit/test_tasks.py +18 -0
- tasktree-0.0.1/uv.lock +226 -0
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
name: Release to PyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- 'v*.*.*' # Triggers on tags like v1.0.0, v1.2.3, etc.
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
release:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
permissions:
|
|
12
|
+
contents: write # For creating GitHub release
|
|
13
|
+
id-token: write # For trusted publishing to PyPI
|
|
14
|
+
|
|
15
|
+
steps:
|
|
16
|
+
- name: Checkout code
|
|
17
|
+
uses: actions/checkout@v4
|
|
18
|
+
with:
|
|
19
|
+
fetch-depth: 0 # Full history for proper version detection
|
|
20
|
+
|
|
21
|
+
- name: Set up Python
|
|
22
|
+
uses: actions/setup-python@v5
|
|
23
|
+
with:
|
|
24
|
+
python-version: '3.11'
|
|
25
|
+
|
|
26
|
+
- name: Install uv
|
|
27
|
+
uses: astral-sh/setup-uv@v4
|
|
28
|
+
|
|
29
|
+
- name: Extract version from tag
|
|
30
|
+
id: get_version
|
|
31
|
+
run: |
|
|
32
|
+
VERSION=${GITHUB_REF#refs/tags/v}
|
|
33
|
+
echo "VERSION=$VERSION" >> $GITHUB_OUTPUT
|
|
34
|
+
echo "Releasing version $VERSION"
|
|
35
|
+
|
|
36
|
+
- name: Update version in pyproject.toml
|
|
37
|
+
run: |
|
|
38
|
+
sed -i 's/version = ".*"/version = "${{ steps.get_version.outputs.VERSION }}"/' pyproject.toml
|
|
39
|
+
cat pyproject.toml | grep version
|
|
40
|
+
|
|
41
|
+
- name: Build package
|
|
42
|
+
run: uv build
|
|
43
|
+
|
|
44
|
+
- name: Verify wheel contents
|
|
45
|
+
run: |
|
|
46
|
+
unzip -l dist/*.whl
|
|
47
|
+
ls -lh dist/
|
|
48
|
+
|
|
49
|
+
- name: Create GitHub Release
|
|
50
|
+
uses: softprops/action-gh-release@v2
|
|
51
|
+
with:
|
|
52
|
+
files: dist/*
|
|
53
|
+
generate_release_notes: true
|
|
54
|
+
draft: false
|
|
55
|
+
prerelease: false
|
|
56
|
+
|
|
57
|
+
- name: Publish to PyPI
|
|
58
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
59
|
+
with:
|
|
60
|
+
# Uses trusted publisher authentication (no API token needed)
|
|
61
|
+
# Configure at https://pypi.org/manage/account/publishing/
|
|
62
|
+
packages-dir: dist/
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
name: Tests
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [ main, develop ]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [ main, develop ]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
test:
|
|
11
|
+
runs-on: ${{ matrix.os }}
|
|
12
|
+
strategy:
|
|
13
|
+
fail-fast: false
|
|
14
|
+
matrix:
|
|
15
|
+
os: [ubuntu-latest, macos-latest, windows-latest]
|
|
16
|
+
python-version: ['3.11', '3.12']
|
|
17
|
+
|
|
18
|
+
steps:
|
|
19
|
+
- uses: actions/checkout@v4
|
|
20
|
+
|
|
21
|
+
- name: Set up Python ${{ matrix.python-version }}
|
|
22
|
+
uses: actions/setup-python@v5
|
|
23
|
+
with:
|
|
24
|
+
python-version: ${{ matrix.python-version }}
|
|
25
|
+
|
|
26
|
+
- name: Install uv
|
|
27
|
+
uses: astral-sh/setup-uv@v4
|
|
28
|
+
|
|
29
|
+
- name: Install dependencies
|
|
30
|
+
run: |
|
|
31
|
+
uv pip install --system -e ".[dev]"
|
|
32
|
+
|
|
33
|
+
- name: Run tests
|
|
34
|
+
run: |
|
|
35
|
+
python -m pytest tests/ -v --tb=short
|
|
36
|
+
|
|
37
|
+
- name: Test CLI commands
|
|
38
|
+
run: |
|
|
39
|
+
python -m tasktree.cli --help
|
|
40
|
+
python -m tasktree.cli --list || true
|
|
41
|
+
|
|
42
|
+
lint:
|
|
43
|
+
runs-on: ubuntu-latest
|
|
44
|
+
steps:
|
|
45
|
+
- uses: actions/checkout@v4
|
|
46
|
+
|
|
47
|
+
- name: Set up Python
|
|
48
|
+
uses: actions/setup-python@v5
|
|
49
|
+
with:
|
|
50
|
+
python-version: '3.12'
|
|
51
|
+
|
|
52
|
+
- name: Install uv
|
|
53
|
+
uses: astral-sh/setup-uv@v4
|
|
54
|
+
|
|
55
|
+
- name: Install dependencies
|
|
56
|
+
run: |
|
|
57
|
+
uv pip install --system -e ".[dev]"
|
|
58
|
+
|
|
59
|
+
- name: Check code can be imported
|
|
60
|
+
run: |
|
|
61
|
+
python -c "from tasktree import Executor, Recipe, Task; print('Import successful')"
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
# Byte-compiled / optimized / DLL files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
|
|
6
|
+
# C extensions
|
|
7
|
+
*.so
|
|
8
|
+
|
|
9
|
+
# Distribution / packaging
|
|
10
|
+
.Python
|
|
11
|
+
build/
|
|
12
|
+
develop-eggs/
|
|
13
|
+
dist/
|
|
14
|
+
downloads/
|
|
15
|
+
eggs/
|
|
16
|
+
.eggs/
|
|
17
|
+
lib/
|
|
18
|
+
lib64/
|
|
19
|
+
parts/
|
|
20
|
+
sdist/
|
|
21
|
+
var/
|
|
22
|
+
wheels/
|
|
23
|
+
share/python-wheels/
|
|
24
|
+
*.egg-info/
|
|
25
|
+
.installed.cfg
|
|
26
|
+
*.egg
|
|
27
|
+
MANIFEST
|
|
28
|
+
|
|
29
|
+
# PyInstaller
|
|
30
|
+
*.manifest
|
|
31
|
+
*.spec
|
|
32
|
+
|
|
33
|
+
# Installer logs
|
|
34
|
+
pip-log.txt
|
|
35
|
+
pip-delete-this-directory.txt
|
|
36
|
+
|
|
37
|
+
# Unit test / coverage reports
|
|
38
|
+
htmlcov/
|
|
39
|
+
.tox/
|
|
40
|
+
.nox/
|
|
41
|
+
.coverage
|
|
42
|
+
.coverage.*
|
|
43
|
+
.cache
|
|
44
|
+
nosetests.xml
|
|
45
|
+
coverage.xml
|
|
46
|
+
*.cover
|
|
47
|
+
*.py,cover
|
|
48
|
+
.hypothesis/
|
|
49
|
+
.pytest_cache/
|
|
50
|
+
cover/
|
|
51
|
+
|
|
52
|
+
# Translations
|
|
53
|
+
*.mo
|
|
54
|
+
*.pot
|
|
55
|
+
|
|
56
|
+
# Django stuff:
|
|
57
|
+
*.log
|
|
58
|
+
local_settings.py
|
|
59
|
+
db.sqlite3
|
|
60
|
+
db.sqlite3-journal
|
|
61
|
+
|
|
62
|
+
# Flask stuff:
|
|
63
|
+
instance/
|
|
64
|
+
.webassets-cache
|
|
65
|
+
|
|
66
|
+
# Scrapy stuff:
|
|
67
|
+
.scrapy
|
|
68
|
+
|
|
69
|
+
# Sphinx documentation
|
|
70
|
+
docs/_build/
|
|
71
|
+
|
|
72
|
+
# PyBuilder
|
|
73
|
+
.pybuilder/
|
|
74
|
+
target/
|
|
75
|
+
|
|
76
|
+
# Jupyter Notebook
|
|
77
|
+
.ipynb_checkpoints
|
|
78
|
+
|
|
79
|
+
# IPython
|
|
80
|
+
profile_default/
|
|
81
|
+
ipython_config.py
|
|
82
|
+
|
|
83
|
+
# pyenv
|
|
84
|
+
.python-version
|
|
85
|
+
|
|
86
|
+
# pipenv
|
|
87
|
+
Pipfile.lock
|
|
88
|
+
|
|
89
|
+
# PEP 582
|
|
90
|
+
__pypackages__/
|
|
91
|
+
|
|
92
|
+
# Celery stuff
|
|
93
|
+
celerybeat-schedule
|
|
94
|
+
celerybeat.pid
|
|
95
|
+
|
|
96
|
+
# SageMath parsed files
|
|
97
|
+
*.sage.py
|
|
98
|
+
|
|
99
|
+
# Environments
|
|
100
|
+
.env
|
|
101
|
+
.venv
|
|
102
|
+
env/
|
|
103
|
+
venv/
|
|
104
|
+
ENV/
|
|
105
|
+
env.bak/
|
|
106
|
+
venv.bak/
|
|
107
|
+
|
|
108
|
+
# Spyder project settings
|
|
109
|
+
.spyderproject
|
|
110
|
+
.spyproject
|
|
111
|
+
|
|
112
|
+
# Rope project settings
|
|
113
|
+
.ropeproject
|
|
114
|
+
|
|
115
|
+
# mkdocs documentation
|
|
116
|
+
/site
|
|
117
|
+
|
|
118
|
+
# mypy
|
|
119
|
+
.mypy_cache/
|
|
120
|
+
.dmypy.json
|
|
121
|
+
dmypy.json
|
|
122
|
+
|
|
123
|
+
# Pyre type checker
|
|
124
|
+
.pyre/
|
|
125
|
+
|
|
126
|
+
# pytype static type analyzer
|
|
127
|
+
.pytype/
|
|
128
|
+
|
|
129
|
+
# Cython debug symbols
|
|
130
|
+
cython_debug/
|
|
131
|
+
|
|
132
|
+
# IDEs
|
|
133
|
+
.idea/
|
|
134
|
+
.vscode/
|
|
135
|
+
*.swp
|
|
136
|
+
*.swo
|
|
137
|
+
*~
|
|
138
|
+
.project
|
|
139
|
+
.pydevproject
|
|
140
|
+
.settings/
|
|
141
|
+
|
|
142
|
+
# OS
|
|
143
|
+
.DS_Store
|
|
144
|
+
.DS_Store?
|
|
145
|
+
._*
|
|
146
|
+
.Spotlight-V100
|
|
147
|
+
.Trashes
|
|
148
|
+
ehthumbs.db
|
|
149
|
+
Thumbs.db
|
|
150
|
+
Desktop.ini
|
|
151
|
+
|
|
152
|
+
# Task Tree specific
|
|
153
|
+
.tasktree-state
|
|
154
|
+
|
|
155
|
+
# Example outputs (keep source files but ignore generated outputs)
|
|
156
|
+
example/output.txt
|
|
157
|
+
example/archive.tar.gz
|
|
158
|
+
example/.tasktree-state
|
|
159
|
+
|
|
160
|
+
# UV lock file (optional - some prefer to commit this)
|
|
161
|
+
# uv.lock
|
tasktree-0.0.1/CLAUDE.md
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
4
|
+
|
|
5
|
+
## Project Overview
|
|
6
|
+
|
|
7
|
+
Task Tree (tt) is a task automation tool that combines simple command execution with intelligent dependency tracking and incremental execution. The project is a Python application built with a focus on:
|
|
8
|
+
|
|
9
|
+
- **Intelligent incremental execution**: Tasks only run when necessary based on input changes, dependency updates, or task definition changes
|
|
10
|
+
- **YAML-based task definition**: Tasks are defined in `tasktree.yaml` or `tt.yaml` files with dependencies, inputs, outputs, and commands
|
|
11
|
+
- **Automatic input inheritance**: Tasks automatically inherit inputs from dependencies
|
|
12
|
+
- **Parameterized tasks**: Tasks can accept typed arguments with defaults
|
|
13
|
+
- **File imports**: Task definitions can be split across multiple files and namespaced
|
|
14
|
+
|
|
15
|
+
## Architecture
|
|
16
|
+
|
|
17
|
+
### Core Components
|
|
18
|
+
|
|
19
|
+
- **`src/tasktree/tasks.py`**: Core task execution logic using subprocess to run shell commands
|
|
20
|
+
- **`src/tasktree/cli.py`**: Command-line interface (currently minimal)
|
|
21
|
+
- **`main.py`**: Entry point for the application
|
|
22
|
+
- **`tests/unit/test_tasks.py`**: Unit tests using Python's unittest framework
|
|
23
|
+
|
|
24
|
+
### Key Dependencies
|
|
25
|
+
|
|
26
|
+
- **PyYAML**: For recipe parsing
|
|
27
|
+
- **Typer, Click, Rich**: For CLI (mentioned in README but not yet implemented)
|
|
28
|
+
- **graphlib.TopologicalSorter**: For dependency resolution
|
|
29
|
+
- **pathlib**: For file operations and glob expansion
|
|
30
|
+
|
|
31
|
+
## Development Commands
|
|
32
|
+
|
|
33
|
+
### Testing
|
|
34
|
+
```bash
|
|
35
|
+
python -m pytest tests/
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### Running the Application
|
|
39
|
+
```bash
|
|
40
|
+
python main.py
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### Package Management
|
|
44
|
+
This project uses `uv` for dependency management (indicated by `uv.lock` file).
|
|
45
|
+
|
|
46
|
+
## State Management
|
|
47
|
+
|
|
48
|
+
The application uses a `.tasktree-state` file at the project root to track:
|
|
49
|
+
- When tasks last ran
|
|
50
|
+
- Timestamps of input files at execution time
|
|
51
|
+
- Task hashes based on command, outputs, and working directory
|
|
52
|
+
|
|
53
|
+
## Testing Approach
|
|
54
|
+
|
|
55
|
+
The project uses Python's built-in `unittest` framework with mocking via `unittest.mock`. Tests focus on verifying subprocess calls for task execution.
|
|
56
|
+
|
|
57
|
+
## Task Definition Format
|
|
58
|
+
|
|
59
|
+
Tasks are defined in YAML with the following structure:
|
|
60
|
+
```yaml
|
|
61
|
+
task-name:
|
|
62
|
+
desc: Description (optional)
|
|
63
|
+
deps: [dependency-tasks]
|
|
64
|
+
inputs: [glob-patterns]
|
|
65
|
+
outputs: [glob-patterns]
|
|
66
|
+
working_dir: execution-directory
|
|
67
|
+
args: [typed-parameters]
|
|
68
|
+
cmd: shell-command
|
|
69
|
+
```
|