hpcflow-new2 0.2.0a189__py3-none-any.whl → 0.2.0a199__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.
- hpcflow/__pyinstaller/hook-hpcflow.py +9 -6
- hpcflow/_version.py +1 -1
- hpcflow/app.py +1 -0
- hpcflow/data/scripts/bad_script.py +2 -0
- hpcflow/data/scripts/do_nothing.py +2 -0
- hpcflow/data/scripts/env_specifier_test/input_file_generator_pass_env_spec.py +4 -0
- hpcflow/data/scripts/env_specifier_test/main_script_test_pass_env_spec.py +8 -0
- hpcflow/data/scripts/env_specifier_test/output_file_parser_pass_env_spec.py +4 -0
- hpcflow/data/scripts/env_specifier_test/v1/input_file_generator_basic.py +4 -0
- hpcflow/data/scripts/env_specifier_test/v1/main_script_test_direct_in_direct_out.py +7 -0
- hpcflow/data/scripts/env_specifier_test/v1/output_file_parser_basic.py +4 -0
- hpcflow/data/scripts/env_specifier_test/v2/main_script_test_direct_in_direct_out.py +7 -0
- hpcflow/data/scripts/input_file_generator_basic.py +3 -0
- hpcflow/data/scripts/input_file_generator_basic_FAIL.py +3 -0
- hpcflow/data/scripts/input_file_generator_test_stdout_stderr.py +8 -0
- hpcflow/data/scripts/main_script_test_direct_in.py +3 -0
- hpcflow/data/scripts/main_script_test_direct_in_direct_out_2.py +6 -0
- hpcflow/data/scripts/main_script_test_direct_in_direct_out_2_fail_allowed.py +6 -0
- hpcflow/data/scripts/main_script_test_direct_in_direct_out_2_fail_allowed_group.py +7 -0
- hpcflow/data/scripts/main_script_test_direct_in_direct_out_3.py +6 -0
- hpcflow/data/scripts/main_script_test_direct_in_group_direct_out_3.py +6 -0
- hpcflow/data/scripts/main_script_test_direct_in_group_one_fail_direct_out_3.py +6 -0
- hpcflow/data/scripts/main_script_test_hdf5_in_obj.py +1 -1
- hpcflow/data/scripts/main_script_test_hdf5_in_obj_2.py +12 -0
- hpcflow/data/scripts/main_script_test_hdf5_out_obj.py +1 -1
- hpcflow/data/scripts/main_script_test_json_out_FAIL.py +3 -0
- hpcflow/data/scripts/main_script_test_shell_env_vars.py +12 -0
- hpcflow/data/scripts/main_script_test_std_out_std_err.py +6 -0
- hpcflow/data/scripts/output_file_parser_basic.py +3 -0
- hpcflow/data/scripts/output_file_parser_basic_FAIL.py +7 -0
- hpcflow/data/scripts/output_file_parser_test_stdout_stderr.py +8 -0
- hpcflow/data/scripts/script_exit_test.py +5 -0
- hpcflow/data/template_components/environments.yaml +1 -1
- hpcflow/sdk/__init__.py +26 -15
- hpcflow/sdk/app.py +2192 -768
- hpcflow/sdk/cli.py +506 -296
- hpcflow/sdk/cli_common.py +105 -7
- hpcflow/sdk/config/__init__.py +1 -1
- hpcflow/sdk/config/callbacks.py +115 -43
- hpcflow/sdk/config/cli.py +126 -103
- hpcflow/sdk/config/config.py +674 -318
- hpcflow/sdk/config/config_file.py +131 -95
- hpcflow/sdk/config/errors.py +125 -84
- hpcflow/sdk/config/types.py +148 -0
- hpcflow/sdk/core/__init__.py +25 -1
- hpcflow/sdk/core/actions.py +1771 -1059
- hpcflow/sdk/core/app_aware.py +24 -0
- hpcflow/sdk/core/cache.py +139 -79
- hpcflow/sdk/core/command_files.py +263 -287
- hpcflow/sdk/core/commands.py +145 -112
- hpcflow/sdk/core/element.py +828 -535
- hpcflow/sdk/core/enums.py +192 -0
- hpcflow/sdk/core/environment.py +74 -93
- hpcflow/sdk/core/errors.py +455 -52
- hpcflow/sdk/core/execute.py +207 -0
- hpcflow/sdk/core/json_like.py +540 -272
- hpcflow/sdk/core/loop.py +751 -347
- hpcflow/sdk/core/loop_cache.py +164 -47
- hpcflow/sdk/core/object_list.py +370 -207
- hpcflow/sdk/core/parameters.py +1100 -627
- hpcflow/sdk/core/rule.py +59 -41
- hpcflow/sdk/core/run_dir_files.py +21 -37
- hpcflow/sdk/core/skip_reason.py +7 -0
- hpcflow/sdk/core/task.py +1649 -1339
- hpcflow/sdk/core/task_schema.py +308 -196
- hpcflow/sdk/core/test_utils.py +191 -114
- hpcflow/sdk/core/types.py +440 -0
- hpcflow/sdk/core/utils.py +485 -309
- hpcflow/sdk/core/validation.py +82 -9
- hpcflow/sdk/core/workflow.py +2544 -1178
- hpcflow/sdk/core/zarr_io.py +98 -137
- hpcflow/sdk/data/workflow_spec_schema.yaml +2 -0
- hpcflow/sdk/demo/cli.py +53 -33
- hpcflow/sdk/helper/cli.py +18 -15
- hpcflow/sdk/helper/helper.py +75 -63
- hpcflow/sdk/helper/watcher.py +61 -28
- hpcflow/sdk/log.py +122 -71
- hpcflow/sdk/persistence/__init__.py +8 -31
- hpcflow/sdk/persistence/base.py +1360 -606
- hpcflow/sdk/persistence/defaults.py +6 -0
- hpcflow/sdk/persistence/discovery.py +38 -0
- hpcflow/sdk/persistence/json.py +568 -188
- hpcflow/sdk/persistence/pending.py +382 -179
- hpcflow/sdk/persistence/store_resource.py +39 -23
- hpcflow/sdk/persistence/types.py +318 -0
- hpcflow/sdk/persistence/utils.py +14 -11
- hpcflow/sdk/persistence/zarr.py +1337 -433
- hpcflow/sdk/runtime.py +44 -41
- hpcflow/sdk/submission/{jobscript_info.py → enums.py} +39 -12
- hpcflow/sdk/submission/jobscript.py +1651 -692
- hpcflow/sdk/submission/schedulers/__init__.py +167 -39
- hpcflow/sdk/submission/schedulers/direct.py +121 -81
- hpcflow/sdk/submission/schedulers/sge.py +170 -129
- hpcflow/sdk/submission/schedulers/slurm.py +291 -268
- hpcflow/sdk/submission/schedulers/utils.py +12 -2
- hpcflow/sdk/submission/shells/__init__.py +14 -15
- hpcflow/sdk/submission/shells/base.py +150 -29
- hpcflow/sdk/submission/shells/bash.py +283 -173
- hpcflow/sdk/submission/shells/os_version.py +31 -30
- hpcflow/sdk/submission/shells/powershell.py +228 -170
- hpcflow/sdk/submission/submission.py +1014 -335
- hpcflow/sdk/submission/types.py +140 -0
- hpcflow/sdk/typing.py +182 -12
- hpcflow/sdk/utils/arrays.py +71 -0
- hpcflow/sdk/utils/deferred_file.py +55 -0
- hpcflow/sdk/utils/hashing.py +16 -0
- hpcflow/sdk/utils/patches.py +12 -0
- hpcflow/sdk/utils/strings.py +33 -0
- hpcflow/tests/api/test_api.py +32 -0
- hpcflow/tests/conftest.py +27 -6
- hpcflow/tests/data/multi_path_sequences.yaml +29 -0
- hpcflow/tests/data/workflow_test_run_abort.yaml +34 -35
- hpcflow/tests/schedulers/sge/test_sge_submission.py +36 -0
- hpcflow/tests/schedulers/slurm/test_slurm_submission.py +5 -2
- hpcflow/tests/scripts/test_input_file_generators.py +282 -0
- hpcflow/tests/scripts/test_main_scripts.py +866 -85
- hpcflow/tests/scripts/test_non_snippet_script.py +46 -0
- hpcflow/tests/scripts/test_ouput_file_parsers.py +353 -0
- hpcflow/tests/shells/wsl/test_wsl_submission.py +12 -4
- hpcflow/tests/unit/test_action.py +262 -75
- hpcflow/tests/unit/test_action_rule.py +9 -4
- hpcflow/tests/unit/test_app.py +33 -6
- hpcflow/tests/unit/test_cache.py +46 -0
- hpcflow/tests/unit/test_cli.py +134 -1
- hpcflow/tests/unit/test_command.py +71 -54
- hpcflow/tests/unit/test_config.py +142 -16
- hpcflow/tests/unit/test_config_file.py +21 -18
- hpcflow/tests/unit/test_element.py +58 -62
- hpcflow/tests/unit/test_element_iteration.py +50 -1
- hpcflow/tests/unit/test_element_set.py +29 -19
- hpcflow/tests/unit/test_group.py +4 -2
- hpcflow/tests/unit/test_input_source.py +116 -93
- hpcflow/tests/unit/test_input_value.py +29 -24
- hpcflow/tests/unit/test_jobscript_unit.py +757 -0
- hpcflow/tests/unit/test_json_like.py +44 -35
- hpcflow/tests/unit/test_loop.py +1396 -84
- hpcflow/tests/unit/test_meta_task.py +325 -0
- hpcflow/tests/unit/test_multi_path_sequences.py +229 -0
- hpcflow/tests/unit/test_object_list.py +17 -12
- hpcflow/tests/unit/test_parameter.py +29 -7
- hpcflow/tests/unit/test_persistence.py +237 -42
- hpcflow/tests/unit/test_resources.py +20 -18
- hpcflow/tests/unit/test_run.py +117 -6
- hpcflow/tests/unit/test_run_directories.py +29 -0
- hpcflow/tests/unit/test_runtime.py +2 -1
- hpcflow/tests/unit/test_schema_input.py +23 -15
- hpcflow/tests/unit/test_shell.py +23 -2
- hpcflow/tests/unit/test_slurm.py +8 -7
- hpcflow/tests/unit/test_submission.py +38 -89
- hpcflow/tests/unit/test_task.py +352 -247
- hpcflow/tests/unit/test_task_schema.py +33 -20
- hpcflow/tests/unit/test_utils.py +9 -11
- hpcflow/tests/unit/test_value_sequence.py +15 -12
- hpcflow/tests/unit/test_workflow.py +114 -83
- hpcflow/tests/unit/test_workflow_template.py +0 -1
- hpcflow/tests/unit/utils/test_arrays.py +40 -0
- hpcflow/tests/unit/utils/test_deferred_file_writer.py +34 -0
- hpcflow/tests/unit/utils/test_hashing.py +65 -0
- hpcflow/tests/unit/utils/test_patches.py +5 -0
- hpcflow/tests/unit/utils/test_redirect_std.py +50 -0
- hpcflow/tests/workflows/__init__.py +0 -0
- hpcflow/tests/workflows/test_directory_structure.py +31 -0
- hpcflow/tests/workflows/test_jobscript.py +334 -1
- hpcflow/tests/workflows/test_run_status.py +198 -0
- hpcflow/tests/workflows/test_skip_downstream.py +696 -0
- hpcflow/tests/workflows/test_submission.py +140 -0
- hpcflow/tests/workflows/test_workflows.py +160 -15
- hpcflow/tests/workflows/test_zip.py +18 -0
- hpcflow/viz_demo.ipynb +6587 -3
- {hpcflow_new2-0.2.0a189.dist-info → hpcflow_new2-0.2.0a199.dist-info}/METADATA +8 -4
- hpcflow_new2-0.2.0a199.dist-info/RECORD +221 -0
- hpcflow/sdk/core/parallel.py +0 -21
- hpcflow_new2-0.2.0a189.dist-info/RECORD +0 -158
- {hpcflow_new2-0.2.0a189.dist-info → hpcflow_new2-0.2.0a199.dist-info}/LICENSE +0 -0
- {hpcflow_new2-0.2.0a189.dist-info → hpcflow_new2-0.2.0a199.dist-info}/WHEEL +0 -0
- {hpcflow_new2-0.2.0a189.dist-info → hpcflow_new2-0.2.0a199.dist-info}/entry_points.txt +0 -0
@@ -2,14 +2,24 @@
|
|
2
2
|
Helper for running a subprocess.
|
3
3
|
"""
|
4
4
|
|
5
|
+
from __future__ import annotations
|
5
6
|
import subprocess
|
7
|
+
from typing import TYPE_CHECKING
|
6
8
|
|
9
|
+
if TYPE_CHECKING:
|
10
|
+
from collections.abc import Sequence
|
11
|
+
from logging import Logger
|
7
12
|
|
8
|
-
|
13
|
+
|
14
|
+
def run_cmd(
|
15
|
+
cmd: str | Sequence[str], logger: Logger | None = None, **kwargs
|
16
|
+
) -> tuple[str, str]:
|
9
17
|
"""Execute a command and return stdout, stderr as strings."""
|
10
18
|
if logger:
|
11
19
|
logger.debug(f"running shell command: {cmd}")
|
12
|
-
proc = subprocess.run(
|
20
|
+
proc = subprocess.run(
|
21
|
+
args=cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, **kwargs
|
22
|
+
)
|
13
23
|
stdout = proc.stdout.decode()
|
14
24
|
stderr = proc.stderr.decode()
|
15
25
|
return stdout, stderr
|
@@ -1,17 +1,17 @@
|
|
1
1
|
"""
|
2
2
|
Adapters for various shells.
|
3
3
|
"""
|
4
|
+
from __future__ import annotations
|
4
5
|
import os
|
5
|
-
from typing import Dict, Optional
|
6
6
|
|
7
7
|
from hpcflow.sdk.core.errors import UnsupportedShellError
|
8
8
|
|
9
|
-
from .base import Shell
|
10
|
-
from .bash import Bash, WSLBash
|
11
|
-
from .powershell import WindowsPowerShell
|
9
|
+
from hpcflow.sdk.submission.shells.base import Shell
|
10
|
+
from hpcflow.sdk.submission.shells.bash import Bash, WSLBash
|
11
|
+
from hpcflow.sdk.submission.shells.powershell import WindowsPowerShell
|
12
12
|
|
13
13
|
#: All supported shells.
|
14
|
-
ALL_SHELLS = {
|
14
|
+
ALL_SHELLS: dict[str, dict[str, type[Shell]]] = {
|
15
15
|
"bash": {"posix": Bash},
|
16
16
|
"powershell": {"nt": WindowsPowerShell},
|
17
17
|
"wsl+bash": {"nt": WSLBash},
|
@@ -25,28 +25,27 @@ DEFAULT_SHELL_NAMES = {
|
|
25
25
|
}
|
26
26
|
|
27
27
|
|
28
|
-
def get_supported_shells(os_name:
|
28
|
+
def get_supported_shells(os_name: str | None = None) -> dict[str, type[Shell]]:
|
29
29
|
"""
|
30
30
|
Get shells supported on the current or given OS.
|
31
31
|
"""
|
32
|
-
|
33
|
-
return {k: v
|
32
|
+
os_name_ = os_name or os.name
|
33
|
+
return {k: v[os_name_] for k, v in ALL_SHELLS.items() if v.get(os_name_)}
|
34
34
|
|
35
35
|
|
36
|
-
def get_shell(shell_name, os_name:
|
36
|
+
def get_shell(shell_name: str | None, os_name: str | None = None, **kwargs) -> Shell:
|
37
37
|
"""
|
38
38
|
Get a shell interface with the given name for a given OS (or the current one).
|
39
39
|
"""
|
40
40
|
# TODO: apply config default shell args?
|
41
41
|
|
42
42
|
os_name = os_name or os.name
|
43
|
-
shell_name =
|
43
|
+
shell_name = (
|
44
|
+
DEFAULT_SHELL_NAMES[os_name] if shell_name is None else shell_name.lower()
|
45
|
+
)
|
44
46
|
|
45
47
|
supported = get_supported_shells(os_name.lower())
|
46
|
-
shell_cls
|
47
|
-
if not shell_cls:
|
48
|
+
if not (shell_cls := supported.get(shell_name)):
|
48
49
|
raise UnsupportedShellError(shell=shell_name, supported=supported)
|
49
50
|
|
50
|
-
|
51
|
-
|
52
|
-
return shell_obj
|
51
|
+
return shell_cls(**kwargs)
|
@@ -2,11 +2,21 @@
|
|
2
2
|
Base model of a shell.
|
3
3
|
"""
|
4
4
|
|
5
|
+
from __future__ import annotations
|
5
6
|
from abc import ABC, abstractmethod
|
6
|
-
from
|
7
|
-
from typing import
|
7
|
+
from typing import TYPE_CHECKING
|
8
|
+
from hpcflow.sdk.typing import hydrate
|
8
9
|
|
10
|
+
if TYPE_CHECKING:
|
11
|
+
from collections.abc import Mapping
|
12
|
+
from pathlib import Path
|
13
|
+
from typing import Any, ClassVar
|
14
|
+
from ..types import JobscriptHeaderArgs, VersionInfo
|
9
15
|
|
16
|
+
from hpcflow.sdk.utils.hashing import get_hash
|
17
|
+
|
18
|
+
|
19
|
+
@hydrate
|
10
20
|
class Shell(ABC):
|
11
21
|
"""Class to represent a shell and templates for jobscript composition.
|
12
22
|
|
@@ -22,68 +32,129 @@ class Shell(ABC):
|
|
22
32
|
Arguments to pass to the shell.
|
23
33
|
"""
|
24
34
|
|
25
|
-
|
35
|
+
#: Default for executable name.
|
36
|
+
DEFAULT_EXE: ClassVar[str] = "/bin/bash"
|
37
|
+
#: File extension for jobscripts.
|
38
|
+
JS_EXT: ClassVar[str]
|
39
|
+
#: Basic indent.
|
40
|
+
JS_INDENT: ClassVar[str]
|
41
|
+
#: Indent for environment setup.
|
42
|
+
JS_ENV_SETUP_INDENT: ClassVar[str]
|
43
|
+
#: Template for the jobscript shebang line.
|
44
|
+
JS_SHEBANG: ClassVar[str]
|
45
|
+
#: Template for the jobscript functions file.
|
46
|
+
JS_FUNCS: ClassVar[str]
|
47
|
+
#: Template for the common part of the jobscript header.
|
48
|
+
JS_HEADER: ClassVar[str]
|
49
|
+
#: Template for the jobscript header when scheduled.
|
50
|
+
JS_SCHEDULER_HEADER: ClassVar[str]
|
51
|
+
#: Template for the jobscript header when directly executed.
|
52
|
+
JS_DIRECT_HEADER: ClassVar[str]
|
53
|
+
#: Template for enabling writing of the app log.
|
54
|
+
JS_RUN_LOG_PATH_ENABLE: ClassVar[str]
|
55
|
+
#: Template for disabling writing of the app log.
|
56
|
+
JS_RUN_LOG_PATH_DISABLE: ClassVar[str]
|
57
|
+
#: Template for the run execution command.
|
58
|
+
JS_RUN_CMD: ClassVar[str]
|
59
|
+
#: Template for the execution command for multiple combined runs.
|
60
|
+
JS_RUN_CMD_COMBINED: ClassVar[str]
|
61
|
+
#: Template for setting up run environment variables and executing the run.
|
62
|
+
JS_RUN: ClassVar[str]
|
63
|
+
#: Template for the action-run processing loop in a jobscript.
|
64
|
+
JS_ACT_MULTI: ClassVar[str]
|
65
|
+
#: Template for the single-action-run execution in a jobscript.
|
66
|
+
JS_ACT_SINGLE: ClassVar[str]
|
67
|
+
#: Template for setting up environment variables and running one or more action-runs.
|
68
|
+
JS_MAIN: ClassVar[str]
|
69
|
+
#: Template for a jobscript-block header.
|
70
|
+
JS_BLOCK_HEADER: ClassVar[str]
|
71
|
+
#: Template for single-element execution.
|
72
|
+
JS_ELEMENT_SINGLE: ClassVar[str]
|
73
|
+
#: Template for the element processing loop in a jobscript.
|
74
|
+
JS_ELEMENT_MULTI_LOOP: ClassVar[str]
|
75
|
+
#: Template for the array handling code in a jobscript.
|
76
|
+
JS_ELEMENT_MULTI_ARRAY: ClassVar[str]
|
77
|
+
#: Template for the jobscript block loop in a jobscript.
|
78
|
+
JS_BLOCK_LOOP: ClassVar[str]
|
79
|
+
#: Template for the jobscript footer.
|
80
|
+
JS_FOOTER: ClassVar[str]
|
81
|
+
|
82
|
+
__slots__ = ("_executable", "os_args")
|
83
|
+
|
84
|
+
def __init__(
|
85
|
+
self, executable: str | None = None, os_args: dict[str, str] | None = None
|
86
|
+
):
|
87
|
+
#: Which executable implements the shell.
|
26
88
|
self._executable = executable or self.DEFAULT_EXE
|
27
|
-
|
89
|
+
#: Arguments to pass to the shell.
|
90
|
+
self.os_args = os_args or {}
|
28
91
|
|
29
|
-
def __eq__(self, other) -> bool:
|
92
|
+
def __eq__(self, other: Any) -> bool:
|
30
93
|
if not isinstance(other, self.__class__):
|
31
94
|
return False
|
32
|
-
|
33
|
-
|
34
|
-
|
95
|
+
return self._executable == other._executable and self.os_args == other.os_args
|
96
|
+
|
97
|
+
def __hash__(self):
|
98
|
+
return get_hash((self._executable, self.os_args))
|
35
99
|
|
36
100
|
@property
|
37
|
-
def executable(self) ->
|
101
|
+
def executable(self) -> list[str]:
|
38
102
|
"""
|
39
103
|
The executable to use plus any mandatory arguments.
|
40
104
|
"""
|
41
105
|
return [self._executable]
|
42
106
|
|
43
107
|
@property
|
44
|
-
def shebang_executable(self) -> str:
|
108
|
+
def shebang_executable(self) -> list[str]:
|
45
109
|
"""
|
46
110
|
The executable to use in a shebang line.
|
47
111
|
"""
|
48
112
|
return self.executable
|
49
113
|
|
50
|
-
def get_direct_submit_command(self, js_path) ->
|
114
|
+
def get_direct_submit_command(self, js_path: str) -> list[str]:
|
51
115
|
"""Get the command for submitting a non-scheduled jobscript."""
|
52
116
|
return self.executable + [js_path]
|
53
117
|
|
118
|
+
def get_command_file_launch_command(self, cmd_file_path: str) -> list[str]:
|
119
|
+
"""Get the command for launching the commands file for a given run."""
|
120
|
+
return self.executable + [cmd_file_path]
|
121
|
+
|
54
122
|
@abstractmethod
|
55
|
-
def get_version_info(self, exclude_os:
|
123
|
+
def get_version_info(self, exclude_os: bool = False) -> VersionInfo:
|
56
124
|
"""Get shell and operating system information."""
|
57
125
|
|
58
|
-
def get_wait_command(
|
126
|
+
def get_wait_command(
|
127
|
+
self, workflow_app_alias: str, sub_idx: int, deps: Mapping[int, Any]
|
128
|
+
):
|
59
129
|
"""
|
60
130
|
Get the command to wait for a workflow.
|
61
131
|
"""
|
62
|
-
if deps:
|
63
|
-
return (
|
64
|
-
f'{workflow_app_alias} workflow $WK_PATH_ARG wait --jobscripts "{sub_idx}:'
|
65
|
-
+ ",".join(str(i) for i in deps.keys())
|
66
|
-
+ '"'
|
67
|
-
)
|
68
|
-
else:
|
132
|
+
if not deps:
|
69
133
|
return ""
|
134
|
+
return (
|
135
|
+
f"{workflow_app_alias} workflow $WK_PATH_ARG wait --jobscripts "
|
136
|
+
f'"{sub_idx}:{",".join(str(i) for i in deps)}"'
|
137
|
+
)
|
70
138
|
|
71
139
|
@staticmethod
|
72
|
-
def process_app_invoc_executable(app_invoc_exe):
|
140
|
+
def process_app_invoc_executable(app_invoc_exe: str) -> str:
|
73
141
|
"""
|
74
142
|
Perform any post-processing of an application invocation command name.
|
75
143
|
"""
|
76
144
|
return app_invoc_exe
|
77
145
|
|
78
|
-
def process_JS_header_args(
|
146
|
+
def process_JS_header_args(
|
147
|
+
self, header_args: JobscriptHeaderArgs
|
148
|
+
) -> JobscriptHeaderArgs:
|
79
149
|
"""
|
80
150
|
Process the application invocation key in the jobscript header arguments.
|
81
151
|
"""
|
82
|
-
|
83
|
-
if
|
84
|
-
app_invoc
|
85
|
-
|
86
|
-
|
152
|
+
app_invoc_ = header_args["app_invoc"]
|
153
|
+
if not isinstance(app_invoc_, str):
|
154
|
+
app_invoc = self.process_app_invoc_executable(app_invoc_[0])
|
155
|
+
for item in app_invoc_[1:]:
|
156
|
+
app_invoc += f' "{item}"'
|
157
|
+
header_args["app_invoc"] = app_invoc
|
87
158
|
return header_args
|
88
159
|
|
89
160
|
def prepare_JS_path(self, js_path: Path) -> str:
|
@@ -92,8 +163,58 @@ class Shell(ABC):
|
|
92
163
|
"""
|
93
164
|
return str(js_path)
|
94
165
|
|
95
|
-
def prepare_element_run_dirs(self, run_dirs:
|
166
|
+
def prepare_element_run_dirs(self, run_dirs: list[list[Path]]) -> list[list[str]]:
|
96
167
|
"""
|
97
168
|
Prepare the element run directory names for use.
|
98
169
|
"""
|
99
|
-
return [[str(
|
170
|
+
return [[str(path) for path in i] for i in run_dirs]
|
171
|
+
|
172
|
+
@abstractmethod
|
173
|
+
def format_save_parameter(
|
174
|
+
self,
|
175
|
+
workflow_app_alias: str,
|
176
|
+
param_name: str,
|
177
|
+
shell_var_name: str,
|
178
|
+
cmd_idx: int,
|
179
|
+
stderr: bool,
|
180
|
+
app_name: str,
|
181
|
+
) -> str:
|
182
|
+
"""
|
183
|
+
Produce code to save a parameter's value into the workflow persistent store.
|
184
|
+
"""
|
185
|
+
|
186
|
+
@abstractmethod
|
187
|
+
def format_stream_assignment(self, shell_var_name: str, command: str) -> str:
|
188
|
+
"""
|
189
|
+
Format a stream assignment.
|
190
|
+
"""
|
191
|
+
|
192
|
+
@abstractmethod
|
193
|
+
def format_env_var_get(self, var: str) -> str:
|
194
|
+
"""
|
195
|
+
Format retrieval of a shell environment variable.
|
196
|
+
"""
|
197
|
+
|
198
|
+
@abstractmethod
|
199
|
+
def format_array(self, lst: list) -> str:
|
200
|
+
"""
|
201
|
+
Format construction of a shell array.
|
202
|
+
"""
|
203
|
+
|
204
|
+
@abstractmethod
|
205
|
+
def format_array_get_item(self, arr_name: str, index: int | str) -> str:
|
206
|
+
"""
|
207
|
+
Format retrieval of a shell array item at a specified index.
|
208
|
+
"""
|
209
|
+
|
210
|
+
@abstractmethod
|
211
|
+
def format_source_functions_file(self, app_name: str, commands: str) -> str:
|
212
|
+
"""
|
213
|
+
Format sourcing (i.e. invocation) of the jobscript functions file.
|
214
|
+
"""
|
215
|
+
|
216
|
+
@abstractmethod
|
217
|
+
def format_commands_file(self, app_name: str, commands: str) -> str:
|
218
|
+
"""
|
219
|
+
Format the commands file.
|
220
|
+
"""
|