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