Skip to content

Commit 81fe4bf

Browse files
committed
Added new recipe graph creation method
1 parent 06f981f commit 81fe4bf

File tree

1 file changed

+81
-0
lines changed

1 file changed

+81
-0
lines changed

pythonforandroid/graph.py

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11

22
from copy import deepcopy
3+
from itertools import product
34

45
from pythonforandroid.logger import (info, info_notify, warning)
56
from 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+
118197
def 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

Comments
 (0)