##// END OF EJS Templates
setup.py: use StrictVersion instead of manual comparison
Dirkjan Ochtman -
r13594:64a45870 stable
parent child Browse files
Show More
@@ -1,404 +1,405 b''
1 #
1 #
2 # This is the mercurial setup script.
2 # This is the mercurial setup script.
3 #
3 #
4 # 'python setup.py install', or
4 # 'python setup.py install', or
5 # 'python setup.py --help' for more options
5 # 'python setup.py --help' for more options
6
6
7 import sys
7 import sys
8 if not hasattr(sys, 'version_info') or sys.version_info < (2, 4, 0, 'final'):
8 if not hasattr(sys, 'version_info') or sys.version_info < (2, 4, 0, 'final'):
9 raise SystemExit("Mercurial requires Python 2.4 or later.")
9 raise SystemExit("Mercurial requires Python 2.4 or later.")
10
10
11 if sys.version_info[0] >= 3:
11 if sys.version_info[0] >= 3:
12 def b(s):
12 def b(s):
13 '''A helper function to emulate 2.6+ bytes literals using string
13 '''A helper function to emulate 2.6+ bytes literals using string
14 literals.'''
14 literals.'''
15 return s.encode('latin1')
15 return s.encode('latin1')
16 else:
16 else:
17 def b(s):
17 def b(s):
18 '''A helper function to emulate 2.6+ bytes literals using string
18 '''A helper function to emulate 2.6+ bytes literals using string
19 literals.'''
19 literals.'''
20 return s
20 return s
21
21
22 # Solaris Python packaging brain damage
22 # Solaris Python packaging brain damage
23 try:
23 try:
24 import hashlib
24 import hashlib
25 sha = hashlib.sha1()
25 sha = hashlib.sha1()
26 except:
26 except:
27 try:
27 try:
28 import sha
28 import sha
29 except:
29 except:
30 raise SystemExit(
30 raise SystemExit(
31 "Couldn't import standard hashlib (incomplete Python install).")
31 "Couldn't import standard hashlib (incomplete Python install).")
32
32
33 try:
33 try:
34 import zlib
34 import zlib
35 except:
35 except:
36 raise SystemExit(
36 raise SystemExit(
37 "Couldn't import standard zlib (incomplete Python install).")
37 "Couldn't import standard zlib (incomplete Python install).")
38
38
39 try:
39 try:
40 import bz2
40 import bz2
41 except:
41 except:
42 raise SystemExit(
42 raise SystemExit(
43 "Couldn't import standard bz2 (incomplete Python install).")
43 "Couldn't import standard bz2 (incomplete Python install).")
44
44
45 import os, subprocess, time
45 import os, subprocess, time
46 import shutil
46 import shutil
47 import tempfile
47 import tempfile
48 from distutils import log
48 from distutils import log
49 from distutils.core import setup, Extension
49 from distutils.core import setup, Extension
50 from distutils.dist import Distribution
50 from distutils.dist import Distribution
51 from distutils.command.build import build
51 from distutils.command.build import build
52 from distutils.command.build_ext import build_ext
52 from distutils.command.build_ext import build_ext
53 from distutils.command.build_py import build_py
53 from distutils.command.build_py import build_py
54 from distutils.command.install_scripts import install_scripts
54 from distutils.command.install_scripts import install_scripts
55 from distutils.spawn import spawn, find_executable
55 from distutils.spawn import spawn, find_executable
56 from distutils.ccompiler import new_compiler
56 from distutils.ccompiler import new_compiler
57 from distutils.errors import CCompilerError
57 from distutils.errors import CCompilerError
58 from distutils.sysconfig import get_python_inc
58 from distutils.sysconfig import get_python_inc
59 from distutils.version import StrictVersion
59
60
60 scripts = ['hg']
61 scripts = ['hg']
61 if os.name == 'nt':
62 if os.name == 'nt':
62 scripts.append('contrib/win32/hg.bat')
63 scripts.append('contrib/win32/hg.bat')
63
64
64 # simplified version of distutils.ccompiler.CCompiler.has_function
65 # simplified version of distutils.ccompiler.CCompiler.has_function
65 # that actually removes its temporary files.
66 # that actually removes its temporary files.
66 def hasfunction(cc, funcname):
67 def hasfunction(cc, funcname):
67 tmpdir = tempfile.mkdtemp(prefix='hg-install-')
68 tmpdir = tempfile.mkdtemp(prefix='hg-install-')
68 devnull = oldstderr = None
69 devnull = oldstderr = None
69 try:
70 try:
70 try:
71 try:
71 fname = os.path.join(tmpdir, 'funcname.c')
72 fname = os.path.join(tmpdir, 'funcname.c')
72 f = open(fname, 'w')
73 f = open(fname, 'w')
73 f.write('int main(void) {\n')
74 f.write('int main(void) {\n')
74 f.write(' %s();\n' % funcname)
75 f.write(' %s();\n' % funcname)
75 f.write('}\n')
76 f.write('}\n')
76 f.close()
77 f.close()
77 # Redirect stderr to /dev/null to hide any error messages
78 # Redirect stderr to /dev/null to hide any error messages
78 # from the compiler.
79 # from the compiler.
79 # This will have to be changed if we ever have to check
80 # This will have to be changed if we ever have to check
80 # for a function on Windows.
81 # for a function on Windows.
81 devnull = open('/dev/null', 'w')
82 devnull = open('/dev/null', 'w')
82 oldstderr = os.dup(sys.stderr.fileno())
83 oldstderr = os.dup(sys.stderr.fileno())
83 os.dup2(devnull.fileno(), sys.stderr.fileno())
84 os.dup2(devnull.fileno(), sys.stderr.fileno())
84 objects = cc.compile([fname], output_dir=tmpdir)
85 objects = cc.compile([fname], output_dir=tmpdir)
85 cc.link_executable(objects, os.path.join(tmpdir, "a.out"))
86 cc.link_executable(objects, os.path.join(tmpdir, "a.out"))
86 except:
87 except:
87 return False
88 return False
88 return True
89 return True
89 finally:
90 finally:
90 if oldstderr is not None:
91 if oldstderr is not None:
91 os.dup2(oldstderr, sys.stderr.fileno())
92 os.dup2(oldstderr, sys.stderr.fileno())
92 if devnull is not None:
93 if devnull is not None:
93 devnull.close()
94 devnull.close()
94 shutil.rmtree(tmpdir)
95 shutil.rmtree(tmpdir)
95
96
96 # py2exe needs to be installed to work
97 # py2exe needs to be installed to work
97 try:
98 try:
98 import py2exe
99 import py2exe
99 py2exeloaded = True
100 py2exeloaded = True
100
101
101 # Help py2exe to find win32com.shell
102 # Help py2exe to find win32com.shell
102 try:
103 try:
103 import modulefinder
104 import modulefinder
104 import win32com
105 import win32com
105 for p in win32com.__path__[1:]: # Take the path to win32comext
106 for p in win32com.__path__[1:]: # Take the path to win32comext
106 modulefinder.AddPackagePath("win32com", p)
107 modulefinder.AddPackagePath("win32com", p)
107 pn = "win32com.shell"
108 pn = "win32com.shell"
108 __import__(pn)
109 __import__(pn)
109 m = sys.modules[pn]
110 m = sys.modules[pn]
110 for p in m.__path__[1:]:
111 for p in m.__path__[1:]:
111 modulefinder.AddPackagePath(pn, p)
112 modulefinder.AddPackagePath(pn, p)
112 except ImportError:
113 except ImportError:
113 pass
114 pass
114
115
115 except ImportError:
116 except ImportError:
116 py2exeloaded = False
117 py2exeloaded = False
117 pass
118 pass
118
119
119 def runcmd(cmd, env):
120 def runcmd(cmd, env):
120 p = subprocess.Popen(cmd, stdout=subprocess.PIPE,
121 p = subprocess.Popen(cmd, stdout=subprocess.PIPE,
121 stderr=subprocess.PIPE, env=env)
122 stderr=subprocess.PIPE, env=env)
122 out, err = p.communicate()
123 out, err = p.communicate()
123 # If root is executing setup.py, but the repository is owned by
124 # If root is executing setup.py, but the repository is owned by
124 # another user (as in "sudo python setup.py install") we will get
125 # another user (as in "sudo python setup.py install") we will get
125 # trust warnings since the .hg/hgrc file is untrusted. That is
126 # trust warnings since the .hg/hgrc file is untrusted. That is
126 # fine, we don't want to load it anyway. Python may warn about
127 # fine, we don't want to load it anyway. Python may warn about
127 # a missing __init__.py in mercurial/locale, we also ignore that.
128 # a missing __init__.py in mercurial/locale, we also ignore that.
128 err = [e for e in err.splitlines()
129 err = [e for e in err.splitlines()
129 if not e.startswith(b('Not trusting file')) \
130 if not e.startswith(b('Not trusting file')) \
130 and not e.startswith(b('warning: Not importing'))]
131 and not e.startswith(b('warning: Not importing'))]
131 if err:
132 if err:
132 return ''
133 return ''
133 return out
134 return out
134
135
135 version = ''
136 version = ''
136
137
137 if os.path.isdir('.hg'):
138 if os.path.isdir('.hg'):
138 # Execute hg out of this directory with a custom environment which
139 # Execute hg out of this directory with a custom environment which
139 # includes the pure Python modules in mercurial/pure. We also take
140 # includes the pure Python modules in mercurial/pure. We also take
140 # care to not use any hgrc files and do no localization.
141 # care to not use any hgrc files and do no localization.
141 pypath = ['mercurial', os.path.join('mercurial', 'pure')]
142 pypath = ['mercurial', os.path.join('mercurial', 'pure')]
142 env = {'PYTHONPATH': os.pathsep.join(pypath),
143 env = {'PYTHONPATH': os.pathsep.join(pypath),
143 'HGRCPATH': '',
144 'HGRCPATH': '',
144 'LANGUAGE': 'C'}
145 'LANGUAGE': 'C'}
145 if 'LD_LIBRARY_PATH' in os.environ:
146 if 'LD_LIBRARY_PATH' in os.environ:
146 env['LD_LIBRARY_PATH'] = os.environ['LD_LIBRARY_PATH']
147 env['LD_LIBRARY_PATH'] = os.environ['LD_LIBRARY_PATH']
147 if 'SystemRoot' in os.environ:
148 if 'SystemRoot' in os.environ:
148 # Copy SystemRoot into the custom environment for Python 2.6
149 # Copy SystemRoot into the custom environment for Python 2.6
149 # under Windows. Otherwise, the subprocess will fail with
150 # under Windows. Otherwise, the subprocess will fail with
150 # error 0xc0150004. See: http://bugs.python.org/issue3440
151 # error 0xc0150004. See: http://bugs.python.org/issue3440
151 env['SystemRoot'] = os.environ['SystemRoot']
152 env['SystemRoot'] = os.environ['SystemRoot']
152 cmd = [sys.executable, 'hg', 'id', '-i', '-t']
153 cmd = [sys.executable, 'hg', 'id', '-i', '-t']
153 l = runcmd(cmd, env).split()
154 l = runcmd(cmd, env).split()
154 while len(l) > 1 and l[-1][0].isalpha(): # remove non-numbered tags
155 while len(l) > 1 and l[-1][0].isalpha(): # remove non-numbered tags
155 l.pop()
156 l.pop()
156 if len(l) > 1: # tag found
157 if len(l) > 1: # tag found
157 version = l[-1]
158 version = l[-1]
158 if l[0].endswith('+'): # propagate the dirty status to the tag
159 if l[0].endswith('+'): # propagate the dirty status to the tag
159 version += '+'
160 version += '+'
160 elif len(l) == 1: # no tag found
161 elif len(l) == 1: # no tag found
161 cmd = [sys.executable, 'hg', 'parents', '--template',
162 cmd = [sys.executable, 'hg', 'parents', '--template',
162 '{latesttag}+{latesttagdistance}-']
163 '{latesttag}+{latesttagdistance}-']
163 version = runcmd(cmd, env) + l[0]
164 version = runcmd(cmd, env) + l[0]
164 if version.endswith('+'):
165 if version.endswith('+'):
165 version += time.strftime('%Y%m%d')
166 version += time.strftime('%Y%m%d')
166 elif os.path.exists('.hg_archival.txt'):
167 elif os.path.exists('.hg_archival.txt'):
167 kw = dict([[t.strip() for t in l.split(':', 1)]
168 kw = dict([[t.strip() for t in l.split(':', 1)]
168 for l in open('.hg_archival.txt')])
169 for l in open('.hg_archival.txt')])
169 if 'tag' in kw:
170 if 'tag' in kw:
170 version = kw['tag']
171 version = kw['tag']
171 elif 'latesttag' in kw:
172 elif 'latesttag' in kw:
172 version = '%(latesttag)s+%(latesttagdistance)s-%(node).12s' % kw
173 version = '%(latesttag)s+%(latesttagdistance)s-%(node).12s' % kw
173 else:
174 else:
174 version = kw.get('node', '')[:12]
175 version = kw.get('node', '')[:12]
175
176
176 if version:
177 if version:
177 f = open("mercurial/__version__.py", "w")
178 f = open("mercurial/__version__.py", "w")
178 f.write('# this file is autogenerated by setup.py\n')
179 f.write('# this file is autogenerated by setup.py\n')
179 f.write('version = "%s"\n' % version)
180 f.write('version = "%s"\n' % version)
180 f.close()
181 f.close()
181
182
182
183
183 try:
184 try:
184 from mercurial import __version__
185 from mercurial import __version__
185 version = __version__.version
186 version = __version__.version
186 except ImportError:
187 except ImportError:
187 version = 'unknown'
188 version = 'unknown'
188
189
189 class hgbuildmo(build):
190 class hgbuildmo(build):
190
191
191 description = "build translations (.mo files)"
192 description = "build translations (.mo files)"
192
193
193 def run(self):
194 def run(self):
194 if not find_executable('msgfmt'):
195 if not find_executable('msgfmt'):
195 self.warn("could not find msgfmt executable, no translations "
196 self.warn("could not find msgfmt executable, no translations "
196 "will be built")
197 "will be built")
197 return
198 return
198
199
199 podir = 'i18n'
200 podir = 'i18n'
200 if not os.path.isdir(podir):
201 if not os.path.isdir(podir):
201 self.warn("could not find %s/ directory" % podir)
202 self.warn("could not find %s/ directory" % podir)
202 return
203 return
203
204
204 join = os.path.join
205 join = os.path.join
205 for po in os.listdir(podir):
206 for po in os.listdir(podir):
206 if not po.endswith('.po'):
207 if not po.endswith('.po'):
207 continue
208 continue
208 pofile = join(podir, po)
209 pofile = join(podir, po)
209 modir = join('locale', po[:-3], 'LC_MESSAGES')
210 modir = join('locale', po[:-3], 'LC_MESSAGES')
210 mofile = join(modir, 'hg.mo')
211 mofile = join(modir, 'hg.mo')
211 mobuildfile = join('mercurial', mofile)
212 mobuildfile = join('mercurial', mofile)
212 cmd = ['msgfmt', '-v', '-o', mobuildfile, pofile]
213 cmd = ['msgfmt', '-v', '-o', mobuildfile, pofile]
213 if sys.platform != 'sunos5':
214 if sys.platform != 'sunos5':
214 # msgfmt on Solaris does not know about -c
215 # msgfmt on Solaris does not know about -c
215 cmd.append('-c')
216 cmd.append('-c')
216 self.mkpath(join('mercurial', modir))
217 self.mkpath(join('mercurial', modir))
217 self.make_file([pofile], mobuildfile, spawn, (cmd,))
218 self.make_file([pofile], mobuildfile, spawn, (cmd,))
218
219
219
220
220 # Insert hgbuildmo first so that files in mercurial/locale/ are found
221 # Insert hgbuildmo first so that files in mercurial/locale/ are found
221 # when build_py is run next.
222 # when build_py is run next.
222 build.sub_commands.insert(0, ('build_mo', None))
223 build.sub_commands.insert(0, ('build_mo', None))
223
224
224 Distribution.pure = 0
225 Distribution.pure = 0
225 Distribution.global_options.append(('pure', None, "use pure (slow) Python "
226 Distribution.global_options.append(('pure', None, "use pure (slow) Python "
226 "code instead of C extensions"))
227 "code instead of C extensions"))
227
228
228 class hgbuildext(build_ext):
229 class hgbuildext(build_ext):
229
230
230 def build_extension(self, ext):
231 def build_extension(self, ext):
231 try:
232 try:
232 build_ext.build_extension(self, ext)
233 build_ext.build_extension(self, ext)
233 except CCompilerError:
234 except CCompilerError:
234 if not getattr(ext, 'optional', False):
235 if not getattr(ext, 'optional', False):
235 raise
236 raise
236 log.warn("Failed to build optional extension '%s' (skipping)",
237 log.warn("Failed to build optional extension '%s' (skipping)",
237 ext.name)
238 ext.name)
238
239
239 class hgbuildpy(build_py):
240 class hgbuildpy(build_py):
240
241
241 def finalize_options(self):
242 def finalize_options(self):
242 build_py.finalize_options(self)
243 build_py.finalize_options(self)
243
244
244 if self.distribution.pure:
245 if self.distribution.pure:
245 if self.py_modules is None:
246 if self.py_modules is None:
246 self.py_modules = []
247 self.py_modules = []
247 for ext in self.distribution.ext_modules:
248 for ext in self.distribution.ext_modules:
248 if ext.name.startswith("mercurial."):
249 if ext.name.startswith("mercurial."):
249 self.py_modules.append("mercurial.pure.%s" % ext.name[10:])
250 self.py_modules.append("mercurial.pure.%s" % ext.name[10:])
250 self.distribution.ext_modules = []
251 self.distribution.ext_modules = []
251 else:
252 else:
252 if not os.path.exists(os.path.join(get_python_inc(), 'Python.h')):
253 if not os.path.exists(os.path.join(get_python_inc(), 'Python.h')):
253 raise SystemExit("Python headers are required to build Mercurial")
254 raise SystemExit("Python headers are required to build Mercurial")
254
255
255 def find_modules(self):
256 def find_modules(self):
256 modules = build_py.find_modules(self)
257 modules = build_py.find_modules(self)
257 for module in modules:
258 for module in modules:
258 if module[0] == "mercurial.pure":
259 if module[0] == "mercurial.pure":
259 if module[1] != "__init__":
260 if module[1] != "__init__":
260 yield ("mercurial", module[1], module[2])
261 yield ("mercurial", module[1], module[2])
261 else:
262 else:
262 yield module
263 yield module
263
264
264 class hginstallscripts(install_scripts):
265 class hginstallscripts(install_scripts):
265 '''
266 '''
266 This is a specialization of install_scripts that replaces the @LIBDIR@ with
267 This is a specialization of install_scripts that replaces the @LIBDIR@ with
267 the configured directory for modules. If possible, the path is made relative
268 the configured directory for modules. If possible, the path is made relative
268 to the directory for scripts.
269 to the directory for scripts.
269 '''
270 '''
270
271
271 def initialize_options(self):
272 def initialize_options(self):
272 install_scripts.initialize_options(self)
273 install_scripts.initialize_options(self)
273
274
274 self.install_lib = None
275 self.install_lib = None
275
276
276 def finalize_options(self):
277 def finalize_options(self):
277 install_scripts.finalize_options(self)
278 install_scripts.finalize_options(self)
278 self.set_undefined_options('install',
279 self.set_undefined_options('install',
279 ('install_lib', 'install_lib'))
280 ('install_lib', 'install_lib'))
280
281
281 def run(self):
282 def run(self):
282 install_scripts.run(self)
283 install_scripts.run(self)
283
284
284 if (os.path.splitdrive(self.install_dir)[0] !=
285 if (os.path.splitdrive(self.install_dir)[0] !=
285 os.path.splitdrive(self.install_lib)[0]):
286 os.path.splitdrive(self.install_lib)[0]):
286 # can't make relative paths from one drive to another, so use an
287 # can't make relative paths from one drive to another, so use an
287 # absolute path instead
288 # absolute path instead
288 libdir = self.install_lib
289 libdir = self.install_lib
289 else:
290 else:
290 common = os.path.commonprefix((self.install_dir, self.install_lib))
291 common = os.path.commonprefix((self.install_dir, self.install_lib))
291 rest = self.install_dir[len(common):]
292 rest = self.install_dir[len(common):]
292 uplevel = len([n for n in os.path.split(rest) if n])
293 uplevel = len([n for n in os.path.split(rest) if n])
293
294
294 libdir = uplevel * ('..' + os.sep) + self.install_lib[len(common):]
295 libdir = uplevel * ('..' + os.sep) + self.install_lib[len(common):]
295
296
296 for outfile in self.outfiles:
297 for outfile in self.outfiles:
297 fp = open(outfile, 'rb')
298 fp = open(outfile, 'rb')
298 data = fp.read()
299 data = fp.read()
299 fp.close()
300 fp.close()
300
301
301 # skip binary files
302 # skip binary files
302 if '\0' in data:
303 if '\0' in data:
303 continue
304 continue
304
305
305 data = data.replace('@LIBDIR@', libdir.encode('string_escape'))
306 data = data.replace('@LIBDIR@', libdir.encode('string_escape'))
306 fp = open(outfile, 'wb')
307 fp = open(outfile, 'wb')
307 fp.write(data)
308 fp.write(data)
308 fp.close()
309 fp.close()
309
310
310 cmdclass = {'build_mo': hgbuildmo,
311 cmdclass = {'build_mo': hgbuildmo,
311 'build_ext': hgbuildext,
312 'build_ext': hgbuildext,
312 'build_py': hgbuildpy,
313 'build_py': hgbuildpy,
313 'install_scripts': hginstallscripts}
314 'install_scripts': hginstallscripts}
314
315
315 packages = ['mercurial', 'mercurial.hgweb', 'hgext', 'hgext.convert',
316 packages = ['mercurial', 'mercurial.hgweb', 'hgext', 'hgext.convert',
316 'hgext.highlight', 'hgext.zeroconf']
317 'hgext.highlight', 'hgext.zeroconf']
317
318
318 pymodules = []
319 pymodules = []
319
320
320 extmodules = [
321 extmodules = [
321 Extension('mercurial.base85', ['mercurial/base85.c']),
322 Extension('mercurial.base85', ['mercurial/base85.c']),
322 Extension('mercurial.bdiff', ['mercurial/bdiff.c']),
323 Extension('mercurial.bdiff', ['mercurial/bdiff.c']),
323 Extension('mercurial.diffhelpers', ['mercurial/diffhelpers.c']),
324 Extension('mercurial.diffhelpers', ['mercurial/diffhelpers.c']),
324 Extension('mercurial.mpatch', ['mercurial/mpatch.c']),
325 Extension('mercurial.mpatch', ['mercurial/mpatch.c']),
325 Extension('mercurial.parsers', ['mercurial/parsers.c']),
326 Extension('mercurial.parsers', ['mercurial/parsers.c']),
326 ]
327 ]
327
328
328 # disable osutil.c under windows + python 2.4 (issue1364)
329 # disable osutil.c under windows + python 2.4 (issue1364)
329 if sys.platform == 'win32' and sys.version_info < (2, 5, 0, 'final'):
330 if sys.platform == 'win32' and sys.version_info < (2, 5, 0, 'final'):
330 pymodules.append('mercurial.pure.osutil')
331 pymodules.append('mercurial.pure.osutil')
331 else:
332 else:
332 extmodules.append(Extension('mercurial.osutil', ['mercurial/osutil.c']))
333 extmodules.append(Extension('mercurial.osutil', ['mercurial/osutil.c']))
333
334
334 if sys.platform == 'linux2' and os.uname()[2] > '2.6':
335 if sys.platform == 'linux2' and os.uname()[2] > '2.6':
335 # The inotify extension is only usable with Linux 2.6 kernels.
336 # The inotify extension is only usable with Linux 2.6 kernels.
336 # You also need a reasonably recent C library.
337 # You also need a reasonably recent C library.
337 # In any case, if it fails to build the error will be skipped ('optional').
338 # In any case, if it fails to build the error will be skipped ('optional').
338 cc = new_compiler()
339 cc = new_compiler()
339 if hasfunction(cc, 'inotify_add_watch'):
340 if hasfunction(cc, 'inotify_add_watch'):
340 inotify = Extension('hgext.inotify.linux._inotify',
341 inotify = Extension('hgext.inotify.linux._inotify',
341 ['hgext/inotify/linux/_inotify.c'],
342 ['hgext/inotify/linux/_inotify.c'],
342 ['mercurial'])
343 ['mercurial'])
343 inotify.optional = True
344 inotify.optional = True
344 extmodules.append(inotify)
345 extmodules.append(inotify)
345 packages.extend(['hgext.inotify', 'hgext.inotify.linux'])
346 packages.extend(['hgext.inotify', 'hgext.inotify.linux'])
346
347
347 packagedata = {'mercurial': ['locale/*/LC_MESSAGES/hg.mo',
348 packagedata = {'mercurial': ['locale/*/LC_MESSAGES/hg.mo',
348 'help/*.txt']}
349 'help/*.txt']}
349
350
350 def ordinarypath(p):
351 def ordinarypath(p):
351 return p and p[0] != '.' and p[-1] != '~'
352 return p and p[0] != '.' and p[-1] != '~'
352
353
353 for root in ('templates',):
354 for root in ('templates',):
354 for curdir, dirs, files in os.walk(os.path.join('mercurial', root)):
355 for curdir, dirs, files in os.walk(os.path.join('mercurial', root)):
355 curdir = curdir.split(os.sep, 1)[1]
356 curdir = curdir.split(os.sep, 1)[1]
356 dirs[:] = filter(ordinarypath, dirs)
357 dirs[:] = filter(ordinarypath, dirs)
357 for f in filter(ordinarypath, files):
358 for f in filter(ordinarypath, files):
358 f = os.path.join(curdir, f)
359 f = os.path.join(curdir, f)
359 packagedata['mercurial'].append(f)
360 packagedata['mercurial'].append(f)
360
361
361 datafiles = []
362 datafiles = []
362 setupversion = version
363 setupversion = version
363 extra = {}
364 extra = {}
364
365
365 if py2exeloaded:
366 if py2exeloaded:
366 extra['console'] = [
367 extra['console'] = [
367 {'script':'hg',
368 {'script':'hg',
368 'copyright':'Copyright (C) 2005-2010 Matt Mackall and others',
369 'copyright':'Copyright (C) 2005-2010 Matt Mackall and others',
369 'product_version':version}]
370 'product_version':version}]
370
371
371 if os.name == 'nt':
372 if os.name == 'nt':
372 # Windows binary file versions for exe/dll files must have the
373 # Windows binary file versions for exe/dll files must have the
373 # form W.X.Y.Z, where W,X,Y,Z are numbers in the range 0..65535
374 # form W.X.Y.Z, where W,X,Y,Z are numbers in the range 0..65535
374 setupversion = version.split('+', 1)[0]
375 setupversion = version.split('+', 1)[0]
375
376
376 if sys.platform == 'darwin' and os.path.exists('/usr/bin/xcodebuild'):
377 if sys.platform == 'darwin' and os.path.exists('/usr/bin/xcodebuild'):
377 # XCode 4.0 dropped support for ppc architecture, which is hardcoded in
378 # XCode 4.0 dropped support for ppc architecture, which is hardcoded in
378 # distutils.sysconfig
379 # distutils.sysconfig
379 version = runcmd(['/usr/bin/xcodebuild', '-version'], {}).splitlines()[0]
380 version = runcmd(['/usr/bin/xcodebuild', '-version'], {}).splitlines()[0]
380 # Also parse only first digit, because 3.2.1 can't be parsed nicely
381 # Also parse only first digit, because 3.2.1 can't be parsed nicely
381 if (version.startswith('Xcode') and
382 if (version.startswith('Xcode') and
382 int(version.split()[1].split('.')[0]) >= 4):
383 StrictVersion(version.split()[1]) >= StrictVersion('4.0')):
383 os.environ['ARCHFLAGS'] = '-arch i386 -arch x86_64'
384 os.environ['ARCHFLAGS'] = '-arch i386 -arch x86_64'
384
385
385 setup(name='mercurial',
386 setup(name='mercurial',
386 version=setupversion,
387 version=setupversion,
387 author='Matt Mackall',
388 author='Matt Mackall',
388 author_email='mpm@selenic.com',
389 author_email='mpm@selenic.com',
389 url='http://mercurial.selenic.com/',
390 url='http://mercurial.selenic.com/',
390 description='Scalable distributed SCM',
391 description='Scalable distributed SCM',
391 license='GNU GPLv2+',
392 license='GNU GPLv2+',
392 scripts=scripts,
393 scripts=scripts,
393 packages=packages,
394 packages=packages,
394 py_modules=pymodules,
395 py_modules=pymodules,
395 ext_modules=extmodules,
396 ext_modules=extmodules,
396 data_files=datafiles,
397 data_files=datafiles,
397 package_data=packagedata,
398 package_data=packagedata,
398 cmdclass=cmdclass,
399 cmdclass=cmdclass,
399 options=dict(py2exe=dict(packages=['hgext', 'email']),
400 options=dict(py2exe=dict(packages=['hgext', 'email']),
400 bdist_mpkg=dict(zipdist=True,
401 bdist_mpkg=dict(zipdist=True,
401 license='COPYING',
402 license='COPYING',
402 readme='contrib/macosx/Readme.html',
403 readme='contrib/macosx/Readme.html',
403 welcome='contrib/macosx/Welcome.html')),
404 welcome='contrib/macosx/Welcome.html')),
404 **extra)
405 **extra)
General Comments 0
You need to be logged in to leave comments. Login now