openjd-cli 0.6.1__tar.gz → 0.7.1__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.
- {openjd_cli-0.6.1 → openjd_cli-0.7.1}/PKG-INFO +4 -4
- {openjd_cli-0.6.1 → openjd_cli-0.7.1}/README.md +1 -1
- {openjd_cli-0.6.1/openjd/cli → openjd_cli-0.7.1}/_version.py +2 -2
- openjd_cli-0.7.1/hatch_version_hook.py +156 -0
- {openjd_cli-0.6.1 → openjd_cli-0.7.1}/pyproject.toml +5 -11
- {openjd_cli-0.6.1 → openjd_cli-0.7.1/src}/openjd/cli/_common/__init__.py +11 -3
- {openjd_cli-0.6.1 → openjd_cli-0.7.1/src}/openjd/cli/_common/_extensions.py +1 -1
- {openjd_cli-0.6.1 → openjd_cli-0.7.1/src}/openjd/cli/_common/_job_from_template.py +18 -8
- {openjd_cli-0.6.1 → openjd_cli-0.7.1/src}/openjd/cli/_run/_local_session/_session_manager.py +15 -12
- {openjd_cli-0.6.1 → openjd_cli-0.7.1/src}/openjd/cli/_run/_run_command.py +20 -1
- {openjd_cli-0.6.1 → openjd_cli-0.7.1/src}/openjd/cli/_summary/_summary_command.py +1 -1
- openjd_cli-0.7.1/src/openjd/cli/_version.py +21 -0
- {openjd_cli-0.6.1 → openjd_cli-0.7.1}/.gitignore +0 -0
- {openjd_cli-0.6.1 → openjd_cli-0.7.1}/LICENSE +0 -0
- {openjd_cli-0.6.1 → openjd_cli-0.7.1}/NOTICE +0 -0
- {openjd_cli-0.6.1 → openjd_cli-0.7.1}/hatch.toml +0 -0
- {openjd_cli-0.6.1 → openjd_cli-0.7.1/src}/openjd/__main__.py +0 -0
- {openjd_cli-0.6.1 → openjd_cli-0.7.1/src}/openjd/cli/__init__.py +0 -0
- {openjd_cli-0.6.1 → openjd_cli-0.7.1/src}/openjd/cli/_check/__init__.py +0 -0
- {openjd_cli-0.6.1 → openjd_cli-0.7.1/src}/openjd/cli/_check/_check_command.py +0 -0
- {openjd_cli-0.6.1 → openjd_cli-0.7.1/src}/openjd/cli/_common/_validation_utils.py +0 -0
- {openjd_cli-0.6.1 → openjd_cli-0.7.1/src}/openjd/cli/_create_argparser.py +0 -0
- {openjd_cli-0.6.1 → openjd_cli-0.7.1/src}/openjd/cli/_run/__init__.py +0 -0
- {openjd_cli-0.6.1 → openjd_cli-0.7.1/src}/openjd/cli/_run/_local_session/__init__.py +0 -0
- {openjd_cli-0.6.1 → openjd_cli-0.7.1/src}/openjd/cli/_run/_local_session/_actions.py +0 -0
- {openjd_cli-0.6.1 → openjd_cli-0.7.1/src}/openjd/cli/_run/_local_session/_logs.py +0 -0
- {openjd_cli-0.6.1 → openjd_cli-0.7.1/src}/openjd/cli/_schema/__init__.py +0 -0
- {openjd_cli-0.6.1 → openjd_cli-0.7.1/src}/openjd/cli/_schema/_schema_command.py +0 -0
- {openjd_cli-0.6.1 → openjd_cli-0.7.1/src}/openjd/cli/_summary/__init__.py +0 -0
- {openjd_cli-0.6.1 → openjd_cli-0.7.1/src}/openjd/cli/_summary/_summary_output.py +0 -0
- {openjd_cli-0.6.1 → openjd_cli-0.7.1/src}/openjd/cli/py.typed +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: openjd-cli
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.7.1
|
|
4
4
|
Summary: Provides a command-line interface for working with Open Job Description templates.
|
|
5
5
|
Project-URL: Homepage, https://github.com/OpenJobDescription/openjd-cli
|
|
6
6
|
Project-URL: Source, https://github.com/OpenJobDescription/openjd-cli
|
|
@@ -22,8 +22,8 @@ Classifier: Programming Language :: Python :: 3.10
|
|
|
22
22
|
Classifier: Programming Language :: Python :: 3.11
|
|
23
23
|
Classifier: Programming Language :: Python :: 3.12
|
|
24
24
|
Requires-Python: >=3.9
|
|
25
|
-
Requires-Dist: openjd-model
|
|
26
|
-
Requires-Dist: openjd-sessions<0.11,>=0.10.
|
|
25
|
+
Requires-Dist: openjd-model<0.9,>=0.8
|
|
26
|
+
Requires-Dist: openjd-sessions<0.11,>=0.10.3
|
|
27
27
|
Description-Content-Type: text/markdown
|
|
28
28
|
|
|
29
29
|
## Open Job Description - CLI
|
|
@@ -205,7 +205,7 @@ You can download this package from:
|
|
|
205
205
|
|
|
206
206
|
### Verifying GitHub Releases
|
|
207
207
|
|
|
208
|
-
See [
|
|
208
|
+
See [Verifying GitHub Releases](https://github.com/OpenJobDescription/openjd-cli?tab=security-ov-file#verifying-github-releases) for more information.
|
|
209
209
|
|
|
210
210
|
## Security
|
|
211
211
|
|
|
@@ -177,7 +177,7 @@ You can download this package from:
|
|
|
177
177
|
|
|
178
178
|
### Verifying GitHub Releases
|
|
179
179
|
|
|
180
|
-
See [
|
|
180
|
+
See [Verifying GitHub Releases](https://github.com/OpenJobDescription/openjd-cli?tab=security-ov-file#verifying-github-releases) for more information.
|
|
181
181
|
|
|
182
182
|
## Security
|
|
183
183
|
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
import os
|
|
3
|
+
import shutil
|
|
4
|
+
import sys
|
|
5
|
+
|
|
6
|
+
from dataclasses import dataclass
|
|
7
|
+
from hatchling.builders.hooks.plugin.interface import BuildHookInterface
|
|
8
|
+
from typing import Any, Optional
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
_logger = logging.Logger(__name__, logging.INFO)
|
|
12
|
+
_stdout_handler = logging.StreamHandler(sys.stdout)
|
|
13
|
+
_stdout_handler.addFilter(lambda record: record.levelno <= logging.INFO)
|
|
14
|
+
_stderr_handler = logging.StreamHandler(sys.stderr)
|
|
15
|
+
_stderr_handler.addFilter(lambda record: record.levelno > logging.INFO)
|
|
16
|
+
_logger.addHandler(_stdout_handler)
|
|
17
|
+
_logger.addHandler(_stderr_handler)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
@dataclass
|
|
21
|
+
class CopyConfig:
|
|
22
|
+
sources: list[str]
|
|
23
|
+
destinations: list[str]
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class CustomBuildHookException(Exception):
|
|
27
|
+
pass
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class CustomBuildHook(BuildHookInterface):
|
|
31
|
+
"""
|
|
32
|
+
A Hatch build hook that is pulled in automatically by Hatch's "custom" hook support
|
|
33
|
+
See: https://hatch.pypa.io/1.6/plugins/build-hook/custom/
|
|
34
|
+
This build hook copies files from one location (sources) to another (destinations).
|
|
35
|
+
Config options:
|
|
36
|
+
- `log_level (str)`: The logging level. Any value accepted by logging.Logger.setLevel is allowed. Default is INFO.
|
|
37
|
+
- `copy_map (list[dict])`: A list of mappings of files to copy and the destinations to copy them into. In TOML files,
|
|
38
|
+
this is expressed as an array of tables. See https://toml.io/en/v1.0.0#array-of-tables
|
|
39
|
+
Example TOML config:
|
|
40
|
+
```
|
|
41
|
+
[tool.hatch.build.hooks.custom]
|
|
42
|
+
path = "hatch_hook.py"
|
|
43
|
+
log_level = "DEBUG"
|
|
44
|
+
[[tool.hatch.build.hooks.custom.copy_map]]
|
|
45
|
+
sources = [
|
|
46
|
+
"_version.py",
|
|
47
|
+
]
|
|
48
|
+
destinations = [
|
|
49
|
+
"src/openjd",
|
|
50
|
+
]
|
|
51
|
+
[[tool.hatch.build.hooks.custom.copy_map]]
|
|
52
|
+
sources = [
|
|
53
|
+
"something_the_tests_need.py",
|
|
54
|
+
"something_else_the_tests_need.ini",
|
|
55
|
+
]
|
|
56
|
+
destinations = [
|
|
57
|
+
"test/openjd",
|
|
58
|
+
]
|
|
59
|
+
```
|
|
60
|
+
"""
|
|
61
|
+
|
|
62
|
+
REQUIRED_OPTS = [
|
|
63
|
+
"copy_map",
|
|
64
|
+
]
|
|
65
|
+
|
|
66
|
+
def initialize(self, version: str, build_data: dict[str, Any]) -> None:
|
|
67
|
+
if not self._prepare():
|
|
68
|
+
return
|
|
69
|
+
|
|
70
|
+
for copy_cfg in self.copy_map:
|
|
71
|
+
_logger.info(f"Copying {copy_cfg.sources} to {copy_cfg.destinations}")
|
|
72
|
+
for destination in copy_cfg.destinations:
|
|
73
|
+
for source in copy_cfg.sources:
|
|
74
|
+
copy_func = shutil.copy if os.path.isfile(source) else shutil.copytree
|
|
75
|
+
copy_func(
|
|
76
|
+
os.path.join(self.root, source),
|
|
77
|
+
os.path.join(self.root, destination),
|
|
78
|
+
)
|
|
79
|
+
_logger.info("Copy complete")
|
|
80
|
+
|
|
81
|
+
def clean(self, versions: list[str]) -> None:
|
|
82
|
+
if not self._prepare():
|
|
83
|
+
return
|
|
84
|
+
|
|
85
|
+
for copy_cfg in self.copy_map:
|
|
86
|
+
_logger.info(f"Cleaning {copy_cfg.sources} from {copy_cfg.destinations}")
|
|
87
|
+
cleaned_count = 0
|
|
88
|
+
for destination in copy_cfg.destinations:
|
|
89
|
+
for source in copy_cfg.sources:
|
|
90
|
+
source_path = os.path.join(self.root, destination, source)
|
|
91
|
+
remove_func = os.remove if os.path.isfile(source_path) else os.rmdir
|
|
92
|
+
try:
|
|
93
|
+
remove_func(source_path)
|
|
94
|
+
except FileNotFoundError:
|
|
95
|
+
_logger.debug(f"Skipping {source_path} because it does not exist...")
|
|
96
|
+
else:
|
|
97
|
+
cleaned_count += 1
|
|
98
|
+
_logger.info(f"Cleaned {cleaned_count} items")
|
|
99
|
+
|
|
100
|
+
def _prepare(self) -> bool:
|
|
101
|
+
missing_required_opts = [
|
|
102
|
+
opt for opt in self.REQUIRED_OPTS if opt not in self.config or not self.config[opt]
|
|
103
|
+
]
|
|
104
|
+
if missing_required_opts:
|
|
105
|
+
_logger.warn(
|
|
106
|
+
f"Required options {missing_required_opts} are missing or empty. "
|
|
107
|
+
"Contining without copying sources to destinations...",
|
|
108
|
+
file=sys.stderr,
|
|
109
|
+
)
|
|
110
|
+
return False
|
|
111
|
+
|
|
112
|
+
log_level = self.config.get("log_level")
|
|
113
|
+
if log_level:
|
|
114
|
+
_logger.setLevel(log_level)
|
|
115
|
+
|
|
116
|
+
return True
|
|
117
|
+
|
|
118
|
+
@property
|
|
119
|
+
def copy_map(self) -> Optional[list[CopyConfig]]:
|
|
120
|
+
raw_copy_map: list[dict] = self.config.get("copy_map")
|
|
121
|
+
if not raw_copy_map:
|
|
122
|
+
return None
|
|
123
|
+
|
|
124
|
+
if not (
|
|
125
|
+
isinstance(raw_copy_map, list)
|
|
126
|
+
and all(isinstance(copy_cfg, dict) for copy_cfg in raw_copy_map)
|
|
127
|
+
):
|
|
128
|
+
raise CustomBuildHookException(
|
|
129
|
+
f'"copy_map" config option is a nonvalid type. Expected list[dict], but got {raw_copy_map}'
|
|
130
|
+
)
|
|
131
|
+
|
|
132
|
+
def verify_list_of_file_paths(file_paths: Any, config_name: str):
|
|
133
|
+
if not (isinstance(file_paths, list) and all(isinstance(fp, str) for fp in file_paths)):
|
|
134
|
+
raise CustomBuildHookException(
|
|
135
|
+
f'"{config_name}" config option is a nonvalid type. Expected list[str], but got {file_paths}'
|
|
136
|
+
)
|
|
137
|
+
|
|
138
|
+
missing_paths = [
|
|
139
|
+
fp for fp in file_paths if not os.path.exists(os.path.join(self.root, fp))
|
|
140
|
+
]
|
|
141
|
+
if len(missing_paths) > 0:
|
|
142
|
+
raise CustomBuildHookException(
|
|
143
|
+
f'"{config_name}" config option contains some file paths that do not exist: {missing_paths}'
|
|
144
|
+
)
|
|
145
|
+
|
|
146
|
+
copy_map: list[CopyConfig] = []
|
|
147
|
+
for copy_cfg in raw_copy_map:
|
|
148
|
+
destinations: list[str] = copy_cfg.get("destinations")
|
|
149
|
+
verify_list_of_file_paths(destinations, "destinations")
|
|
150
|
+
|
|
151
|
+
sources: list[str] = copy_cfg.get("sources")
|
|
152
|
+
verify_list_of_file_paths(sources, "source")
|
|
153
|
+
|
|
154
|
+
copy_map.append(CopyConfig(sources, destinations))
|
|
155
|
+
|
|
156
|
+
return copy_map
|
|
@@ -29,8 +29,8 @@ classifiers = [
|
|
|
29
29
|
"Intended Audience :: End Users/Desktop"
|
|
30
30
|
]
|
|
31
31
|
dependencies = [
|
|
32
|
-
"openjd-sessions >= 0.10.
|
|
33
|
-
"openjd-model
|
|
32
|
+
"openjd-sessions >= 0.10.3,< 0.11",
|
|
33
|
+
"openjd-model >= 0.8,< 0.9"
|
|
34
34
|
]
|
|
35
35
|
|
|
36
36
|
[project.urls]
|
|
@@ -46,8 +46,6 @@ openjd = "openjd.cli:main"
|
|
|
46
46
|
artifacts = [
|
|
47
47
|
"*_version.py",
|
|
48
48
|
]
|
|
49
|
-
only-packages = true
|
|
50
|
-
|
|
51
49
|
|
|
52
50
|
[tool.hatch.version]
|
|
53
51
|
source = "vcs"
|
|
@@ -70,15 +68,10 @@ destinations = [
|
|
|
70
68
|
]
|
|
71
69
|
|
|
72
70
|
[tool.hatch.build.targets.sdist]
|
|
73
|
-
|
|
71
|
+
include = [
|
|
74
72
|
"src/openjd",
|
|
73
|
+
"hatch_version_hook.py",
|
|
75
74
|
]
|
|
76
|
-
only-include = [
|
|
77
|
-
"src/openjd",
|
|
78
|
-
]
|
|
79
|
-
|
|
80
|
-
[tool.hatch.build.targets.sdist.force-include]
|
|
81
|
-
"src/openjd/__main__.py" = "openjd/__main__.py"
|
|
82
75
|
|
|
83
76
|
[tool.hatch.build.targets.wheel]
|
|
84
77
|
packages = [
|
|
@@ -176,6 +169,7 @@ omit= [
|
|
|
176
169
|
# Can be removed or set to true once we are v1
|
|
177
170
|
major_on_zero = false
|
|
178
171
|
tag_format = "{version}"
|
|
172
|
+
allow_zero_version = true
|
|
179
173
|
|
|
180
174
|
[tool.semantic_release.commit_parser_options]
|
|
181
175
|
allowed_tags = [
|
|
@@ -9,7 +9,7 @@ import json
|
|
|
9
9
|
import yaml
|
|
10
10
|
import os
|
|
11
11
|
|
|
12
|
-
from ._extensions import add_extensions_argument, process_extensions_argument
|
|
12
|
+
from ._extensions import add_extensions_argument, process_extensions_argument, SUPPORTED_EXTENSIONS
|
|
13
13
|
from ._job_from_template import (
|
|
14
14
|
job_from_template,
|
|
15
15
|
get_job_params,
|
|
@@ -21,7 +21,7 @@ from ._validation_utils import (
|
|
|
21
21
|
read_job_template,
|
|
22
22
|
read_environment_template,
|
|
23
23
|
)
|
|
24
|
-
from openjd.model import DecodeValidationError, Job
|
|
24
|
+
from openjd.model import DecodeValidationError, Job, JobParameterValues, EnvironmentTemplate
|
|
25
25
|
|
|
26
26
|
__all__ = [
|
|
27
27
|
"add_extensions_argument",
|
|
@@ -33,6 +33,7 @@ __all__ = [
|
|
|
33
33
|
"read_job_template",
|
|
34
34
|
"read_environment_template",
|
|
35
35
|
"validate_task_parameters",
|
|
36
|
+
"SUPPORTED_EXTENSIONS",
|
|
36
37
|
]
|
|
37
38
|
|
|
38
39
|
|
|
@@ -112,13 +113,20 @@ class SubparserGroup:
|
|
|
112
113
|
return self.group.add_parser(name, **kwargs)
|
|
113
114
|
|
|
114
115
|
|
|
115
|
-
def generate_job(
|
|
116
|
+
def generate_job(
|
|
117
|
+
args: Namespace,
|
|
118
|
+
environments: list[EnvironmentTemplate] = [],
|
|
119
|
+
*,
|
|
120
|
+
supported_extensions: list[str],
|
|
121
|
+
) -> tuple[Job, JobParameterValues]:
|
|
116
122
|
try:
|
|
117
123
|
# Raises: RuntimeError, DecodeValidationError
|
|
118
124
|
template = read_job_template(args.path, supported_extensions=supported_extensions)
|
|
125
|
+
|
|
119
126
|
# Raises: RuntimeError
|
|
120
127
|
return job_from_template(
|
|
121
128
|
template,
|
|
129
|
+
environments,
|
|
122
130
|
args.job_params if args.job_params else None,
|
|
123
131
|
Path(os.path.abspath(args.path.parent)),
|
|
124
132
|
Path(os.getcwd()),
|
|
@@ -4,7 +4,7 @@ from argparse import ArgumentParser
|
|
|
4
4
|
from typing import Optional
|
|
5
5
|
|
|
6
6
|
# This is the list of Open Job Description extensions with implemented support
|
|
7
|
-
SUPPORTED_EXTENSIONS = ["TASK_CHUNKING"]
|
|
7
|
+
SUPPORTED_EXTENSIONS = ["TASK_CHUNKING", "REDACTED_ENV_VARS"]
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
def add_extensions_argument(run_parser: ArgumentParser):
|
|
@@ -4,14 +4,16 @@ from __future__ import annotations
|
|
|
4
4
|
import json
|
|
5
5
|
from pathlib import Path
|
|
6
6
|
import re
|
|
7
|
-
from typing import Union
|
|
7
|
+
from typing import Optional, Union
|
|
8
8
|
import yaml
|
|
9
9
|
|
|
10
10
|
from ._validation_utils import get_doc_type
|
|
11
11
|
from openjd.model import (
|
|
12
12
|
DecodeValidationError,
|
|
13
13
|
DocumentType,
|
|
14
|
+
EnvironmentTemplate,
|
|
14
15
|
Job,
|
|
16
|
+
JobParameterValues,
|
|
15
17
|
JobTemplate,
|
|
16
18
|
create_job,
|
|
17
19
|
preprocess_job_parameters,
|
|
@@ -54,7 +56,7 @@ def get_params_from_file(parameter_string: str) -> Union[dict, list]:
|
|
|
54
56
|
return parameters
|
|
55
57
|
|
|
56
58
|
|
|
57
|
-
def get_job_params(parameter_args: list[str]) -> dict:
|
|
59
|
+
def get_job_params(parameter_args: Optional[list[str]]) -> dict:
|
|
58
60
|
"""
|
|
59
61
|
Resolves Job Parameters from a list of command-line arguments.
|
|
60
62
|
Arguments may be a filepath or a string with format 'Key=Value'.
|
|
@@ -62,7 +64,8 @@ def get_job_params(parameter_args: list[str]) -> dict:
|
|
|
62
64
|
Raises: RuntimeError if the provided Parameters are formatted incorrectly or can't be opened
|
|
63
65
|
"""
|
|
64
66
|
parameter_dict: dict = {}
|
|
65
|
-
|
|
67
|
+
|
|
68
|
+
for arg in parameter_args or []:
|
|
66
69
|
arg = arg.strip()
|
|
67
70
|
# Case 1: Provided argument is a filepath
|
|
68
71
|
if arg.startswith("file://"):
|
|
@@ -104,17 +107,18 @@ def get_job_params(parameter_args: list[str]) -> dict:
|
|
|
104
107
|
|
|
105
108
|
def job_from_template(
|
|
106
109
|
template: JobTemplate,
|
|
110
|
+
environments: list[EnvironmentTemplate],
|
|
107
111
|
parameter_args: list[str] | None,
|
|
108
112
|
job_template_dir: Path,
|
|
109
113
|
current_working_dir: Path,
|
|
110
|
-
) -> Job:
|
|
114
|
+
) -> tuple[Job, JobParameterValues]:
|
|
111
115
|
"""
|
|
112
|
-
Given a decoded Job Template and a user-
|
|
113
|
-
generates a Job object.
|
|
116
|
+
Given a decoded Job Template and a user-input parameter dictionary,
|
|
117
|
+
generates a Job object and the parameter values for running the job.
|
|
114
118
|
|
|
115
119
|
Raises: RuntimeError if parameters are an unsupported type or don't correspond to the template
|
|
116
120
|
"""
|
|
117
|
-
parameter_dict = get_job_params(parameter_args)
|
|
121
|
+
parameter_dict = get_job_params(parameter_args)
|
|
118
122
|
|
|
119
123
|
try:
|
|
120
124
|
parameter_values = preprocess_job_parameters(
|
|
@@ -122,11 +126,17 @@ def job_from_template(
|
|
|
122
126
|
job_parameter_values=parameter_dict,
|
|
123
127
|
job_template_dir=job_template_dir,
|
|
124
128
|
current_working_dir=current_working_dir,
|
|
129
|
+
environment_templates=environments,
|
|
125
130
|
)
|
|
126
131
|
except ValueError as ve:
|
|
127
132
|
raise RuntimeError(str(ve))
|
|
128
133
|
|
|
129
134
|
try:
|
|
130
|
-
|
|
135
|
+
job = create_job(
|
|
136
|
+
job_template=template,
|
|
137
|
+
job_parameter_values=parameter_values,
|
|
138
|
+
environment_templates=environments,
|
|
139
|
+
)
|
|
140
|
+
return (job, parameter_values)
|
|
131
141
|
except DecodeValidationError as dve:
|
|
132
142
|
raise RuntimeError(f"Could not generate Job from template and parameters: {str(dve)}")
|
{openjd_cli-0.6.1 → openjd_cli-0.7.1/src}/openjd/cli/_run/_local_session/_session_manager.py
RENAMED
|
@@ -17,12 +17,14 @@ from ._actions import (
|
|
|
17
17
|
EnvironmentType,
|
|
18
18
|
)
|
|
19
19
|
from ._logs import LocalSessionLogHandler, LogEntry, LoggingTimestampFormat
|
|
20
|
+
from ..._common import SUPPORTED_EXTENSIONS
|
|
21
|
+
|
|
20
22
|
from openjd.model import (
|
|
21
23
|
IntRangeExpr,
|
|
22
24
|
Job,
|
|
23
25
|
JobParameterValues,
|
|
24
|
-
|
|
25
|
-
|
|
26
|
+
RevisionExtensions,
|
|
27
|
+
SpecificationRevision,
|
|
26
28
|
Step,
|
|
27
29
|
StepParameterSpaceIterator,
|
|
28
30
|
TaskParameterSet,
|
|
@@ -78,12 +80,16 @@ class LocalSession:
|
|
|
78
80
|
self,
|
|
79
81
|
*,
|
|
80
82
|
job: Job,
|
|
83
|
+
job_parameter_values: JobParameterValues,
|
|
81
84
|
session_id: str,
|
|
82
85
|
timestamp_format: LoggingTimestampFormat = LoggingTimestampFormat.RELATIVE,
|
|
83
86
|
path_mapping_rules: Optional[list[PathMappingRule]] = None,
|
|
84
87
|
environments: Optional[list[Any]] = None,
|
|
85
88
|
should_print_logs: bool = True,
|
|
86
89
|
retain_working_dir: bool = False,
|
|
90
|
+
revision_extensions: RevisionExtensions = RevisionExtensions(
|
|
91
|
+
spec_rev=SpecificationRevision.v2023_09, supported_extensions=SUPPORTED_EXTENSIONS
|
|
92
|
+
),
|
|
87
93
|
):
|
|
88
94
|
self.session_id = session_id
|
|
89
95
|
self._action_ended = Event()
|
|
@@ -93,21 +99,13 @@ class LocalSession:
|
|
|
93
99
|
self._environments = environments
|
|
94
100
|
|
|
95
101
|
# Create an OpenJD Session
|
|
96
|
-
job_parameters: JobParameterValues
|
|
97
|
-
if job.parameters:
|
|
98
|
-
job_parameters = {
|
|
99
|
-
name: ParameterValue(type=ParameterValueType(param.type.value), value=param.value)
|
|
100
|
-
for name, param in job.parameters.items()
|
|
101
|
-
}
|
|
102
|
-
else:
|
|
103
|
-
job_parameters = dict[str, ParameterValue]()
|
|
104
|
-
|
|
105
102
|
self._openjd_session = Session(
|
|
106
103
|
session_id=self.session_id,
|
|
107
|
-
job_parameter_values=
|
|
104
|
+
job_parameter_values=job_parameter_values,
|
|
108
105
|
path_mapping_rules=self._path_mapping_rules,
|
|
109
106
|
callback=self._action_callback,
|
|
110
107
|
retain_working_dir=retain_working_dir,
|
|
108
|
+
revision_extensions=revision_extensions,
|
|
111
109
|
)
|
|
112
110
|
|
|
113
111
|
self._should_print_logs = should_print_logs
|
|
@@ -131,6 +129,11 @@ class LocalSession:
|
|
|
131
129
|
signal(SIGTERM, SIG_DFL)
|
|
132
130
|
self._started = False
|
|
133
131
|
|
|
132
|
+
# A blank line to separate the job log output from this status message
|
|
133
|
+
LOG.info(
|
|
134
|
+
msg="",
|
|
135
|
+
extra={"session_id": self.session_id},
|
|
136
|
+
)
|
|
134
137
|
if self.failed:
|
|
135
138
|
LOG.info(
|
|
136
139
|
msg=f"Open Job Description CLI: ERROR executing action: '{self.failed_action}' (see Task logs for details)",
|
|
@@ -28,11 +28,14 @@ from openjd.model import (
|
|
|
28
28
|
DecodeValidationError,
|
|
29
29
|
EnvironmentTemplate,
|
|
30
30
|
Job,
|
|
31
|
+
JobParameterValues,
|
|
31
32
|
Step,
|
|
32
33
|
StepDependencyGraph,
|
|
33
34
|
StepParameterSpaceIterator,
|
|
34
35
|
ParameterValue,
|
|
35
36
|
ParameterValueType,
|
|
37
|
+
RevisionExtensions,
|
|
38
|
+
SpecificationRevision,
|
|
36
39
|
TaskParameterSet,
|
|
37
40
|
)
|
|
38
41
|
from openjd.sessions import PathMappingRule, LOG
|
|
@@ -317,6 +320,7 @@ def _validate_task_params(step: Step, task_params: list[dict[str, str]]) -> None
|
|
|
317
320
|
def _run_local_session(
|
|
318
321
|
*,
|
|
319
322
|
job: Job,
|
|
323
|
+
job_parameter_values: JobParameterValues,
|
|
320
324
|
step_list: list[Step],
|
|
321
325
|
selected_step: Optional[Step],
|
|
322
326
|
timestamp_format: LoggingTimestampFormat,
|
|
@@ -326,6 +330,9 @@ def _run_local_session(
|
|
|
326
330
|
path_mapping_rules: Optional[list[PathMappingRule]],
|
|
327
331
|
should_print_logs: bool = True,
|
|
328
332
|
retain_working_dir: bool = False,
|
|
333
|
+
revision_extensions: RevisionExtensions = RevisionExtensions(
|
|
334
|
+
spec_rev=SpecificationRevision.v2023_09, supported_extensions=[]
|
|
335
|
+
),
|
|
329
336
|
) -> OpenJDCliResult:
|
|
330
337
|
"""
|
|
331
338
|
Creates a Session object and listens for log messages to synchronously end the session.
|
|
@@ -337,12 +344,14 @@ def _run_local_session(
|
|
|
337
344
|
step_name = ""
|
|
338
345
|
with LocalSession(
|
|
339
346
|
job=job,
|
|
347
|
+
job_parameter_values=job_parameter_values,
|
|
340
348
|
timestamp_format=timestamp_format,
|
|
341
349
|
session_id="CLI-session",
|
|
342
350
|
path_mapping_rules=path_mapping_rules,
|
|
343
351
|
environments=[env.environment for env in environments] if environments else [],
|
|
344
352
|
should_print_logs=should_print_logs,
|
|
345
353
|
retain_working_dir=retain_working_dir,
|
|
354
|
+
revision_extensions=revision_extensions,
|
|
346
355
|
) as session:
|
|
347
356
|
for dep_step in step_list:
|
|
348
357
|
step_name = dep_step.name
|
|
@@ -442,7 +451,9 @@ def do_run(args: Namespace) -> OpenJDCliResult:
|
|
|
442
451
|
|
|
443
452
|
try:
|
|
444
453
|
# Raises: RuntimeError
|
|
445
|
-
the_job = generate_job(
|
|
454
|
+
the_job, job_parameter_values = generate_job(
|
|
455
|
+
args, environments, supported_extensions=extensions
|
|
456
|
+
)
|
|
446
457
|
|
|
447
458
|
# Map Step names to Step objects so they can be easily accessed
|
|
448
459
|
step_map = {step.name: step for step in the_job.steps}
|
|
@@ -507,8 +518,15 @@ def do_run(args: Namespace) -> OpenJDCliResult:
|
|
|
507
518
|
except RuntimeError as rte:
|
|
508
519
|
return OpenJDCliResult(status="error", message=str(rte))
|
|
509
520
|
|
|
521
|
+
# Create a RevisionExtensions object with the default specification version and enabled extensions
|
|
522
|
+
# We use the default v2023_09 since that's what we're currently supporting
|
|
523
|
+
revision_extensions = RevisionExtensions(
|
|
524
|
+
spec_rev=the_job.revision, supported_extensions=extensions
|
|
525
|
+
)
|
|
526
|
+
|
|
510
527
|
return _run_local_session(
|
|
511
528
|
job=the_job,
|
|
529
|
+
job_parameter_values=job_parameter_values,
|
|
512
530
|
step_list=step_list,
|
|
513
531
|
selected_step=selected_step,
|
|
514
532
|
task_parameter_values=task_parameter_values,
|
|
@@ -518,4 +536,5 @@ def do_run(args: Namespace) -> OpenJDCliResult:
|
|
|
518
536
|
path_mapping_rules=path_mapping_rules,
|
|
519
537
|
should_print_logs=(args.output == "human-readable"),
|
|
520
538
|
retain_working_dir=args.preserve,
|
|
539
|
+
revision_extensions=revision_extensions,
|
|
521
540
|
)
|
|
@@ -35,7 +35,7 @@ def do_summary(args: Namespace) -> OpenJDCliResult:
|
|
|
35
35
|
|
|
36
36
|
try:
|
|
37
37
|
# Raises: RuntimeError
|
|
38
|
-
sample_job = generate_job(args, supported_extensions=extensions)
|
|
38
|
+
sample_job, _ = generate_job(args, supported_extensions=extensions)
|
|
39
39
|
except RuntimeError as rte:
|
|
40
40
|
return OpenJDCliResult(status="error", message=str(rte))
|
|
41
41
|
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# file generated by setuptools-scm
|
|
2
|
+
# don't change, don't track in version control
|
|
3
|
+
|
|
4
|
+
__all__ = ["__version__", "__version_tuple__", "version", "version_tuple"]
|
|
5
|
+
|
|
6
|
+
TYPE_CHECKING = False
|
|
7
|
+
if TYPE_CHECKING:
|
|
8
|
+
from typing import Tuple
|
|
9
|
+
from typing import Union
|
|
10
|
+
|
|
11
|
+
VERSION_TUPLE = Tuple[Union[int, str], ...]
|
|
12
|
+
else:
|
|
13
|
+
VERSION_TUPLE = object
|
|
14
|
+
|
|
15
|
+
version: str
|
|
16
|
+
__version__: str
|
|
17
|
+
__version_tuple__: VERSION_TUPLE
|
|
18
|
+
version_tuple: VERSION_TUPLE
|
|
19
|
+
|
|
20
|
+
__version__ = version = '0.7.1'
|
|
21
|
+
__version_tuple__ = version_tuple = (0, 7, 1)
|
|
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
|
|
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
|
|
File without changes
|