1
1
import os
2
- from schema_salad . ref_resolver import Loader
3
- import schema_salad . validate as validate
2
+ import logging
3
+ import re
4
4
import urlparse
5
5
import sys
6
- import update
7
- import process
8
-
9
- def load_tool (argsworkflow , updateonly , strict , makeTool , debug ,
10
- print_pre = False ,
11
- print_rdf = False ,
12
- print_dot = False ,
13
- print_deps = False ,
14
- relative_deps = False ,
15
- rdf_serializer = None ,
16
- enable_dev = False ,
17
- stdout = sys .stdout ,
18
- urifrag = None ):
19
- # type: (Union[str,unicode,dict[unicode,Any]], bool, bool, Callable[...,Process], bool, bool, bool, bool, bool, bool, Any, Any, Any) -> Any
6
+ from schema_salad .ref_resolver import Loader
7
+ import schema_salad .validate as validate
8
+ import schema_salad .schema as schema
9
+ from . import update
10
+ from . import process
11
+
12
+ _logger = logging .getLogger ("cwltool" )
20
13
14
+ def fetch_document (argsworkflow ):
21
15
document_loader = Loader ({"cwl" : "https://w3id.org/cwl/cwl#" , "id" : "@id" })
22
16
23
17
jobobj = None
@@ -33,87 +27,105 @@ def load_tool(argsworkflow, updateonly, strict, makeTool, debug,
33
27
workflowobj = document_loader .fetch (fileuri )
34
28
elif isinstance (argsworkflow , dict ):
35
29
workflowobj = argsworkflow
36
- uri = urifrag
37
- fileuri = "#"
30
+ uri = "#" + str (id (argsworkflow ))
38
31
else :
39
- raise validate .ValidationException ("Must be URI or dict" )
32
+ raise validate .ValidationException ("Must be URI or object: '%s'" % argsworkflow )
33
+
34
+ return document_loader , workflowobj , uri
40
35
36
+
37
+ def validate_document (document_loader , workflowobj , uri , defaultVersion = None , enable_dev = False , strict = True ):
38
+ jobobj = None
41
39
if "cwl:tool" in workflowobj :
42
40
jobobj = workflowobj
43
41
uri = urlparse .urljoin (uri , jobobj ["cwl:tool" ])
44
- fileuri , urifrag = urlparse .urldefrag (uri )
45
- workflowobj = document_loader .fetch (fileuri )
46
42
del jobobj ["cwl:tool" ]
43
+ workflowobj = fetch_document (uri )
47
44
48
- if isinstance (workflowobj , list ):
45
+ if not isinstance (workflowobj , dict ):
49
46
if enable_dev :
50
- # bare list without a version must be treated as draft-2
51
- workflowobj = { "cwlVersion" : "https://w3id.org/cwl/cwl# draft-2" ,
52
- "id " : fileuri ,
53
- "@graph" : workflowobj }
47
+ workflowobj = {
48
+ "cwlVersion" : "draft-2" ,
49
+ "@graph " : workflowobj
50
+ }
54
51
else :
55
52
raise validate .ValidationException ("Missing 'cwlVersion'" )
56
53
57
- workflowobj = update .update (workflowobj , document_loader , fileuri , enable_dev )
58
- document_loader .idx .clear ()
54
+ fileuri , urifrag = urlparse .urldefrag (uri )
55
+
56
+ if "cwlVersion" in workflowobj :
57
+ workflowobj ["cwlVersion" ] = re .sub (r"^(?:cwl:|https://w3id.org/cwl/cwl#)" , "" , workflowobj ["cwlVersion" ])
58
+ elif defaultVersion :
59
+ workflowobj ["cwlVersion" ] = defaultVersion
60
+ else :
61
+ raise validate .ValidationException ("Missing 'cwlVersion'" )
62
+
63
+ if workflowobj ["cwlVersion" ] == "draft-2" or ".dev" in workflowobj ["cwlVersion" ]:
64
+ # can't validate draft-2 directly, must run updater
65
+ workflowobj = update .update (workflowobj , document_loader , fileuri , enable_dev , {})
59
66
60
67
(document_loader , avsc_names , schema_metadata ) = process .get_schema (workflowobj ["cwlVersion" ])
61
68
62
69
if isinstance (avsc_names , Exception ):
63
70
raise avsc_names
64
71
65
- if updateonly :
66
- stdout .write (json .dumps (workflowobj , indent = 4 ))
67
- return 0
72
+ workflowobj ["id" ] = fileuri
73
+ processobj , metadata = schema .load_and_validate (document_loader , avsc_names , workflowobj , strict )
74
+
75
+ if not metadata :
76
+ metadata = {"$namespaces" : processobj .get ("$namespaces" , {}),
77
+ "$schemas" : processobj .get ("$schemas" , []),
78
+ "cwlVersion" : processobj ["cwlVersion" ]}
68
79
69
- if print_deps :
70
- printdeps (workflowobj , document_loader , stdout , relative_deps )
71
- return 0
80
+ if metadata .get ("cwlVersion" ) != update .latest :
81
+ processobj = update .update (processobj , document_loader , fileuri , enable_dev , metadata )
72
82
73
- try :
74
- processobj , metadata = schema_salad .schema .load_and_validate (document_loader , avsc_names , workflowobj , strict )
75
- except (validate .ValidationException , RuntimeError ) as e :
76
- _logger .error (u"Tool definition failed validation:\n %s" , e , exc_info = (e if debug else False ))
77
- return 1
83
+ if jobobj :
84
+ metadata ["cwl:defaults" ] = jobobj
78
85
79
- if print_pre :
80
- stdout .write (json .dumps (processobj , indent = 4 ))
81
- return 0
86
+ return document_loader , avsc_names , processobj , metadata , uri
82
87
83
- if print_rdf :
84
- printrdf (argsworkflow , processobj , document_loader .ctx , rdf_serializer , stdout )
85
- return 0
86
88
87
- if print_dot :
88
- printdot (argsworkflow , processobj , document_loader .ctx , stdout )
89
- return 0
89
+ def make_tool (document_loader , avsc_names , processobj , metadata , uri , makeTool , kwargs ):
90
+ processobj , _ = document_loader .resolve_ref (uri )
90
91
91
- if urifrag :
92
- processobj , _ = document_loader .resolve_ref (uri )
93
- elif isinstance (processobj , list ):
92
+ if isinstance (processobj , list ):
94
93
if 1 == len (processobj ):
95
94
processobj = processobj [0 ]
96
95
else :
97
- _logger .error (u"Tool file contains graph of multiple objects, must specify one of #%s" ,
98
- ", #" .join (urlparse .urldefrag (i ["id" ])[1 ]
99
- for i in processobj if "id" in i ))
100
- return 1
101
-
102
- if not metadata :
103
- metadata = {"$namespaces" : processobj .get ("$namespaces" , {}), "$schemas" : processobj .get ("$schemas" , []), 'cwlVersion' : processobj ["cwlVersion" ]}
104
-
105
- try :
106
- t = makeTool (processobj , strict = strict , makeTool = makeTool , loader = document_loader , avsc_names = avsc_names , metadata = metadata )
107
- except (validate .ValidationException ) as e :
108
- _logger .error (u"Tool definition failed validation:\n %s" , e , exc_info = (e if debug else False ))
109
- return 1
110
- except (RuntimeError , workflow .WorkflowException ) as e :
111
- _logger .error (u"Tool definition failed initialization:\n %s" , e , exc_info = (e if debug else False ))
112
- return 1
113
-
114
- if jobobj :
96
+ raise WorkflowException (u"Tool file contains graph of multiple objects, "
97
+ "must specify one of #%s" %
98
+ ", #" .join (urlparse .urldefrag (i ["id" ])[1 ]
99
+ for i in processobj if "id" in i ))
100
+
101
+ kwargs = kwargs .copy ()
102
+ kwargs .update ({
103
+ "makeTool" : makeTool ,
104
+ "loader" : document_loader ,
105
+ "avsc_names" : avsc_names ,
106
+ "metadata" : metadata
107
+ })
108
+ t = makeTool (processobj , ** kwargs )
109
+
110
+ if "cwl:defaults" in metadata :
111
+ jobobj = metadata ["cwl:defaults" ]
115
112
for inp in t .tool ["inputs" ]:
116
113
if shortname (inp ["id" ]) in jobobj :
117
114
inp ["default" ] = jobobj [shortname (inp ["id" ])]
118
115
119
116
return t
117
+
118
+
119
+ def load_tool (argsworkflow , makeTool , kwargs ,
120
+ defaultVersion = None ,
121
+ enable_dev = False ,
122
+ strict = True ):
123
+
124
+ document_loader , workflowobj , uri = fetch_document (argsworkflow )
125
+ document_loader , avsc_names , processobj , metadata , uri = validate_document (document_loader ,
126
+ workflowobj ,
127
+ uri ,
128
+ defaultVersion = defaultVersion ,
129
+ enable_dev = enable_dev ,
130
+ strict = strict )
131
+ return make_tool (document_loader , avsc_names , processobj , metadata , uri , makeTool , kwargs )
0 commit comments