tasktree 0.0.16__tar.gz → 0.0.18__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.
Files changed (67) hide show
  1. {tasktree-0.0.16 → tasktree-0.0.18}/PKG-INFO +1 -1
  2. {tasktree-0.0.16 → tasktree-0.0.18}/pyproject.toml +1 -1
  3. {tasktree-0.0.16 → tasktree-0.0.18}/src/tasktree/parser.py +46 -3
  4. {tasktree-0.0.16 → tasktree-0.0.18}/tasktree.yaml +1 -1
  5. {tasktree-0.0.16 → tasktree-0.0.18}/.claude/settings.local.json +0 -0
  6. {tasktree-0.0.16 → tasktree-0.0.18}/.github/workflows/claude-code-review.yml +0 -0
  7. {tasktree-0.0.16 → tasktree-0.0.18}/.github/workflows/claude.yml +0 -0
  8. {tasktree-0.0.16 → tasktree-0.0.18}/.github/workflows/release.yml +0 -0
  9. {tasktree-0.0.16 → tasktree-0.0.18}/.github/workflows/test.yml +0 -0
  10. {tasktree-0.0.16 → tasktree-0.0.18}/.github/workflows/validate-pipx-install.yml +0 -0
  11. {tasktree-0.0.16 → tasktree-0.0.18}/.gitignore +0 -0
  12. {tasktree-0.0.16 → tasktree-0.0.18}/.python-version +0 -0
  13. {tasktree-0.0.16 → tasktree-0.0.18}/CLAUDE.md +0 -0
  14. {tasktree-0.0.16 → tasktree-0.0.18}/README.md +0 -0
  15. {tasktree-0.0.16 → tasktree-0.0.18}/example/source.txt +0 -0
  16. {tasktree-0.0.16 → tasktree-0.0.18}/example/tasktree.yaml +0 -0
  17. {tasktree-0.0.16 → tasktree-0.0.18}/schema/README.md +0 -0
  18. {tasktree-0.0.16 → tasktree-0.0.18}/schema/tasktree-schema.json +0 -0
  19. {tasktree-0.0.16 → tasktree-0.0.18}/schema/vscode-settings-snippet.json +0 -0
  20. {tasktree-0.0.16 → tasktree-0.0.18}/src/__init__.py +0 -0
  21. {tasktree-0.0.16 → tasktree-0.0.18}/src/tasktree/__init__.py +0 -0
  22. {tasktree-0.0.16 → tasktree-0.0.18}/src/tasktree/cli.py +0 -0
  23. {tasktree-0.0.16 → tasktree-0.0.18}/src/tasktree/docker.py +0 -0
  24. {tasktree-0.0.16 → tasktree-0.0.18}/src/tasktree/executor.py +0 -0
  25. {tasktree-0.0.16 → tasktree-0.0.18}/src/tasktree/graph.py +0 -0
  26. {tasktree-0.0.16 → tasktree-0.0.18}/src/tasktree/hasher.py +0 -0
  27. {tasktree-0.0.16 → tasktree-0.0.18}/src/tasktree/state.py +0 -0
  28. {tasktree-0.0.16 → tasktree-0.0.18}/src/tasktree/substitution.py +0 -0
  29. {tasktree-0.0.16 → tasktree-0.0.18}/src/tasktree/types.py +0 -0
  30. {tasktree-0.0.16 → tasktree-0.0.18}/tests/e2e/__init__.py +0 -0
  31. {tasktree-0.0.16 → tasktree-0.0.18}/tests/e2e/test_docker_basic.py +0 -0
  32. {tasktree-0.0.16 → tasktree-0.0.18}/tests/e2e/test_docker_environment.py +0 -0
  33. {tasktree-0.0.16 → tasktree-0.0.18}/tests/e2e/test_docker_ownership.py +0 -0
  34. {tasktree-0.0.16 → tasktree-0.0.18}/tests/e2e/test_docker_volumes.py +0 -0
  35. {tasktree-0.0.16 → tasktree-0.0.18}/tests/e2e/test_non_docker.py +0 -0
  36. {tasktree-0.0.16 → tasktree-0.0.18}/tests/integration/test_arg_choices.py +0 -0
  37. {tasktree-0.0.16 → tasktree-0.0.18}/tests/integration/test_arg_min_max.py +0 -0
  38. {tasktree-0.0.16 → tasktree-0.0.18}/tests/integration/test_builtin_variables.py +0 -0
  39. {tasktree-0.0.16 → tasktree-0.0.18}/tests/integration/test_clean_state.py +0 -0
  40. {tasktree-0.0.16 → tasktree-0.0.18}/tests/integration/test_cli_options.py +0 -0
  41. {tasktree-0.0.16 → tasktree-0.0.18}/tests/integration/test_dependency_execution.py +0 -0
  42. {tasktree-0.0.16 → tasktree-0.0.18}/tests/integration/test_docker_build_args.py +0 -0
  43. {tasktree-0.0.16 → tasktree-0.0.18}/tests/integration/test_end_to_end.py +0 -0
  44. {tasktree-0.0.16 → tasktree-0.0.18}/tests/integration/test_exported_args.py +0 -0
  45. {tasktree-0.0.16 → tasktree-0.0.18}/tests/integration/test_input_detection.py +0 -0
  46. {tasktree-0.0.16 → tasktree-0.0.18}/tests/integration/test_missing_outputs.py +0 -0
  47. {tasktree-0.0.16 → tasktree-0.0.18}/tests/integration/test_nested_imports.py +0 -0
  48. {tasktree-0.0.16 → tasktree-0.0.18}/tests/integration/test_parameterized_dependencies.yaml +0 -0
  49. {tasktree-0.0.16 → tasktree-0.0.18}/tests/integration/test_parameterized_deps_execution.py +0 -0
  50. {tasktree-0.0.16 → tasktree-0.0.18}/tests/integration/test_parameterized_deps_templates.py +0 -0
  51. {tasktree-0.0.16 → tasktree-0.0.18}/tests/integration/test_state_persistence.py +0 -0
  52. {tasktree-0.0.16 → tasktree-0.0.18}/tests/integration/test_variables.py +0 -0
  53. {tasktree-0.0.16 → tasktree-0.0.18}/tests/integration/test_working_directory.py +0 -0
  54. {tasktree-0.0.16 → tasktree-0.0.18}/tests/unit/test_cli.py +0 -0
  55. {tasktree-0.0.16 → tasktree-0.0.18}/tests/unit/test_dependency_parsing.py +0 -0
  56. {tasktree-0.0.16 → tasktree-0.0.18}/tests/unit/test_docker.py +0 -0
  57. {tasktree-0.0.16 → tasktree-0.0.18}/tests/unit/test_environment_tracking.py +0 -0
  58. {tasktree-0.0.16 → tasktree-0.0.18}/tests/unit/test_executor.py +0 -0
  59. {tasktree-0.0.16 → tasktree-0.0.18}/tests/unit/test_graph.py +0 -0
  60. {tasktree-0.0.16 → tasktree-0.0.18}/tests/unit/test_hasher.py +0 -0
  61. {tasktree-0.0.16 → tasktree-0.0.18}/tests/unit/test_list_formatting.py +0 -0
  62. {tasktree-0.0.16 → tasktree-0.0.18}/tests/unit/test_parameterized_graph.py +0 -0
  63. {tasktree-0.0.16 → tasktree-0.0.18}/tests/unit/test_parser.py +0 -0
  64. {tasktree-0.0.16 → tasktree-0.0.18}/tests/unit/test_state.py +0 -0
  65. {tasktree-0.0.16 → tasktree-0.0.18}/tests/unit/test_substitution.py +0 -0
  66. {tasktree-0.0.16 → tasktree-0.0.18}/tests/unit/test_types.py +0 -0
  67. {tasktree-0.0.16 → tasktree-0.0.18}/uv.lock +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tasktree
3
- Version: 0.0.16
3
+ Version: 0.0.18
4
4
  Summary: A task automation tool with incremental execution
5
5
  Requires-Python: >=3.11
6
6
  Requires-Dist: click>=8.1.0
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "tasktree"
3
- version = "0.0.16"
3
+ version = "0.0.18"
4
4
  description = "A task automation tool with incremental execution"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.11"
@@ -232,14 +232,16 @@ class Recipe:
232
232
  # (CLI will provide its own "Task not found" error)
233
233
  try:
234
234
  reachable_tasks = collect_reachable_tasks(self.tasks, root_task)
235
- variables_to_eval = collect_reachable_variables(self.tasks, reachable_tasks)
235
+ variables_to_eval = collect_reachable_variables(self.tasks, self.environments, reachable_tasks)
236
236
  except ValueError:
237
237
  # Root task not found - fall back to eager evaluation
238
238
  # This allows the recipe to be parsed even with invalid task names
239
239
  # so the CLI can provide its own error message
240
+ reachable_tasks = self.tasks.keys()
240
241
  variables_to_eval = set(self.raw_variables.keys())
241
242
  else:
242
243
  # Eager path: evaluate all variables (for --list command)
244
+ reachable_tasks = self.tasks.keys()
243
245
  variables_to_eval = set(self.raw_variables.keys())
244
246
 
245
247
  # Evaluate the selected variables using helper function
@@ -256,7 +258,10 @@ class Recipe:
256
258
  # Substitute evaluated variables into all tasks
257
259
  from tasktree.substitution import substitute_variables
258
260
 
259
- for task in self.tasks.values():
261
+ for task_name, task in self.tasks.items():
262
+ if task_name not in reachable_tasks:
263
+ continue
264
+
260
265
  task.cmd = substitute_variables(task.cmd, self.evaluated_variables)
261
266
  task.desc = substitute_variables(task.desc, self.evaluated_variables)
262
267
  task.working_dir = substitute_variables(task.working_dir, self.evaluated_variables)
@@ -1311,15 +1316,17 @@ def collect_reachable_tasks(tasks: dict[str, Task], root_task: str) -> set[str]:
1311
1316
 
1312
1317
  def collect_reachable_variables(
1313
1318
  tasks: dict[str, Task],
1319
+ environments: dict[str, Environment],
1314
1320
  reachable_task_names: set[str]
1315
1321
  ) -> set[str]:
1316
1322
  """Extract variable names used by reachable tasks.
1317
1323
 
1318
- Searches for {{ var.* }} placeholders in task definitions to determine
1324
+ Searches for {{ var.* }} placeholders in task and environment definitions to determine
1319
1325
  which variables are actually needed for execution.
1320
1326
 
1321
1327
  Args:
1322
1328
  tasks: Dictionary mapping task names to Task objects
1329
+ environments: Dictionary mapping environment names to Environment objects
1323
1330
  reachable_task_names: Set of task names that will be executed
1324
1331
 
1325
1332
  Returns:
@@ -1398,6 +1405,42 @@ def collect_reachable_variables(
1398
1405
  for match in var_pattern.finditer(val):
1399
1406
  variables.add(match.group(1))
1400
1407
 
1408
+ if task.env:
1409
+ if task.env in environments:
1410
+ env = environments[task.env]
1411
+
1412
+ if env.dockerfile and env.dockerfile != "":
1413
+ for match in var_pattern.finditer(env.dockerfile):
1414
+ variables.add(match.group(1))
1415
+
1416
+ if env.context != "":
1417
+ for match in var_pattern.finditer(env.context):
1418
+ variables.add(match.group(1))
1419
+
1420
+ if 0 != len(env.volumes):
1421
+ for v in env.volumes:
1422
+ for match in var_pattern.finditer(v):
1423
+ variables.add(match.group(1))
1424
+
1425
+ if 0 != len(env.ports):
1426
+ for p in env.ports:
1427
+ for match in var_pattern.finditer(p):
1428
+ variables.add(match.group(1))
1429
+
1430
+ if 0 != len(env.env_vars):
1431
+ for k, v in env.env_vars.items():
1432
+ for match in var_pattern.finditer(v):
1433
+ variables.add(match.group(1))
1434
+
1435
+ if env.working_dir != "":
1436
+ for match in var_pattern.finditer(env.working_dir):
1437
+ variables.add(match.group(1))
1438
+
1439
+ if 0 != len(env.extra_args):
1440
+ for e in env.extra_args:
1441
+ for match in var_pattern.finditer(e):
1442
+ variables.add(match.group(1))
1443
+
1401
1444
  return variables
1402
1445
 
1403
1446
 
@@ -1,4 +1,4 @@
1
- # yaml-language-server: $schema=https://raw.githubusercontent.com/kevinchannon/tasktree/main/schema/tasktree-schema.json
1
+ # yaml-language-server: $schema=schema/tasktree-schema.json
2
2
 
3
3
  tasks:
4
4
  dev-setup:
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes