11
22from copy import deepcopy
3+ from itertools import product
34
45from pythonforandroid .logger import (info , info_notify , warning )
56from pythonforandroid .recipe import Recipe
@@ -115,6 +116,84 @@ def find_order(self, index=0):
115116 bset .discard (result )
116117
117118
119+ class RecipeOrder (dict ):
120+
121+ def __init__ (self , ctx ):
122+ self .ctx = ctx
123+
124+ def conflicts (self , name ):
125+ for name in self .keys ():
126+ try :
127+ recipe = Recipe .get_recipe (name , self .ctx )
128+ conflicts = recipe .conflicts
129+ except OSError :
130+ conflicts = []
131+
132+ if any ([c in self for c in recipe .conflicts ]):
133+ return True
134+ return False
135+
136+ def recursively_collect_orders (name , ctx , orders = []):
137+ '''For each possible recipe ordering we were passed, try to add the
138+ new recipe name to that order. Recursively do the same thing with
139+ all the dependencies of each recipe.
140+ '''
141+ try :
142+ recipe = Recipe .get_recipe (name , ctx )
143+ if recipe .depends is None :
144+ dependencies = []
145+ else :
146+ # make all dependencies into lists so that product will work
147+ dependencies = [([dependency ] if not isinstance (dependency , (list , tuple ))
148+ else dependency ) for dependency in recipe .depends ]
149+ except OSError :
150+ # The recipe does not exist, so we assume it can be installed
151+ # via pip with no extra dependencies
152+ dependencies = []
153+
154+ new_orders = []
155+ # for each existing recipe order, see if we can add the new recipe name
156+ for order in orders :
157+ if name in order :
158+ new_orders .append (deepcopy (order ))
159+ continue
160+ if order .conflicts (name ):
161+ continue
162+
163+ for dependency_set in product (* dependencies ):
164+ new_order = deepcopy (order )
165+ new_order [name ] = set (dependency_set )
166+
167+ dependency_new_orders = [new_order ]
168+ for dependency in dependency_set :
169+ dependency_new_orders = recursively_collect_orders (
170+ dependency , ctx , dependency_new_orders )
171+
172+ new_orders .extend (dependency_new_orders )
173+
174+ return new_orders
175+
176+
177+ def new_get_recipe_order_and_bootstrap (ctx , names , bs = None ):
178+ 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 )]
183+
184+ # get all possible recipe orders
185+ for name in names :
186+ possible_orders = recursively_collect_orders (name , ctx , orders = possible_orders )
187+
188+ # prefer python2 and SDL2 if available
189+ possible_orders = sorted (possible_orders ,
190+ key = lambda order : - ('python2' in order ) - ('sdl2' in order ))
191+
192+
193+
194+ return possible_orders
195+
196+
118197def get_recipe_order_and_bootstrap (ctx , names , bs = None ):
119198 '''Takes a list of recipe names and (optionally) a bootstrap. Then
120199 works out the dependency graph (including bootstrap recipes if
@@ -129,7 +208,9 @@ def get_recipe_order_and_bootstrap(ctx, names, bs=None):
129208 recipes_to_load = list (recipes_to_load )
130209 recipe_loaded = []
131210 python_modules = []
211+ print ('recipes_to_load' , recipes_to_load )
132212 while recipes_to_load :
213+ info ('Current recipes to load: {}' .format (', ' .join (map (str , recipes_to_load ))))
133214 name = recipes_to_load .pop (0 )
134215 if name in recipe_loaded or isinstance (name , (list , tuple )):
135216 continue
0 commit comments