@@ -95,17 +95,12 @@ def reproduce(
95
95
path , name = name , recursive = recursive , graph = active_graph
96
96
)
97
97
98
- ret = []
99
- for target in targets :
100
- stages = _reproduce_stages (active_graph , target , ** kwargs )
101
- ret .extend (stages )
102
-
103
- return ret
98
+ return _reproduce_stages (active_graph , targets , ** kwargs )
104
99
105
100
106
101
def _reproduce_stages (
107
102
G ,
108
- stage ,
103
+ stages ,
109
104
downstream = False ,
110
105
ignore_build_cache = False ,
111
106
single_item = False ,
@@ -148,23 +143,34 @@ def _reproduce_stages(
148
143
import networkx as nx
149
144
150
145
if single_item :
151
- pipeline = [stage ]
152
- elif downstream :
153
- # NOTE (py3 only):
154
- # Python's `deepcopy` defaults to pickle/unpickle the object.
155
- # Stages are complex objects (with references to `repo`, `outs`,
156
- # and `deps`) that cause struggles when you try to serialize them.
157
- # We need to create a copy of the graph itself, and then reverse it,
158
- # instead of using graph.reverse() directly because it calls
159
- # `deepcopy` underneath -- unless copy=False is specified.
160
- pipeline = nx .dfs_preorder_nodes (G .copy ().reverse (copy = False ), stage )
146
+ all_pipelines = stages
161
147
else :
162
- pipeline = nx .dfs_postorder_nodes (G , stage )
148
+ all_pipelines = []
149
+ for stage in stages :
150
+ if downstream :
151
+ # NOTE (py3 only):
152
+ # Python's `deepcopy` defaults to pickle/unpickle the object.
153
+ # Stages are complex objects (with references to `repo`,
154
+ # `outs`, and `deps`) that cause struggles when you try
155
+ # to serialize them. We need to create a copy of the graph
156
+ # itself, and then reverse it, instead of using
157
+ # graph.reverse() directly because it calls `deepcopy`
158
+ # underneath -- unless copy=False is specified.
159
+ all_pipelines += nx .dfs_preorder_nodes (
160
+ G .copy ().reverse (copy = False ), stage
161
+ )
162
+ else :
163
+ all_pipelines += nx .dfs_postorder_nodes (G , stage )
164
+
165
+ pipeline = []
166
+ for stage in all_pipelines :
167
+ if stage not in pipeline :
168
+ pipeline .append (stage )
163
169
164
170
result = []
165
- for st in pipeline :
171
+ for stage in pipeline :
166
172
try :
167
- ret = _reproduce_stage (st , ** kwargs )
173
+ ret = _reproduce_stage (stage , ** kwargs )
168
174
169
175
if len (ret ) != 0 and ignore_build_cache :
170
176
# NOTE: we are walking our pipeline from the top to the
@@ -176,5 +182,6 @@ def _reproduce_stages(
176
182
177
183
result .extend (ret )
178
184
except Exception as exc :
179
- raise ReproductionError (st .relpath ) from exc
185
+ raise ReproductionError (stage .relpath ) from exc
186
+
180
187
return result
0 commit comments