11from __future__ import absolute_import
22import copy
3+ import re
34from typing import Any , Callable , Dict , List , Set , Text , Union , cast
45
56from schema_salad .ref_resolver import Loader
67from six .moves import urllib
8+ from ruamel .yaml .comments import CommentedSeq , CommentedMap
79
810from .process import shortname , uniquename
911import six
@@ -64,7 +66,12 @@ def replace_refs(d, rewrite, stem, newstem):
6466 if v in rewrite :
6567 d [s ] = rewrite [v ]
6668 elif v .startswith (stem ):
67- d [s ] = newstem + v [len (stem ):]
69+ id_ = v [len (stem ):]
70+ # prevent appending newstems if tool is already packed
71+ if id_ .startswith (newstem .strip ("#" )):
72+ d [s ] = "#" + id_
73+ else :
74+ d [s ] = newstem + id_
6875 replace_refs (v , rewrite , stem , newstem )
6976
7077def import_embed (d , seen ):
@@ -106,12 +113,16 @@ def loadref(b, u):
106113
107114 mainpath , _ = urllib .parse .urldefrag (uri )
108115
109- def rewrite_id (r , mainuri ):
110- # type: (Text, Text) -> None
116+ def rewrite_id (r , mainuri , document_packed = False ):
117+ # type: (Text, Text, bool ) -> None
111118 if r == mainuri :
112119 rewrite [r ] = "#main"
113120 elif r .startswith (mainuri ) and r [len (mainuri )] in ("#" , "/" ):
114- pass
121+ if document_packed :
122+ # rewrite tool and mainuri ids in a packed document
123+ tool_id = re .search ("#[^/]*$" , r )
124+ if tool_id :
125+ rewrite [r ] = tool_id .group ()
115126 else :
116127 path , frag = urllib .parse .urldefrag (r )
117128 if path == mainpath :
@@ -122,16 +133,20 @@ def rewrite_id(r, mainuri):
122133
123134 sortedids = sorted (ids )
124135
136+ is_document_packed = all (id .startswith (uri ) for id in sortedids )
125137 for r in sortedids :
126138 if r in document_loader .idx :
127- rewrite_id (r , uri )
139+ rewrite_id (r , uri , is_document_packed )
128140
129141 packed = {"$graph" : [], "cwlVersion" : metadata ["cwlVersion" ]
130142 } # type: Dict[Text, Any]
131143
132144 schemas = set () # type: Set[Text]
133145 for r in sorted (runs ):
134146 dcr , metadata = document_loader .resolve_ref (r )
147+ if isinstance (dcr , CommentedSeq ):
148+ dcr = dcr [0 ]
149+ dcr = cast (CommentedMap , dcr )
135150 if not isinstance (dcr , dict ):
136151 continue
137152 for doc in (dcr , metadata ):
@@ -141,7 +156,7 @@ def rewrite_id(r, mainuri):
141156 if dcr .get ("class" ) not in ("Workflow" , "CommandLineTool" , "ExpressionTool" ):
142157 continue
143158 dc = cast (Dict [Text , Any ], copy .deepcopy (dcr ))
144- v = rewrite [ r ]
159+ v = rewrite . get ( r , r + "#main" )
145160 dc ["id" ] = v
146161 for n in ("name" , "cwlVersion" , "$namespaces" , "$schemas" ):
147162 if n in dc :
0 commit comments