22import importlib
33import zipfile
44import glob
5+ from six import PY2
6+
57import sh
68import shutil
79from os import listdir , unlink , environ , mkdir
1315from pythonforandroid .logger import (logger , info , warning , shprint , info_main )
1416from pythonforandroid .util import (urlretrieve , current_directory , ensure_dir )
1517
18+ # this import is necessary to keep imp.load_source from complaining :)
19+ import pythonforandroid .recipes
20+
21+
22+ if PY2 :
23+ import imp
24+ import_recipe = imp .load_source
25+ else :
26+ import importlib .util
27+ if hasattr (importlib .util , 'module_from_spec' ):
28+ def import_recipe (module , filename ):
29+ spec = importlib .util .spec_from_file_location (module , filename )
30+ mod = importlib .util .module_from_spec (spec )
31+ spec .loader .exec_module (mod )
32+ return mod
33+ else :
34+ from importlib .machinery import SourceFileLoader
35+
36+ def import_recipe (module , filename ):
37+ return SourceFileLoader (module , filename ).load_module ()
38+
1639
1740class Recipe (object ):
1841 url = None
@@ -514,15 +537,22 @@ def clean_build(self, arch=None):
514537 'did not exist' ).format (self .name ))
515538
516539 @classmethod
517- def list_recipes (cls ):
540+ def recipe_dirs (cls , ctx ):
541+ return [ctx .local_recipes ,
542+ join (ctx .storage_dir , 'recipes' ),
543+ join (ctx .root_dir , "recipes" )]
544+
545+ @classmethod
546+ def list_recipes (cls , ctx ):
518547 forbidden_dirs = ('__pycache__' , )
519- recipes_dir = join (dirname (__file__ ), "recipes" )
520- for name in listdir (recipes_dir ):
521- if name in forbidden_dirs :
522- continue
523- fn = join (recipes_dir , name )
524- if isdir (fn ):
525- yield name
548+ for recipes_dir in cls .recipe_dirs (ctx ):
549+ if recipes_dir and exists (recipes_dir ):
550+ for name in listdir (recipes_dir ):
551+ if name in forbidden_dirs :
552+ continue
553+ fn = join (recipes_dir , name )
554+ if isdir (fn ):
555+ yield name
526556
527557 @classmethod
528558 def get_recipe (cls , name , ctx ):
@@ -531,17 +561,24 @@ def get_recipe(cls, name, ctx):
531561 cls .recipes = {}
532562 if name in cls .recipes :
533563 return cls .recipes [name ]
534- recipe_dir = join (ctx .root_dir , 'recipes' , name )
535- if not exists (recipe_dir ): # AND: This will need modifying
536- # for user-supplied recipes
564+
565+ recipe_file = None
566+ for recipes_dir in cls .recipe_dirs (ctx ):
567+ recipe_file = join (recipes_dir , name , '__init__.py' )
568+ if exists (recipe_file ):
569+ break
570+ recipe_file = None
571+
572+ if not recipe_file :
537573 raise IOError ('Recipe folder does not exist' )
538- mod = importlib . import_module (
539- " pythonforandroid.recipes.{}" .format (name ))
574+
575+ mod = import_recipe ( ' pythonforandroid.recipes.{}' .format (name ), recipe_file )
540576 if len (logger .handlers ) > 1 :
541577 logger .removeHandler (logger .handlers [1 ])
542578 recipe = mod .recipe
543- recipe .recipe_dir = recipe_dir
579+ recipe .recipe_dir = dirname ( recipe_file )
544580 recipe .ctx = ctx
581+ cls .recipes [name ] = recipe
545582 return recipe
546583
547584
0 commit comments