openjd-cli 0.7.2__tar.gz → 0.7.4__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.7.2 → openjd_cli-0.7.4}/PKG-INFO +1 -1
- {openjd_cli-0.7.2 → openjd_cli-0.7.4}/_version.py +2 -2
- {openjd_cli-0.7.2 → openjd_cli-0.7.4}/pyproject.toml +1 -0
- {openjd_cli-0.7.2 → openjd_cli-0.7.4}/src/openjd/cli/_common/_validation_utils.py +3 -2
- {openjd_cli-0.7.2 → openjd_cli-0.7.4}/src/openjd/cli/_run/__init__.py +11 -0
- openjd_cli-0.7.4/src/openjd/cli/_run/_help_formatter.py +353 -0
- {openjd_cli-0.7.2 → openjd_cli-0.7.4}/src/openjd/cli/_run/_run_command.py +27 -3
- {openjd_cli-0.7.2 → openjd_cli-0.7.4}/src/openjd/cli/_version.py +2 -2
- {openjd_cli-0.7.2 → openjd_cli-0.7.4}/.gitignore +0 -0
- {openjd_cli-0.7.2 → openjd_cli-0.7.4}/LICENSE +0 -0
- {openjd_cli-0.7.2 → openjd_cli-0.7.4}/NOTICE +0 -0
- {openjd_cli-0.7.2 → openjd_cli-0.7.4}/README.md +0 -0
- {openjd_cli-0.7.2 → openjd_cli-0.7.4}/hatch.toml +0 -0
- {openjd_cli-0.7.2 → openjd_cli-0.7.4}/hatch_version_hook.py +0 -0
- {openjd_cli-0.7.2 → openjd_cli-0.7.4}/src/openjd/__main__.py +0 -0
- {openjd_cli-0.7.2 → openjd_cli-0.7.4}/src/openjd/cli/__init__.py +0 -0
- {openjd_cli-0.7.2 → openjd_cli-0.7.4}/src/openjd/cli/_check/__init__.py +0 -0
- {openjd_cli-0.7.2 → openjd_cli-0.7.4}/src/openjd/cli/_check/_check_command.py +0 -0
- {openjd_cli-0.7.2 → openjd_cli-0.7.4}/src/openjd/cli/_common/__init__.py +0 -0
- {openjd_cli-0.7.2 → openjd_cli-0.7.4}/src/openjd/cli/_common/_extensions.py +0 -0
- {openjd_cli-0.7.2 → openjd_cli-0.7.4}/src/openjd/cli/_common/_job_from_template.py +0 -0
- {openjd_cli-0.7.2 → openjd_cli-0.7.4}/src/openjd/cli/_create_argparser.py +0 -0
- {openjd_cli-0.7.2 → openjd_cli-0.7.4}/src/openjd/cli/_run/_local_session/__init__.py +0 -0
- {openjd_cli-0.7.2 → openjd_cli-0.7.4}/src/openjd/cli/_run/_local_session/_actions.py +0 -0
- {openjd_cli-0.7.2 → openjd_cli-0.7.4}/src/openjd/cli/_run/_local_session/_logs.py +0 -0
- {openjd_cli-0.7.2 → openjd_cli-0.7.4}/src/openjd/cli/_run/_local_session/_session_manager.py +0 -0
- {openjd_cli-0.7.2 → openjd_cli-0.7.4}/src/openjd/cli/_schema/__init__.py +0 -0
- {openjd_cli-0.7.2 → openjd_cli-0.7.4}/src/openjd/cli/_schema/_schema_command.py +0 -0
- {openjd_cli-0.7.2 → openjd_cli-0.7.4}/src/openjd/cli/_summary/__init__.py +0 -0
- {openjd_cli-0.7.2 → openjd_cli-0.7.4}/src/openjd/cli/_summary/_summary_command.py +0 -0
- {openjd_cli-0.7.2 → openjd_cli-0.7.4}/src/openjd/cli/_summary/_summary_output.py +0 -0
- {openjd_cli-0.7.2 → openjd_cli-0.7.4}/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.7.
|
|
3
|
+
Version: 0.7.4
|
|
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
|
|
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
|
|
|
28
28
|
commit_id: COMMIT_ID
|
|
29
29
|
__commit_id__: COMMIT_ID
|
|
30
30
|
|
|
31
|
-
__version__ = version = '0.7.
|
|
32
|
-
__version_tuple__ = version_tuple = (0, 7,
|
|
31
|
+
__version__ = version = '0.7.4'
|
|
32
|
+
__version_tuple__ = version_tuple = (0, 7, 4)
|
|
33
33
|
|
|
34
34
|
__commit_id__ = commit_id = None
|
|
@@ -15,11 +15,12 @@ from openjd.model import (
|
|
|
15
15
|
|
|
16
16
|
|
|
17
17
|
def get_doc_type(filepath: Path) -> DocumentType:
|
|
18
|
+
# If the file has a .json extension, treat it strictly
|
|
19
|
+
# as JSON, otherwise treat it as YAML.
|
|
18
20
|
if filepath.suffix.lower() == ".json":
|
|
19
21
|
return DocumentType.JSON
|
|
20
|
-
|
|
22
|
+
else:
|
|
21
23
|
return DocumentType.YAML
|
|
22
|
-
raise RuntimeError(f"'{str(filepath)}' is not JSON or YAML.")
|
|
23
24
|
|
|
24
25
|
|
|
25
26
|
def read_template(template_file: Path) -> dict[str, Any]:
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
2
2
|
|
|
3
3
|
from ._run_command import add_run_arguments, do_run
|
|
4
|
+
from ._help_formatter import JobTemplateHelpAction
|
|
4
5
|
from .._common import add_common_arguments, CommonArgument, SubparserGroup
|
|
5
6
|
|
|
6
7
|
|
|
@@ -10,7 +11,17 @@ def populate_argparser(subcommands: SubparserGroup) -> None:
|
|
|
10
11
|
"run",
|
|
11
12
|
description="Takes a Job Template and runs the entire job or a selected Step from the job.",
|
|
12
13
|
usage="openjd run JOB_TEMPLATE_PATH [arguments]",
|
|
14
|
+
add_help=False, # Disable default help to use custom action
|
|
13
15
|
)
|
|
14
16
|
add_common_arguments(run_parser, {CommonArgument.PATH, CommonArgument.JOB_PARAMS})
|
|
15
17
|
add_run_arguments(run_parser)
|
|
18
|
+
|
|
19
|
+
# Add custom help action that provides context-aware help based on job template
|
|
20
|
+
run_parser.add_argument(
|
|
21
|
+
"-h",
|
|
22
|
+
"--help",
|
|
23
|
+
action=JobTemplateHelpAction,
|
|
24
|
+
help="Show help message. When a job template path is provided, displays job-specific help including parameter definitions.",
|
|
25
|
+
)
|
|
26
|
+
|
|
16
27
|
run_parser.set_defaults(func=do_run)
|
|
@@ -0,0 +1,353 @@
|
|
|
1
|
+
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
2
|
+
|
|
3
|
+
"""
|
|
4
|
+
Help formatter module for generating context-aware help text for job templates.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from argparse import Action, ArgumentParser, Namespace
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
import sys
|
|
10
|
+
import textwrap
|
|
11
|
+
from typing import Any, Dict, Optional
|
|
12
|
+
|
|
13
|
+
from openjd.model import DecodeValidationError, JobTemplate
|
|
14
|
+
from .._common import read_job_template, process_extensions_argument
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def format_parameter_info(param_def: Dict[str, Any]) -> str:
|
|
18
|
+
"""
|
|
19
|
+
Format a single parameter definition for help display.
|
|
20
|
+
|
|
21
|
+
This function converts a parameter definition from a job template into
|
|
22
|
+
readable help text that includes the parameter's type, constraints, and
|
|
23
|
+
default value (if any).
|
|
24
|
+
|
|
25
|
+
Args:
|
|
26
|
+
param_def: Parameter definition dictionary from job template containing:
|
|
27
|
+
- name (str): Parameter name
|
|
28
|
+
- type (str): Parameter type (STRING, INT, FLOAT, PATH)
|
|
29
|
+
- description (str, optional): Parameter description
|
|
30
|
+
- default (Any, optional): Default value
|
|
31
|
+
- minValue (int|float, optional): Minimum value for numeric types
|
|
32
|
+
- maxValue (int|float, optional): Maximum value for numeric types
|
|
33
|
+
- minLength (int, optional): Minimum length for string types
|
|
34
|
+
- maxLength (int, optional): Maximum length for string types
|
|
35
|
+
- allowedValues (list, optional): List of allowed values
|
|
36
|
+
|
|
37
|
+
Returns:
|
|
38
|
+
Formatted string describing the parameter in argparse-style help format.
|
|
39
|
+
|
|
40
|
+
Example output formats:
|
|
41
|
+
"ParamName (STRING) [required]"
|
|
42
|
+
"ParamName (INT) [default: 42]"
|
|
43
|
+
"ParamName (FLOAT) [default: 3.14] (range: 0.0 to 10.0)"
|
|
44
|
+
"ParamName (STRING) [default: 'hello'] (allowed: 'hello', 'world')"
|
|
45
|
+
"""
|
|
46
|
+
param_name = param_def.get("name", "")
|
|
47
|
+
param_type = param_def.get("type", "STRING")
|
|
48
|
+
description = param_def.get("description", "")
|
|
49
|
+
default_value = param_def.get("default")
|
|
50
|
+
|
|
51
|
+
# Start building the parameter info string
|
|
52
|
+
parts = []
|
|
53
|
+
|
|
54
|
+
# Add parameter name and type
|
|
55
|
+
type_info = f"{param_name} ({param_type})"
|
|
56
|
+
parts.append(type_info)
|
|
57
|
+
|
|
58
|
+
# Add required/default status
|
|
59
|
+
has_multiline_default = False
|
|
60
|
+
if default_value is not None:
|
|
61
|
+
# Check if default value contains newlines (multi-line string)
|
|
62
|
+
if (
|
|
63
|
+
param_type in ("STRING", "PATH")
|
|
64
|
+
and isinstance(default_value, str)
|
|
65
|
+
and "\n" in default_value
|
|
66
|
+
):
|
|
67
|
+
has_multiline_default = True
|
|
68
|
+
parts.append("[default: see below]")
|
|
69
|
+
else:
|
|
70
|
+
# Format default value based on type
|
|
71
|
+
if param_type in ("STRING", "PATH"):
|
|
72
|
+
default_str = f"[default: '{default_value}']"
|
|
73
|
+
else:
|
|
74
|
+
default_str = f"[default: {default_value}]"
|
|
75
|
+
parts.append(default_str)
|
|
76
|
+
else:
|
|
77
|
+
parts.append("[required]")
|
|
78
|
+
|
|
79
|
+
# Build the first line with name, type, and default/required
|
|
80
|
+
first_line = " ".join(parts)
|
|
81
|
+
|
|
82
|
+
# Build constraint information
|
|
83
|
+
constraints = []
|
|
84
|
+
|
|
85
|
+
# Handle numeric constraints (minValue, maxValue)
|
|
86
|
+
min_val = param_def.get("minValue")
|
|
87
|
+
max_val = param_def.get("maxValue")
|
|
88
|
+
|
|
89
|
+
if min_val is not None and max_val is not None:
|
|
90
|
+
constraints.append(f"range: {min_val} to {max_val}")
|
|
91
|
+
elif min_val is not None:
|
|
92
|
+
constraints.append(f"minimum: {min_val}")
|
|
93
|
+
elif max_val is not None:
|
|
94
|
+
constraints.append(f"maximum: {max_val}")
|
|
95
|
+
|
|
96
|
+
# Handle string length constraints
|
|
97
|
+
min_len = param_def.get("minLength")
|
|
98
|
+
max_len = param_def.get("maxLength")
|
|
99
|
+
|
|
100
|
+
if min_len is not None and max_len is not None:
|
|
101
|
+
constraints.append(f"length: {min_len} to {max_len} characters")
|
|
102
|
+
elif min_len is not None:
|
|
103
|
+
constraints.append(f"minimum length: {min_len} characters")
|
|
104
|
+
elif max_len is not None:
|
|
105
|
+
constraints.append(f"maximum length: {max_len} characters")
|
|
106
|
+
|
|
107
|
+
# Handle allowed values constraint
|
|
108
|
+
allowed_values = param_def.get("allowedValues")
|
|
109
|
+
if allowed_values:
|
|
110
|
+
# Format allowed values based on type
|
|
111
|
+
if param_type in ("STRING", "PATH"):
|
|
112
|
+
formatted_values = ", ".join(f"'{v}'" for v in allowed_values)
|
|
113
|
+
else:
|
|
114
|
+
formatted_values = ", ".join(str(v) for v in allowed_values)
|
|
115
|
+
constraints.append(f"allowed: {formatted_values}")
|
|
116
|
+
|
|
117
|
+
# Combine everything
|
|
118
|
+
result_lines = [first_line]
|
|
119
|
+
|
|
120
|
+
# Add description if present
|
|
121
|
+
if description:
|
|
122
|
+
result_lines.append(f" {description}")
|
|
123
|
+
|
|
124
|
+
# Add constraints if present
|
|
125
|
+
if constraints:
|
|
126
|
+
constraint_str = " (" + ", ".join(constraints) + ")"
|
|
127
|
+
result_lines[0] += constraint_str
|
|
128
|
+
|
|
129
|
+
# Add multi-line default value if present
|
|
130
|
+
if has_multiline_default and isinstance(default_value, str):
|
|
131
|
+
result_lines.append(" Default value:")
|
|
132
|
+
# Indent each line of the default value
|
|
133
|
+
result_lines.append(textwrap.indent(default_value, " "))
|
|
134
|
+
|
|
135
|
+
return "\n".join(result_lines)
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
def generate_job_template_help(
|
|
139
|
+
template: JobTemplate, parser: ArgumentParser, template_path: Path
|
|
140
|
+
) -> str:
|
|
141
|
+
"""
|
|
142
|
+
Generate help text for a specific job template.
|
|
143
|
+
|
|
144
|
+
This function creates formatted help text that includes the job name,
|
|
145
|
+
description (if present), parameter definitions with their types and
|
|
146
|
+
constraints, and standard command options from the argument parser.
|
|
147
|
+
|
|
148
|
+
Args:
|
|
149
|
+
template: The decoded job template object (JobTemplate from openjd.model)
|
|
150
|
+
parser: The argument parser for the run command
|
|
151
|
+
template_path: Path to the template file
|
|
152
|
+
|
|
153
|
+
Returns:
|
|
154
|
+
Formatted help text string in argparse-style format
|
|
155
|
+
|
|
156
|
+
Example output:
|
|
157
|
+
usage: openjd run my-template.yaml [arguments]
|
|
158
|
+
|
|
159
|
+
Job: my-job
|
|
160
|
+
This is a sample job that demonstrates parameter usage.
|
|
161
|
+
|
|
162
|
+
Job Parameters (-p/--job-param PARAM_NAME=VALUE):
|
|
163
|
+
Message (STRING) [default: 'Hello, world!']
|
|
164
|
+
A message to display
|
|
165
|
+
|
|
166
|
+
Standard Options:
|
|
167
|
+
--step STEP_NAME The name of the Step in the Job to run Tasks from.
|
|
168
|
+
...
|
|
169
|
+
"""
|
|
170
|
+
lines = []
|
|
171
|
+
|
|
172
|
+
# Add usage line with actual template path instead of symbolic placeholder
|
|
173
|
+
usage = parser.format_usage().strip()
|
|
174
|
+
# Replace the symbolic JOB_TEMPLATE_PATH with the actual path provided
|
|
175
|
+
usage = usage.replace("JOB_TEMPLATE_PATH", str(template_path))
|
|
176
|
+
lines.append(usage)
|
|
177
|
+
lines.append("")
|
|
178
|
+
|
|
179
|
+
# Print the job name and description (if present)
|
|
180
|
+
lines.append(f"Job: {template.name}")
|
|
181
|
+
if template.description:
|
|
182
|
+
lines.append(template.description)
|
|
183
|
+
lines.append("")
|
|
184
|
+
|
|
185
|
+
# Extract parameter definitions (optional field)
|
|
186
|
+
param_definitions = template.parameterDefinitions
|
|
187
|
+
|
|
188
|
+
if param_definitions:
|
|
189
|
+
lines.append("Job Parameters (-p/--job-param PARAM_NAME=VALUE):")
|
|
190
|
+
|
|
191
|
+
for param_def in param_definitions:
|
|
192
|
+
param_dict: Dict[str, Any] = {
|
|
193
|
+
"name": param_def.name,
|
|
194
|
+
"type": param_def.type.value,
|
|
195
|
+
"description": param_def.description,
|
|
196
|
+
"default": param_def.default,
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
# Add optional constraint fields if they exist
|
|
200
|
+
for constraint in [
|
|
201
|
+
"minValue",
|
|
202
|
+
"maxValue",
|
|
203
|
+
"minLength",
|
|
204
|
+
"maxLength",
|
|
205
|
+
"allowedValues",
|
|
206
|
+
]:
|
|
207
|
+
if hasattr(param_def, constraint):
|
|
208
|
+
value = getattr(param_def, constraint)
|
|
209
|
+
if value is not None:
|
|
210
|
+
param_dict[constraint] = value
|
|
211
|
+
|
|
212
|
+
# Format the parameter info
|
|
213
|
+
param_info = format_parameter_info(param_dict)
|
|
214
|
+
|
|
215
|
+
# Indent the parameter info with 2 spaces
|
|
216
|
+
lines.append(textwrap.indent(param_info, " "))
|
|
217
|
+
|
|
218
|
+
lines.append("")
|
|
219
|
+
|
|
220
|
+
# Add standard options section
|
|
221
|
+
lines.append("Standard Options:")
|
|
222
|
+
|
|
223
|
+
# Get the help text for all other arguments
|
|
224
|
+
full_help = parser.format_help()
|
|
225
|
+
|
|
226
|
+
# Split into lines and find where the arguments section starts
|
|
227
|
+
help_lines = full_help.split("\n")
|
|
228
|
+
|
|
229
|
+
# Skip usage and positional arguments, capture optional arguments
|
|
230
|
+
in_options = False
|
|
231
|
+
for line in help_lines:
|
|
232
|
+
# Look for optional arguments section or specific argument patterns
|
|
233
|
+
if "optional arguments:" in line.lower() or "options:" in line.lower():
|
|
234
|
+
in_options = True
|
|
235
|
+
continue
|
|
236
|
+
elif "positional arguments:" in line.lower():
|
|
237
|
+
continue
|
|
238
|
+
elif in_options:
|
|
239
|
+
# Add all option lines
|
|
240
|
+
lines.append(line)
|
|
241
|
+
|
|
242
|
+
return "\n".join(lines)
|
|
243
|
+
|
|
244
|
+
|
|
245
|
+
class JobTemplateHelpAction(Action):
|
|
246
|
+
"""
|
|
247
|
+
Custom argparse Action that intercepts help requests (-h/--help) and generates
|
|
248
|
+
context-aware help text based on the job template file provided.
|
|
249
|
+
|
|
250
|
+
This action is triggered when the user invokes the run command with a job template
|
|
251
|
+
path and the -h or --help flag. It loads and validates the template, then generates
|
|
252
|
+
and displays help text that includes job-specific information (name, description,
|
|
253
|
+
parameters) alongside standard command options.
|
|
254
|
+
|
|
255
|
+
The action handles errors gracefully, displaying user-friendly error messages for
|
|
256
|
+
issues like missing files, invalid syntax, or schema validation failures.
|
|
257
|
+
"""
|
|
258
|
+
|
|
259
|
+
def __init__(
|
|
260
|
+
self,
|
|
261
|
+
option_strings,
|
|
262
|
+
dest,
|
|
263
|
+
default=False,
|
|
264
|
+
required=False,
|
|
265
|
+
help=None,
|
|
266
|
+
):
|
|
267
|
+
"""
|
|
268
|
+
Initialize the custom help action.
|
|
269
|
+
|
|
270
|
+
Args:
|
|
271
|
+
option_strings: List of option strings (e.g., ['-h', '--help'])
|
|
272
|
+
dest: Destination attribute name in the namespace
|
|
273
|
+
default: Default value for the action
|
|
274
|
+
required: Whether this argument is required
|
|
275
|
+
help: Help text for this option
|
|
276
|
+
"""
|
|
277
|
+
super().__init__(
|
|
278
|
+
option_strings=option_strings,
|
|
279
|
+
dest=dest,
|
|
280
|
+
default=default,
|
|
281
|
+
nargs=0,
|
|
282
|
+
required=required,
|
|
283
|
+
help=help,
|
|
284
|
+
)
|
|
285
|
+
|
|
286
|
+
def __call__(
|
|
287
|
+
self,
|
|
288
|
+
parser: ArgumentParser,
|
|
289
|
+
namespace: Namespace,
|
|
290
|
+
values: Any,
|
|
291
|
+
option_string: Optional[str] = None,
|
|
292
|
+
) -> None:
|
|
293
|
+
"""
|
|
294
|
+
Invoked when -h or --help is encountered.
|
|
295
|
+
|
|
296
|
+
This method intercepts the help request, checks if a job template path
|
|
297
|
+
has been provided, loads and validates the template, generates custom
|
|
298
|
+
help text, and displays it before exiting.
|
|
299
|
+
|
|
300
|
+
Args:
|
|
301
|
+
parser: The argument parser instance
|
|
302
|
+
namespace: The namespace containing parsed arguments so far
|
|
303
|
+
values: The value associated with the action (unused for help)
|
|
304
|
+
option_string: The option string that triggered this action ('-h' or '--help')
|
|
305
|
+
|
|
306
|
+
Exits:
|
|
307
|
+
- Code 0: Help displayed successfully
|
|
308
|
+
- Code 1: Error occurred (file not found, validation failed, etc.)
|
|
309
|
+
"""
|
|
310
|
+
# Check if a template path has been provided
|
|
311
|
+
template_path = getattr(namespace, "path", None)
|
|
312
|
+
|
|
313
|
+
if template_path is None:
|
|
314
|
+
# No template path provided, show standard help
|
|
315
|
+
parser.print_help()
|
|
316
|
+
sys.exit(0)
|
|
317
|
+
|
|
318
|
+
# Convert to Path object if it's a string
|
|
319
|
+
if isinstance(template_path, str):
|
|
320
|
+
template_path = Path(template_path)
|
|
321
|
+
|
|
322
|
+
try:
|
|
323
|
+
# Process extensions argument (defaults to all supported extensions if not provided)
|
|
324
|
+
extensions_arg = getattr(namespace, "extensions", None)
|
|
325
|
+
supported_extensions = process_extensions_argument(extensions_arg)
|
|
326
|
+
|
|
327
|
+
# Load and validate the job template
|
|
328
|
+
# This will raise RuntimeError for file issues or DecodeValidationError for validation issues
|
|
329
|
+
template = read_job_template(template_path, supported_extensions=supported_extensions)
|
|
330
|
+
|
|
331
|
+
# Generate the custom help text
|
|
332
|
+
help_text = generate_job_template_help(template, parser, template_path)
|
|
333
|
+
|
|
334
|
+
# Display the help text
|
|
335
|
+
print(help_text)
|
|
336
|
+
|
|
337
|
+
# Exit successfully
|
|
338
|
+
sys.exit(0)
|
|
339
|
+
|
|
340
|
+
except RuntimeError as e:
|
|
341
|
+
# Handle file not found, parse errors, etc.
|
|
342
|
+
print(f"Error: {str(e)}", file=sys.stderr)
|
|
343
|
+
sys.exit(1)
|
|
344
|
+
|
|
345
|
+
except DecodeValidationError as e:
|
|
346
|
+
# Handle template validation errors
|
|
347
|
+
print(f"Error: Invalid job template: {str(e)}", file=sys.stderr)
|
|
348
|
+
sys.exit(1)
|
|
349
|
+
|
|
350
|
+
except Exception as e:
|
|
351
|
+
# Catch any unexpected errors
|
|
352
|
+
print(f"Error: Failed to generate help: {str(e)}", file=sys.stderr)
|
|
353
|
+
sys.exit(1)
|
|
@@ -415,8 +415,8 @@ def do_run(args: Namespace) -> OpenJDCliResult:
|
|
|
415
415
|
filename = Path(env).expanduser()
|
|
416
416
|
try:
|
|
417
417
|
# Raises: RuntimeError, DecodeValidationError
|
|
418
|
-
|
|
419
|
-
environments.append(
|
|
418
|
+
env_template = read_environment_template(filename)
|
|
419
|
+
environments.append(env_template)
|
|
420
420
|
except (RuntimeError, DecodeValidationError) as e:
|
|
421
421
|
return OpenJDCliResult(status="error", message=str(e))
|
|
422
422
|
|
|
@@ -504,7 +504,31 @@ def do_run(args: Namespace) -> OpenJDCliResult:
|
|
|
504
504
|
task_parameter_values = []
|
|
505
505
|
|
|
506
506
|
except RuntimeError as rte:
|
|
507
|
-
|
|
507
|
+
error_message = str(rte)
|
|
508
|
+
# Print the help information along with the error
|
|
509
|
+
from ._help_formatter import generate_job_template_help
|
|
510
|
+
from .._common import read_job_template, add_common_arguments, CommonArgument
|
|
511
|
+
|
|
512
|
+
try:
|
|
513
|
+
# Load the template to generate help
|
|
514
|
+
job_template = read_job_template(args.path, supported_extensions=extensions)
|
|
515
|
+
# Create a minimal parser for help generation with the same usage format
|
|
516
|
+
temp_parser = ArgumentParser(
|
|
517
|
+
prog="openjd run",
|
|
518
|
+
usage="openjd run JOB_TEMPLATE_PATH [arguments]",
|
|
519
|
+
add_help=False,
|
|
520
|
+
)
|
|
521
|
+
temp_parser.add_argument("path")
|
|
522
|
+
add_common_arguments(temp_parser, {CommonArgument.PATH, CommonArgument.JOB_PARAMS})
|
|
523
|
+
add_run_arguments(temp_parser)
|
|
524
|
+
|
|
525
|
+
help_text = generate_job_template_help(job_template, temp_parser, args.path)
|
|
526
|
+
error_message = f"{error_message}\n\n{help_text}"
|
|
527
|
+
except Exception:
|
|
528
|
+
# If we can't generate help, just show the original error
|
|
529
|
+
pass
|
|
530
|
+
|
|
531
|
+
return OpenJDCliResult(status="error", message=error_message)
|
|
508
532
|
|
|
509
533
|
step_list: list[Step] = []
|
|
510
534
|
try:
|
|
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
|
|
|
28
28
|
commit_id: COMMIT_ID
|
|
29
29
|
__commit_id__: COMMIT_ID
|
|
30
30
|
|
|
31
|
-
__version__ = version = '0.7.
|
|
32
|
-
__version_tuple__ = version_tuple = (0, 7,
|
|
31
|
+
__version__ = version = '0.7.4'
|
|
32
|
+
__version_tuple__ = version_tuple = (0, 7, 4)
|
|
33
33
|
|
|
34
34
|
__commit_id__ = commit_id = None
|
|
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
|
{openjd_cli-0.7.2 → openjd_cli-0.7.4}/src/openjd/cli/_run/_local_session/_session_manager.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|