##// END OF EJS Templates
setup.py: install packagescan before any mercurial modules is imported...
Volker Kleinfeld -
r2323:c58a403a default
parent child Browse files
Show More
@@ -1,80 +1,86 b''
1 1 # packagescan.py - Helper module for identifing used modules.
2 2 # Used for the py2exe distutil.
3 # This module must be the first mercurial module imported in setup.py
3 4 #
4 5 # Copyright 2005 Volker Kleinfeld <Volker.Kleinfeld@gmx.de>
5 6 #
6 7 # This software may be used and distributed according to the terms
7 8 # of the GNU General Public License, incorporated herein by reference.
8 9 import glob
9 10 import os
10 11 import sys
11 import demandload
12 12 import ihooks
13 13
14 requiredmodules = {} # Will contain the modules imported by demandload
14 # Install this module as fake demandload module
15 sys.modules['mercurial.demandload'] = sys.modules[__name__]
16
17 # Requiredmodules contains the modules imported by demandload.
18 # Please note that demandload can be invoked before the
19 # mercurial.packagescan.scan method is invoked in case a mercurial
20 # module is imported.
21 requiredmodules = {}
15 22 def demandload(scope, modules):
16 23 """ fake demandload function that collects the required modules """
17 24 for m in modules.split():
18 25 mod = None
19 26 try:
20 27 module, submodules = m.split(':')
21 28 submodules = submodules.split(',')
22 29 except:
23 30 module = m
24 31 submodules = []
25 32 mod = __import__(module, scope, scope, submodules)
26 33 scope[module] = mod
27 34 requiredmodules[mod.__name__] = 1
28 35
29 def getmodules(libpath,packagename):
36 def scan(libpath,packagename):
30 37 """ helper for finding all required modules of package <packagename> """
31 38 # Use the package in the build directory
32 39 libpath = os.path.abspath(libpath)
33 40 sys.path.insert(0,libpath)
34 41 packdir = os.path.join(libpath,packagename)
35 42 # A normal import would not find the package in
36 43 # the build directory. ihook is used to force the import.
37 44 # After the package is imported the import scope for
38 45 # the following imports is settled.
39 46 p = importfrom(packdir)
40 47 globals()[packagename] = p
41 48 sys.modules[packagename] = p
42 49 # Fetch the python modules in the package
43 50 cwd = os.getcwd()
44 51 os.chdir(packdir)
45 52 pymodulefiles = glob.glob('*.py')
46 53 extmodulefiles = glob.glob('*.pyd')
47 54 os.chdir(cwd)
48 # Install a fake demandload module
49 sys.modules['mercurial.demandload'] = sys.modules['mercurial.packagescan']
50 55 # Import all python modules and by that run the fake demandload
51 56 for m in pymodulefiles:
52 57 if m == '__init__.py': continue
53 58 tmp = {}
54 59 mname,ext = os.path.splitext(m)
55 60 fullname = packagename+'.'+mname
56 61 __import__(fullname,tmp,tmp)
57 62 requiredmodules[fullname] = 1
58 63 # Import all extension modules and by that run the fake demandload
59 64 for m in extmodulefiles:
60 65 tmp = {}
61 66 mname,ext = os.path.splitext(m)
62 67 fullname = packagename+'.'+mname
63 68 __import__(fullname,tmp,tmp)
64 69 requiredmodules[fullname] = 1
65 includes = requiredmodules.keys()
66 return includes
70
71 def getmodules():
72 return requiredmodules.keys()
67 73
68 74 def importfrom(filename):
69 75 """
70 76 import module/package from a named file and returns the module.
71 77 It does not check on sys.modules or includes the module in the scope.
72 78 """
73 79 loader = ihooks.BasicModuleLoader()
74 80 path, file = os.path.split(filename)
75 81 name, ext = os.path.splitext(file)
76 82 m = loader.find_module_in_dir(name, path)
77 83 if not m:
78 84 raise ImportError, name
79 85 m = loader.load_module(name, m)
80 86 return m
@@ -1,103 +1,103 b''
1 1 #!/usr/bin/env python
2 2 #
3 3 # This is the mercurial setup script.
4 4 #
5 5 # './setup.py install', or
6 6 # './setup.py --help' for more options
7 7
8 8 import sys
9 9 if not hasattr(sys, 'version_info') or sys.version_info < (2, 3):
10 10 raise SystemExit, "Mercurial requires python 2.3 or later."
11 11
12 12 import glob
13 13 from distutils.core import setup, Extension
14 14 from distutils.command.install_data import install_data
15 15
16 # mercurial.packagescan must be the first mercurial module imported
17 import mercurial.packagescan
16 18 import mercurial.version
17 19
18 20 # py2exe needs to be installed to work
19 21 try:
20 22 import py2exe
21 23
22 24 # Help py2exe to find win32com.shell
23 25 try:
24 26 import modulefinder
25 27 import win32com
26 28 for p in win32com.__path__[1:]: # Take the path to win32comext
27 29 modulefinder.AddPackagePath("win32com", p)
28 30 pn = "win32com.shell"
29 31 __import__(pn)
30 32 m = sys.modules[pn]
31 33 for p in m.__path__[1:]:
32 34 modulefinder.AddPackagePath(pn, p)
33 35 except ImportError:
34 36 pass
35 37
36 38 # Due to the use of demandload py2exe is not finding the modules.
37 39 # packagescan.getmodules creates a list of modules included in
38 40 # the mercurial package plus depdent modules.
39 import mercurial.packagescan
40 41 from py2exe.build_exe import py2exe as build_exe
41 42
42 43 class py2exe_for_demandload(build_exe):
43 44 """ overwrites the py2exe command class for getting the build
44 45 directory and for setting the 'includes' option."""
45 46 def initialize_options(self):
46 47 self.build_lib = None
47 48 build_exe.initialize_options(self)
48 49 def finalize_options(self):
49 50 # Get the build directory, ie. where to search for modules.
50 51 self.set_undefined_options('build',
51 52 ('build_lib', 'build_lib'))
52 53 # Sets the 'includes' option with the list of needed modules
53 54 if not self.includes:
54 55 self.includes = []
55 56 else:
56 57 self.includes = self.includes.split(',')
57 self.includes += mercurial.packagescan.getmodules(self.build_lib,
58 'mercurial')
59 self.includes += mercurial.packagescan.getmodules(self.build_lib,
60 'hgext')
58 mercurial.packagescan.scan(self.build_lib,'mercurial')
59 mercurial.packagescan.scan(self.build_lib,'hgext')
60 self.includes += mercurial.packagescan.getmodules()
61 61 build_exe.finalize_options(self)
62 62 except ImportError:
63 63 py2exe_for_demandload = None
64 64
65 65
66 66 # specify version string, otherwise 'hg identify' will be used:
67 67 version = ''
68 68
69 69 class install_package_data(install_data):
70 70 def finalize_options(self):
71 71 self.set_undefined_options('install',
72 72 ('install_lib', 'install_dir'))
73 73 install_data.finalize_options(self)
74 74
75 75 mercurial.version.remember_version(version)
76 76 cmdclass = {'install_data': install_package_data}
77 77 py2exe_opts = {}
78 78 if py2exe_for_demandload is not None:
79 79 cmdclass['py2exe'] = py2exe_for_demandload
80 80 py2exe_opts['console'] = ['hg']
81 81 setup(name='mercurial',
82 82 version=mercurial.version.get_version(),
83 83 author='Matt Mackall',
84 84 author_email='mpm@selenic.com',
85 85 url='http://selenic.com/mercurial',
86 86 description='Scalable distributed SCM',
87 87 license='GNU GPL',
88 88 packages=['mercurial', 'hgext'],
89 89 ext_modules=[Extension('mercurial.mpatch', ['mercurial/mpatch.c']),
90 90 Extension('mercurial.bdiff', ['mercurial/bdiff.c'])],
91 91 data_files=[('mercurial/templates',
92 92 ['templates/map'] +
93 93 glob.glob('templates/map-*') +
94 94 glob.glob('templates/*.tmpl')),
95 95 ('mercurial/templates/static',
96 96 glob.glob('templates/static/*'))],
97 97 cmdclass=cmdclass,
98 98 scripts=['hg', 'hgmerge'],
99 99 options=dict(bdist_mpkg=dict(zipdist=True,
100 100 license='COPYING',
101 101 readme='contrib/macosx/Readme.html',
102 102 welcome='contrib/macosx/Welcome.html')),
103 103 **py2exe_opts)
General Comments 0
You need to be logged in to leave comments. Login now