Show More
@@ -0,0 +1,74 b'' | |||||
|
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 |
@@ -11,6 +11,34 b' from distutils.command.install_data impo' | |||||
11 |
|
11 | |||
12 | import mercurial.version |
|
12 | import mercurial.version | |
13 |
|
13 | |||
|
14 | # py2exe needs to be installed to work | |||
|
15 | try: | |||
|
16 | import py2exe | |||
|
17 | ||||
|
18 | # Due to the use of demandload py2exe is not finding the modules. | |||
|
19 | # packagescan.getmodules creates a list of modules included in | |||
|
20 | # the mercurial package plus depdent modules. | |||
|
21 | import mercurial.packagescan | |||
|
22 | from py2exe.build_exe import py2exe as build_exe | |||
|
23 | ||||
|
24 | class py2exe_for_demandload(build_exe): | |||
|
25 | """ overwrites the py2exe command class for getting the build | |||
|
26 | directory and for setting the 'includes' option.""" | |||
|
27 | def initialize_options(self): | |||
|
28 | self.build_lib = None | |||
|
29 | build_exe.initialize_options(self) | |||
|
30 | def finalize_options(self): | |||
|
31 | # Get the build directory, ie. where to search for modules. | |||
|
32 | self.set_undefined_options('build', | |||
|
33 | ('build_lib', 'build_lib')) | |||
|
34 | # Sets the 'includes' option with the list of needed modules | |||
|
35 | if not self.includes: | |||
|
36 | self.includes = [] | |||
|
37 | self.includes += mercurial.packagescan.getmodules(self.build_lib,'mercurial') | |||
|
38 | build_exe.finalize_options(self) | |||
|
39 | except ImportError: pass | |||
|
40 | ||||
|
41 | ||||
14 | # specify version string, otherwise 'hg identify' will be used: |
|
42 | # specify version string, otherwise 'hg identify' will be used: | |
15 | version = '' |
|
43 | version = '' | |
16 |
|
44 | |||
@@ -36,7 +64,9 b' try:' | |||||
36 | ['templates/map'] + |
|
64 | ['templates/map'] + | |
37 | glob.glob('templates/map-*') + |
|
65 | glob.glob('templates/map-*') + | |
38 | glob.glob('templates/*.tmpl'))], |
|
66 | glob.glob('templates/*.tmpl'))], | |
39 |
cmdclass = { 'install_data' : install_package_data |
|
67 | cmdclass = { 'install_data' : install_package_data, | |
40 | scripts=['hg', 'hgmerge']) |
|
68 | 'py2exe' : py2exe_for_demandload}, | |
|
69 | scripts=['hg', 'hgmerge'], | |||
|
70 | console = ['hg']) | |||
41 | finally: |
|
71 | finally: | |
42 | mercurial.version.forget_version() |
|
72 | mercurial.version.forget_version() |
General Comments 0
You need to be logged in to leave comments.
Login now