Skip to content

Commit 8092536

Browse files
authored
Merge pull request #175 from jmchilton/app_models
CLI Tweaks
2 parents 1cd2647 + 6d26475 commit 8092536

File tree

3 files changed

+82
-9
lines changed

3 files changed

+82
-9
lines changed

gxformat2/converter.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -98,22 +98,28 @@ def main(argv=None):
9898
args = _parser().parse_args(argv)
9999

100100
format2_path = args.input_path
101-
output_path = args.output_path or (format2_path + ".gxwf.yml")
101+
output_path = args.output or args.output_path
102102

103-
workflow_directory = os.path.abspath(format2_path)
103+
workflow_directory = os.path.dirname(os.path.abspath(format2_path))
104104

105105
with open(format2_path) as f:
106106
has_workflow = ordered_load(f)
107107

108108
output = python_to_workflow(has_workflow, workflow_directory=workflow_directory)
109-
with open(output_path, "w") as f:
110-
json.dump(output, f, indent=4)
109+
output_text = json.dumps(output, indent=4) + "\n"
110+
111+
if output_path:
112+
with open(output_path, "w") as f:
113+
f.write(output_text)
114+
else:
115+
sys.stdout.write(output_text)
111116

112117

113118
def _parser():
114119
parser = argparse.ArgumentParser(description=SCRIPT_DESCRIPTION)
115120
parser.add_argument("input_path", metavar="INPUT", type=str, help="input workflow path (.gxwf.yml)")
116121
parser.add_argument("output_path", metavar="OUTPUT", type=str, nargs="?", help="output workflow path (.ga)")
122+
parser.add_argument("--output", "-o", help="output file (default: stdout)")
117123
return parser
118124

119125

gxformat2/export.py

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
"""
66

77
import argparse
8+
import io
89
import json
910
import sys
1011
from collections import OrderedDict
@@ -138,20 +139,33 @@ def main(argv=None):
138139
args = _parser().parse_args(argv)
139140

140141
format2_path = args.input_path
141-
output_path = args.output_path or (format2_path + ".gxwf.yml")
142+
output_path = args.output or args.output_path
142143
with open(format2_path) as f:
143144
native_workflow_dict = json.load(f)
144145

145146
as_dict = from_galaxy_native(native_workflow_dict, compact=args.compact)
146-
with open(output_path, "w") as f:
147-
ordered_dump(as_dict, f)
147+
148+
if args.json_output:
149+
output_text = json.dumps(as_dict, indent=4) + "\n"
150+
else:
151+
stream = io.StringIO()
152+
ordered_dump(as_dict, stream)
153+
output_text = stream.getvalue()
154+
155+
if output_path:
156+
with open(output_path, "w") as f:
157+
f.write(output_text)
158+
else:
159+
sys.stdout.write(output_text)
148160

149161

150162
def _parser():
151163
parser = argparse.ArgumentParser(description=SCRIPT_DESCRIPTION)
152164
parser.add_argument("input_path", metavar="INPUT", type=str, help="input workflow path (.ga)")
153-
parser.add_argument("output_path", metavar="OUTPUT", type=str, nargs="?", help="output workflow path (.gxfw.yml)")
154-
parser.add_argument("--compact", action="store_true", help="Generate compact workflow without position information")
165+
parser.add_argument("output_path", metavar="OUTPUT", type=str, nargs="?", help="output workflow path (.gxwf.yml)")
166+
parser.add_argument("--output", "-o", help="output file (default: stdout)")
167+
parser.add_argument("--compact", action="store_true", help="generate compact workflow without position information")
168+
parser.add_argument("--json", dest="json_output", action="store_true", help="output JSON instead of YAML")
155169
return parser
156170

157171

gxformat2/schema/json_schema.py

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
"""JSON Schema export for gxformat2 workflow models.
2+
3+
Provides export functions that generate standard Draft 2020-12 JSON Schema
4+
from gxformat2's Pydantic models. Exported schemas are intended for consumption
5+
by external validators (Python jsonschema, TypeScript ajv, VSCode YAML extension).
6+
"""
7+
8+
import json
9+
from typing import (
10+
Any,
11+
Dict,
12+
Type,
13+
)
14+
15+
from pydantic import BaseModel
16+
from pydantic.json_schema import GenerateJsonSchema
17+
from typing_extensions import Literal
18+
19+
MODE = Literal["validation", "serialization"]
20+
21+
22+
class GxFormat2GenerateJsonSchema(GenerateJsonSchema):
23+
"""Custom JSON Schema generator that injects $schema dialect."""
24+
25+
def generate(self, schema, mode: MODE = "validation"):
26+
"""Generate JSON Schema with $schema dialect injected."""
27+
json_schema = super().generate(schema, mode=mode)
28+
json_schema["$schema"] = self.schema_dialect
29+
return json_schema
30+
31+
32+
def workflow_json_schema(*, strict: bool = False, mode: MODE = "validation") -> Dict[str, Any]:
33+
"""Export GalaxyWorkflow JSON Schema.
34+
35+
Args:
36+
strict: If True, use strict model (extra="forbid" — rejects unknown keys).
37+
mode: Pydantic schema mode ("validation" or "serialization").
38+
"""
39+
model_class: Type[BaseModel]
40+
if strict:
41+
from .gxformat2_strict import GalaxyWorkflow as model_class
42+
else:
43+
from .gxformat2 import GalaxyWorkflow as model_class
44+
45+
return model_class.model_json_schema(
46+
schema_generator=GxFormat2GenerateJsonSchema,
47+
mode=mode,
48+
)
49+
50+
51+
def workflow_json_schema_string(*, strict: bool = False, mode: MODE = "validation") -> str:
52+
"""Export GalaxyWorkflow JSON Schema as formatted string."""
53+
return json.dumps(workflow_json_schema(strict=strict, mode=mode), indent=4)

0 commit comments

Comments
 (0)