diff --git a/src/wic/api/pythonapi.py b/src/wic/api/pythonapi.py index cce9a4f9..575f01c3 100644 --- a/src/wic/api/pythonapi.py +++ b/src/wic/api/pythonapi.py @@ -281,9 +281,13 @@ def _yml(self) -> dict: } return d - def _save_cwl(self, path: Path) -> None: + def _save_cwl(self, path: Path, overwrite: bool) -> None: cwl_adapters = path.joinpath("cwl_adapters") cwl_adapters.mkdir(exist_ok=True, parents=True) + if not overwrite: + if cwl_adapters.joinpath(f"{self.clt_name}.cwl").exists(): + return + # does not exist: with open( cwl_adapters.joinpath(f"{self.clt_name}.cwl"), "w", @@ -299,7 +303,8 @@ def _save_cwl(self, path: Path) -> None: class Workflow: steps: list[Step] name: str - yml_path: Optional[Path] = field(default=None, init=False, repr=False) + path: Path = field(default=Path.cwd()) + yml_path: Optional[Path] = field(default=None, init=False, repr=False) # pylint: disable=E3701 def __post_init__(self) -> None: for s in self.steps: @@ -309,6 +314,7 @@ def __post_init__(self) -> None: raise InvalidStepError( f"{s.clt_name} is missing required inputs" ) from exc + self.path.joinpath(self.name).mkdir(parents=True, exist_ok=True) def append(self, step_: Step) -> None: """Append step to Workflow.""" @@ -328,7 +334,11 @@ def _save_yaml(self) -> None: with open(self.yml_path, "w", encoding="utf-8") as file: file.write(yaml.dump(self.yaml)) - def _save_all_cwl(self) -> None: + # copy to wf path, only informational, not used by WIC + with open(self.path.joinpath(self.name, f"{self.name}.yml"), "w", encoding="utf-8") as file: + file.write(yaml.dump(self.yaml)) + + def _save_all_cwl(self, overwrite: bool) -> None: """Save CWL files to cwl_adapters. This is necessary for WIC to compile the workflow. @@ -336,17 +346,24 @@ def _save_all_cwl(self) -> None: _WIC_PATH.mkdir(parents=True, exist_ok=True) for s in self.steps: try: - s._save_cwl(_WIC_PATH) # pylint: disable=W0212 + s._save_cwl(_WIC_PATH, overwrite) # pylint: disable=W0212 + except BaseException as exc: + raise exc + + # copy to wf path, only informational, not used by WIC + for s in self.steps: + try: + s._save_cwl(self.path.joinpath(self.name), overwrite) # pylint: disable=W0212 except BaseException as exc: raise exc - def compile(self, run_local: bool = False) -> Path: + def compile(self, run_local: bool = False, overwrite: bool = False) -> Path: """Compile Workflow using WIC. Returns path to compiled CWL Workflow. """ - self._save_all_cwl() + self._save_all_cwl(overwrite) self._save_yaml() logger.info(f"Compiling {self.name}") args = ["wic", "--yaml", f"{self.name}.yml"] @@ -366,9 +383,12 @@ def compile(self, run_local: bool = False) -> Path: logger.info(exc.stdout) raise exc logger.info(proc.stdout) - return _WIC_PATH.joinpath("autogenerated", f"{self.name}.cwl") + # copy files to wf path + compiled_cwl_path = _WIC_PATH.joinpath("autogenerated", f"{self.name}.cwl") + self.path.joinpath(self.name, f"{self.name}.cwl").symlink_to(compiled_cwl_path) + return compiled_cwl_path - def run(self) -> None: + def run(self, overwrite: bool = False) -> None: """Run compiled workflow.""" logger.info(f"Running {self.name}") - self.compile(run_local=True) + self.compile(run_local=True, overwrite=overwrite)