Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow $schemas in codegen #346

Merged
merged 10 commits into from
Aug 11, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions schema_salad/python_codegen.py
Original file line number Diff line number Diff line change
Expand Up @@ -246,9 +246,12 @@ def end_class(self, classname, field_names):

self.serializer.write(
"""
if top and self.loadingOptions.namespaces:
r["$namespaces"] = self.loadingOptions.namespaces

# top refers to the directory level
if top:
if self.loadingOptions.namespaces:
r["$namespaces"] = self.loadingOptions.namespaces
if self.loadingOptions.schemas:
r["$schemas"] = self.loadingOptions.schemas
"""
)

Expand Down
12 changes: 9 additions & 3 deletions schema_salad/python_codegen_support.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,15 @@ def __init__(
self,
fetcher=None, # type: Optional[Fetcher]
namespaces=None, # type: Optional[Dict[str, str]]
schemas=None, # type: Optional[Dict[str, str]]
fileuri=None, # type: Optional[str]
copyfrom=None, # type: Optional[LoadingOptions]
original_doc=None, # type: Optional[Any]
): # type: (...) -> None
self.idx = {} # type: Dict[str, Dict[str, Any]]
self.fileuri = fileuri # type: Optional[str]
self.namespaces = namespaces
self.schemas = schemas
self.original_doc = original_doc
if copyfrom is not None:
self.idx = copyfrom.idx
Expand All @@ -60,6 +62,8 @@ def __init__(
self.fileuri = copyfrom.fileuri
if namespaces is None:
self.namespaces = copyfrom.namespaces
if schemas is None:
self.schemas = copyfrom.schemas

if fetcher is None:
import requests
Expand Down Expand Up @@ -466,11 +470,13 @@ def _document_load(loader, doc, baseuri, loadingOptions):
)

if isinstance(doc, MutableMapping):
if "$namespaces" in doc:
if "$namespaces" in doc or "$schemas" in doc:
loadingOptions = LoadingOptions(
copyfrom=loadingOptions, namespaces=doc["$namespaces"]
copyfrom=loadingOptions,
namespaces=doc.get("$namespaces", None),
schemas=doc.get("$schemas", None),
)
doc = {k: v for k, v in doc.items() if k != "$namespaces"}
doc = {k: v for k, v in doc.items() if k not in ["$namespaces", "$schemas"]}

if "$base" in doc:
baseuri = doc["$base"]
Expand Down
28 changes: 28 additions & 0 deletions schema_salad/tests/formattest2.cwl
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
$namespaces:
edam: http://edamontology.org/
$schemas:
- EDAM.owl
class: CommandLineTool
cwlVersion: v1.0
doc: "Reverse each line using the `rev` command"
hints:
ResourceRequirement:
ramMin: 8
DockerRequirement:
dockerPull: "debian:stretch-slim"

inputs:
input:
type: File
inputBinding: {}
format: edam:format_2330

outputs:
output:
type: File
outputBinding:
glob: output.txt
format: $(inputs.input.format)

baseCommand: rev
stdout: output.txt
49 changes: 49 additions & 0 deletions schema_salad/tests/test_schemas_directive.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
"""
Checks for accepting $schemas directive

run individually as py.test -k tests/test_schemas_directive.py
"""

from typing import Any, Dict, Union, Tuple
from schema_salad.avro.schema import Names, SchemaParseException
from schema_salad.schema import load_and_validate, load_schema
from schema_salad.ref_resolver import Loader
import os

from .util import get_data

test_dir_name = "tests/"


class TestSchemasDirective:
"""Ensure codegen-produced parsers accept $schemas directives"""

document_loader = None # type: Loader
avsc_names = None # type: Union[Names, SchemaParseException]
schema_metadata = None # type: Dict[str, Any]
metaschema_loader = None # type: Loader

@classmethod
def setup_class(cls) -> None:
path = get_data("tests/test_schema/CommonWorkflowLanguage.yml")
assert path
(
cls.document_loader,
cls.avsc_names,
schema_metadata,
metaschema_loader,
) = load_schema(path)

def load_cwl(self, src: str) -> Tuple[Any, Dict[str, Any]]:
path = get_data(test_dir_name + src)
assert path
assert isinstance(self.avsc_names, Names)
res = load_and_validate(self.document_loader, self.avsc_names, path, True)
return res

def test_dollarsign_schema(self) -> None:
"""EDAM.owl as a schema"""
res = self.load_cwl(src="formattest2.cwl")

# EDAM.owl resides in this directory
assert os.path.split(str(res[0]["$schemas"][0]))[1] == "EDAM.owl"