|
26 | 26 | import re |
27 | 27 | import subprocess |
28 | 28 | import sys |
| 29 | +import tempfile |
29 | 30 | from pathlib import Path |
30 | 31 |
|
31 | 32 | from dotenv import load_dotenv |
32 | 33 | from griptape_nodes.common.project_templates import load_project_template_from_yaml |
| 34 | +from griptape_nodes.common.project_templates.directory import DirectoryDefinition |
33 | 35 | from griptape_nodes.common.project_templates.validation import ProjectValidationInfo, ProjectValidationStatus |
34 | 36 | from output_protocol import emit_payload |
35 | 37 |
|
@@ -254,16 +256,50 @@ def main() -> None: |
254 | 256 | sys.exit(1) |
255 | 257 |
|
256 | 258 | script_dir = Path(__file__).parent |
257 | | - project_file = script_dir / "project.yml" |
| 259 | + bundle_project_file = script_dir / "project.yml" |
| 260 | + |
| 261 | + # When an output directory is specified, build a per-run temp project.yml that |
| 262 | + # redirects {outputs} to the requested directory. The bundle's situation macro |
| 263 | + # and OVERWRITE policy are kept exactly as authored — only the directory changes. |
| 264 | + # This makes the engine's actual save path agree with the path we report to Nuke. |
| 265 | + # The bundle file itself is never modified. |
| 266 | + temp_project_file = None |
| 267 | + project_file_path: str | None = str(bundle_project_file) if bundle_project_file.exists() else None |
| 268 | + |
| 269 | + if args.output_dir and bundle_project_file.exists(): |
| 270 | + validation_info = ProjectValidationInfo(status=ProjectValidationStatus.GOOD) |
| 271 | + template = load_project_template_from_yaml(bundle_project_file.read_text(encoding="utf-8"), validation_info) |
| 272 | + if template is not None: |
| 273 | + template.directories["outputs"] = DirectoryDefinition( |
| 274 | + name="outputs", |
| 275 | + path_macro=args.output_dir, |
| 276 | + ) |
| 277 | + tmp = tempfile.NamedTemporaryFile( |
| 278 | + mode="w", |
| 279 | + suffix=".yml", |
| 280 | + prefix="griptape_nuke_run_", |
| 281 | + delete=False, |
| 282 | + encoding="utf-8", |
| 283 | + ) |
| 284 | + tmp.write(template.to_yaml()) |
| 285 | + tmp.close() |
| 286 | + temp_project_file = tmp.name |
| 287 | + project_file_path = temp_project_file |
258 | 288 |
|
259 | 289 | try: |
260 | 290 | output = module.execute_workflow( |
261 | 291 | input=flow_input, |
262 | | - project_file_path=str(project_file) if project_file.exists() else None, |
| 292 | + project_file_path=project_file_path, |
263 | 293 | ) |
264 | 294 | except Exception as e: |
265 | 295 | emit_payload({"error": f"Workflow execution failed: {e}"}) |
266 | 296 | sys.exit(1) |
| 297 | + finally: |
| 298 | + if temp_project_file is not None: |
| 299 | + try: |
| 300 | + Path(temp_project_file).unlink(missing_ok=True) |
| 301 | + except OSError: |
| 302 | + pass |
267 | 303 |
|
268 | 304 | workspace_dir = Path(args.nk_script_dir) if args.nk_script_dir else None |
269 | 305 | macro_map = _build_macro_map(Path(__file__).parent, workspace_dir=workspace_dir) |
|
0 commit comments