1
1
2
2
from copy import deepcopy
3
+ from itertools import product
3
4
4
5
from pythonforandroid .logger import (info , info_notify , warning )
5
6
from pythonforandroid .recipe import Recipe
@@ -115,6 +116,84 @@ def find_order(self, index=0):
115
116
bset .discard (result )
116
117
117
118
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
+
118
197
def get_recipe_order_and_bootstrap (ctx , names , bs = None ):
119
198
'''Takes a list of recipe names and (optionally) a bootstrap. Then
120
199
works out the dependency graph (including bootstrap recipes if
@@ -129,7 +208,9 @@ def get_recipe_order_and_bootstrap(ctx, names, bs=None):
129
208
recipes_to_load = list (recipes_to_load )
130
209
recipe_loaded = []
131
210
python_modules = []
211
+ print ('recipes_to_load' , recipes_to_load )
132
212
while recipes_to_load :
213
+ info ('Current recipes to load: {}' .format (', ' .join (map (str , recipes_to_load ))))
133
214
name = recipes_to_load .pop (0 )
134
215
if name in recipe_loaded or isinstance (name , (list , tuple )):
135
216
continue
0 commit comments