##// END OF EJS Templates
xdiff: remove xmerge related logic...
Jun Wu -
r36782:3cf40112 default
parent child Browse files
Show More
@@ -1,113 +1,83 b''
1 1 /*
2 2 * LibXDiff by Davide Libenzi ( File Differential Library )
3 3 * Copyright (C) 2003 Davide Libenzi
4 4 *
5 5 * This library is free software; you can redistribute it and/or
6 6 * modify it under the terms of the GNU Lesser General Public
7 7 * License as published by the Free Software Foundation; either
8 8 * version 2.1 of the License, or (at your option) any later version.
9 9 *
10 10 * This library is distributed in the hope that it will be useful,
11 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 13 * Lesser General Public License for more details.
14 14 *
15 15 * You should have received a copy of the GNU Lesser General Public
16 16 * License along with this library; if not, see
17 17 * <http://www.gnu.org/licenses/>.
18 18 *
19 19 * Davide Libenzi <davidel@xmailserver.org>
20 20 *
21 21 */
22 22
23 23 #if !defined(XDIFF_H)
24 24 #define XDIFF_H
25 25
26 26 #ifdef __cplusplus
27 27 extern "C" {
28 28 #endif /* #ifdef __cplusplus */
29 29
30 30 #include <stddef.h> /* size_t */
31 31
32 32 /* xpparm_t.flags */
33 33 #define XDF_NEED_MINIMAL (1 << 0)
34 34
35 35 #define XDF_INDENT_HEURISTIC (1 << 23)
36 36
37 37 /* emit bdiff-style "matched" (a1, a2, b1, b2) hunks instead of "different"
38 38 * (a1, a2 - a1, b1, b2 - b1) hunks */
39 39 #define XDL_EMIT_BDIFFHUNK (1 << 4)
40 40
41 /* merge simplification levels */
42 #define XDL_MERGE_MINIMAL 0
43 #define XDL_MERGE_EAGER 1
44 #define XDL_MERGE_ZEALOUS 2
45 #define XDL_MERGE_ZEALOUS_ALNUM 3
46
47 /* merge favor modes */
48 #define XDL_MERGE_FAVOR_OURS 1
49 #define XDL_MERGE_FAVOR_THEIRS 2
50 #define XDL_MERGE_FAVOR_UNION 3
51
52 /* merge output styles */
53 #define XDL_MERGE_DIFF3 1
54
55 41 typedef struct s_mmfile {
56 42 char *ptr;
57 43 long size;
58 44 } mmfile_t;
59 45
60 46 typedef struct s_mmbuffer {
61 47 char *ptr;
62 48 long size;
63 49 } mmbuffer_t;
64 50
65 51 typedef struct s_xpparam {
66 52 unsigned long flags;
67 53 } xpparam_t;
68 54
69 55 typedef struct s_xdemitcb {
70 56 void *priv;
71 57 } xdemitcb_t;
72 58
73 59 typedef int (*xdl_emit_hunk_consume_func_t)(long start_a, long count_a,
74 60 long start_b, long count_b,
75 61 void *cb_data);
76 62
77 63 typedef struct s_xdemitconf {
78 64 unsigned long flags;
79 65 xdl_emit_hunk_consume_func_t hunk_func;
80 66 } xdemitconf_t;
81 67
82 68
83 69 #define xdl_malloc(x) malloc(x)
84 70 #define xdl_free(ptr) free(ptr)
85 71 #define xdl_realloc(ptr,x) realloc(ptr,x)
86 72
87 73 void *xdl_mmfile_first(mmfile_t *mmf, long *size);
88 74 long xdl_mmfile_size(mmfile_t *mmf);
89 75
90 76 int xdl_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp,
91 77 xdemitconf_t const *xecfg, xdemitcb_t *ecb);
92 78
93 typedef struct s_xmparam {
94 xpparam_t xpp;
95 int marker_size;
96 int level;
97 int favor;
98 int style;
99 const char *ancestor; /* label for orig */
100 const char *file1; /* label for mf1 */
101 const char *file2; /* label for mf2 */
102 } xmparam_t;
103
104 #define DEFAULT_CONFLICT_MARKER_SIZE 7
105
106 int xdl_merge(mmfile_t *orig, mmfile_t *mf1, mmfile_t *mf2,
107 xmparam_t const *xmp, mmbuffer_t *result);
108
109 79 #ifdef __cplusplus
110 80 }
111 81 #endif /* #ifdef __cplusplus */
112 82
113 83 #endif /* #if !defined(XDIFF_H) */
@@ -1,1073 +1,1072 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 os
8 8
9 9 supportedpy = '~= 2.7'
10 10 if os.environ.get('HGALLOWPYTHON3', ''):
11 11 # Mercurial will never work on Python 3 before 3.5 due to a lack
12 12 # of % formatting on bytestrings, and can't work on 3.6.0 or 3.6.1
13 13 # due to a bug in % formatting in bytestrings.
14 14 #
15 15 # TODO: when we actually work on Python 3, use this string as the
16 16 # actual supportedpy string.
17 17 supportedpy = ','.join([
18 18 '>=2.7',
19 19 '!=3.0.*',
20 20 '!=3.1.*',
21 21 '!=3.2.*',
22 22 '!=3.3.*',
23 23 '!=3.4.*',
24 24 '!=3.6.0',
25 25 '!=3.6.1',
26 26 ])
27 27
28 28 import sys, platform
29 29 if sys.version_info[0] >= 3:
30 30 printf = eval('print')
31 31 libdir_escape = 'unicode_escape'
32 32 def sysstr(s):
33 33 return s.decode('latin-1')
34 34 else:
35 35 libdir_escape = 'string_escape'
36 36 def printf(*args, **kwargs):
37 37 f = kwargs.get('file', sys.stdout)
38 38 end = kwargs.get('end', '\n')
39 39 f.write(b' '.join(args) + end)
40 40 def sysstr(s):
41 41 return s
42 42
43 43 # Attempt to guide users to a modern pip - this means that 2.6 users
44 44 # should have a chance of getting a 4.2 release, and when we ratchet
45 45 # the version requirement forward again hopefully everyone will get
46 46 # something that works for them.
47 47 if sys.version_info < (2, 7, 0, 'final'):
48 48 pip_message = ('This may be due to an out of date pip. '
49 49 'Make sure you have pip >= 9.0.1.')
50 50 try:
51 51 import pip
52 52 pip_version = tuple([int(x) for x in pip.__version__.split('.')[:3]])
53 53 if pip_version < (9, 0, 1) :
54 54 pip_message = (
55 55 'Your pip version is out of date, please install '
56 56 'pip >= 9.0.1. pip {} detected.'.format(pip.__version__))
57 57 else:
58 58 # pip is new enough - it must be something else
59 59 pip_message = ''
60 60 except Exception:
61 61 pass
62 62 error = """
63 63 Mercurial does not support Python older than 2.7.
64 64 Python {py} detected.
65 65 {pip}
66 66 """.format(py=sys.version_info, pip=pip_message)
67 67 printf(error, file=sys.stderr)
68 68 sys.exit(1)
69 69
70 70 # We don't yet officially support Python 3. But we want to allow developers to
71 71 # hack on. Detect and disallow running on Python 3 by default. But provide a
72 72 # backdoor to enable working on Python 3.
73 73 if sys.version_info[0] != 2:
74 74 badpython = True
75 75
76 76 # Allow Python 3 from source checkouts.
77 77 if os.path.isdir('.hg'):
78 78 badpython = False
79 79
80 80 if badpython:
81 81 error = """
82 82 Mercurial only supports Python 2.7.
83 83 Python {py} detected.
84 84 Please re-run with Python 2.7.
85 85 """.format(py=sys.version_info)
86 86
87 87 printf(error, file=sys.stderr)
88 88 sys.exit(1)
89 89
90 90 # Solaris Python packaging brain damage
91 91 try:
92 92 import hashlib
93 93 sha = hashlib.sha1()
94 94 except ImportError:
95 95 try:
96 96 import sha
97 97 sha.sha # silence unused import warning
98 98 except ImportError:
99 99 raise SystemExit(
100 100 "Couldn't import standard hashlib (incomplete Python install).")
101 101
102 102 try:
103 103 import zlib
104 104 zlib.compressobj # silence unused import warning
105 105 except ImportError:
106 106 raise SystemExit(
107 107 "Couldn't import standard zlib (incomplete Python install).")
108 108
109 109 # The base IronPython distribution (as of 2.7.1) doesn't support bz2
110 110 isironpython = False
111 111 try:
112 112 isironpython = (platform.python_implementation()
113 113 .lower().find("ironpython") != -1)
114 114 except AttributeError:
115 115 pass
116 116
117 117 if isironpython:
118 118 sys.stderr.write("warning: IronPython detected (no bz2 support)\n")
119 119 else:
120 120 try:
121 121 import bz2
122 122 bz2.BZ2Compressor # silence unused import warning
123 123 except ImportError:
124 124 raise SystemExit(
125 125 "Couldn't import standard bz2 (incomplete Python install).")
126 126
127 127 ispypy = "PyPy" in sys.version
128 128
129 129 import ctypes
130 130 import stat, subprocess, time
131 131 import re
132 132 import shutil
133 133 import tempfile
134 134 from distutils import log
135 135 # We have issues with setuptools on some platforms and builders. Until
136 136 # those are resolved, setuptools is opt-in except for platforms where
137 137 # we don't have issues.
138 138 issetuptools = (os.name == 'nt' or 'FORCE_SETUPTOOLS' in os.environ)
139 139 if issetuptools:
140 140 from setuptools import setup
141 141 else:
142 142 from distutils.core import setup
143 143 from distutils.ccompiler import new_compiler
144 144 from distutils.core import Command, Extension
145 145 from distutils.dist import Distribution
146 146 from distutils.command.build import build
147 147 from distutils.command.build_ext import build_ext
148 148 from distutils.command.build_py import build_py
149 149 from distutils.command.build_scripts import build_scripts
150 150 from distutils.command.install import install
151 151 from distutils.command.install_lib import install_lib
152 152 from distutils.command.install_scripts import install_scripts
153 153 from distutils.spawn import spawn, find_executable
154 154 from distutils import file_util
155 155 from distutils.errors import (
156 156 CCompilerError,
157 157 DistutilsError,
158 158 DistutilsExecError,
159 159 )
160 160 from distutils.sysconfig import get_python_inc, get_config_var
161 161 from distutils.version import StrictVersion
162 162
163 163 def write_if_changed(path, content):
164 164 """Write content to a file iff the content hasn't changed."""
165 165 if os.path.exists(path):
166 166 with open(path, 'rb') as fh:
167 167 current = fh.read()
168 168 else:
169 169 current = b''
170 170
171 171 if current != content:
172 172 with open(path, 'wb') as fh:
173 173 fh.write(content)
174 174
175 175 scripts = ['hg']
176 176 if os.name == 'nt':
177 177 # We remove hg.bat if we are able to build hg.exe.
178 178 scripts.append('contrib/win32/hg.bat')
179 179
180 180 def cancompile(cc, code):
181 181 tmpdir = tempfile.mkdtemp(prefix='hg-install-')
182 182 devnull = oldstderr = None
183 183 try:
184 184 fname = os.path.join(tmpdir, 'testcomp.c')
185 185 f = open(fname, 'w')
186 186 f.write(code)
187 187 f.close()
188 188 # Redirect stderr to /dev/null to hide any error messages
189 189 # from the compiler.
190 190 # This will have to be changed if we ever have to check
191 191 # for a function on Windows.
192 192 devnull = open('/dev/null', 'w')
193 193 oldstderr = os.dup(sys.stderr.fileno())
194 194 os.dup2(devnull.fileno(), sys.stderr.fileno())
195 195 objects = cc.compile([fname], output_dir=tmpdir)
196 196 cc.link_executable(objects, os.path.join(tmpdir, "a.out"))
197 197 return True
198 198 except Exception:
199 199 return False
200 200 finally:
201 201 if oldstderr is not None:
202 202 os.dup2(oldstderr, sys.stderr.fileno())
203 203 if devnull is not None:
204 204 devnull.close()
205 205 shutil.rmtree(tmpdir)
206 206
207 207 # simplified version of distutils.ccompiler.CCompiler.has_function
208 208 # that actually removes its temporary files.
209 209 def hasfunction(cc, funcname):
210 210 code = 'int main(void) { %s(); }\n' % funcname
211 211 return cancompile(cc, code)
212 212
213 213 def hasheader(cc, headername):
214 214 code = '#include <%s>\nint main(void) { return 0; }\n' % headername
215 215 return cancompile(cc, code)
216 216
217 217 # py2exe needs to be installed to work
218 218 try:
219 219 import py2exe
220 220 py2exe.Distribution # silence unused import warning
221 221 py2exeloaded = True
222 222 # import py2exe's patched Distribution class
223 223 from distutils.core import Distribution
224 224 except ImportError:
225 225 py2exeloaded = False
226 226
227 227 def runcmd(cmd, env):
228 228 p = subprocess.Popen(cmd, stdout=subprocess.PIPE,
229 229 stderr=subprocess.PIPE, env=env)
230 230 out, err = p.communicate()
231 231 return p.returncode, out, err
232 232
233 233 class hgcommand(object):
234 234 def __init__(self, cmd, env):
235 235 self.cmd = cmd
236 236 self.env = env
237 237
238 238 def run(self, args):
239 239 cmd = self.cmd + args
240 240 returncode, out, err = runcmd(cmd, self.env)
241 241 err = filterhgerr(err)
242 242 if err or returncode != 0:
243 243 printf("stderr from '%s':" % (' '.join(cmd)), file=sys.stderr)
244 244 printf(err, file=sys.stderr)
245 245 return ''
246 246 return out
247 247
248 248 def filterhgerr(err):
249 249 # If root is executing setup.py, but the repository is owned by
250 250 # another user (as in "sudo python setup.py install") we will get
251 251 # trust warnings since the .hg/hgrc file is untrusted. That is
252 252 # fine, we don't want to load it anyway. Python may warn about
253 253 # a missing __init__.py in mercurial/locale, we also ignore that.
254 254 err = [e for e in err.splitlines()
255 255 if (not e.startswith(b'not trusting file')
256 256 and not e.startswith(b'warning: Not importing')
257 257 and not e.startswith(b'obsolete feature not enabled')
258 258 and not e.startswith(b'*** failed to import extension')
259 259 and not e.startswith(b'devel-warn:'))]
260 260 return b'\n'.join(b' ' + e for e in err)
261 261
262 262 def findhg():
263 263 """Try to figure out how we should invoke hg for examining the local
264 264 repository contents.
265 265
266 266 Returns an hgcommand object."""
267 267 # By default, prefer the "hg" command in the user's path. This was
268 268 # presumably the hg command that the user used to create this repository.
269 269 #
270 270 # This repository may require extensions or other settings that would not
271 271 # be enabled by running the hg script directly from this local repository.
272 272 hgenv = os.environ.copy()
273 273 # Use HGPLAIN to disable hgrc settings that would change output formatting,
274 274 # and disable localization for the same reasons.
275 275 hgenv['HGPLAIN'] = '1'
276 276 hgenv['LANGUAGE'] = 'C'
277 277 hgcmd = ['hg']
278 278 # Run a simple "hg log" command just to see if using hg from the user's
279 279 # path works and can successfully interact with this repository.
280 280 check_cmd = ['log', '-r.', '-Ttest']
281 281 try:
282 282 retcode, out, err = runcmd(hgcmd + check_cmd, hgenv)
283 283 except EnvironmentError:
284 284 retcode = -1
285 285 if retcode == 0 and not filterhgerr(err):
286 286 return hgcommand(hgcmd, hgenv)
287 287
288 288 # Fall back to trying the local hg installation.
289 289 hgenv = localhgenv()
290 290 hgcmd = [sys.executable, 'hg']
291 291 try:
292 292 retcode, out, err = runcmd(hgcmd + check_cmd, hgenv)
293 293 except EnvironmentError:
294 294 retcode = -1
295 295 if retcode == 0 and not filterhgerr(err):
296 296 return hgcommand(hgcmd, hgenv)
297 297
298 298 raise SystemExit('Unable to find a working hg binary to extract the '
299 299 'version from the repository tags')
300 300
301 301 def localhgenv():
302 302 """Get an environment dictionary to use for invoking or importing
303 303 mercurial from the local repository."""
304 304 # Execute hg out of this directory with a custom environment which takes
305 305 # care to not use any hgrc files and do no localization.
306 306 env = {'HGMODULEPOLICY': 'py',
307 307 'HGRCPATH': '',
308 308 'LANGUAGE': 'C',
309 309 'PATH': ''} # make pypi modules that use os.environ['PATH'] happy
310 310 if 'LD_LIBRARY_PATH' in os.environ:
311 311 env['LD_LIBRARY_PATH'] = os.environ['LD_LIBRARY_PATH']
312 312 if 'SystemRoot' in os.environ:
313 313 # SystemRoot is required by Windows to load various DLLs. See:
314 314 # https://bugs.python.org/issue13524#msg148850
315 315 env['SystemRoot'] = os.environ['SystemRoot']
316 316 return env
317 317
318 318 version = ''
319 319
320 320 if os.path.isdir('.hg'):
321 321 hg = findhg()
322 322 cmd = ['log', '-r', '.', '--template', '{tags}\n']
323 323 numerictags = [t for t in sysstr(hg.run(cmd)).split() if t[0:1].isdigit()]
324 324 hgid = sysstr(hg.run(['id', '-i'])).strip()
325 325 if not hgid:
326 326 # Bail out if hg is having problems interacting with this repository,
327 327 # rather than falling through and producing a bogus version number.
328 328 # Continuing with an invalid version number will break extensions
329 329 # that define minimumhgversion.
330 330 raise SystemExit('Unable to determine hg version from local repository')
331 331 if numerictags: # tag(s) found
332 332 version = numerictags[-1]
333 333 if hgid.endswith('+'): # propagate the dirty status to the tag
334 334 version += '+'
335 335 else: # no tag found
336 336 ltagcmd = ['parents', '--template', '{latesttag}']
337 337 ltag = sysstr(hg.run(ltagcmd))
338 338 changessincecmd = ['log', '-T', 'x\n', '-r', "only(.,'%s')" % ltag]
339 339 changessince = len(hg.run(changessincecmd).splitlines())
340 340 version = '%s+%s-%s' % (ltag, changessince, hgid)
341 341 if version.endswith('+'):
342 342 version += time.strftime('%Y%m%d')
343 343 elif os.path.exists('.hg_archival.txt'):
344 344 kw = dict([[t.strip() for t in l.split(':', 1)]
345 345 for l in open('.hg_archival.txt')])
346 346 if 'tag' in kw:
347 347 version = kw['tag']
348 348 elif 'latesttag' in kw:
349 349 if 'changessincelatesttag' in kw:
350 350 version = '%(latesttag)s+%(changessincelatesttag)s-%(node).12s' % kw
351 351 else:
352 352 version = '%(latesttag)s+%(latesttagdistance)s-%(node).12s' % kw
353 353 else:
354 354 version = kw.get('node', '')[:12]
355 355
356 356 if version:
357 357 versionb = version
358 358 if not isinstance(versionb, bytes):
359 359 versionb = versionb.encode('ascii')
360 360
361 361 write_if_changed('mercurial/__version__.py', b''.join([
362 362 b'# this file is autogenerated by setup.py\n'
363 363 b'version = "%s"\n' % versionb,
364 364 ]))
365 365
366 366 try:
367 367 oldpolicy = os.environ.get('HGMODULEPOLICY', None)
368 368 os.environ['HGMODULEPOLICY'] = 'py'
369 369 from mercurial import __version__
370 370 version = __version__.version
371 371 except ImportError:
372 372 version = 'unknown'
373 373 finally:
374 374 if oldpolicy is None:
375 375 del os.environ['HGMODULEPOLICY']
376 376 else:
377 377 os.environ['HGMODULEPOLICY'] = oldpolicy
378 378
379 379 class hgbuild(build):
380 380 # Insert hgbuildmo first so that files in mercurial/locale/ are found
381 381 # when build_py is run next.
382 382 sub_commands = [('build_mo', None)] + build.sub_commands
383 383
384 384 class hgbuildmo(build):
385 385
386 386 description = "build translations (.mo files)"
387 387
388 388 def run(self):
389 389 if not find_executable('msgfmt'):
390 390 self.warn("could not find msgfmt executable, no translations "
391 391 "will be built")
392 392 return
393 393
394 394 podir = 'i18n'
395 395 if not os.path.isdir(podir):
396 396 self.warn("could not find %s/ directory" % podir)
397 397 return
398 398
399 399 join = os.path.join
400 400 for po in os.listdir(podir):
401 401 if not po.endswith('.po'):
402 402 continue
403 403 pofile = join(podir, po)
404 404 modir = join('locale', po[:-3], 'LC_MESSAGES')
405 405 mofile = join(modir, 'hg.mo')
406 406 mobuildfile = join('mercurial', mofile)
407 407 cmd = ['msgfmt', '-v', '-o', mobuildfile, pofile]
408 408 if sys.platform != 'sunos5':
409 409 # msgfmt on Solaris does not know about -c
410 410 cmd.append('-c')
411 411 self.mkpath(join('mercurial', modir))
412 412 self.make_file([pofile], mobuildfile, spawn, (cmd,))
413 413
414 414
415 415 class hgdist(Distribution):
416 416 pure = False
417 417 cffi = ispypy
418 418
419 419 global_options = Distribution.global_options + \
420 420 [('pure', None, "use pure (slow) Python "
421 421 "code instead of C extensions"),
422 422 ]
423 423
424 424 def has_ext_modules(self):
425 425 # self.ext_modules is emptied in hgbuildpy.finalize_options which is
426 426 # too late for some cases
427 427 return not self.pure and Distribution.has_ext_modules(self)
428 428
429 429 # This is ugly as a one-liner. So use a variable.
430 430 buildextnegops = dict(getattr(build_ext, 'negative_options', {}))
431 431 buildextnegops['no-zstd'] = 'zstd'
432 432
433 433 class hgbuildext(build_ext):
434 434 user_options = build_ext.user_options + [
435 435 ('zstd', None, 'compile zstd bindings [default]'),
436 436 ('no-zstd', None, 'do not compile zstd bindings'),
437 437 ]
438 438
439 439 boolean_options = build_ext.boolean_options + ['zstd']
440 440 negative_opt = buildextnegops
441 441
442 442 def initialize_options(self):
443 443 self.zstd = True
444 444 return build_ext.initialize_options(self)
445 445
446 446 def build_extensions(self):
447 447 # Filter out zstd if disabled via argument.
448 448 if not self.zstd:
449 449 self.extensions = [e for e in self.extensions
450 450 if e.name != 'mercurial.zstd']
451 451
452 452 return build_ext.build_extensions(self)
453 453
454 454 def build_extension(self, ext):
455 455 try:
456 456 build_ext.build_extension(self, ext)
457 457 except CCompilerError:
458 458 if not getattr(ext, 'optional', False):
459 459 raise
460 460 log.warn("Failed to build optional extension '%s' (skipping)",
461 461 ext.name)
462 462
463 463 class hgbuildscripts(build_scripts):
464 464 def run(self):
465 465 if os.name != 'nt' or self.distribution.pure:
466 466 return build_scripts.run(self)
467 467
468 468 exebuilt = False
469 469 try:
470 470 self.run_command('build_hgexe')
471 471 exebuilt = True
472 472 except (DistutilsError, CCompilerError):
473 473 log.warn('failed to build optional hg.exe')
474 474
475 475 if exebuilt:
476 476 # Copying hg.exe to the scripts build directory ensures it is
477 477 # installed by the install_scripts command.
478 478 hgexecommand = self.get_finalized_command('build_hgexe')
479 479 dest = os.path.join(self.build_dir, 'hg.exe')
480 480 self.mkpath(self.build_dir)
481 481 self.copy_file(hgexecommand.hgexepath, dest)
482 482
483 483 # Remove hg.bat because it is redundant with hg.exe.
484 484 self.scripts.remove('contrib/win32/hg.bat')
485 485
486 486 return build_scripts.run(self)
487 487
488 488 class hgbuildpy(build_py):
489 489 def finalize_options(self):
490 490 build_py.finalize_options(self)
491 491
492 492 if self.distribution.pure:
493 493 self.distribution.ext_modules = []
494 494 elif self.distribution.cffi:
495 495 from mercurial.cffi import (
496 496 bdiffbuild,
497 497 mpatchbuild,
498 498 )
499 499 exts = [mpatchbuild.ffi.distutils_extension(),
500 500 bdiffbuild.ffi.distutils_extension()]
501 501 # cffi modules go here
502 502 if sys.platform == 'darwin':
503 503 from mercurial.cffi import osutilbuild
504 504 exts.append(osutilbuild.ffi.distutils_extension())
505 505 self.distribution.ext_modules = exts
506 506 else:
507 507 h = os.path.join(get_python_inc(), 'Python.h')
508 508 if not os.path.exists(h):
509 509 raise SystemExit('Python headers are required to build '
510 510 'Mercurial but weren\'t found in %s' % h)
511 511
512 512 def run(self):
513 513 basepath = os.path.join(self.build_lib, 'mercurial')
514 514 self.mkpath(basepath)
515 515
516 516 if self.distribution.pure:
517 517 modulepolicy = 'py'
518 518 elif self.build_lib == '.':
519 519 # in-place build should run without rebuilding C extensions
520 520 modulepolicy = 'allow'
521 521 else:
522 522 modulepolicy = 'c'
523 523
524 524 content = b''.join([
525 525 b'# this file is autogenerated by setup.py\n',
526 526 b'modulepolicy = b"%s"\n' % modulepolicy.encode('ascii'),
527 527 ])
528 528 write_if_changed(os.path.join(basepath, '__modulepolicy__.py'),
529 529 content)
530 530
531 531 build_py.run(self)
532 532
533 533 class buildhgextindex(Command):
534 534 description = 'generate prebuilt index of hgext (for frozen package)'
535 535 user_options = []
536 536 _indexfilename = 'hgext/__index__.py'
537 537
538 538 def initialize_options(self):
539 539 pass
540 540
541 541 def finalize_options(self):
542 542 pass
543 543
544 544 def run(self):
545 545 if os.path.exists(self._indexfilename):
546 546 with open(self._indexfilename, 'w') as f:
547 547 f.write('# empty\n')
548 548
549 549 # here no extension enabled, disabled() lists up everything
550 550 code = ('import pprint; from mercurial import extensions; '
551 551 'pprint.pprint(extensions.disabled())')
552 552 returncode, out, err = runcmd([sys.executable, '-c', code],
553 553 localhgenv())
554 554 if err or returncode != 0:
555 555 raise DistutilsExecError(err)
556 556
557 557 with open(self._indexfilename, 'w') as f:
558 558 f.write('# this file is autogenerated by setup.py\n')
559 559 f.write('docs = ')
560 560 f.write(out)
561 561
562 562 class buildhgexe(build_ext):
563 563 description = 'compile hg.exe from mercurial/exewrapper.c'
564 564 user_options = build_ext.user_options + [
565 565 ('long-paths-support', None, 'enable support for long paths on '
566 566 'Windows (off by default and '
567 567 'experimental)'),
568 568 ]
569 569
570 570 LONG_PATHS_MANIFEST = """
571 571 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
572 572 <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
573 573 <application>
574 574 <windowsSettings
575 575 xmlns:ws2="http://schemas.microsoft.com/SMI/2016/WindowsSettings">
576 576 <ws2:longPathAware>true</ws2:longPathAware>
577 577 </windowsSettings>
578 578 </application>
579 579 </assembly>"""
580 580
581 581 def initialize_options(self):
582 582 build_ext.initialize_options(self)
583 583 self.long_paths_support = False
584 584
585 585 def build_extensions(self):
586 586 if os.name != 'nt':
587 587 return
588 588 if isinstance(self.compiler, HackedMingw32CCompiler):
589 589 self.compiler.compiler_so = self.compiler.compiler # no -mdll
590 590 self.compiler.dll_libraries = [] # no -lmsrvc90
591 591
592 592 # Different Python installs can have different Python library
593 593 # names. e.g. the official CPython distribution uses pythonXY.dll
594 594 # and MinGW uses libpythonX.Y.dll.
595 595 _kernel32 = ctypes.windll.kernel32
596 596 _kernel32.GetModuleFileNameA.argtypes = [ctypes.c_void_p,
597 597 ctypes.c_void_p,
598 598 ctypes.c_ulong]
599 599 _kernel32.GetModuleFileNameA.restype = ctypes.c_ulong
600 600 size = 1000
601 601 buf = ctypes.create_string_buffer(size + 1)
602 602 filelen = _kernel32.GetModuleFileNameA(sys.dllhandle, ctypes.byref(buf),
603 603 size)
604 604
605 605 if filelen > 0 and filelen != size:
606 606 dllbasename = os.path.basename(buf.value)
607 607 if not dllbasename.lower().endswith('.dll'):
608 608 raise SystemExit('Python DLL does not end with .dll: %s' %
609 609 dllbasename)
610 610 pythonlib = dllbasename[:-4]
611 611 else:
612 612 log.warn('could not determine Python DLL filename; '
613 613 'assuming pythonXY')
614 614
615 615 hv = sys.hexversion
616 616 pythonlib = 'python%d%d' % (hv >> 24, (hv >> 16) & 0xff)
617 617
618 618 log.info('using %s as Python library name' % pythonlib)
619 619 with open('mercurial/hgpythonlib.h', 'wb') as f:
620 620 f.write('/* this file is autogenerated by setup.py */\n')
621 621 f.write('#define HGPYTHONLIB "%s"\n' % pythonlib)
622 622 objects = self.compiler.compile(['mercurial/exewrapper.c'],
623 623 output_dir=self.build_temp)
624 624 dir = os.path.dirname(self.get_ext_fullpath('dummy'))
625 625 self.hgtarget = os.path.join(dir, 'hg')
626 626 self.compiler.link_executable(objects, self.hgtarget,
627 627 libraries=[],
628 628 output_dir=self.build_temp)
629 629 if self.long_paths_support:
630 630 self.addlongpathsmanifest()
631 631
632 632 def addlongpathsmanifest(self):
633 633 """Add manifest pieces so that hg.exe understands long paths
634 634
635 635 This is an EXPERIMENTAL feature, use with care.
636 636 To enable long paths support, one needs to do two things:
637 637 - build Mercurial with --long-paths-support option
638 638 - change HKLM\SYSTEM\CurrentControlSet\Control\FileSystem\
639 639 LongPathsEnabled to have value 1.
640 640
641 641 Please ignore 'warning 81010002: Unrecognized Element "longPathAware"';
642 642 it happens because Mercurial uses mt.exe circa 2008, which is not
643 643 yet aware of long paths support in the manifest (I think so at least).
644 644 This does not stop mt.exe from embedding/merging the XML properly.
645 645
646 646 Why resource #1 should be used for .exe manifests? I don't know and
647 647 wasn't able to find an explanation for mortals. But it seems to work.
648 648 """
649 649 exefname = self.compiler.executable_filename(self.hgtarget)
650 650 fdauto, manfname = tempfile.mkstemp(suffix='.hg.exe.manifest')
651 651 os.close(fdauto)
652 652 with open(manfname, 'w') as f:
653 653 f.write(self.LONG_PATHS_MANIFEST)
654 654 log.info("long paths manifest is written to '%s'" % manfname)
655 655 inputresource = '-inputresource:%s;#1' % exefname
656 656 outputresource = '-outputresource:%s;#1' % exefname
657 657 log.info("running mt.exe to update hg.exe's manifest in-place")
658 658 # supplying both -manifest and -inputresource to mt.exe makes
659 659 # it merge the embedded and supplied manifests in the -outputresource
660 660 self.spawn(['mt.exe', '-nologo', '-manifest', manfname,
661 661 inputresource, outputresource])
662 662 log.info("done updating hg.exe's manifest")
663 663 os.remove(manfname)
664 664
665 665 @property
666 666 def hgexepath(self):
667 667 dir = os.path.dirname(self.get_ext_fullpath('dummy'))
668 668 return os.path.join(self.build_temp, dir, 'hg.exe')
669 669
670 670 class hginstall(install):
671 671
672 672 user_options = install.user_options + [
673 673 ('old-and-unmanageable', None,
674 674 'noop, present for eggless setuptools compat'),
675 675 ('single-version-externally-managed', None,
676 676 'noop, present for eggless setuptools compat'),
677 677 ]
678 678
679 679 # Also helps setuptools not be sad while we refuse to create eggs.
680 680 single_version_externally_managed = True
681 681
682 682 def get_sub_commands(self):
683 683 # Screen out egg related commands to prevent egg generation. But allow
684 684 # mercurial.egg-info generation, since that is part of modern
685 685 # packaging.
686 686 excl = set(['bdist_egg'])
687 687 return filter(lambda x: x not in excl, install.get_sub_commands(self))
688 688
689 689 class hginstalllib(install_lib):
690 690 '''
691 691 This is a specialization of install_lib that replaces the copy_file used
692 692 there so that it supports setting the mode of files after copying them,
693 693 instead of just preserving the mode that the files originally had. If your
694 694 system has a umask of something like 027, preserving the permissions when
695 695 copying will lead to a broken install.
696 696
697 697 Note that just passing keep_permissions=False to copy_file would be
698 698 insufficient, as it might still be applying a umask.
699 699 '''
700 700
701 701 def run(self):
702 702 realcopyfile = file_util.copy_file
703 703 def copyfileandsetmode(*args, **kwargs):
704 704 src, dst = args[0], args[1]
705 705 dst, copied = realcopyfile(*args, **kwargs)
706 706 if copied:
707 707 st = os.stat(src)
708 708 # Persist executable bit (apply it to group and other if user
709 709 # has it)
710 710 if st[stat.ST_MODE] & stat.S_IXUSR:
711 711 setmode = int('0755', 8)
712 712 else:
713 713 setmode = int('0644', 8)
714 714 m = stat.S_IMODE(st[stat.ST_MODE])
715 715 m = (m & ~int('0777', 8)) | setmode
716 716 os.chmod(dst, m)
717 717 file_util.copy_file = copyfileandsetmode
718 718 try:
719 719 install_lib.run(self)
720 720 finally:
721 721 file_util.copy_file = realcopyfile
722 722
723 723 class hginstallscripts(install_scripts):
724 724 '''
725 725 This is a specialization of install_scripts that replaces the @LIBDIR@ with
726 726 the configured directory for modules. If possible, the path is made relative
727 727 to the directory for scripts.
728 728 '''
729 729
730 730 def initialize_options(self):
731 731 install_scripts.initialize_options(self)
732 732
733 733 self.install_lib = None
734 734
735 735 def finalize_options(self):
736 736 install_scripts.finalize_options(self)
737 737 self.set_undefined_options('install',
738 738 ('install_lib', 'install_lib'))
739 739
740 740 def run(self):
741 741 install_scripts.run(self)
742 742
743 743 # It only makes sense to replace @LIBDIR@ with the install path if
744 744 # the install path is known. For wheels, the logic below calculates
745 745 # the libdir to be "../..". This is because the internal layout of a
746 746 # wheel archive looks like:
747 747 #
748 748 # mercurial-3.6.1.data/scripts/hg
749 749 # mercurial/__init__.py
750 750 #
751 751 # When installing wheels, the subdirectories of the "<pkg>.data"
752 752 # directory are translated to system local paths and files therein
753 753 # are copied in place. The mercurial/* files are installed into the
754 754 # site-packages directory. However, the site-packages directory
755 755 # isn't known until wheel install time. This means we have no clue
756 756 # at wheel generation time what the installed site-packages directory
757 757 # will be. And, wheels don't appear to provide the ability to register
758 758 # custom code to run during wheel installation. This all means that
759 759 # we can't reliably set the libdir in wheels: the default behavior
760 760 # of looking in sys.path must do.
761 761
762 762 if (os.path.splitdrive(self.install_dir)[0] !=
763 763 os.path.splitdrive(self.install_lib)[0]):
764 764 # can't make relative paths from one drive to another, so use an
765 765 # absolute path instead
766 766 libdir = self.install_lib
767 767 else:
768 768 common = os.path.commonprefix((self.install_dir, self.install_lib))
769 769 rest = self.install_dir[len(common):]
770 770 uplevel = len([n for n in os.path.split(rest) if n])
771 771
772 772 libdir = uplevel * ('..' + os.sep) + self.install_lib[len(common):]
773 773
774 774 for outfile in self.outfiles:
775 775 with open(outfile, 'rb') as fp:
776 776 data = fp.read()
777 777
778 778 # skip binary files
779 779 if b'\0' in data:
780 780 continue
781 781
782 782 # During local installs, the shebang will be rewritten to the final
783 783 # install path. During wheel packaging, the shebang has a special
784 784 # value.
785 785 if data.startswith(b'#!python'):
786 786 log.info('not rewriting @LIBDIR@ in %s because install path '
787 787 'not known' % outfile)
788 788 continue
789 789
790 790 data = data.replace(b'@LIBDIR@', libdir.encode(libdir_escape))
791 791 with open(outfile, 'wb') as fp:
792 792 fp.write(data)
793 793
794 794 cmdclass = {'build': hgbuild,
795 795 'build_mo': hgbuildmo,
796 796 'build_ext': hgbuildext,
797 797 'build_py': hgbuildpy,
798 798 'build_scripts': hgbuildscripts,
799 799 'build_hgextindex': buildhgextindex,
800 800 'install': hginstall,
801 801 'install_lib': hginstalllib,
802 802 'install_scripts': hginstallscripts,
803 803 'build_hgexe': buildhgexe,
804 804 }
805 805
806 806 packages = ['mercurial',
807 807 'mercurial.cext',
808 808 'mercurial.cffi',
809 809 'mercurial.hgweb',
810 810 'mercurial.pure',
811 811 'mercurial.thirdparty',
812 812 'mercurial.thirdparty.attr',
813 813 'mercurial.utils',
814 814 'hgext', 'hgext.convert', 'hgext.fsmonitor',
815 815 'hgext.fsmonitor.pywatchman', 'hgext.highlight',
816 816 'hgext.largefiles', 'hgext.lfs', 'hgext.narrow',
817 817 'hgext.zeroconf', 'hgext3rd',
818 818 'hgdemandimport']
819 819
820 820 common_depends = ['mercurial/bitmanipulation.h',
821 821 'mercurial/compat.h',
822 822 'mercurial/cext/util.h']
823 823 common_include_dirs = ['mercurial']
824 824
825 825 osutil_cflags = []
826 826 osutil_ldflags = []
827 827
828 828 # platform specific macros
829 829 for plat, func in [('bsd', 'setproctitle')]:
830 830 if re.search(plat, sys.platform) and hasfunction(new_compiler(), func):
831 831 osutil_cflags.append('-DHAVE_%s' % func.upper())
832 832
833 833 for plat, macro, code in [
834 834 ('bsd|darwin', 'BSD_STATFS', '''
835 835 #include <sys/param.h>
836 836 #include <sys/mount.h>
837 837 int main() { struct statfs s; return sizeof(s.f_fstypename); }
838 838 '''),
839 839 ('linux', 'LINUX_STATFS', '''
840 840 #include <linux/magic.h>
841 841 #include <sys/vfs.h>
842 842 int main() { struct statfs s; return sizeof(s.f_type); }
843 843 '''),
844 844 ]:
845 845 if re.search(plat, sys.platform) and cancompile(new_compiler(), code):
846 846 osutil_cflags.append('-DHAVE_%s' % macro)
847 847
848 848 if sys.platform == 'darwin':
849 849 osutil_ldflags += ['-framework', 'ApplicationServices']
850 850
851 851 xdiff_srcs = [
852 852 'mercurial/thirdparty/xdiff/xdiffi.c',
853 'mercurial/thirdparty/xdiff/xmerge.c',
854 853 'mercurial/thirdparty/xdiff/xprepare.c',
855 854 'mercurial/thirdparty/xdiff/xutils.c',
856 855 ]
857 856
858 857 xdiff_headers = [
859 858 'mercurial/thirdparty/xdiff/xdiff.h',
860 859 'mercurial/thirdparty/xdiff/xdiffi.h',
861 860 'mercurial/thirdparty/xdiff/xinclude.h',
862 861 'mercurial/thirdparty/xdiff/xmacros.h',
863 862 'mercurial/thirdparty/xdiff/xprepare.h',
864 863 'mercurial/thirdparty/xdiff/xtypes.h',
865 864 'mercurial/thirdparty/xdiff/xutils.h',
866 865 ]
867 866
868 867 extmodules = [
869 868 Extension('mercurial.cext.base85', ['mercurial/cext/base85.c'],
870 869 include_dirs=common_include_dirs,
871 870 depends=common_depends),
872 871 Extension('mercurial.cext.bdiff', ['mercurial/bdiff.c',
873 872 'mercurial/cext/bdiff.c'] + xdiff_srcs,
874 873 include_dirs=common_include_dirs,
875 874 depends=common_depends + ['mercurial/bdiff.h'] + xdiff_headers),
876 875 Extension('mercurial.cext.diffhelpers', ['mercurial/cext/diffhelpers.c'],
877 876 include_dirs=common_include_dirs,
878 877 depends=common_depends),
879 878 Extension('mercurial.cext.mpatch', ['mercurial/mpatch.c',
880 879 'mercurial/cext/mpatch.c'],
881 880 include_dirs=common_include_dirs,
882 881 depends=common_depends),
883 882 Extension('mercurial.cext.parsers', ['mercurial/cext/charencode.c',
884 883 'mercurial/cext/dirs.c',
885 884 'mercurial/cext/manifest.c',
886 885 'mercurial/cext/parsers.c',
887 886 'mercurial/cext/pathencode.c',
888 887 'mercurial/cext/revlog.c'],
889 888 include_dirs=common_include_dirs,
890 889 depends=common_depends + ['mercurial/cext/charencode.h']),
891 890 Extension('mercurial.cext.osutil', ['mercurial/cext/osutil.c'],
892 891 include_dirs=common_include_dirs,
893 892 extra_compile_args=osutil_cflags,
894 893 extra_link_args=osutil_ldflags,
895 894 depends=common_depends),
896 895 Extension('hgext.fsmonitor.pywatchman.bser',
897 896 ['hgext/fsmonitor/pywatchman/bser.c']),
898 897 ]
899 898
900 899 sys.path.insert(0, 'contrib/python-zstandard')
901 900 import setup_zstd
902 901 extmodules.append(setup_zstd.get_c_extension(name='mercurial.zstd'))
903 902
904 903 try:
905 904 from distutils import cygwinccompiler
906 905
907 906 # the -mno-cygwin option has been deprecated for years
908 907 mingw32compilerclass = cygwinccompiler.Mingw32CCompiler
909 908
910 909 class HackedMingw32CCompiler(cygwinccompiler.Mingw32CCompiler):
911 910 def __init__(self, *args, **kwargs):
912 911 mingw32compilerclass.__init__(self, *args, **kwargs)
913 912 for i in 'compiler compiler_so linker_exe linker_so'.split():
914 913 try:
915 914 getattr(self, i).remove('-mno-cygwin')
916 915 except ValueError:
917 916 pass
918 917
919 918 cygwinccompiler.Mingw32CCompiler = HackedMingw32CCompiler
920 919 except ImportError:
921 920 # the cygwinccompiler package is not available on some Python
922 921 # distributions like the ones from the optware project for Synology
923 922 # DiskStation boxes
924 923 class HackedMingw32CCompiler(object):
925 924 pass
926 925
927 926 if os.name == 'nt':
928 927 # Allow compiler/linker flags to be added to Visual Studio builds. Passing
929 928 # extra_link_args to distutils.extensions.Extension() doesn't have any
930 929 # effect.
931 930 from distutils import msvccompiler
932 931
933 932 msvccompilerclass = msvccompiler.MSVCCompiler
934 933
935 934 class HackedMSVCCompiler(msvccompiler.MSVCCompiler):
936 935 def initialize(self):
937 936 msvccompilerclass.initialize(self)
938 937 # "warning LNK4197: export 'func' specified multiple times"
939 938 self.ldflags_shared.append('/ignore:4197')
940 939 self.ldflags_shared_debug.append('/ignore:4197')
941 940
942 941 msvccompiler.MSVCCompiler = HackedMSVCCompiler
943 942
944 943 packagedata = {'mercurial': ['locale/*/LC_MESSAGES/hg.mo',
945 944 'help/*.txt',
946 945 'help/internals/*.txt',
947 946 'default.d/*.rc',
948 947 'dummycert.pem']}
949 948
950 949 def ordinarypath(p):
951 950 return p and p[0] != '.' and p[-1] != '~'
952 951
953 952 for root in ('templates',):
954 953 for curdir, dirs, files in os.walk(os.path.join('mercurial', root)):
955 954 curdir = curdir.split(os.sep, 1)[1]
956 955 dirs[:] = filter(ordinarypath, dirs)
957 956 for f in filter(ordinarypath, files):
958 957 f = os.path.join(curdir, f)
959 958 packagedata['mercurial'].append(f)
960 959
961 960 datafiles = []
962 961
963 962 # distutils expects version to be str/unicode. Converting it to
964 963 # unicode on Python 2 still works because it won't contain any
965 964 # non-ascii bytes and will be implicitly converted back to bytes
966 965 # when operated on.
967 966 assert isinstance(version, bytes)
968 967 setupversion = version.decode('ascii')
969 968
970 969 extra = {}
971 970
972 971 if issetuptools:
973 972 extra['python_requires'] = supportedpy
974 973 if py2exeloaded:
975 974 extra['console'] = [
976 975 {'script':'hg',
977 976 'copyright':'Copyright (C) 2005-2018 Matt Mackall and others',
978 977 'product_version':version}]
979 978 # sub command of 'build' because 'py2exe' does not handle sub_commands
980 979 build.sub_commands.insert(0, ('build_hgextindex', None))
981 980 # put dlls in sub directory so that they won't pollute PATH
982 981 extra['zipfile'] = 'lib/library.zip'
983 982
984 983 if os.name == 'nt':
985 984 # Windows binary file versions for exe/dll files must have the
986 985 # form W.X.Y.Z, where W,X,Y,Z are numbers in the range 0..65535
987 986 setupversion = version.split('+', 1)[0]
988 987
989 988 if sys.platform == 'darwin' and os.path.exists('/usr/bin/xcodebuild'):
990 989 version = runcmd(['/usr/bin/xcodebuild', '-version'], {})[1].splitlines()
991 990 if version:
992 991 version = version[0]
993 992 if sys.version_info[0] == 3:
994 993 version = version.decode('utf-8')
995 994 xcode4 = (version.startswith('Xcode') and
996 995 StrictVersion(version.split()[1]) >= StrictVersion('4.0'))
997 996 xcode51 = re.match(r'^Xcode\s+5\.1', version) is not None
998 997 else:
999 998 # xcodebuild returns empty on OS X Lion with XCode 4.3 not
1000 999 # installed, but instead with only command-line tools. Assume
1001 1000 # that only happens on >= Lion, thus no PPC support.
1002 1001 xcode4 = True
1003 1002 xcode51 = False
1004 1003
1005 1004 # XCode 4.0 dropped support for ppc architecture, which is hardcoded in
1006 1005 # distutils.sysconfig
1007 1006 if xcode4:
1008 1007 os.environ['ARCHFLAGS'] = ''
1009 1008
1010 1009 # XCode 5.1 changes clang such that it now fails to compile if the
1011 1010 # -mno-fused-madd flag is passed, but the version of Python shipped with
1012 1011 # OS X 10.9 Mavericks includes this flag. This causes problems in all
1013 1012 # C extension modules, and a bug has been filed upstream at
1014 1013 # http://bugs.python.org/issue21244. We also need to patch this here
1015 1014 # so Mercurial can continue to compile in the meantime.
1016 1015 if xcode51:
1017 1016 cflags = get_config_var('CFLAGS')
1018 1017 if cflags and re.search(r'-mno-fused-madd\b', cflags) is not None:
1019 1018 os.environ['CFLAGS'] = (
1020 1019 os.environ.get('CFLAGS', '') + ' -Qunused-arguments')
1021 1020
1022 1021 setup(name='mercurial',
1023 1022 version=setupversion,
1024 1023 author='Matt Mackall and many others',
1025 1024 author_email='mercurial@mercurial-scm.org',
1026 1025 url='https://mercurial-scm.org/',
1027 1026 download_url='https://mercurial-scm.org/release/',
1028 1027 description=('Fast scalable distributed SCM (revision control, version '
1029 1028 'control) system'),
1030 1029 long_description=('Mercurial is a distributed SCM tool written in Python.'
1031 1030 ' It is used by a number of large projects that require'
1032 1031 ' fast, reliable distributed revision control, such as '
1033 1032 'Mozilla.'),
1034 1033 license='GNU GPLv2 or any later version',
1035 1034 classifiers=[
1036 1035 'Development Status :: 6 - Mature',
1037 1036 'Environment :: Console',
1038 1037 'Intended Audience :: Developers',
1039 1038 'Intended Audience :: System Administrators',
1040 1039 'License :: OSI Approved :: GNU General Public License (GPL)',
1041 1040 'Natural Language :: Danish',
1042 1041 'Natural Language :: English',
1043 1042 'Natural Language :: German',
1044 1043 'Natural Language :: Italian',
1045 1044 'Natural Language :: Japanese',
1046 1045 'Natural Language :: Portuguese (Brazilian)',
1047 1046 'Operating System :: Microsoft :: Windows',
1048 1047 'Operating System :: OS Independent',
1049 1048 'Operating System :: POSIX',
1050 1049 'Programming Language :: C',
1051 1050 'Programming Language :: Python',
1052 1051 'Topic :: Software Development :: Version Control',
1053 1052 ],
1054 1053 scripts=scripts,
1055 1054 packages=packages,
1056 1055 ext_modules=extmodules,
1057 1056 data_files=datafiles,
1058 1057 package_data=packagedata,
1059 1058 cmdclass=cmdclass,
1060 1059 distclass=hgdist,
1061 1060 options={'py2exe': {'packages': ['hgdemandimport', 'hgext', 'email',
1062 1061 # implicitly imported per module policy
1063 1062 # (cffi wouldn't be used as a frozen exe)
1064 1063 'mercurial.cext',
1065 1064 #'mercurial.cffi',
1066 1065 'mercurial.pure']},
1067 1066 'bdist_mpkg': {'zipdist': False,
1068 1067 'license': 'COPYING',
1069 1068 'readme': 'contrib/macosx/Readme.html',
1070 1069 'welcome': 'contrib/macosx/Welcome.html',
1071 1070 },
1072 1071 },
1073 1072 **extra)
1 NO CONTENT: file was removed
This diff has been collapsed as it changes many lines, (686 lines changed) Show them Hide them
General Comments 0
You need to be logged in to leave comments. Login now