Skip to content

Commit 3d34153

Browse files
committed
Merge pull request #641 from inclement/bootstrap_recipe_alternatives
Fixed some bugs with recipe graph calculations
2 parents 9273780 + f69bfdd commit 3d34153

File tree

9 files changed

+85
-22
lines changed

9 files changed

+85
-22
lines changed

pythonforandroid/bootstrap.py

Lines changed: 34 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -135,22 +135,24 @@ def get_bootstrap_from_recipes(cls, recipes, ctx):
135135
for name in cls.list_bootstraps()]
136136
acceptable_bootstraps = []
137137
for bs in bootstraps:
138-
ok = True
139138
if not bs.can_be_chosen_automatically:
140-
ok = False
141-
for recipe in bs.recipe_depends:
142-
recipe = Recipe.get_recipe(recipe, ctx)
143-
if any([conflict in recipes for conflict in recipe.conflicts]):
144-
ok = False
145-
break
146-
for recipe in recipes:
147-
recipe = Recipe.get_recipe(recipe, ctx)
148-
if any([conflict in bs.recipe_depends
149-
for conflict in recipe.conflicts]):
150-
ok = False
151-
break
152-
if ok:
153-
acceptable_bootstraps.append(bs)
139+
continue
140+
possible_dependency_lists = expand_dependencies(bs.recipe_depends)
141+
for possible_dependencies in possible_dependency_lists:
142+
ok = True
143+
for recipe in possible_dependencies:
144+
recipe = Recipe.get_recipe(recipe, ctx)
145+
if any([conflict in recipes for conflict in recipe.conflicts]):
146+
ok = False
147+
break
148+
for recipe in recipes:
149+
recipe = Recipe.get_recipe(recipe, ctx)
150+
if any([conflict in possible_dependencies
151+
for conflict in recipe.conflicts]):
152+
ok = False
153+
break
154+
if ok:
155+
acceptable_bootstraps.append(bs)
154156
info('Found {} acceptable bootstraps: {}'.format(
155157
len(acceptable_bootstraps),
156158
[bs.name for bs in acceptable_bootstraps]))
@@ -264,3 +266,20 @@ def fry_eggs(self, sitepackages):
264266
if files:
265267
shprint(sh.mv, '-t', sitepackages, *files)
266268
shprint(sh.rm, '-rf', d)
269+
270+
271+
def expand_dependencies(recipes):
272+
recipe_lists = [[]]
273+
for recipe in recipes:
274+
if isinstance(recipe, (tuple, list)):
275+
new_recipe_lists = []
276+
for alternative in recipe:
277+
for old_list in recipe_lists:
278+
new_list = [i for i in old_list]
279+
new_list.append(alternative)
280+
new_recipe_lists.append(new_list)
281+
recipe_lists = new_recipe_lists
282+
else:
283+
for old_list in recipe_lists:
284+
old_list.append(recipe)
285+
return recipe_lists

pythonforandroid/graph.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,10 +60,11 @@ def _add(self, graph, dependent, dependency):
6060

6161
def conflicts(self, conflict):
6262
graphs = self.graphs
63+
initial_num = len(graphs)
6364
for i in range(len(graphs)):
64-
graph = graphs[len(graphs) - 1 - i]
65+
graph = graphs[initial_num - 1 - i]
6566
if conflict in graph:
66-
graphs.pop(len(graphs) - 1 - i)
67+
graphs.pop(initial_num - 1 - i)
6768
return len(graphs) == 0
6869

6970
def remove_remaining_conflicts(self, ctx):
@@ -227,6 +228,8 @@ def get_recipe_order_and_bootstrap(ctx, names, bs=None):
227228
recipe_loaded.append(name)
228229
graph.remove_remaining_conflicts(ctx)
229230
build_order = list(graph.find_order(0))
231+
build_order, python_modules, bs = get_recipe_order_and_bootstrap(
232+
ctx, build_order + python_modules, bs)
230233
return build_order, python_modules, bs
231234

232235
# Do a final check that the new bs doesn't pull in any conflicts

pythonforandroid/logger.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -217,5 +217,3 @@ def printtail(out, name, forecolor, tail_n=0,
217217

218218
return output
219219

220-
221-
from pythonforandroid.util import unistr

pythonforandroid/recipe.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -580,9 +580,12 @@ def has_libs(self, arch, *libs):
580580

581581
@classmethod
582582
def recipe_dirs(cls, ctx):
583-
return [ctx.local_recipes,
584-
join(ctx.storage_dir, 'recipes'),
585-
join(ctx.root_dir, "recipes")]
583+
recipe_dirs = []
584+
if ctx.local_recipes is not None:
585+
recipe_dirs.append(ctx.local_recipes)
586+
recipe_dirs.extend([join(ctx.storage_dir, 'recipes'),
587+
join(ctx.root_dir, "recipes")])
588+
return recipe_dirs
586589

587590
@classmethod
588591
def list_recipes(cls, ctx):
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.

tests/test_graph.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
2+
from pythonforandroid.build import Context
3+
from pythonforandroid.graph import get_recipe_order_and_bootstrap
4+
from pythonforandroid.bootstrap import Bootstrap
5+
from itertools import product
6+
7+
import pytest
8+
9+
10+
ctx = Context()
11+
12+
name_sets = [['python2'],
13+
['kivy']]
14+
bootstraps = [None,
15+
Bootstrap.get_bootstrap('pygame', ctx),
16+
Bootstrap.get_bootstrap('sdl2', ctx)]
17+
valid_combinations = list(product(name_sets, bootstraps))
18+
valid_combinations.extend(
19+
[(['python3crystax'], Bootstrap.get_bootstrap('sdl2', ctx)),
20+
(['kivy', 'python3crystax'], Bootstrap.get_bootstrap('sdl2', ctx))])
21+
22+
@pytest.mark.parametrize('names,bootstrap', valid_combinations)
23+
def test_valid_recipe_order_and_bootstrap(names, bootstrap):
24+
get_recipe_order_and_bootstrap(ctx, names, bootstrap)
25+
26+
invalid_combinations = [[['python2', 'python3crystax'], None],
27+
[['python3'], Bootstrap.get_bootstrap('pygame', ctx)]]
28+
29+
@pytest.mark.parametrize('names,bootstrap', invalid_combinations)
30+
def test_invalid_recipe_order_and_bootstrap(names, bootstrap):
31+
with pytest.raises(SystemExit):
32+
get_recipe_order_and_bootstrap(ctx, names, bootstrap)
33+
34+
def test_bootstrap_dependency_addition():
35+
build_order, python_modules, bs = get_recipe_order_and_bootstrap(
36+
ctx, ['kivy'], None)
37+
assert (('hostpython2' in build_order) or ('hostpython3' in build_order))
38+
39+
if __name__ == "__main__":
40+
get_recipe_order_and_bootstrap(ctx, ['python3'], Bootstrap.get_bootstrap('sdl2', ctx))

0 commit comments

Comments
 (0)