##// END OF EJS Templates
httpclient: omit tests for the client since we don't run them anyway
Augie Fackler -
r16775:e6af8676 default
parent child Browse files
Show More
@@ -1,499 +1,498 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, platform
7 import sys, platform
8 if getattr(sys, 'version_info', (0, 0, 0)) < (2, 4, 0, 'final'):
8 if getattr(sys, 'version_info', (0, 0, 0)) < (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 ImportError:
26 except ImportError:
27 try:
27 try:
28 import sha
28 import sha
29 except ImportError:
29 except ImportError:
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 ImportError:
35 except ImportError:
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 # The base IronPython distribution (as of 2.7.1) doesn't support bz2
39 # The base IronPython distribution (as of 2.7.1) doesn't support bz2
40 isironpython = False
40 isironpython = False
41 try:
41 try:
42 isironpython = (platform.python_implementation()
42 isironpython = (platform.python_implementation()
43 .lower().find("ironpython") != -1)
43 .lower().find("ironpython") != -1)
44 except AttributeError:
44 except AttributeError:
45 pass
45 pass
46
46
47 if isironpython:
47 if isironpython:
48 sys.stderr.write("warning: IronPython detected (no bz2 support)\n")
48 sys.stderr.write("warning: IronPython detected (no bz2 support)\n")
49 else:
49 else:
50 try:
50 try:
51 import bz2
51 import bz2
52 except ImportError:
52 except ImportError:
53 raise SystemExit(
53 raise SystemExit(
54 "Couldn't import standard bz2 (incomplete Python install).")
54 "Couldn't import standard bz2 (incomplete Python install).")
55
55
56 import os, subprocess, time
56 import os, subprocess, time
57 import shutil
57 import shutil
58 import tempfile
58 import tempfile
59 from distutils import log
59 from distutils import log
60 from distutils.core import setup, Command, Extension
60 from distutils.core import setup, Command, Extension
61 from distutils.dist import Distribution
61 from distutils.dist import Distribution
62 from distutils.command.build import build
62 from distutils.command.build import build
63 from distutils.command.build_ext import build_ext
63 from distutils.command.build_ext import build_ext
64 from distutils.command.build_py import build_py
64 from distutils.command.build_py import build_py
65 from distutils.command.install_scripts import install_scripts
65 from distutils.command.install_scripts import install_scripts
66 from distutils.spawn import spawn, find_executable
66 from distutils.spawn import spawn, find_executable
67 from distutils.ccompiler import new_compiler
67 from distutils.ccompiler import new_compiler
68 from distutils.errors import CCompilerError, DistutilsExecError
68 from distutils.errors import CCompilerError, DistutilsExecError
69 from distutils.sysconfig import get_python_inc
69 from distutils.sysconfig import get_python_inc
70 from distutils.version import StrictVersion
70 from distutils.version import StrictVersion
71
71
72 convert2to3 = '--c2to3' in sys.argv
72 convert2to3 = '--c2to3' in sys.argv
73 if convert2to3:
73 if convert2to3:
74 try:
74 try:
75 from distutils.command.build_py import build_py_2to3 as build_py
75 from distutils.command.build_py import build_py_2to3 as build_py
76 from lib2to3.refactor import get_fixers_from_package as getfixers
76 from lib2to3.refactor import get_fixers_from_package as getfixers
77 except ImportError:
77 except ImportError:
78 if sys.version_info[0] < 3:
78 if sys.version_info[0] < 3:
79 raise SystemExit("--c2to3 is only compatible with python3.")
79 raise SystemExit("--c2to3 is only compatible with python3.")
80 raise
80 raise
81 sys.path.append('contrib')
81 sys.path.append('contrib')
82 elif sys.version_info[0] >= 3:
82 elif sys.version_info[0] >= 3:
83 raise SystemExit("setup.py with python3 needs --c2to3 (experimental)")
83 raise SystemExit("setup.py with python3 needs --c2to3 (experimental)")
84
84
85 scripts = ['hg']
85 scripts = ['hg']
86 if os.name == 'nt':
86 if os.name == 'nt':
87 scripts.append('contrib/win32/hg.bat')
87 scripts.append('contrib/win32/hg.bat')
88
88
89 # simplified version of distutils.ccompiler.CCompiler.has_function
89 # simplified version of distutils.ccompiler.CCompiler.has_function
90 # that actually removes its temporary files.
90 # that actually removes its temporary files.
91 def hasfunction(cc, funcname):
91 def hasfunction(cc, funcname):
92 tmpdir = tempfile.mkdtemp(prefix='hg-install-')
92 tmpdir = tempfile.mkdtemp(prefix='hg-install-')
93 devnull = oldstderr = None
93 devnull = oldstderr = None
94 try:
94 try:
95 try:
95 try:
96 fname = os.path.join(tmpdir, 'funcname.c')
96 fname = os.path.join(tmpdir, 'funcname.c')
97 f = open(fname, 'w')
97 f = open(fname, 'w')
98 f.write('int main(void) {\n')
98 f.write('int main(void) {\n')
99 f.write(' %s();\n' % funcname)
99 f.write(' %s();\n' % funcname)
100 f.write('}\n')
100 f.write('}\n')
101 f.close()
101 f.close()
102 # Redirect stderr to /dev/null to hide any error messages
102 # Redirect stderr to /dev/null to hide any error messages
103 # from the compiler.
103 # from the compiler.
104 # This will have to be changed if we ever have to check
104 # This will have to be changed if we ever have to check
105 # for a function on Windows.
105 # for a function on Windows.
106 devnull = open('/dev/null', 'w')
106 devnull = open('/dev/null', 'w')
107 oldstderr = os.dup(sys.stderr.fileno())
107 oldstderr = os.dup(sys.stderr.fileno())
108 os.dup2(devnull.fileno(), sys.stderr.fileno())
108 os.dup2(devnull.fileno(), sys.stderr.fileno())
109 objects = cc.compile([fname], output_dir=tmpdir)
109 objects = cc.compile([fname], output_dir=tmpdir)
110 cc.link_executable(objects, os.path.join(tmpdir, "a.out"))
110 cc.link_executable(objects, os.path.join(tmpdir, "a.out"))
111 except Exception:
111 except Exception:
112 return False
112 return False
113 return True
113 return True
114 finally:
114 finally:
115 if oldstderr is not None:
115 if oldstderr is not None:
116 os.dup2(oldstderr, sys.stderr.fileno())
116 os.dup2(oldstderr, sys.stderr.fileno())
117 if devnull is not None:
117 if devnull is not None:
118 devnull.close()
118 devnull.close()
119 shutil.rmtree(tmpdir)
119 shutil.rmtree(tmpdir)
120
120
121 # py2exe needs to be installed to work
121 # py2exe needs to be installed to work
122 try:
122 try:
123 import py2exe
123 import py2exe
124 py2exeloaded = True
124 py2exeloaded = True
125 # import py2exe's patched Distribution class
125 # import py2exe's patched Distribution class
126 from distutils.core import Distribution
126 from distutils.core import Distribution
127 except ImportError:
127 except ImportError:
128 py2exeloaded = False
128 py2exeloaded = False
129
129
130 def runcmd(cmd, env):
130 def runcmd(cmd, env):
131 if sys.platform == 'plan9':
131 if sys.platform == 'plan9':
132 # subprocess kludge to work around issues in half-baked Python
132 # subprocess kludge to work around issues in half-baked Python
133 # ports, notably bichued/python:
133 # ports, notably bichued/python:
134 _, out, err = os.popen3(cmd)
134 _, out, err = os.popen3(cmd)
135 return str(out), str(err)
135 return str(out), str(err)
136 else:
136 else:
137 p = subprocess.Popen(cmd, stdout=subprocess.PIPE,
137 p = subprocess.Popen(cmd, stdout=subprocess.PIPE,
138 stderr=subprocess.PIPE, env=env)
138 stderr=subprocess.PIPE, env=env)
139 out, err = p.communicate()
139 out, err = p.communicate()
140 return out, err
140 return out, err
141
141
142 def runhg(cmd, env):
142 def runhg(cmd, env):
143 out, err = runcmd(cmd, env)
143 out, err = runcmd(cmd, env)
144 # If root is executing setup.py, but the repository is owned by
144 # If root is executing setup.py, but the repository is owned by
145 # another user (as in "sudo python setup.py install") we will get
145 # another user (as in "sudo python setup.py install") we will get
146 # trust warnings since the .hg/hgrc file is untrusted. That is
146 # trust warnings since the .hg/hgrc file is untrusted. That is
147 # fine, we don't want to load it anyway. Python may warn about
147 # fine, we don't want to load it anyway. Python may warn about
148 # a missing __init__.py in mercurial/locale, we also ignore that.
148 # a missing __init__.py in mercurial/locale, we also ignore that.
149 err = [e for e in err.splitlines()
149 err = [e for e in err.splitlines()
150 if not e.startswith(b('Not trusting file')) \
150 if not e.startswith(b('Not trusting file')) \
151 and not e.startswith(b('warning: Not importing'))]
151 and not e.startswith(b('warning: Not importing'))]
152 if err:
152 if err:
153 return ''
153 return ''
154 return out
154 return out
155
155
156 version = ''
156 version = ''
157
157
158 # Execute hg out of this directory with a custom environment which
158 # Execute hg out of this directory with a custom environment which
159 # includes the pure Python modules in mercurial/pure. We also take
159 # includes the pure Python modules in mercurial/pure. We also take
160 # care to not use any hgrc files and do no localization.
160 # care to not use any hgrc files and do no localization.
161 pypath = ['mercurial', os.path.join('mercurial', 'pure')]
161 pypath = ['mercurial', os.path.join('mercurial', 'pure')]
162 env = {'PYTHONPATH': os.pathsep.join(pypath),
162 env = {'PYTHONPATH': os.pathsep.join(pypath),
163 'HGRCPATH': '',
163 'HGRCPATH': '',
164 'LANGUAGE': 'C'}
164 'LANGUAGE': 'C'}
165 if 'LD_LIBRARY_PATH' in os.environ:
165 if 'LD_LIBRARY_PATH' in os.environ:
166 env['LD_LIBRARY_PATH'] = os.environ['LD_LIBRARY_PATH']
166 env['LD_LIBRARY_PATH'] = os.environ['LD_LIBRARY_PATH']
167 if 'SystemRoot' in os.environ:
167 if 'SystemRoot' in os.environ:
168 # Copy SystemRoot into the custom environment for Python 2.6
168 # Copy SystemRoot into the custom environment for Python 2.6
169 # under Windows. Otherwise, the subprocess will fail with
169 # under Windows. Otherwise, the subprocess will fail with
170 # error 0xc0150004. See: http://bugs.python.org/issue3440
170 # error 0xc0150004. See: http://bugs.python.org/issue3440
171 env['SystemRoot'] = os.environ['SystemRoot']
171 env['SystemRoot'] = os.environ['SystemRoot']
172
172
173 if os.path.isdir('.hg'):
173 if os.path.isdir('.hg'):
174 cmd = [sys.executable, 'hg', 'id', '-i', '-t']
174 cmd = [sys.executable, 'hg', 'id', '-i', '-t']
175 l = runhg(cmd, env).split()
175 l = runhg(cmd, env).split()
176 while len(l) > 1 and l[-1][0].isalpha(): # remove non-numbered tags
176 while len(l) > 1 and l[-1][0].isalpha(): # remove non-numbered tags
177 l.pop()
177 l.pop()
178 if len(l) > 1: # tag found
178 if len(l) > 1: # tag found
179 version = l[-1]
179 version = l[-1]
180 if l[0].endswith('+'): # propagate the dirty status to the tag
180 if l[0].endswith('+'): # propagate the dirty status to the tag
181 version += '+'
181 version += '+'
182 elif len(l) == 1: # no tag found
182 elif len(l) == 1: # no tag found
183 cmd = [sys.executable, 'hg', 'parents', '--template',
183 cmd = [sys.executable, 'hg', 'parents', '--template',
184 '{latesttag}+{latesttagdistance}-']
184 '{latesttag}+{latesttagdistance}-']
185 version = runhg(cmd, env) + l[0]
185 version = runhg(cmd, env) + l[0]
186 if version.endswith('+'):
186 if version.endswith('+'):
187 version += time.strftime('%Y%m%d')
187 version += time.strftime('%Y%m%d')
188 elif os.path.exists('.hg_archival.txt'):
188 elif os.path.exists('.hg_archival.txt'):
189 kw = dict([[t.strip() for t in l.split(':', 1)]
189 kw = dict([[t.strip() for t in l.split(':', 1)]
190 for l in open('.hg_archival.txt')])
190 for l in open('.hg_archival.txt')])
191 if 'tag' in kw:
191 if 'tag' in kw:
192 version = kw['tag']
192 version = kw['tag']
193 elif 'latesttag' in kw:
193 elif 'latesttag' in kw:
194 version = '%(latesttag)s+%(latesttagdistance)s-%(node).12s' % kw
194 version = '%(latesttag)s+%(latesttagdistance)s-%(node).12s' % kw
195 else:
195 else:
196 version = kw.get('node', '')[:12]
196 version = kw.get('node', '')[:12]
197
197
198 if version:
198 if version:
199 f = open("mercurial/__version__.py", "w")
199 f = open("mercurial/__version__.py", "w")
200 f.write('# this file is autogenerated by setup.py\n')
200 f.write('# this file is autogenerated by setup.py\n')
201 f.write('version = "%s"\n' % version)
201 f.write('version = "%s"\n' % version)
202 f.close()
202 f.close()
203
203
204
204
205 try:
205 try:
206 from mercurial import __version__
206 from mercurial import __version__
207 version = __version__.version
207 version = __version__.version
208 except ImportError:
208 except ImportError:
209 version = 'unknown'
209 version = 'unknown'
210
210
211 class hgbuild(build):
211 class hgbuild(build):
212 # Insert hgbuildmo first so that files in mercurial/locale/ are found
212 # Insert hgbuildmo first so that files in mercurial/locale/ are found
213 # when build_py is run next.
213 # when build_py is run next.
214 sub_commands = [('build_mo', None),
214 sub_commands = [('build_mo', None),
215
215
216 # We also need build_ext before build_py. Otherwise, when 2to3 is
216 # We also need build_ext before build_py. Otherwise, when 2to3 is
217 # called (in build_py), it will not find osutil & friends,
217 # called (in build_py), it will not find osutil & friends,
218 # thinking that those modules are global and, consequently, making
218 # thinking that those modules are global and, consequently, making
219 # a mess, now that all module imports are global.
219 # a mess, now that all module imports are global.
220
220
221 ('build_ext', build.has_ext_modules),
221 ('build_ext', build.has_ext_modules),
222 ] + build.sub_commands
222 ] + build.sub_commands
223
223
224 class hgbuildmo(build):
224 class hgbuildmo(build):
225
225
226 description = "build translations (.mo files)"
226 description = "build translations (.mo files)"
227
227
228 def run(self):
228 def run(self):
229 if not find_executable('msgfmt'):
229 if not find_executable('msgfmt'):
230 self.warn("could not find msgfmt executable, no translations "
230 self.warn("could not find msgfmt executable, no translations "
231 "will be built")
231 "will be built")
232 return
232 return
233
233
234 podir = 'i18n'
234 podir = 'i18n'
235 if not os.path.isdir(podir):
235 if not os.path.isdir(podir):
236 self.warn("could not find %s/ directory" % podir)
236 self.warn("could not find %s/ directory" % podir)
237 return
237 return
238
238
239 join = os.path.join
239 join = os.path.join
240 for po in os.listdir(podir):
240 for po in os.listdir(podir):
241 if not po.endswith('.po'):
241 if not po.endswith('.po'):
242 continue
242 continue
243 pofile = join(podir, po)
243 pofile = join(podir, po)
244 modir = join('locale', po[:-3], 'LC_MESSAGES')
244 modir = join('locale', po[:-3], 'LC_MESSAGES')
245 mofile = join(modir, 'hg.mo')
245 mofile = join(modir, 'hg.mo')
246 mobuildfile = join('mercurial', mofile)
246 mobuildfile = join('mercurial', mofile)
247 cmd = ['msgfmt', '-v', '-o', mobuildfile, pofile]
247 cmd = ['msgfmt', '-v', '-o', mobuildfile, pofile]
248 if sys.platform != 'sunos5':
248 if sys.platform != 'sunos5':
249 # msgfmt on Solaris does not know about -c
249 # msgfmt on Solaris does not know about -c
250 cmd.append('-c')
250 cmd.append('-c')
251 self.mkpath(join('mercurial', modir))
251 self.mkpath(join('mercurial', modir))
252 self.make_file([pofile], mobuildfile, spawn, (cmd,))
252 self.make_file([pofile], mobuildfile, spawn, (cmd,))
253
253
254
254
255 class hgdist(Distribution):
255 class hgdist(Distribution):
256 pure = 0
256 pure = 0
257
257
258 global_options = Distribution.global_options + \
258 global_options = Distribution.global_options + \
259 [('pure', None, "use pure (slow) Python "
259 [('pure', None, "use pure (slow) Python "
260 "code instead of C extensions"),
260 "code instead of C extensions"),
261 ('c2to3', None, "(experimental!) convert "
261 ('c2to3', None, "(experimental!) convert "
262 "code with 2to3"),
262 "code with 2to3"),
263 ]
263 ]
264
264
265 def has_ext_modules(self):
265 def has_ext_modules(self):
266 # self.ext_modules is emptied in hgbuildpy.finalize_options which is
266 # self.ext_modules is emptied in hgbuildpy.finalize_options which is
267 # too late for some cases
267 # too late for some cases
268 return not self.pure and Distribution.has_ext_modules(self)
268 return not self.pure and Distribution.has_ext_modules(self)
269
269
270 class hgbuildext(build_ext):
270 class hgbuildext(build_ext):
271
271
272 def build_extension(self, ext):
272 def build_extension(self, ext):
273 try:
273 try:
274 build_ext.build_extension(self, ext)
274 build_ext.build_extension(self, ext)
275 except CCompilerError:
275 except CCompilerError:
276 if not getattr(ext, 'optional', False):
276 if not getattr(ext, 'optional', False):
277 raise
277 raise
278 log.warn("Failed to build optional extension '%s' (skipping)",
278 log.warn("Failed to build optional extension '%s' (skipping)",
279 ext.name)
279 ext.name)
280
280
281 class hgbuildpy(build_py):
281 class hgbuildpy(build_py):
282 if convert2to3:
282 if convert2to3:
283 fixer_names = sorted(set(getfixers("lib2to3.fixes") +
283 fixer_names = sorted(set(getfixers("lib2to3.fixes") +
284 getfixers("hgfixes")))
284 getfixers("hgfixes")))
285
285
286 def finalize_options(self):
286 def finalize_options(self):
287 build_py.finalize_options(self)
287 build_py.finalize_options(self)
288
288
289 if self.distribution.pure:
289 if self.distribution.pure:
290 if self.py_modules is None:
290 if self.py_modules is None:
291 self.py_modules = []
291 self.py_modules = []
292 for ext in self.distribution.ext_modules:
292 for ext in self.distribution.ext_modules:
293 if ext.name.startswith("mercurial."):
293 if ext.name.startswith("mercurial."):
294 self.py_modules.append("mercurial.pure.%s" % ext.name[10:])
294 self.py_modules.append("mercurial.pure.%s" % ext.name[10:])
295 self.distribution.ext_modules = []
295 self.distribution.ext_modules = []
296 else:
296 else:
297 if not os.path.exists(os.path.join(get_python_inc(), 'Python.h')):
297 if not os.path.exists(os.path.join(get_python_inc(), 'Python.h')):
298 raise SystemExit('Python headers are required to build '
298 raise SystemExit('Python headers are required to build '
299 'Mercurial')
299 'Mercurial')
300
300
301 def find_modules(self):
301 def find_modules(self):
302 modules = build_py.find_modules(self)
302 modules = build_py.find_modules(self)
303 for module in modules:
303 for module in modules:
304 if module[0] == "mercurial.pure":
304 if module[0] == "mercurial.pure":
305 if module[1] != "__init__":
305 if module[1] != "__init__":
306 yield ("mercurial", module[1], module[2])
306 yield ("mercurial", module[1], module[2])
307 else:
307 else:
308 yield module
308 yield module
309
309
310 class buildhgextindex(Command):
310 class buildhgextindex(Command):
311 description = 'generate prebuilt index of hgext (for frozen package)'
311 description = 'generate prebuilt index of hgext (for frozen package)'
312 user_options = []
312 user_options = []
313 _indexfilename = 'hgext/__index__.py'
313 _indexfilename = 'hgext/__index__.py'
314
314
315 def initialize_options(self):
315 def initialize_options(self):
316 pass
316 pass
317
317
318 def finalize_options(self):
318 def finalize_options(self):
319 pass
319 pass
320
320
321 def run(self):
321 def run(self):
322 if os.path.exists(self._indexfilename):
322 if os.path.exists(self._indexfilename):
323 os.unlink(self._indexfilename)
323 os.unlink(self._indexfilename)
324
324
325 # here no extension enabled, disabled() lists up everything
325 # here no extension enabled, disabled() lists up everything
326 code = ('import pprint; from mercurial import extensions; '
326 code = ('import pprint; from mercurial import extensions; '
327 'pprint.pprint(extensions.disabled())')
327 'pprint.pprint(extensions.disabled())')
328 out, err = runcmd([sys.executable, '-c', code], env)
328 out, err = runcmd([sys.executable, '-c', code], env)
329 if err:
329 if err:
330 raise DistutilsExecError(err)
330 raise DistutilsExecError(err)
331
331
332 f = open(self._indexfilename, 'w')
332 f = open(self._indexfilename, 'w')
333 f.write('# this file is autogenerated by setup.py\n')
333 f.write('# this file is autogenerated by setup.py\n')
334 f.write('docs = ')
334 f.write('docs = ')
335 f.write(out)
335 f.write(out)
336 f.close()
336 f.close()
337
337
338 class hginstallscripts(install_scripts):
338 class hginstallscripts(install_scripts):
339 '''
339 '''
340 This is a specialization of install_scripts that replaces the @LIBDIR@ with
340 This is a specialization of install_scripts that replaces the @LIBDIR@ with
341 the configured directory for modules. If possible, the path is made relative
341 the configured directory for modules. If possible, the path is made relative
342 to the directory for scripts.
342 to the directory for scripts.
343 '''
343 '''
344
344
345 def initialize_options(self):
345 def initialize_options(self):
346 install_scripts.initialize_options(self)
346 install_scripts.initialize_options(self)
347
347
348 self.install_lib = None
348 self.install_lib = None
349
349
350 def finalize_options(self):
350 def finalize_options(self):
351 install_scripts.finalize_options(self)
351 install_scripts.finalize_options(self)
352 self.set_undefined_options('install',
352 self.set_undefined_options('install',
353 ('install_lib', 'install_lib'))
353 ('install_lib', 'install_lib'))
354
354
355 def run(self):
355 def run(self):
356 install_scripts.run(self)
356 install_scripts.run(self)
357
357
358 if (os.path.splitdrive(self.install_dir)[0] !=
358 if (os.path.splitdrive(self.install_dir)[0] !=
359 os.path.splitdrive(self.install_lib)[0]):
359 os.path.splitdrive(self.install_lib)[0]):
360 # can't make relative paths from one drive to another, so use an
360 # can't make relative paths from one drive to another, so use an
361 # absolute path instead
361 # absolute path instead
362 libdir = self.install_lib
362 libdir = self.install_lib
363 else:
363 else:
364 common = os.path.commonprefix((self.install_dir, self.install_lib))
364 common = os.path.commonprefix((self.install_dir, self.install_lib))
365 rest = self.install_dir[len(common):]
365 rest = self.install_dir[len(common):]
366 uplevel = len([n for n in os.path.split(rest) if n])
366 uplevel = len([n for n in os.path.split(rest) if n])
367
367
368 libdir = uplevel * ('..' + os.sep) + self.install_lib[len(common):]
368 libdir = uplevel * ('..' + os.sep) + self.install_lib[len(common):]
369
369
370 for outfile in self.outfiles:
370 for outfile in self.outfiles:
371 fp = open(outfile, 'rb')
371 fp = open(outfile, 'rb')
372 data = fp.read()
372 data = fp.read()
373 fp.close()
373 fp.close()
374
374
375 # skip binary files
375 # skip binary files
376 if b('\0') in data:
376 if b('\0') in data:
377 continue
377 continue
378
378
379 data = data.replace('@LIBDIR@', libdir.encode('string_escape'))
379 data = data.replace('@LIBDIR@', libdir.encode('string_escape'))
380 fp = open(outfile, 'wb')
380 fp = open(outfile, 'wb')
381 fp.write(data)
381 fp.write(data)
382 fp.close()
382 fp.close()
383
383
384 cmdclass = {'build': hgbuild,
384 cmdclass = {'build': hgbuild,
385 'build_mo': hgbuildmo,
385 'build_mo': hgbuildmo,
386 'build_ext': hgbuildext,
386 'build_ext': hgbuildext,
387 'build_py': hgbuildpy,
387 'build_py': hgbuildpy,
388 'build_hgextindex': buildhgextindex,
388 'build_hgextindex': buildhgextindex,
389 'install_scripts': hginstallscripts}
389 'install_scripts': hginstallscripts}
390
390
391 packages = ['mercurial', 'mercurial.hgweb',
391 packages = ['mercurial', 'mercurial.hgweb', 'mercurial.httpclient',
392 'mercurial.httpclient', 'mercurial.httpclient.tests',
393 'hgext', 'hgext.convert', 'hgext.highlight', 'hgext.zeroconf',
392 'hgext', 'hgext.convert', 'hgext.highlight', 'hgext.zeroconf',
394 'hgext.largefiles']
393 'hgext.largefiles']
395
394
396 pymodules = []
395 pymodules = []
397
396
398 extmodules = [
397 extmodules = [
399 Extension('mercurial.base85', ['mercurial/base85.c']),
398 Extension('mercurial.base85', ['mercurial/base85.c']),
400 Extension('mercurial.bdiff', ['mercurial/bdiff.c']),
399 Extension('mercurial.bdiff', ['mercurial/bdiff.c']),
401 Extension('mercurial.diffhelpers', ['mercurial/diffhelpers.c']),
400 Extension('mercurial.diffhelpers', ['mercurial/diffhelpers.c']),
402 Extension('mercurial.mpatch', ['mercurial/mpatch.c']),
401 Extension('mercurial.mpatch', ['mercurial/mpatch.c']),
403 Extension('mercurial.parsers', ['mercurial/parsers.c']),
402 Extension('mercurial.parsers', ['mercurial/parsers.c']),
404 ]
403 ]
405
404
406 osutil_ldflags = []
405 osutil_ldflags = []
407
406
408 if sys.platform == 'darwin':
407 if sys.platform == 'darwin':
409 osutil_ldflags += ['-framework', 'ApplicationServices']
408 osutil_ldflags += ['-framework', 'ApplicationServices']
410
409
411 # disable osutil.c under windows + python 2.4 (issue1364)
410 # disable osutil.c under windows + python 2.4 (issue1364)
412 if sys.platform == 'win32' and sys.version_info < (2, 5, 0, 'final'):
411 if sys.platform == 'win32' and sys.version_info < (2, 5, 0, 'final'):
413 pymodules.append('mercurial.pure.osutil')
412 pymodules.append('mercurial.pure.osutil')
414 else:
413 else:
415 extmodules.append(Extension('mercurial.osutil', ['mercurial/osutil.c'],
414 extmodules.append(Extension('mercurial.osutil', ['mercurial/osutil.c'],
416 extra_link_args=osutil_ldflags))
415 extra_link_args=osutil_ldflags))
417
416
418 if sys.platform.startswith('linux') and os.uname()[2] > '2.6':
417 if sys.platform.startswith('linux') and os.uname()[2] > '2.6':
419 # The inotify extension is only usable with Linux 2.6 kernels.
418 # The inotify extension is only usable with Linux 2.6 kernels.
420 # You also need a reasonably recent C library.
419 # You also need a reasonably recent C library.
421 # In any case, if it fails to build the error will be skipped ('optional').
420 # In any case, if it fails to build the error will be skipped ('optional').
422 cc = new_compiler()
421 cc = new_compiler()
423 if hasfunction(cc, 'inotify_add_watch'):
422 if hasfunction(cc, 'inotify_add_watch'):
424 inotify = Extension('hgext.inotify.linux._inotify',
423 inotify = Extension('hgext.inotify.linux._inotify',
425 ['hgext/inotify/linux/_inotify.c'],
424 ['hgext/inotify/linux/_inotify.c'],
426 ['mercurial'])
425 ['mercurial'])
427 inotify.optional = True
426 inotify.optional = True
428 extmodules.append(inotify)
427 extmodules.append(inotify)
429 packages.extend(['hgext.inotify', 'hgext.inotify.linux'])
428 packages.extend(['hgext.inotify', 'hgext.inotify.linux'])
430
429
431 packagedata = {'mercurial': ['locale/*/LC_MESSAGES/hg.mo',
430 packagedata = {'mercurial': ['locale/*/LC_MESSAGES/hg.mo',
432 'help/*.txt']}
431 'help/*.txt']}
433
432
434 def ordinarypath(p):
433 def ordinarypath(p):
435 return p and p[0] != '.' and p[-1] != '~'
434 return p and p[0] != '.' and p[-1] != '~'
436
435
437 for root in ('templates',):
436 for root in ('templates',):
438 for curdir, dirs, files in os.walk(os.path.join('mercurial', root)):
437 for curdir, dirs, files in os.walk(os.path.join('mercurial', root)):
439 curdir = curdir.split(os.sep, 1)[1]
438 curdir = curdir.split(os.sep, 1)[1]
440 dirs[:] = filter(ordinarypath, dirs)
439 dirs[:] = filter(ordinarypath, dirs)
441 for f in filter(ordinarypath, files):
440 for f in filter(ordinarypath, files):
442 f = os.path.join(curdir, f)
441 f = os.path.join(curdir, f)
443 packagedata['mercurial'].append(f)
442 packagedata['mercurial'].append(f)
444
443
445 datafiles = []
444 datafiles = []
446 setupversion = version
445 setupversion = version
447 extra = {}
446 extra = {}
448
447
449 if py2exeloaded:
448 if py2exeloaded:
450 extra['console'] = [
449 extra['console'] = [
451 {'script':'hg',
450 {'script':'hg',
452 'copyright':'Copyright (C) 2005-2010 Matt Mackall and others',
451 'copyright':'Copyright (C) 2005-2010 Matt Mackall and others',
453 'product_version':version}]
452 'product_version':version}]
454 # sub command of 'build' because 'py2exe' does not handle sub_commands
453 # sub command of 'build' because 'py2exe' does not handle sub_commands
455 build.sub_commands.insert(0, ('build_hgextindex', None))
454 build.sub_commands.insert(0, ('build_hgextindex', None))
456
455
457 if os.name == 'nt':
456 if os.name == 'nt':
458 # Windows binary file versions for exe/dll files must have the
457 # Windows binary file versions for exe/dll files must have the
459 # form W.X.Y.Z, where W,X,Y,Z are numbers in the range 0..65535
458 # form W.X.Y.Z, where W,X,Y,Z are numbers in the range 0..65535
460 setupversion = version.split('+', 1)[0]
459 setupversion = version.split('+', 1)[0]
461
460
462 if sys.platform == 'darwin' and os.path.exists('/usr/bin/xcodebuild'):
461 if sys.platform == 'darwin' and os.path.exists('/usr/bin/xcodebuild'):
463 # XCode 4.0 dropped support for ppc architecture, which is hardcoded in
462 # XCode 4.0 dropped support for ppc architecture, which is hardcoded in
464 # distutils.sysconfig
463 # distutils.sysconfig
465 version = runcmd(['/usr/bin/xcodebuild', '-version'], {})[0].splitlines()
464 version = runcmd(['/usr/bin/xcodebuild', '-version'], {})[0].splitlines()
466 if version:
465 if version:
467 version = version[0]
466 version = version[0]
468 xcode4 = (version.startswith('Xcode') and
467 xcode4 = (version.startswith('Xcode') and
469 StrictVersion(version.split()[1]) >= StrictVersion('4.0'))
468 StrictVersion(version.split()[1]) >= StrictVersion('4.0'))
470 else:
469 else:
471 # xcodebuild returns empty on OS X Lion with XCode 4.3 not
470 # xcodebuild returns empty on OS X Lion with XCode 4.3 not
472 # installed, but instead with only command-line tools. Assume
471 # installed, but instead with only command-line tools. Assume
473 # that only happens on >= Lion, thus no PPC support.
472 # that only happens on >= Lion, thus no PPC support.
474 xcode4 = True
473 xcode4 = True
475
474
476 if xcode4:
475 if xcode4:
477 os.environ['ARCHFLAGS'] = ''
476 os.environ['ARCHFLAGS'] = ''
478
477
479 setup(name='mercurial',
478 setup(name='mercurial',
480 version=setupversion,
479 version=setupversion,
481 author='Matt Mackall',
480 author='Matt Mackall',
482 author_email='mpm@selenic.com',
481 author_email='mpm@selenic.com',
483 url='http://mercurial.selenic.com/',
482 url='http://mercurial.selenic.com/',
484 description='Scalable distributed SCM',
483 description='Scalable distributed SCM',
485 license='GNU GPLv2+',
484 license='GNU GPLv2+',
486 scripts=scripts,
485 scripts=scripts,
487 packages=packages,
486 packages=packages,
488 py_modules=pymodules,
487 py_modules=pymodules,
489 ext_modules=extmodules,
488 ext_modules=extmodules,
490 data_files=datafiles,
489 data_files=datafiles,
491 package_data=packagedata,
490 package_data=packagedata,
492 cmdclass=cmdclass,
491 cmdclass=cmdclass,
493 distclass=hgdist,
492 distclass=hgdist,
494 options=dict(py2exe=dict(packages=['hgext', 'email']),
493 options=dict(py2exe=dict(packages=['hgext', 'email']),
495 bdist_mpkg=dict(zipdist=True,
494 bdist_mpkg=dict(zipdist=True,
496 license='COPYING',
495 license='COPYING',
497 readme='contrib/macosx/Readme.html',
496 readme='contrib/macosx/Readme.html',
498 welcome='contrib/macosx/Welcome.html')),
497 welcome='contrib/macosx/Welcome.html')),
499 **extra)
498 **extra)
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
This diff has been collapsed as it changes many lines, (508 lines changed) Show them Hide them
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
General Comments 0
You need to be logged in to leave comments. Login now