@@ -129,7 +129,7 @@ def conflicts(self, name):
129
129
except OSError :
130
130
conflicts = []
131
131
132
- if any ([c in self for c in recipe . conflicts ]):
132
+ if any ([c in self for c in conflicts ]):
133
133
return True
134
134
return False
135
135
@@ -151,6 +151,8 @@ def recursively_collect_orders(name, ctx, orders=[]):
151
151
# via pip with no extra dependencies
152
152
dependencies = []
153
153
154
+ # TODO: Also check recipe conflicts
155
+
154
156
new_orders = []
155
157
# for each existing recipe order, see if we can add the new recipe name
156
158
for order in orders :
@@ -174,24 +176,72 @@ def recursively_collect_orders(name, ctx, orders=[]):
174
176
return new_orders
175
177
176
178
179
+ def find_order (graph ):
180
+ '''
181
+ Do a topological sort on the dependency graph dict.
182
+ '''
183
+ while graph :
184
+ # Find all items without a parent
185
+ leftmost = [l for l , s in graph .items () if not s ]
186
+ if not leftmost :
187
+ raise ValueError ('Dependency cycle detected! %s' % graph )
188
+ # If there is more than one, sort them for predictable order
189
+ leftmost .sort ()
190
+ for result in leftmost :
191
+ # Yield and remove them from the graph
192
+ yield result
193
+ graph .pop (result )
194
+ for bset in graph .values ():
195
+ bset .discard (result )
196
+
197
+
177
198
def new_get_recipe_order_and_bootstrap (ctx , names , bs = None ):
178
199
recipes_to_load = set (names )
179
- # if bs is not None and bs.recipe_depends:
180
- # recipes_to_load = recipes_to_load.union(set(bs.recipe_depends))
181
-
182
- possible_orders = [RecipeOrder (ctx )]
200
+ if bs is not None and bs .recipe_depends :
201
+ recipes_to_load = recipes_to_load .union (set (bs .recipe_depends ))
183
202
184
- # get all possible recipe orders
185
- for name in names :
186
- possible_orders = recursively_collect_orders (name , ctx , orders = possible_orders )
203
+ possible_orders = []
204
+
205
+ # get all possible recipe sets if names includes alternative
206
+ # dependencies
207
+ names = [([name ] if not isinstance (name , (list , tuple )) else name )
208
+ for name in names ]
209
+ for name_set in product (* names ):
210
+ new_possible_orders = [RecipeOrder (ctx )]
211
+ for name in name_set :
212
+ new_possible_orders = recursively_collect_orders (
213
+ name , ctx , orders = new_possible_orders )
214
+ possible_orders .extend (new_possible_orders )
215
+
216
+ # turn each order graph into a linear list if possible
217
+ orders = []
218
+ for possible_order in possible_orders :
219
+ try :
220
+ order = find_order (possible_order )
221
+ except ValueError : # a circular dependency was found
222
+ info ('Circular dependency found in graph {}' .format (possible_order ))
223
+ continue
224
+ orders .append (list (order ))
187
225
188
226
# prefer python2 and SDL2 if available
189
- possible_orders = sorted (possible_orders ,
190
- key = lambda order : - ('python2' in order ) - ('sdl2' in order ))
227
+ orders = sorted (orders ,
228
+ key = lambda order : - ('python2' in order ) - ('sdl2' in order ))
191
229
230
+ # It would be better to check against possible orders other
231
+ # than the first one, but in practice clashes will be rare,
232
+ # and can be resolved by specifying more parameters
233
+ order = orders [0 ]
192
234
235
+ print ('pre-bs order is' , order )
236
+
237
+ if bs is None :
238
+ bs = Bootstrap .get_bootstrap_from_recipes (order , ctx )
239
+ orders , bs = new_get_recipe_order_and_bootstrap (ctx , order , bs = bs )
240
+ order = orders [0 ]
193
241
194
- return possible_orders
242
+ return order , bs
243
+
244
+
195
245
196
246
197
247
def get_recipe_order_and_bootstrap (ctx , names , bs = None ):
@@ -210,7 +260,6 @@ def get_recipe_order_and_bootstrap(ctx, names, bs=None):
210
260
python_modules = []
211
261
print ('recipes_to_load' , recipes_to_load )
212
262
while recipes_to_load :
213
- info ('Current recipes to load: {}' .format (', ' .join (map (str , recipes_to_load ))))
214
263
name = recipes_to_load .pop (0 )
215
264
if name in recipe_loaded or isinstance (name , (list , tuple )):
216
265
continue
0 commit comments