tasktree 0.0.9__py3-none-any.whl → 0.0.10__py3-none-any.whl

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/docker.py CHANGED
@@ -87,16 +87,24 @@ class DockerManager:
87
87
 
88
88
  # Build the image
89
89
  try:
90
+ docker_build_cmd = [
91
+ "docker",
92
+ "build",
93
+ "-t",
94
+ image_tag,
95
+ "-f",
96
+ str(dockerfile_path),
97
+ ]
98
+
99
+ # Add build args if environment has them (docker environments use dict for args)
100
+ if isinstance(env.args, dict):
101
+ for arg_name, arg_value in env.args.items():
102
+ docker_build_cmd.extend(["--build-arg", f"{arg_name}={arg_value}"])
103
+
104
+ docker_build_cmd.append(str(context_path))
105
+
90
106
  subprocess.run(
91
- [
92
- "docker",
93
- "build",
94
- "-t",
95
- image_tag,
96
- "-f",
97
- str(dockerfile_path),
98
- str(context_path),
99
- ],
107
+ docker_build_cmd,
100
108
  check=True,
101
109
  capture_output=False, # Show build output to user
102
110
  )
tasktree/hasher.py CHANGED
@@ -104,9 +104,16 @@ def hash_environment_definition(env) -> str:
104
104
  # Import inside function to avoid circular dependency
105
105
  from tasktree.parser import Environment
106
106
 
107
+ # Handle args - can be list (shell args) or dict (docker build args)
108
+ args_value = env.args
109
+ if isinstance(env.args, dict):
110
+ args_value = dict(sorted(env.args.items())) # Sort dict for determinism
111
+ elif isinstance(env.args, list):
112
+ args_value = sorted(env.args) # Sort list for determinism
113
+
107
114
  data = {
108
115
  "shell": env.shell,
109
- "args": sorted(env.args), # Sort for determinism
116
+ "args": args_value,
110
117
  "preamble": env.preamble,
111
118
  "dockerfile": env.dockerfile,
112
119
  "context": env.context,
tasktree/parser.py CHANGED
@@ -31,7 +31,7 @@ class Environment:
31
31
 
32
32
  name: str
33
33
  shell: str = "" # Path to shell (required for shell envs, optional for Docker)
34
- args: list[str] = field(default_factory=list)
34
+ args: list[str] | dict[str, str] = field(default_factory=list) # Shell args (list) or Docker build args (dict)
35
35
  preamble: str = ""
36
36
  # Docker-specific fields (presence of dockerfile indicates Docker environment)
37
37
  dockerfile: str = "" # Path to Dockerfile
@@ -44,7 +44,7 @@ class Environment:
44
44
  run_as_root: bool = False # If True, skip user mapping (run as root in container)
45
45
 
46
46
  def __post_init__(self):
47
- """Ensure args is always a list."""
47
+ """Ensure args is in the correct format."""
48
48
  if isinstance(self.args, str):
49
49
  self.args = [self.args]
50
50
 
@@ -60,7 +60,7 @@ class Task:
60
60
  inputs: list[str] = field(default_factory=list)
61
61
  outputs: list[str] = field(default_factory=list)
62
62
  working_dir: str = ""
63
- args: list[str] = field(default_factory=list)
63
+ args: list[str | dict[str, Any]] = field(default_factory=list) # Can be strings or dicts (each dict has single key: arg name)
64
64
  source_file: str = "" # Track which file defined this task
65
65
  env: str = "" # Environment name to use for execution
66
66
 
@@ -75,6 +75,19 @@ class Task:
75
75
  if isinstance(self.args, str):
76
76
  self.args = [self.args]
77
77
 
78
+ # Validate args is not a dict (common YAML mistake)
79
+ if isinstance(self.args, dict):
80
+ raise ValueError(
81
+ f"Task '{self.name}' has invalid 'args' syntax.\n\n"
82
+ f"Found dictionary syntax (without dashes):\n"
83
+ f" args:\n"
84
+ f" {list(self.args.keys())[0] if self.args else 'key'}: ...\n\n"
85
+ f"Correct syntax uses list format (with dashes):\n"
86
+ f" args:\n"
87
+ f" - {list(self.args.keys())[0] if self.args else 'key'}: ...\n\n"
88
+ f"Arguments must be defined as a list, not a dictionary."
89
+ )
90
+
78
91
 
79
92
  @dataclass
80
93
  class DependencyInvocation:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tasktree
3
- Version: 0.0.9
3
+ Version: 0.0.10
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,15 +1,15 @@
1
1
  tasktree/__init__.py,sha256=MVmdvKb3JdqLlo0x2_TPGMfgFC0HsDnP79HAzGnFnjI,1081
2
2
  tasktree/cli.py,sha256=H5T8wOxLBGx-ZTQEnkoJrX3srgD5b_7BLf1IWl18M2M,17597
3
- tasktree/docker.py,sha256=R69NcZw4MyaxEXyJAwniYCm877iaI10jRhxlLmkA6Fs,14119
3
+ tasktree/docker.py,sha256=qvja8G63uAcC73YMVY739egda1_CcBtoqzm0qIJU_Q8,14443
4
4
  tasktree/executor.py,sha256=Q7Bks5B88i-IyZDpxGSps9MM3uflz0U3yn4Rtq_uHMM,42266
5
5
  tasktree/graph.py,sha256=oXLxX0Ix4zSkVBg8_3x9K7WxSFpg136sp4MF-d2mDEQ,9682
6
- tasktree/hasher.py,sha256=C8oN-K6dtL3vLHSPhKR7uu5c1d4vplGSAMZUq5M4scw,4125
7
- tasktree/parser.py,sha256=DjdfsKErdBggqS8Tw_mwuMvMSavIJqq2BCdsh1O82CY,66333
6
+ tasktree/hasher.py,sha256=0GrnCfwAXnwq_kpnHFFb12B5_2VFNXx6Ng7hTdcCyXo,4415
7
+ tasktree/parser.py,sha256=N_dXHl5UF0rBvIVdbsVZOo5Ur5uFEKgY1sSPNfScTxc,67135
8
8
  tasktree/state.py,sha256=Cktl4D8iDZVd55aO2LqVyPrc-BnljkesxxkcMcdcfOY,3541
9
9
  tasktree/substitution.py,sha256=M_qcP0NKJATrKcNShSqHJatneuth1RVwTk1ci8-ZuxQ,6473
10
10
  tasktree/tasks.py,sha256=2QdQZtJAX2rSGbyXKG1z9VF_siz1DUzdvzCgPkykxtU,173
11
11
  tasktree/types.py,sha256=R_YAyO5bMLB6XZnkMRT7VAtlkA_Xx6xu0aIpzQjrBXs,4357
12
- tasktree-0.0.9.dist-info/METADATA,sha256=VBgQ1ZF2hacw1CajhxcjkrGTyygnf-uWxiZm7H92AyE,37123
13
- tasktree-0.0.9.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
14
- tasktree-0.0.9.dist-info/entry_points.txt,sha256=lQINlvRYnimvteBbnhH84A9clTg8NnpEjCWqWkqg8KE,40
15
- tasktree-0.0.9.dist-info/RECORD,,
12
+ tasktree-0.0.10.dist-info/METADATA,sha256=JyhF89pfUwr0bkV33rNae-0ytPyOEr2bKHfiWN-YsK0,37124
13
+ tasktree-0.0.10.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
14
+ tasktree-0.0.10.dist-info/entry_points.txt,sha256=lQINlvRYnimvteBbnhH84A9clTg8NnpEjCWqWkqg8KE,40
15
+ tasktree-0.0.10.dist-info/RECORD,,