##// END OF EJS Templates
setup: remove support for 2to3...
Gregory Szorc -
r28398:71229894 default
parent child Browse files
Show More
@@ -1,707 +1,680 b''
1 1 #
2 2 # This is the mercurial setup script.
3 3 #
4 4 # 'python setup.py install', or
5 5 # 'python setup.py --help' for more options
6 6
7 7 import sys, platform
8 8 if getattr(sys, 'version_info', (0, 0, 0)) < (2, 6, 0, 'final'):
9 9 raise SystemExit("Mercurial requires Python 2.6 or later.")
10 10
11 11 if sys.version_info[0] >= 3:
12 12 printf = eval('print')
13 13 libdir_escape = 'unicode_escape'
14 14 else:
15 15 libdir_escape = 'string_escape'
16 16 def printf(*args, **kwargs):
17 17 f = kwargs.get('file', sys.stdout)
18 18 end = kwargs.get('end', '\n')
19 19 f.write(b' '.join(args) + end)
20 20
21 21 # Solaris Python packaging brain damage
22 22 try:
23 23 import hashlib
24 24 sha = hashlib.sha1()
25 25 except ImportError:
26 26 try:
27 27 import sha
28 28 sha.sha # silence unused import warning
29 29 except ImportError:
30 30 raise SystemExit(
31 31 "Couldn't import standard hashlib (incomplete Python install).")
32 32
33 33 try:
34 34 import zlib
35 35 zlib.compressobj # silence unused import warning
36 36 except ImportError:
37 37 raise SystemExit(
38 38 "Couldn't import standard zlib (incomplete Python install).")
39 39
40 40 # The base IronPython distribution (as of 2.7.1) doesn't support bz2
41 41 isironpython = False
42 42 try:
43 43 isironpython = (platform.python_implementation()
44 44 .lower().find("ironpython") != -1)
45 45 except AttributeError:
46 46 pass
47 47
48 48 if isironpython:
49 49 sys.stderr.write("warning: IronPython detected (no bz2 support)\n")
50 50 else:
51 51 try:
52 52 import bz2
53 53 bz2.BZ2Compressor # silence unused import warning
54 54 except ImportError:
55 55 raise SystemExit(
56 56 "Couldn't import standard bz2 (incomplete Python install).")
57 57
58 58 ispypy = "PyPy" in sys.version
59 59
60 60 import os, stat, subprocess, time
61 61 import re
62 62 import shutil
63 63 import tempfile
64 64 from distutils import log
65 65 if 'FORCE_SETUPTOOLS' in os.environ:
66 66 from setuptools import setup
67 67 else:
68 68 from distutils.core import setup
69 69 from distutils.core import Command, Extension
70 70 from distutils.dist import Distribution
71 71 from distutils.command.build import build
72 72 from distutils.command.build_ext import build_ext
73 73 from distutils.command.build_py import build_py
74 74 from distutils.command.build_scripts import build_scripts
75 75 from distutils.command.install_lib import install_lib
76 76 from distutils.command.install_scripts import install_scripts
77 77 from distutils.spawn import spawn, find_executable
78 78 from distutils import file_util
79 79 from distutils.errors import (
80 80 CCompilerError,
81 81 DistutilsError,
82 82 DistutilsExecError,
83 83 )
84 84 from distutils.sysconfig import get_python_inc, get_config_var
85 85 from distutils.version import StrictVersion
86 86
87 convert2to3 = '--c2to3' in sys.argv
88 if convert2to3:
89 try:
90 from distutils.command.build_py import build_py_2to3 as build_py
91 from lib2to3.refactor import get_fixers_from_package as getfixers
92 except ImportError:
93 if sys.version_info[0] < 3:
94 raise SystemExit("--c2to3 is only compatible with python3.")
95 raise
96 sys.path.append('contrib')
97 elif sys.version_info[0] >= 3:
98 raise SystemExit("setup.py with python3 needs --c2to3 (experimental)")
99
100 87 scripts = ['hg']
101 88 if os.name == 'nt':
102 89 # We remove hg.bat if we are able to build hg.exe.
103 90 scripts.append('contrib/win32/hg.bat')
104 91
105 92 # simplified version of distutils.ccompiler.CCompiler.has_function
106 93 # that actually removes its temporary files.
107 94 def hasfunction(cc, funcname):
108 95 tmpdir = tempfile.mkdtemp(prefix='hg-install-')
109 96 devnull = oldstderr = None
110 97 try:
111 98 fname = os.path.join(tmpdir, 'funcname.c')
112 99 f = open(fname, 'w')
113 100 f.write('int main(void) {\n')
114 101 f.write(' %s();\n' % funcname)
115 102 f.write('}\n')
116 103 f.close()
117 104 # Redirect stderr to /dev/null to hide any error messages
118 105 # from the compiler.
119 106 # This will have to be changed if we ever have to check
120 107 # for a function on Windows.
121 108 devnull = open('/dev/null', 'w')
122 109 oldstderr = os.dup(sys.stderr.fileno())
123 110 os.dup2(devnull.fileno(), sys.stderr.fileno())
124 111 objects = cc.compile([fname], output_dir=tmpdir)
125 112 cc.link_executable(objects, os.path.join(tmpdir, "a.out"))
126 113 return True
127 114 except Exception:
128 115 return False
129 116 finally:
130 117 if oldstderr is not None:
131 118 os.dup2(oldstderr, sys.stderr.fileno())
132 119 if devnull is not None:
133 120 devnull.close()
134 121 shutil.rmtree(tmpdir)
135 122
136 123 # py2exe needs to be installed to work
137 124 try:
138 125 import py2exe
139 126 py2exe.Distribution # silence unused import warning
140 127 py2exeloaded = True
141 128 # import py2exe's patched Distribution class
142 129 from distutils.core import Distribution
143 130 except ImportError:
144 131 py2exeloaded = False
145 132
146 133 def runcmd(cmd, env):
147 134 if (sys.platform == 'plan9'
148 135 and (sys.version_info[0] == 2 and sys.version_info[1] < 7)):
149 136 # subprocess kludge to work around issues in half-baked Python
150 137 # ports, notably bichued/python:
151 138 _, out, err = os.popen3(cmd)
152 139 return str(out), str(err)
153 140 else:
154 141 p = subprocess.Popen(cmd, stdout=subprocess.PIPE,
155 142 stderr=subprocess.PIPE, env=env)
156 143 out, err = p.communicate()
157 144 return out, err
158 145
159 146 def runhg(cmd, env):
160 147 out, err = runcmd(cmd, env)
161 148 # If root is executing setup.py, but the repository is owned by
162 149 # another user (as in "sudo python setup.py install") we will get
163 150 # trust warnings since the .hg/hgrc file is untrusted. That is
164 151 # fine, we don't want to load it anyway. Python may warn about
165 152 # a missing __init__.py in mercurial/locale, we also ignore that.
166 153 err = [e for e in err.splitlines()
167 154 if not e.startswith(b'not trusting file') \
168 155 and not e.startswith(b'warning: Not importing') \
169 156 and not e.startswith(b'obsolete feature not enabled')]
170 157 if err:
171 158 printf("stderr from '%s':" % (' '.join(cmd)), file=sys.stderr)
172 159 printf(b'\n'.join([b' ' + e for e in err]), file=sys.stderr)
173 160 return ''
174 161 return out
175 162
176 163 version = ''
177 164
178 165 # Execute hg out of this directory with a custom environment which takes care
179 166 # to not use any hgrc files and do no localization.
180 167 env = {'HGMODULEPOLICY': 'py',
181 168 'HGRCPATH': '',
182 169 'LANGUAGE': 'C'}
183 170 if 'LD_LIBRARY_PATH' in os.environ:
184 171 env['LD_LIBRARY_PATH'] = os.environ['LD_LIBRARY_PATH']
185 172 if 'SystemRoot' in os.environ:
186 173 # Copy SystemRoot into the custom environment for Python 2.6
187 174 # under Windows. Otherwise, the subprocess will fail with
188 175 # error 0xc0150004. See: http://bugs.python.org/issue3440
189 176 env['SystemRoot'] = os.environ['SystemRoot']
190 177
191 178 if os.path.isdir('.hg'):
192 179 cmd = [sys.executable, 'hg', 'log', '-r', '.', '--template', '{tags}\n']
193 180 numerictags = [t for t in runhg(cmd, env).split() if t[0].isdigit()]
194 181 hgid = runhg([sys.executable, 'hg', 'id', '-i'], env).strip()
195 182 if numerictags: # tag(s) found
196 183 version = numerictags[-1]
197 184 if hgid.endswith('+'): # propagate the dirty status to the tag
198 185 version += '+'
199 186 else: # no tag found
200 187 ltagcmd = [sys.executable, 'hg', 'parents', '--template',
201 188 '{latesttag}']
202 189 ltag = runhg(ltagcmd, env)
203 190 changessincecmd = [sys.executable, 'hg', 'log', '-T', 'x\n', '-r',
204 191 "only(.,'%s')" % ltag]
205 192 changessince = len(runhg(changessincecmd, env).splitlines())
206 193 version = '%s+%s-%s' % (ltag, changessince, hgid)
207 194 if version.endswith('+'):
208 195 version += time.strftime('%Y%m%d')
209 196 elif os.path.exists('.hg_archival.txt'):
210 197 kw = dict([[t.strip() for t in l.split(':', 1)]
211 198 for l in open('.hg_archival.txt')])
212 199 if 'tag' in kw:
213 200 version = kw['tag']
214 201 elif 'latesttag' in kw:
215 202 if 'changessincelatesttag' in kw:
216 203 version = '%(latesttag)s+%(changessincelatesttag)s-%(node).12s' % kw
217 204 else:
218 205 version = '%(latesttag)s+%(latesttagdistance)s-%(node).12s' % kw
219 206 else:
220 207 version = kw.get('node', '')[:12]
221 208
222 209 if version:
223 210 f = open("mercurial/__version__.py", "w")
224 211 f.write('# this file is autogenerated by setup.py\n')
225 212 f.write('version = "%s"\n' % version)
226 213 f.close()
227 214
228 215
229 216 try:
230 217 from mercurial import __version__
231 218 version = __version__.version
232 219 except ImportError:
233 220 version = 'unknown'
234 221
235 222 class hgbuild(build):
236 223 # Insert hgbuildmo first so that files in mercurial/locale/ are found
237 224 # when build_py is run next.
238 sub_commands = [('build_mo', None),
239
240 # We also need build_ext before build_py. Otherwise, when 2to3 is
241 # called (in build_py), it will not find osutil & friends,
242 # thinking that those modules are global and, consequently, making
243 # a mess, now that all module imports are global.
244
245 ('build_ext', build.has_ext_modules),
246 ] + build.sub_commands
225 sub_commands = [('build_mo', None)] + build.sub_commands
247 226
248 227 class hgbuildmo(build):
249 228
250 229 description = "build translations (.mo files)"
251 230
252 231 def run(self):
253 232 if not find_executable('msgfmt'):
254 233 self.warn("could not find msgfmt executable, no translations "
255 234 "will be built")
256 235 return
257 236
258 237 podir = 'i18n'
259 238 if not os.path.isdir(podir):
260 239 self.warn("could not find %s/ directory" % podir)
261 240 return
262 241
263 242 join = os.path.join
264 243 for po in os.listdir(podir):
265 244 if not po.endswith('.po'):
266 245 continue
267 246 pofile = join(podir, po)
268 247 modir = join('locale', po[:-3], 'LC_MESSAGES')
269 248 mofile = join(modir, 'hg.mo')
270 249 mobuildfile = join('mercurial', mofile)
271 250 cmd = ['msgfmt', '-v', '-o', mobuildfile, pofile]
272 251 if sys.platform != 'sunos5':
273 252 # msgfmt on Solaris does not know about -c
274 253 cmd.append('-c')
275 254 self.mkpath(join('mercurial', modir))
276 255 self.make_file([pofile], mobuildfile, spawn, (cmd,))
277 256
278 257
279 258 class hgdist(Distribution):
280 259 pure = ispypy
281 260
282 261 global_options = Distribution.global_options + \
283 262 [('pure', None, "use pure (slow) Python "
284 263 "code instead of C extensions"),
285 ('c2to3', None, "(experimental!) convert "
286 "code with 2to3"),
287 264 ]
288 265
289 266 def has_ext_modules(self):
290 267 # self.ext_modules is emptied in hgbuildpy.finalize_options which is
291 268 # too late for some cases
292 269 return not self.pure and Distribution.has_ext_modules(self)
293 270
294 271 class hgbuildext(build_ext):
295 272
296 273 def build_extension(self, ext):
297 274 try:
298 275 build_ext.build_extension(self, ext)
299 276 except CCompilerError:
300 277 if not getattr(ext, 'optional', False):
301 278 raise
302 279 log.warn("Failed to build optional extension '%s' (skipping)",
303 280 ext.name)
304 281
305 282 class hgbuildscripts(build_scripts):
306 283 def run(self):
307 284 if os.name != 'nt' or self.distribution.pure:
308 285 return build_scripts.run(self)
309 286
310 287 exebuilt = False
311 288 try:
312 289 self.run_command('build_hgexe')
313 290 exebuilt = True
314 291 except (DistutilsError, CCompilerError):
315 292 log.warn('failed to build optional hg.exe')
316 293
317 294 if exebuilt:
318 295 # Copying hg.exe to the scripts build directory ensures it is
319 296 # installed by the install_scripts command.
320 297 hgexecommand = self.get_finalized_command('build_hgexe')
321 298 dest = os.path.join(self.build_dir, 'hg.exe')
322 299 self.mkpath(self.build_dir)
323 300 self.copy_file(hgexecommand.hgexepath, dest)
324 301
325 302 # Remove hg.bat because it is redundant with hg.exe.
326 303 self.scripts.remove('contrib/win32/hg.bat')
327 304
328 305 return build_scripts.run(self)
329 306
330 307 class hgbuildpy(build_py):
331 if convert2to3:
332 fixer_names = sorted(set(getfixers("lib2to3.fixes") +
333 getfixers("hgfixes")))
334
335 308 def finalize_options(self):
336 309 build_py.finalize_options(self)
337 310
338 311 if self.distribution.pure:
339 312 self.distribution.ext_modules = []
340 313 else:
341 314 h = os.path.join(get_python_inc(), 'Python.h')
342 315 if not os.path.exists(h):
343 316 raise SystemExit('Python headers are required to build '
344 317 'Mercurial but weren\'t found in %s' % h)
345 318
346 319 def copy_file(self, *args, **kwargs):
347 320 dst, copied = build_py.copy_file(self, *args, **kwargs)
348 321
349 322 if copied and dst.endswith('__init__.py'):
350 323 if self.distribution.pure:
351 324 modulepolicy = 'py'
352 325 else:
353 326 modulepolicy = 'c'
354 327 content = open(dst, 'rb').read()
355 328 content = content.replace(b'@MODULELOADPOLICY@',
356 329 modulepolicy.encode(libdir_escape))
357 330 with open(dst, 'wb') as fh:
358 331 fh.write(content)
359 332
360 333 return dst, copied
361 334
362 335 class buildhgextindex(Command):
363 336 description = 'generate prebuilt index of hgext (for frozen package)'
364 337 user_options = []
365 338 _indexfilename = 'hgext/__index__.py'
366 339
367 340 def initialize_options(self):
368 341 pass
369 342
370 343 def finalize_options(self):
371 344 pass
372 345
373 346 def run(self):
374 347 if os.path.exists(self._indexfilename):
375 348 f = open(self._indexfilename, 'w')
376 349 f.write('# empty\n')
377 350 f.close()
378 351
379 352 # here no extension enabled, disabled() lists up everything
380 353 code = ('import pprint; from mercurial import extensions; '
381 354 'pprint.pprint(extensions.disabled())')
382 355 out, err = runcmd([sys.executable, '-c', code], env)
383 356 if err:
384 357 raise DistutilsExecError(err)
385 358
386 359 f = open(self._indexfilename, 'w')
387 360 f.write('# this file is autogenerated by setup.py\n')
388 361 f.write('docs = ')
389 362 f.write(out)
390 363 f.close()
391 364
392 365 class buildhgexe(build_ext):
393 366 description = 'compile hg.exe from mercurial/exewrapper.c'
394 367
395 368 def build_extensions(self):
396 369 if os.name != 'nt':
397 370 return
398 371 if isinstance(self.compiler, HackedMingw32CCompiler):
399 372 self.compiler.compiler_so = self.compiler.compiler # no -mdll
400 373 self.compiler.dll_libraries = [] # no -lmsrvc90
401 374 hv = sys.hexversion
402 375 pythonlib = 'python%d%d' % (hv >> 24, (hv >> 16) & 0xff)
403 376 f = open('mercurial/hgpythonlib.h', 'wb')
404 377 f.write('/* this file is autogenerated by setup.py */\n')
405 378 f.write('#define HGPYTHONLIB "%s"\n' % pythonlib)
406 379 f.close()
407 380 objects = self.compiler.compile(['mercurial/exewrapper.c'],
408 381 output_dir=self.build_temp)
409 382 dir = os.path.dirname(self.get_ext_fullpath('dummy'))
410 383 target = os.path.join(dir, 'hg')
411 384 self.compiler.link_executable(objects, target,
412 385 libraries=[],
413 386 output_dir=self.build_temp)
414 387
415 388 @property
416 389 def hgexepath(self):
417 390 dir = os.path.dirname(self.get_ext_fullpath('dummy'))
418 391 return os.path.join(self.build_temp, dir, 'hg.exe')
419 392
420 393 class hginstalllib(install_lib):
421 394 '''
422 395 This is a specialization of install_lib that replaces the copy_file used
423 396 there so that it supports setting the mode of files after copying them,
424 397 instead of just preserving the mode that the files originally had. If your
425 398 system has a umask of something like 027, preserving the permissions when
426 399 copying will lead to a broken install.
427 400
428 401 Note that just passing keep_permissions=False to copy_file would be
429 402 insufficient, as it might still be applying a umask.
430 403 '''
431 404
432 405 def run(self):
433 406 realcopyfile = file_util.copy_file
434 407 def copyfileandsetmode(*args, **kwargs):
435 408 src, dst = args[0], args[1]
436 409 dst, copied = realcopyfile(*args, **kwargs)
437 410 if copied:
438 411 st = os.stat(src)
439 412 # Persist executable bit (apply it to group and other if user
440 413 # has it)
441 414 if st[stat.ST_MODE] & stat.S_IXUSR:
442 415 setmode = int('0755', 8)
443 416 else:
444 417 setmode = int('0644', 8)
445 418 m = stat.S_IMODE(st[stat.ST_MODE])
446 419 m = (m & ~int('0777', 8)) | setmode
447 420 os.chmod(dst, m)
448 421 file_util.copy_file = copyfileandsetmode
449 422 try:
450 423 install_lib.run(self)
451 424 finally:
452 425 file_util.copy_file = realcopyfile
453 426
454 427 class hginstallscripts(install_scripts):
455 428 '''
456 429 This is a specialization of install_scripts that replaces the @LIBDIR@ with
457 430 the configured directory for modules. If possible, the path is made relative
458 431 to the directory for scripts.
459 432 '''
460 433
461 434 def initialize_options(self):
462 435 install_scripts.initialize_options(self)
463 436
464 437 self.install_lib = None
465 438
466 439 def finalize_options(self):
467 440 install_scripts.finalize_options(self)
468 441 self.set_undefined_options('install',
469 442 ('install_lib', 'install_lib'))
470 443
471 444 def run(self):
472 445 install_scripts.run(self)
473 446
474 447 # It only makes sense to replace @LIBDIR@ with the install path if
475 448 # the install path is known. For wheels, the logic below calculates
476 449 # the libdir to be "../..". This is because the internal layout of a
477 450 # wheel archive looks like:
478 451 #
479 452 # mercurial-3.6.1.data/scripts/hg
480 453 # mercurial/__init__.py
481 454 #
482 455 # When installing wheels, the subdirectories of the "<pkg>.data"
483 456 # directory are translated to system local paths and files therein
484 457 # are copied in place. The mercurial/* files are installed into the
485 458 # site-packages directory. However, the site-packages directory
486 459 # isn't known until wheel install time. This means we have no clue
487 460 # at wheel generation time what the installed site-packages directory
488 461 # will be. And, wheels don't appear to provide the ability to register
489 462 # custom code to run during wheel installation. This all means that
490 463 # we can't reliably set the libdir in wheels: the default behavior
491 464 # of looking in sys.path must do.
492 465
493 466 if (os.path.splitdrive(self.install_dir)[0] !=
494 467 os.path.splitdrive(self.install_lib)[0]):
495 468 # can't make relative paths from one drive to another, so use an
496 469 # absolute path instead
497 470 libdir = self.install_lib
498 471 else:
499 472 common = os.path.commonprefix((self.install_dir, self.install_lib))
500 473 rest = self.install_dir[len(common):]
501 474 uplevel = len([n for n in os.path.split(rest) if n])
502 475
503 476 libdir = uplevel * ('..' + os.sep) + self.install_lib[len(common):]
504 477
505 478 for outfile in self.outfiles:
506 479 fp = open(outfile, 'rb')
507 480 data = fp.read()
508 481 fp.close()
509 482
510 483 # skip binary files
511 484 if b'\0' in data:
512 485 continue
513 486
514 487 # During local installs, the shebang will be rewritten to the final
515 488 # install path. During wheel packaging, the shebang has a special
516 489 # value.
517 490 if data.startswith(b'#!python'):
518 491 log.info('not rewriting @LIBDIR@ in %s because install path '
519 492 'not known' % outfile)
520 493 continue
521 494
522 495 data = data.replace(b'@LIBDIR@', libdir.encode(libdir_escape))
523 496 fp = open(outfile, 'wb')
524 497 fp.write(data)
525 498 fp.close()
526 499
527 500 cmdclass = {'build': hgbuild,
528 501 'build_mo': hgbuildmo,
529 502 'build_ext': hgbuildext,
530 503 'build_py': hgbuildpy,
531 504 'build_scripts': hgbuildscripts,
532 505 'build_hgextindex': buildhgextindex,
533 506 'install_lib': hginstalllib,
534 507 'install_scripts': hginstallscripts,
535 508 'build_hgexe': buildhgexe,
536 509 }
537 510
538 511 packages = ['mercurial', 'mercurial.hgweb', 'mercurial.httpclient',
539 512 'mercurial.pure',
540 513 'hgext', 'hgext.convert', 'hgext.highlight', 'hgext.zeroconf',
541 514 'hgext.largefiles']
542 515
543 516 common_depends = ['mercurial/util.h']
544 517
545 518 osutil_ldflags = []
546 519
547 520 if sys.platform == 'darwin':
548 521 osutil_ldflags += ['-framework', 'ApplicationServices']
549 522
550 523 extmodules = [
551 524 Extension('mercurial.base85', ['mercurial/base85.c'],
552 525 depends=common_depends),
553 526 Extension('mercurial.bdiff', ['mercurial/bdiff.c'],
554 527 depends=common_depends),
555 528 Extension('mercurial.diffhelpers', ['mercurial/diffhelpers.c'],
556 529 depends=common_depends),
557 530 Extension('mercurial.mpatch', ['mercurial/mpatch.c'],
558 531 depends=common_depends),
559 532 Extension('mercurial.parsers', ['mercurial/dirs.c',
560 533 'mercurial/manifest.c',
561 534 'mercurial/parsers.c',
562 535 'mercurial/pathencode.c'],
563 536 depends=common_depends),
564 537 Extension('mercurial.osutil', ['mercurial/osutil.c'],
565 538 extra_link_args=osutil_ldflags,
566 539 depends=common_depends),
567 540 ]
568 541
569 542 try:
570 543 from distutils import cygwinccompiler
571 544
572 545 # the -mno-cygwin option has been deprecated for years
573 546 compiler = cygwinccompiler.Mingw32CCompiler
574 547
575 548 class HackedMingw32CCompiler(cygwinccompiler.Mingw32CCompiler):
576 549 def __init__(self, *args, **kwargs):
577 550 compiler.__init__(self, *args, **kwargs)
578 551 for i in 'compiler compiler_so linker_exe linker_so'.split():
579 552 try:
580 553 getattr(self, i).remove('-mno-cygwin')
581 554 except ValueError:
582 555 pass
583 556
584 557 cygwinccompiler.Mingw32CCompiler = HackedMingw32CCompiler
585 558 except ImportError:
586 559 # the cygwinccompiler package is not available on some Python
587 560 # distributions like the ones from the optware project for Synology
588 561 # DiskStation boxes
589 562 class HackedMingw32CCompiler(object):
590 563 pass
591 564
592 565 packagedata = {'mercurial': ['locale/*/LC_MESSAGES/hg.mo',
593 566 'help/*.txt',
594 567 'help/internals/*.txt',
595 568 'default.d/*.rc',
596 569 'dummycert.pem']}
597 570
598 571 def ordinarypath(p):
599 572 return p and p[0] != '.' and p[-1] != '~'
600 573
601 574 for root in ('templates',):
602 575 for curdir, dirs, files in os.walk(os.path.join('mercurial', root)):
603 576 curdir = curdir.split(os.sep, 1)[1]
604 577 dirs[:] = filter(ordinarypath, dirs)
605 578 for f in filter(ordinarypath, files):
606 579 f = os.path.join(curdir, f)
607 580 packagedata['mercurial'].append(f)
608 581
609 582 datafiles = []
610 583 setupversion = version
611 584 extra = {}
612 585
613 586 if py2exeloaded:
614 587 extra['console'] = [
615 588 {'script':'hg',
616 589 'copyright':'Copyright (C) 2005-2016 Matt Mackall and others',
617 590 'product_version':version}]
618 591 # sub command of 'build' because 'py2exe' does not handle sub_commands
619 592 build.sub_commands.insert(0, ('build_hgextindex', None))
620 593 # put dlls in sub directory so that they won't pollute PATH
621 594 extra['zipfile'] = 'lib/library.zip'
622 595
623 596 if os.name == 'nt':
624 597 # Windows binary file versions for exe/dll files must have the
625 598 # form W.X.Y.Z, where W,X,Y,Z are numbers in the range 0..65535
626 599 setupversion = version.split('+', 1)[0]
627 600
628 601 if sys.platform == 'darwin' and os.path.exists('/usr/bin/xcodebuild'):
629 602 version = runcmd(['/usr/bin/xcodebuild', '-version'], {})[0].splitlines()
630 603 if version:
631 604 version = version[0]
632 605 if sys.version_info[0] == 3:
633 606 version = version.decode('utf-8')
634 607 xcode4 = (version.startswith('Xcode') and
635 608 StrictVersion(version.split()[1]) >= StrictVersion('4.0'))
636 609 xcode51 = re.match(r'^Xcode\s+5\.1', version) is not None
637 610 else:
638 611 # xcodebuild returns empty on OS X Lion with XCode 4.3 not
639 612 # installed, but instead with only command-line tools. Assume
640 613 # that only happens on >= Lion, thus no PPC support.
641 614 xcode4 = True
642 615 xcode51 = False
643 616
644 617 # XCode 4.0 dropped support for ppc architecture, which is hardcoded in
645 618 # distutils.sysconfig
646 619 if xcode4:
647 620 os.environ['ARCHFLAGS'] = ''
648 621
649 622 # XCode 5.1 changes clang such that it now fails to compile if the
650 623 # -mno-fused-madd flag is passed, but the version of Python shipped with
651 624 # OS X 10.9 Mavericks includes this flag. This causes problems in all
652 625 # C extension modules, and a bug has been filed upstream at
653 626 # http://bugs.python.org/issue21244. We also need to patch this here
654 627 # so Mercurial can continue to compile in the meantime.
655 628 if xcode51:
656 629 cflags = get_config_var('CFLAGS')
657 630 if cflags and re.search(r'-mno-fused-madd\b', cflags) is not None:
658 631 os.environ['CFLAGS'] = (
659 632 os.environ.get('CFLAGS', '') + ' -Qunused-arguments')
660 633
661 634 setup(name='mercurial',
662 635 version=setupversion,
663 636 author='Matt Mackall and many others',
664 637 author_email='mercurial@selenic.com',
665 638 url='https://mercurial-scm.org/',
666 639 download_url='https://mercurial-scm.org/release/',
667 640 description=('Fast scalable distributed SCM (revision control, version '
668 641 'control) system'),
669 642 long_description=('Mercurial is a distributed SCM tool written in Python.'
670 643 ' It is used by a number of large projects that require'
671 644 ' fast, reliable distributed revision control, such as '
672 645 'Mozilla.'),
673 646 license='GNU GPLv2 or any later version',
674 647 classifiers=[
675 648 'Development Status :: 6 - Mature',
676 649 'Environment :: Console',
677 650 'Intended Audience :: Developers',
678 651 'Intended Audience :: System Administrators',
679 652 'License :: OSI Approved :: GNU General Public License (GPL)',
680 653 'Natural Language :: Danish',
681 654 'Natural Language :: English',
682 655 'Natural Language :: German',
683 656 'Natural Language :: Italian',
684 657 'Natural Language :: Japanese',
685 658 'Natural Language :: Portuguese (Brazilian)',
686 659 'Operating System :: Microsoft :: Windows',
687 660 'Operating System :: OS Independent',
688 661 'Operating System :: POSIX',
689 662 'Programming Language :: C',
690 663 'Programming Language :: Python',
691 664 'Topic :: Software Development :: Version Control',
692 665 ],
693 666 scripts=scripts,
694 667 packages=packages,
695 668 ext_modules=extmodules,
696 669 data_files=datafiles,
697 670 package_data=packagedata,
698 671 cmdclass=cmdclass,
699 672 distclass=hgdist,
700 673 options={'py2exe': {'packages': ['hgext', 'email']},
701 674 'bdist_mpkg': {'zipdist': False,
702 675 'license': 'COPYING',
703 676 'readme': 'contrib/macosx/Readme.html',
704 677 'welcome': 'contrib/macosx/Welcome.html',
705 678 },
706 679 },
707 680 **extra)
General Comments 0
You need to be logged in to leave comments. Login now