1
1
import copy
2
- import json
2
+ import urlparse
3
3
4
4
from schema_salad .ref_resolver import Loader
5
5
@@ -19,68 +19,114 @@ def flatten_deps(d, files): # type: (Any, Set[Text]) -> None
19
19
if "listing" in d :
20
20
flatten_deps (d ["listing" ], files )
21
21
22
- def find_run (d , runs ): # type: (Any, Set[Text]) -> None
22
+ def find_run (d , loadref , runs ): # type: (Any, Callable[[Text, Text], Union[Dict, List, Text]] , Set[Text]) -> None
23
23
if isinstance (d , list ):
24
24
for s in d :
25
- find_run (s , runs )
25
+ find_run (s , loadref , runs )
26
26
elif isinstance (d , dict ):
27
27
if "run" in d and isinstance (d ["run" ], (str , unicode )):
28
- runs .add (d ["run" ])
28
+ if d ["run" ] not in runs :
29
+ runs .add (d ["run" ])
30
+ find_run (loadref (None , d ["run" ]), loadref , runs )
29
31
for s in d .values ():
30
- find_run (s , runs )
32
+ find_run (s , loadref , runs )
33
+
34
+ def find_ids (d , ids ): # type: (Any, Set[Text]) -> None
35
+ if isinstance (d , list ):
36
+ for s in d :
37
+ find_ids (s , ids )
38
+ elif isinstance (d , dict ):
39
+ for i in ("id" , "name" ):
40
+ if i in d and isinstance (d [i ], (str , unicode )):
41
+ ids .add (d [i ])
42
+ for s in d .values ():
43
+ find_ids (s , ids )
31
44
32
45
def replace_refs (d , rewrite , stem , newstem ):
33
46
# type: (Any, Dict[Text, Text], Text, Text) -> None
34
47
if isinstance (d , list ):
35
48
for s ,v in enumerate (d ):
36
- if isinstance (v , (str , unicode )) and v .startswith (stem ):
37
- d [s ] = newstem + v [len (stem ):]
49
+ if isinstance (v , (str , unicode )):
50
+ if v in rewrite :
51
+ d [s ] = rewrite [v ]
52
+ elif v .startswith (stem ):
53
+ d [s ] = newstem + v [len (stem ):]
38
54
else :
39
55
replace_refs (v , rewrite , stem , newstem )
40
56
elif isinstance (d , dict ):
41
- if "run" in d and isinstance (d ["run" ], (str , unicode )):
42
- d ["run" ] = rewrite [d ["run" ]]
43
57
for s ,v in d .items ():
44
- if isinstance (v , (str , unicode )) and v .startswith (stem ):
45
- d [s ] = newstem + v [len (stem ):]
58
+ if isinstance (v , (str , unicode )):
59
+ if v in rewrite :
60
+ d [s ] = rewrite [v ]
61
+ elif v .startswith (stem ):
62
+ d [s ] = newstem + v [len (stem ):]
46
63
replace_refs (v , rewrite , stem , newstem )
47
64
48
65
def pack (document_loader , processobj , uri , metadata ):
49
66
# type: (Loader, Union[Dict[Text, Any], List[Dict[Text, Any]]], Text, Dict[Text, Text]) -> Dict[Text, Any]
50
67
def loadref (b , u ):
51
68
# type: (Text, Text) -> Union[Dict, List, Text]
52
69
return document_loader .resolve_ref (u , base_url = b )[0 ]
53
- deps = scandeps (uri , processobj , set (("run" ,)), set (), loadref )
54
70
55
- fdeps = set ((uri ,))
56
- flatten_deps ( deps , fdeps )
71
+ runs = set ((uri ,))
72
+ find_run ( processobj , loadref , runs )
57
73
58
- runs = set () # type: Set[Text]
59
- for f in fdeps :
60
- find_run (document_loader .idx [ f ], runs )
74
+ ids = set () # type: Set[Text]
75
+ for f in runs :
76
+ find_ids (document_loader .resolve_ref ( f )[ 0 ], ids )
61
77
62
78
names = set () # type: Set[Text]
63
- rewrite = {}
64
- if isinstance (processobj , list ):
65
- for p in processobj :
66
- rewrite [p ["id" ]] = "#" + uniquename (shortname (p ["id" ]), names )
67
- else :
68
- rewrite [uri ] = "#main"
79
+ rewrite = {} # type: Dict[Text, Text]
69
80
70
- for r in sorted (runs ):
71
- rewrite [r ] = "#" + uniquename (shortname (r ), names )
81
+ mainpath , _ = urlparse .urldefrag (uri )
82
+
83
+ def rewrite_id (r , mainuri ):
84
+ # type: (Text, Text) -> None
85
+ if r == mainuri :
86
+ rewrite [r ] = "#main"
87
+ elif r .startswith (mainuri ) and r [len (mainuri )] in ("#" , "/" ):
88
+ pass
89
+ else :
90
+ path , frag = urlparse .urldefrag (r )
91
+ if path == mainpath :
92
+ rewrite [r ] = "#" + uniquename (frag , names )
93
+ else :
94
+ if path not in rewrite :
95
+ rewrite [path ] = "#" + uniquename (shortname (path ), names )
96
+
97
+ sortedids = sorted (ids )
98
+
99
+ for r in sortedids :
100
+ if r .startswith ("file://" ):
101
+ rewrite_id (r , uri )
72
102
73
103
packed = {"$graph" : [], "cwlVersion" : metadata ["cwlVersion" ]
74
104
} # type: Dict[Text, Any]
75
105
76
- for r in sorted (rewrite .keys ()):
106
+ schemas = set () # type: Set[Text]
107
+ for r in sorted (runs ):
108
+ dcr , metadata = document_loader .resolve_ref (r )
109
+ if not isinstance (dcr , dict ):
110
+ continue
111
+ for doc in (dcr , metadata ):
112
+ if "$schemas" in doc :
113
+ for s in doc ["$schemas" ]:
114
+ schemas .add (s )
115
+ if dcr .get ("class" ) not in ("Workflow" , "CommandLineTool" , "ExpressionTool" ):
116
+ continue
117
+ dc = cast (Dict [Text , Any ], copy .deepcopy (dcr ))
77
118
v = rewrite [r ]
78
- dc = cast (Dict [Text , Any ], copy .deepcopy (document_loader .idx [r ]))
79
119
dc ["id" ] = v
80
- for n in ("name" , "cwlVersion" ):
120
+ for n in ("name" , "cwlVersion" , "$namespaces" , "$schemas" ):
81
121
if n in dc :
82
122
del dc [n ]
83
- replace_refs (dc , rewrite , r + "/" if "#" in r else r + "#" , v + "/" )
84
123
packed ["$graph" ].append (dc )
85
124
125
+ if schemas :
126
+ packed ["$schemas" ] = list (schemas )
127
+
128
+ for r in rewrite :
129
+ v = rewrite [r ]
130
+ replace_refs (packed , rewrite , r + "/" if "#" in r else r + "#" , v + "/" )
131
+
86
132
return packed
0 commit comments