mercurial/packagescan.py
changeset 1283 f5faab34f32e
child 1308 2073e5a71008
equal deleted inserted replaced
1282:c1a507ba398b 1283:f5faab34f32e
       
     1 # packagescan.py - Helper module for identifing used modules. 
       
     2 # Used for the py2exe distutil.
       
     3 #
       
     4 # Copyright 2005 Volker Kleinfeld <Volker.Kleinfeld@gmx.de>
       
     5 #
       
     6 # This software may be used and distributed according to the terms
       
     7 # of the GNU General Public License, incorporated herein by reference.
       
     8 import glob
       
     9 import os
       
    10 import sys
       
    11 import demandload
       
    12 import ihooks
       
    13 
       
    14 requiredmodules = {} # Will contain the modules imported by demandload
       
    15 def demandload(scope, modules):
       
    16     """ fake demandload function that collects the required modules """
       
    17     for m in modules.split():
       
    18         mod = None
       
    19         mod = __import__(m,scope,scope)
       
    20         scope[m] = mod
       
    21         requiredmodules[mod.__name__] = 1
       
    22 
       
    23 def getmodules(libpath,packagename):
       
    24     """ helper for finding all required modules of package <packagename> """
       
    25     # Use the package in the build directory
       
    26     libpath = os.path.abspath(libpath)
       
    27     sys.path.insert(0,libpath)
       
    28     packdir = os.path.join(libpath,packagename)
       
    29     # A normal import would not find the package in 
       
    30     # the build directory. ihook is used to force the import.
       
    31     # After the package is imported the import scope for 
       
    32     # the following imports is settled.
       
    33     p = importfrom(packdir)
       
    34     globals()[packagename] = p
       
    35     sys.modules[packagename] = p
       
    36     # Fetch the python modules in the package
       
    37     cwd = os.getcwd()
       
    38     os.chdir(packdir)
       
    39     pymodulefiles = glob.glob('*.py')
       
    40     extmodulefiles = glob.glob('*.pyd')
       
    41     os.chdir(cwd)
       
    42     # Install a fake demandload module
       
    43     sys.modules['mercurial.demandload'] = sys.modules['mercurial.packagescan']
       
    44     # Import all python modules and by that run the fake demandload
       
    45     for m in pymodulefiles:
       
    46         if m == '__init__.py': continue
       
    47         tmp = {}
       
    48         mname,ext = os.path.splitext(m)
       
    49         fullname = packagename+'.'+mname 
       
    50         __import__(fullname,tmp,tmp)
       
    51         requiredmodules[fullname] = 1
       
    52     # Import all extension modules and by that run the fake demandload
       
    53     for m in extmodulefiles:
       
    54         tmp = {}
       
    55         mname,ext = os.path.splitext(m)
       
    56         fullname = packagename+'.'+mname
       
    57         __import__(fullname,tmp,tmp)
       
    58         requiredmodules[fullname] = 1
       
    59     includes = requiredmodules.keys()
       
    60     return includes
       
    61 
       
    62 def importfrom(filename):
       
    63     """
       
    64     import module/package from a named file and returns the module.
       
    65     It does not check on sys.modules or includes the module in the scope.
       
    66     """
       
    67     loader = ihooks.BasicModuleLoader()
       
    68     path, file = os.path.split(filename)
       
    69     name, ext  = os.path.splitext(file)
       
    70     m = loader.find_module_in_dir(name, path)
       
    71     if not m:
       
    72         raise ImportError, name
       
    73     m = loader.load_module(name, m)
       
    74     return m