##// END OF EJS Templates
setup: don't ship i18n directory...
Martin Geisler -
r9998:4a3c388f default
parent child Browse files
Show More
@@ -1,283 +1,283
1 #!/usr/bin/env python
1 #!/usr/bin/env python
2 #
2 #
3 # This is the mercurial setup script.
3 # This is the mercurial setup script.
4 #
4 #
5 # 'python setup.py install', or
5 # 'python setup.py install', or
6 # 'python setup.py --help' for more options
6 # 'python setup.py --help' for more options
7
7
8 import sys
8 import sys
9 if not hasattr(sys, 'version_info') or sys.version_info < (2, 4, 0, 'final'):
9 if not hasattr(sys, 'version_info') or sys.version_info < (2, 4, 0, 'final'):
10 raise SystemExit("Mercurial requires Python 2.4 or later.")
10 raise SystemExit("Mercurial requires Python 2.4 or later.")
11
11
12 # Solaris Python packaging brain damage
12 # Solaris Python packaging brain damage
13 try:
13 try:
14 import hashlib
14 import hashlib
15 sha = hashlib.sha1()
15 sha = hashlib.sha1()
16 except:
16 except:
17 try:
17 try:
18 import sha
18 import sha
19 except:
19 except:
20 raise SystemExit(
20 raise SystemExit(
21 "Couldn't import standard hashlib (incomplete Python install).")
21 "Couldn't import standard hashlib (incomplete Python install).")
22
22
23 try:
23 try:
24 import zlib
24 import zlib
25 except:
25 except:
26 raise SystemExit(
26 raise SystemExit(
27 "Couldn't import standard zlib (incomplete Python install).")
27 "Couldn't import standard zlib (incomplete Python install).")
28
28
29 import os, subprocess, time
29 import os, subprocess, time
30 import shutil
30 import shutil
31 import tempfile
31 import tempfile
32 from distutils.core import setup, Extension
32 from distutils.core import setup, Extension
33 from distutils.dist import Distribution
33 from distutils.dist import Distribution
34 from distutils.command.install_data import install_data
34 from distutils.command.install_data import install_data
35 from distutils.command.build import build
35 from distutils.command.build import build
36 from distutils.command.build_py import build_py
36 from distutils.command.build_py import build_py
37 from distutils.spawn import spawn, find_executable
37 from distutils.spawn import spawn, find_executable
38 from distutils.ccompiler import new_compiler
38 from distutils.ccompiler import new_compiler
39
39
40 extra = {}
40 extra = {}
41 scripts = ['hg']
41 scripts = ['hg']
42 if os.name == 'nt':
42 if os.name == 'nt':
43 scripts.append('contrib/win32/hg.bat')
43 scripts.append('contrib/win32/hg.bat')
44
44
45 # simplified version of distutils.ccompiler.CCompiler.has_function
45 # simplified version of distutils.ccompiler.CCompiler.has_function
46 # that actually removes its temporary files.
46 # that actually removes its temporary files.
47 def has_function(cc, funcname):
47 def has_function(cc, funcname):
48 tmpdir = tempfile.mkdtemp(prefix='hg-install-')
48 tmpdir = tempfile.mkdtemp(prefix='hg-install-')
49 devnull = oldstderr = None
49 devnull = oldstderr = None
50 try:
50 try:
51 try:
51 try:
52 fname = os.path.join(tmpdir, 'funcname.c')
52 fname = os.path.join(tmpdir, 'funcname.c')
53 f = open(fname, 'w')
53 f = open(fname, 'w')
54 f.write('int main(void) {\n')
54 f.write('int main(void) {\n')
55 f.write(' %s();\n' % funcname)
55 f.write(' %s();\n' % funcname)
56 f.write('}\n')
56 f.write('}\n')
57 f.close()
57 f.close()
58 # Redirect stderr to /dev/null to hide any error messages
58 # Redirect stderr to /dev/null to hide any error messages
59 # from the compiler.
59 # from the compiler.
60 # This will have to be changed if we ever have to check
60 # This will have to be changed if we ever have to check
61 # for a function on Windows.
61 # for a function on Windows.
62 devnull = open('/dev/null', 'w')
62 devnull = open('/dev/null', 'w')
63 oldstderr = os.dup(sys.stderr.fileno())
63 oldstderr = os.dup(sys.stderr.fileno())
64 os.dup2(devnull.fileno(), sys.stderr.fileno())
64 os.dup2(devnull.fileno(), sys.stderr.fileno())
65 objects = cc.compile([fname], output_dir=tmpdir)
65 objects = cc.compile([fname], output_dir=tmpdir)
66 cc.link_executable(objects, os.path.join(tmpdir, "a.out"))
66 cc.link_executable(objects, os.path.join(tmpdir, "a.out"))
67 except:
67 except:
68 return False
68 return False
69 return True
69 return True
70 finally:
70 finally:
71 if oldstderr is not None:
71 if oldstderr is not None:
72 os.dup2(oldstderr, sys.stderr.fileno())
72 os.dup2(oldstderr, sys.stderr.fileno())
73 if devnull is not None:
73 if devnull is not None:
74 devnull.close()
74 devnull.close()
75 shutil.rmtree(tmpdir)
75 shutil.rmtree(tmpdir)
76
76
77 # py2exe needs to be installed to work
77 # py2exe needs to be installed to work
78 try:
78 try:
79 import py2exe
79 import py2exe
80
80
81 # Help py2exe to find win32com.shell
81 # Help py2exe to find win32com.shell
82 try:
82 try:
83 import modulefinder
83 import modulefinder
84 import win32com
84 import win32com
85 for p in win32com.__path__[1:]: # Take the path to win32comext
85 for p in win32com.__path__[1:]: # Take the path to win32comext
86 modulefinder.AddPackagePath("win32com", p)
86 modulefinder.AddPackagePath("win32com", p)
87 pn = "win32com.shell"
87 pn = "win32com.shell"
88 __import__(pn)
88 __import__(pn)
89 m = sys.modules[pn]
89 m = sys.modules[pn]
90 for p in m.__path__[1:]:
90 for p in m.__path__[1:]:
91 modulefinder.AddPackagePath(pn, p)
91 modulefinder.AddPackagePath(pn, p)
92 except ImportError:
92 except ImportError:
93 pass
93 pass
94
94
95 extra['console'] = ['hg']
95 extra['console'] = ['hg']
96
96
97 except ImportError:
97 except ImportError:
98 pass
98 pass
99
99
100 def runcmd(cmd, env):
100 def runcmd(cmd, env):
101 p = subprocess.Popen(cmd, stdout=subprocess.PIPE,
101 p = subprocess.Popen(cmd, stdout=subprocess.PIPE,
102 stderr=subprocess.PIPE, env=env)
102 stderr=subprocess.PIPE, env=env)
103 out, err = p.communicate()
103 out, err = p.communicate()
104 # If root is executing setup.py, but the repository is owned by
104 # If root is executing setup.py, but the repository is owned by
105 # another user (as in "sudo python setup.py install") we will get
105 # another user (as in "sudo python setup.py install") we will get
106 # trust warnings since the .hg/hgrc file is untrusted. That is
106 # trust warnings since the .hg/hgrc file is untrusted. That is
107 # fine, we don't want to load it anyway.
107 # fine, we don't want to load it anyway.
108 err = [e for e in err.splitlines()
108 err = [e for e in err.splitlines()
109 if not e.startswith('Not trusting file')]
109 if not e.startswith('Not trusting file')]
110 if err:
110 if err:
111 return ''
111 return ''
112 return out
112 return out
113
113
114 version = ''
114 version = ''
115
115
116 if os.path.isdir('.hg'):
116 if os.path.isdir('.hg'):
117 # Execute hg out of this directory with a custom environment which
117 # Execute hg out of this directory with a custom environment which
118 # includes the pure Python modules in mercurial/pure. We also take
118 # includes the pure Python modules in mercurial/pure. We also take
119 # care to not use any hgrc files and do no localization.
119 # care to not use any hgrc files and do no localization.
120 pypath = ['mercurial', os.path.join('mercurial', 'pure')]
120 pypath = ['mercurial', os.path.join('mercurial', 'pure')]
121 env = {'PYTHONPATH': os.pathsep.join(pypath),
121 env = {'PYTHONPATH': os.pathsep.join(pypath),
122 'HGRCPATH': '',
122 'HGRCPATH': '',
123 'LANGUAGE': 'C'}
123 'LANGUAGE': 'C'}
124 if 'LD_LIBRARY_PATH' in os.environ:
124 if 'LD_LIBRARY_PATH' in os.environ:
125 env['LD_LIBRARY_PATH'] = os.environ['LD_LIBRARY_PATH']
125 env['LD_LIBRARY_PATH'] = os.environ['LD_LIBRARY_PATH']
126 if 'SystemRoot' in os.environ:
126 if 'SystemRoot' in os.environ:
127 # Copy SystemRoot into the custom environment for Python 2.6
127 # Copy SystemRoot into the custom environment for Python 2.6
128 # under Windows. Otherwise, the subprocess will fail with
128 # under Windows. Otherwise, the subprocess will fail with
129 # error 0xc0150004. See: http://bugs.python.org/issue3440
129 # error 0xc0150004. See: http://bugs.python.org/issue3440
130 env['SystemRoot'] = os.environ['SystemRoot']
130 env['SystemRoot'] = os.environ['SystemRoot']
131 cmd = [sys.executable, 'hg', 'id', '-i', '-t']
131 cmd = [sys.executable, 'hg', 'id', '-i', '-t']
132 l = runcmd(cmd, env).split()
132 l = runcmd(cmd, env).split()
133 while len(l) > 1 and l[-1][0].isalpha(): # remove non-numbered tags
133 while len(l) > 1 and l[-1][0].isalpha(): # remove non-numbered tags
134 l.pop()
134 l.pop()
135 if len(l) > 1: # tag found
135 if len(l) > 1: # tag found
136 version = l[-1]
136 version = l[-1]
137 if l[0].endswith('+'): # propagate the dirty status to the tag
137 if l[0].endswith('+'): # propagate the dirty status to the tag
138 version += '+'
138 version += '+'
139 elif len(l) == 1: # no tag found
139 elif len(l) == 1: # no tag found
140 cmd = [sys.executable, 'hg', 'parents', '--template',
140 cmd = [sys.executable, 'hg', 'parents', '--template',
141 '{latesttag}+{latesttagdistance}-']
141 '{latesttag}+{latesttagdistance}-']
142 version = runcmd(cmd, env) + l[0]
142 version = runcmd(cmd, env) + l[0]
143 if version.endswith('+'):
143 if version.endswith('+'):
144 version += time.strftime('%Y%m%d')
144 version += time.strftime('%Y%m%d')
145 elif os.path.exists('.hg_archival.txt'):
145 elif os.path.exists('.hg_archival.txt'):
146 kw = dict([t.strip() for t in l.split(':', 1)]
146 kw = dict([t.strip() for t in l.split(':', 1)]
147 for l in open('.hg_archival.txt'))
147 for l in open('.hg_archival.txt'))
148 if 'tag' in kw:
148 if 'tag' in kw:
149 version = kw['tag']
149 version = kw['tag']
150 elif 'latesttag' in kw:
150 elif 'latesttag' in kw:
151 version = '%(latesttag)s+%(latesttagdistance)s-%(node).12s' % kw
151 version = '%(latesttag)s+%(latesttagdistance)s-%(node).12s' % kw
152 else:
152 else:
153 version = kw.get('node', '')[:12]
153 version = kw.get('node', '')[:12]
154
154
155 if version:
155 if version:
156 f = open("mercurial/__version__.py", "w")
156 f = open("mercurial/__version__.py", "w")
157 f.write('# this file is autogenerated by setup.py\n')
157 f.write('# this file is autogenerated by setup.py\n')
158 f.write('version = "%s"\n' % version)
158 f.write('version = "%s"\n' % version)
159 f.close()
159 f.close()
160
160
161
161
162 try:
162 try:
163 from mercurial import __version__
163 from mercurial import __version__
164 version = __version__.version
164 version = __version__.version
165 except ImportError:
165 except ImportError:
166 version = 'unknown'
166 version = 'unknown'
167
167
168 class install_package_data(install_data):
168 class install_package_data(install_data):
169 def finalize_options(self):
169 def finalize_options(self):
170 self.set_undefined_options('install',
170 self.set_undefined_options('install',
171 ('install_lib', 'install_dir'))
171 ('install_lib', 'install_dir'))
172 install_data.finalize_options(self)
172 install_data.finalize_options(self)
173
173
174 class build_mo(build):
174 class build_mo(build):
175
175
176 description = "build translations (.mo files)"
176 description = "build translations (.mo files)"
177
177
178 def run(self):
178 def run(self):
179 if not find_executable('msgfmt'):
179 if not find_executable('msgfmt'):
180 self.warn("could not find msgfmt executable, no translations "
180 self.warn("could not find msgfmt executable, no translations "
181 "will be built")
181 "will be built")
182 return
182 return
183
183
184 podir = 'i18n'
184 podir = 'i18n'
185 if not os.path.isdir(podir):
185 if not os.path.isdir(podir):
186 self.warn("could not find %s/ directory" % podir)
186 self.warn("could not find %s/ directory" % podir)
187 return
187 return
188
188
189 join = os.path.join
189 join = os.path.join
190 for po in os.listdir(podir):
190 for po in os.listdir(podir):
191 if not po.endswith('.po'):
191 if not po.endswith('.po'):
192 continue
192 continue
193 pofile = join(podir, po)
193 pofile = join(podir, po)
194 modir = join('locale', po[:-3], 'LC_MESSAGES')
194 modir = join('locale', po[:-3], 'LC_MESSAGES')
195 mofile = join(modir, 'hg.mo')
195 mofile = join(modir, 'hg.mo')
196 cmd = ['msgfmt', '-v', '-o', mofile, pofile]
196 cmd = ['msgfmt', '-v', '-o', mofile, pofile]
197 if sys.platform != 'sunos5':
197 if sys.platform != 'sunos5':
198 # msgfmt on Solaris does not know about -c
198 # msgfmt on Solaris does not know about -c
199 cmd.append('-c')
199 cmd.append('-c')
200 self.mkpath(modir)
200 self.mkpath(modir)
201 self.make_file([pofile], mofile, spawn, (cmd,))
201 self.make_file([pofile], mofile, spawn, (cmd,))
202 self.distribution.data_files.append((join('mercurial', modir),
202 self.distribution.data_files.append((join('mercurial', modir),
203 [mofile]))
203 [mofile]))
204
204
205 build.sub_commands.append(('build_mo', None))
205 build.sub_commands.append(('build_mo', None))
206
206
207 Distribution.pure = 0
207 Distribution.pure = 0
208 Distribution.global_options.append(('pure', None, "use pure (slow) Python "
208 Distribution.global_options.append(('pure', None, "use pure (slow) Python "
209 "code instead of C extensions"))
209 "code instead of C extensions"))
210
210
211 class hg_build_py(build_py):
211 class hg_build_py(build_py):
212
212
213 def finalize_options(self):
213 def finalize_options(self):
214 build_py.finalize_options(self)
214 build_py.finalize_options(self)
215
215
216 if self.distribution.pure:
216 if self.distribution.pure:
217 if self.py_modules is None:
217 if self.py_modules is None:
218 self.py_modules = []
218 self.py_modules = []
219 for ext in self.distribution.ext_modules:
219 for ext in self.distribution.ext_modules:
220 if ext.name.startswith("mercurial."):
220 if ext.name.startswith("mercurial."):
221 self.py_modules.append("mercurial.pure.%s" % ext.name[10:])
221 self.py_modules.append("mercurial.pure.%s" % ext.name[10:])
222 self.distribution.ext_modules = []
222 self.distribution.ext_modules = []
223
223
224 def find_modules(self):
224 def find_modules(self):
225 modules = build_py.find_modules(self)
225 modules = build_py.find_modules(self)
226 for module in modules:
226 for module in modules:
227 if module[0] == "mercurial.pure":
227 if module[0] == "mercurial.pure":
228 if module[1] != "__init__":
228 if module[1] != "__init__":
229 yield ("mercurial", module[1], module[2])
229 yield ("mercurial", module[1], module[2])
230 else:
230 else:
231 yield module
231 yield module
232
232
233 cmdclass = {'install_data': install_package_data,
233 cmdclass = {'install_data': install_package_data,
234 'build_mo': build_mo,
234 'build_mo': build_mo,
235 'build_py': hg_build_py}
235 'build_py': hg_build_py}
236
236
237 ext_modules=[
237 ext_modules=[
238 Extension('mercurial.base85', ['mercurial/base85.c']),
238 Extension('mercurial.base85', ['mercurial/base85.c']),
239 Extension('mercurial.bdiff', ['mercurial/bdiff.c']),
239 Extension('mercurial.bdiff', ['mercurial/bdiff.c']),
240 Extension('mercurial.diffhelpers', ['mercurial/diffhelpers.c']),
240 Extension('mercurial.diffhelpers', ['mercurial/diffhelpers.c']),
241 Extension('mercurial.mpatch', ['mercurial/mpatch.c']),
241 Extension('mercurial.mpatch', ['mercurial/mpatch.c']),
242 Extension('mercurial.parsers', ['mercurial/parsers.c']),
242 Extension('mercurial.parsers', ['mercurial/parsers.c']),
243 Extension('mercurial.osutil', ['mercurial/osutil.c']),
243 Extension('mercurial.osutil', ['mercurial/osutil.c']),
244 ]
244 ]
245
245
246 packages = ['mercurial', 'mercurial.hgweb', 'hgext', 'hgext.convert',
246 packages = ['mercurial', 'mercurial.hgweb', 'hgext', 'hgext.convert',
247 'hgext.highlight', 'hgext.zeroconf', ]
247 'hgext.highlight', 'hgext.zeroconf', ]
248
248
249 if sys.platform == 'linux2' and os.uname()[2] > '2.6':
249 if sys.platform == 'linux2' and os.uname()[2] > '2.6':
250 # The inotify extension is only usable with Linux 2.6 kernels.
250 # The inotify extension is only usable with Linux 2.6 kernels.
251 # You also need a reasonably recent C library.
251 # You also need a reasonably recent C library.
252 cc = new_compiler()
252 cc = new_compiler()
253 if has_function(cc, 'inotify_add_watch'):
253 if has_function(cc, 'inotify_add_watch'):
254 ext_modules.append(Extension('hgext.inotify.linux._inotify',
254 ext_modules.append(Extension('hgext.inotify.linux._inotify',
255 ['hgext/inotify/linux/_inotify.c']))
255 ['hgext/inotify/linux/_inotify.c']))
256 packages.extend(['hgext.inotify', 'hgext.inotify.linux'])
256 packages.extend(['hgext.inotify', 'hgext.inotify.linux'])
257
257
258 datafiles = []
258 datafiles = []
259 for root in ('templates', 'i18n', 'help'):
259 for root in ('templates', 'help'):
260 for dir, dirs, files in os.walk(root):
260 for dir, dirs, files in os.walk(root):
261 dirs[:] = [x for x in dirs if not x.startswith('.')]
261 dirs[:] = [x for x in dirs if not x.startswith('.')]
262 files = [x for x in files if not x.startswith('.')]
262 files = [x for x in files if not x.startswith('.')]
263 datafiles.append((os.path.join('mercurial', dir),
263 datafiles.append((os.path.join('mercurial', dir),
264 [os.path.join(dir, file_) for file_ in files]))
264 [os.path.join(dir, file_) for file_ in files]))
265
265
266 setup(name='mercurial',
266 setup(name='mercurial',
267 version=version,
267 version=version,
268 author='Matt Mackall',
268 author='Matt Mackall',
269 author_email='mpm@selenic.com',
269 author_email='mpm@selenic.com',
270 url='http://mercurial.selenic.com/',
270 url='http://mercurial.selenic.com/',
271 description='Scalable distributed SCM',
271 description='Scalable distributed SCM',
272 license='GNU GPL',
272 license='GNU GPL',
273 scripts=scripts,
273 scripts=scripts,
274 packages=packages,
274 packages=packages,
275 ext_modules=ext_modules,
275 ext_modules=ext_modules,
276 data_files=datafiles,
276 data_files=datafiles,
277 cmdclass=cmdclass,
277 cmdclass=cmdclass,
278 options=dict(py2exe=dict(packages=['hgext', 'email']),
278 options=dict(py2exe=dict(packages=['hgext', 'email']),
279 bdist_mpkg=dict(zipdist=True,
279 bdist_mpkg=dict(zipdist=True,
280 license='COPYING',
280 license='COPYING',
281 readme='contrib/macosx/Readme.html',
281 readme='contrib/macosx/Readme.html',
282 welcome='contrib/macosx/Welcome.html')),
282 welcome='contrib/macosx/Welcome.html')),
283 **extra)
283 **extra)
General Comments 0
You need to be logged in to leave comments. Login now