##// END OF EJS Templates
osx: create dmg with installer instead of zip...
Mads Kiilerich -
r22358:198e2da3 default
parent child Browse files
Show More
@@ -1,168 +1,169 b''
1 # If you want to change PREFIX, do not just edit it below. The changed
1 # If you want to change PREFIX, do not just edit it below. The changed
2 # value wont get passed on to recursive make calls. You should instead
2 # value wont get passed on to recursive make calls. You should instead
3 # override the variable on the command like:
3 # override the variable on the command like:
4 #
4 #
5 # % make PREFIX=/opt/ install
5 # % make PREFIX=/opt/ install
6
6
7 PREFIX=/usr/local
7 PREFIX=/usr/local
8 export PREFIX
8 export PREFIX
9 PYTHON=python
9 PYTHON=python
10 PURE=
10 PURE=
11 PYFILES:=$(shell find mercurial hgext doc -name '*.py')
11 PYFILES:=$(shell find mercurial hgext doc -name '*.py')
12 DOCFILES=mercurial/help/*.txt
12 DOCFILES=mercurial/help/*.txt
13 export LANGUAGE=C
13 export LANGUAGE=C
14 export LC_ALL=C
14 export LC_ALL=C
15
15
16 # Set this to e.g. "mingw32" to use a non-default compiler.
16 # Set this to e.g. "mingw32" to use a non-default compiler.
17 COMPILER=
17 COMPILER=
18
18
19 help:
19 help:
20 @echo 'Commonly used make targets:'
20 @echo 'Commonly used make targets:'
21 @echo ' all - build program and documentation'
21 @echo ' all - build program and documentation'
22 @echo ' install - install program and man pages to $$PREFIX ($(PREFIX))'
22 @echo ' install - install program and man pages to $$PREFIX ($(PREFIX))'
23 @echo ' install-home - install with setup.py install --home=$$HOME ($(HOME))'
23 @echo ' install-home - install with setup.py install --home=$$HOME ($(HOME))'
24 @echo ' local - build for inplace usage'
24 @echo ' local - build for inplace usage'
25 @echo ' tests - run all tests in the automatic test suite'
25 @echo ' tests - run all tests in the automatic test suite'
26 @echo ' test-foo - run only specified tests (e.g. test-merge1.t)'
26 @echo ' test-foo - run only specified tests (e.g. test-merge1.t)'
27 @echo ' dist - run all tests and create a source tarball in dist/'
27 @echo ' dist - run all tests and create a source tarball in dist/'
28 @echo ' clean - remove files created by other targets'
28 @echo ' clean - remove files created by other targets'
29 @echo ' (except installed files or dist source tarball)'
29 @echo ' (except installed files or dist source tarball)'
30 @echo ' update-pot - update i18n/hg.pot'
30 @echo ' update-pot - update i18n/hg.pot'
31 @echo
31 @echo
32 @echo 'Example for a system-wide installation under /usr/local:'
32 @echo 'Example for a system-wide installation under /usr/local:'
33 @echo ' make all && su -c "make install" && hg version'
33 @echo ' make all && su -c "make install" && hg version'
34 @echo
34 @echo
35 @echo 'Example for a local installation (usable in this directory):'
35 @echo 'Example for a local installation (usable in this directory):'
36 @echo ' make local && ./hg version'
36 @echo ' make local && ./hg version'
37
37
38 all: build doc
38 all: build doc
39
39
40 local:
40 local:
41 $(PYTHON) setup.py $(PURE) \
41 $(PYTHON) setup.py $(PURE) \
42 build_py -c -d . \
42 build_py -c -d . \
43 build_ext $(COMPILER:%=-c %) -i \
43 build_ext $(COMPILER:%=-c %) -i \
44 build_hgexe $(COMPILER:%=-c %) -i \
44 build_hgexe $(COMPILER:%=-c %) -i \
45 build_mo
45 build_mo
46 env HGRCPATH= $(PYTHON) hg version
46 env HGRCPATH= $(PYTHON) hg version
47
47
48 build:
48 build:
49 $(PYTHON) setup.py $(PURE) build $(COMPILER:%=-c %)
49 $(PYTHON) setup.py $(PURE) build $(COMPILER:%=-c %)
50
50
51 doc:
51 doc:
52 $(MAKE) -C doc
52 $(MAKE) -C doc
53
53
54 clean:
54 clean:
55 -$(PYTHON) setup.py clean --all # ignore errors from this command
55 -$(PYTHON) setup.py clean --all # ignore errors from this command
56 find contrib doc hgext i18n mercurial tests \
56 find contrib doc hgext i18n mercurial tests \
57 \( -name '*.py[cdo]' -o -name '*.so' \) -exec rm -f '{}' ';'
57 \( -name '*.py[cdo]' -o -name '*.so' \) -exec rm -f '{}' ';'
58 rm -f $(addprefix mercurial/,$(notdir $(wildcard mercurial/pure/[a-z]*.py)))
58 rm -f $(addprefix mercurial/,$(notdir $(wildcard mercurial/pure/[a-z]*.py)))
59 rm -f MANIFEST MANIFEST.in mercurial/__version__.py hgext/__index__.py tests/*.err
59 rm -f MANIFEST MANIFEST.in mercurial/__version__.py hgext/__index__.py tests/*.err
60 rm -rf build mercurial/locale
60 rm -rf build mercurial/locale
61 $(MAKE) -C doc clean
61 $(MAKE) -C doc clean
62
62
63 install: install-bin install-doc
63 install: install-bin install-doc
64
64
65 install-bin: build
65 install-bin: build
66 $(PYTHON) setup.py $(PURE) install --root="$(DESTDIR)/" --prefix="$(PREFIX)" --force
66 $(PYTHON) setup.py $(PURE) install --root="$(DESTDIR)/" --prefix="$(PREFIX)" --force
67
67
68 install-doc: doc
68 install-doc: doc
69 cd doc && $(MAKE) $(MFLAGS) install
69 cd doc && $(MAKE) $(MFLAGS) install
70
70
71 install-home: install-home-bin install-home-doc
71 install-home: install-home-bin install-home-doc
72
72
73 install-home-bin: build
73 install-home-bin: build
74 $(PYTHON) setup.py $(PURE) install --home="$(HOME)" --prefix="" --force
74 $(PYTHON) setup.py $(PURE) install --home="$(HOME)" --prefix="" --force
75
75
76 install-home-doc: doc
76 install-home-doc: doc
77 cd doc && $(MAKE) $(MFLAGS) PREFIX="$(HOME)" install
77 cd doc && $(MAKE) $(MFLAGS) PREFIX="$(HOME)" install
78
78
79 MANIFEST-doc:
79 MANIFEST-doc:
80 $(MAKE) -C doc MANIFEST
80 $(MAKE) -C doc MANIFEST
81
81
82 MANIFEST.in: MANIFEST-doc
82 MANIFEST.in: MANIFEST-doc
83 hg manifest | sed -e 's/^/include /' > MANIFEST.in
83 hg manifest | sed -e 's/^/include /' > MANIFEST.in
84 echo include mercurial/__version__.py >> MANIFEST.in
84 echo include mercurial/__version__.py >> MANIFEST.in
85 sed -e 's/^/include /' < doc/MANIFEST >> MANIFEST.in
85 sed -e 's/^/include /' < doc/MANIFEST >> MANIFEST.in
86
86
87 dist: tests dist-notests
87 dist: tests dist-notests
88
88
89 dist-notests: doc MANIFEST.in
89 dist-notests: doc MANIFEST.in
90 TAR_OPTIONS="--owner=root --group=root --mode=u+w,go-w,a+rX-s" $(PYTHON) setup.py -q sdist
90 TAR_OPTIONS="--owner=root --group=root --mode=u+w,go-w,a+rX-s" $(PYTHON) setup.py -q sdist
91
91
92 check: tests
92 check: tests
93
93
94 tests:
94 tests:
95 cd tests && $(PYTHON) run-tests.py $(TESTFLAGS)
95 cd tests && $(PYTHON) run-tests.py $(TESTFLAGS)
96
96
97 test-%:
97 test-%:
98 cd tests && $(PYTHON) run-tests.py $(TESTFLAGS) $@
98 cd tests && $(PYTHON) run-tests.py $(TESTFLAGS) $@
99
99
100 check-code:
100 check-code:
101 hg manifest | xargs python contrib/check-code.py
101 hg manifest | xargs python contrib/check-code.py
102
102
103 update-pot: i18n/hg.pot
103 update-pot: i18n/hg.pot
104
104
105 i18n/hg.pot: $(PYFILES) $(DOCFILES) i18n/posplit i18n/hggettext
105 i18n/hg.pot: $(PYFILES) $(DOCFILES) i18n/posplit i18n/hggettext
106 $(PYTHON) i18n/hggettext mercurial/commands.py \
106 $(PYTHON) i18n/hggettext mercurial/commands.py \
107 hgext/*.py hgext/*/__init__.py \
107 hgext/*.py hgext/*/__init__.py \
108 mercurial/fileset.py mercurial/revset.py \
108 mercurial/fileset.py mercurial/revset.py \
109 mercurial/templatefilters.py mercurial/templatekw.py \
109 mercurial/templatefilters.py mercurial/templatekw.py \
110 mercurial/filemerge.py \
110 mercurial/filemerge.py \
111 $(DOCFILES) > i18n/hg.pot.tmp
111 $(DOCFILES) > i18n/hg.pot.tmp
112 # All strings marked for translation in Mercurial contain
112 # All strings marked for translation in Mercurial contain
113 # ASCII characters only. But some files contain string
113 # ASCII characters only. But some files contain string
114 # literals like this '\037\213'. xgettext thinks it has to
114 # literals like this '\037\213'. xgettext thinks it has to
115 # parse them even though they are not marked for translation.
115 # parse them even though they are not marked for translation.
116 # Extracting with an explicit encoding of ISO-8859-1 will make
116 # Extracting with an explicit encoding of ISO-8859-1 will make
117 # xgettext "parse" and ignore them.
117 # xgettext "parse" and ignore them.
118 echo $(PYFILES) | xargs \
118 echo $(PYFILES) | xargs \
119 xgettext --package-name "Mercurial" \
119 xgettext --package-name "Mercurial" \
120 --msgid-bugs-address "<mercurial-devel@selenic.com>" \
120 --msgid-bugs-address "<mercurial-devel@selenic.com>" \
121 --copyright-holder "Matt Mackall <mpm@selenic.com> and others" \
121 --copyright-holder "Matt Mackall <mpm@selenic.com> and others" \
122 --from-code ISO-8859-1 --join --sort-by-file --add-comments=i18n: \
122 --from-code ISO-8859-1 --join --sort-by-file --add-comments=i18n: \
123 -d hg -p i18n -o hg.pot.tmp
123 -d hg -p i18n -o hg.pot.tmp
124 $(PYTHON) i18n/posplit i18n/hg.pot.tmp
124 $(PYTHON) i18n/posplit i18n/hg.pot.tmp
125 # The target file is not created before the last step. So it never is in
125 # The target file is not created before the last step. So it never is in
126 # an intermediate state.
126 # an intermediate state.
127 mv -f i18n/hg.pot.tmp i18n/hg.pot
127 mv -f i18n/hg.pot.tmp i18n/hg.pot
128
128
129 %.po: i18n/hg.pot
129 %.po: i18n/hg.pot
130 # work on a temporary copy for never having a half completed target
130 # work on a temporary copy for never having a half completed target
131 cp $@ $@.tmp
131 cp $@ $@.tmp
132 msgmerge --no-location --update $@.tmp $^
132 msgmerge --no-location --update $@.tmp $^
133 mv -f $@.tmp $@
133 mv -f $@.tmp $@
134
134
135 # Packaging targets
135 # Packaging targets
136
136
137 osx:
137 osx:
138 @which bdist_mpkg >/dev/null || \
138 @which bdist_mpkg >/dev/null || \
139 (echo "Missing bdist_mpkg (easy_install bdist_mpkg)"; false)
139 (echo "Missing bdist_mpkg (easy_install bdist_mpkg)"; false)
140 rm -rf dist/mercurial-*.mpkg
140 bdist_mpkg setup.py
141 bdist_mpkg setup.py
141 mkdir -p packages/osx
142 mkdir -p packages/osx
143 N=`cd dist && echo mercurial-*.mpkg | sed 's,\.mpkg$$,,'` && hdiutil create -srcfolder dist/$$N.mpkg/ -scrub -volname "$$N" -ov packages/osx/$$N.dmg
142 rm -rf dist/mercurial-*.mpkg
144 rm -rf dist/mercurial-*.mpkg
143 mv dist/mercurial*macosx*.zip packages/osx
144
145
145 fedora:
146 fedora:
146 mkdir -p packages/fedora
147 mkdir -p packages/fedora
147 contrib/buildrpm
148 contrib/buildrpm
148 cp rpmbuild/RPMS/*/* packages/fedora
149 cp rpmbuild/RPMS/*/* packages/fedora
149 cp rpmbuild/SRPMS/* packages/fedora
150 cp rpmbuild/SRPMS/* packages/fedora
150 rm -rf rpmbuild
151 rm -rf rpmbuild
151
152
152 docker-fedora:
153 docker-fedora:
153 mkdir -p packages/fedora
154 mkdir -p packages/fedora
154 contrib/dockerrpm fedora
155 contrib/dockerrpm fedora
155
156
156 centos6:
157 centos6:
157 mkdir -p packages/centos6
158 mkdir -p packages/centos6
158 contrib/buildrpm
159 contrib/buildrpm
159 cp rpmbuild/RPMS/*/* packages/centos6
160 cp rpmbuild/RPMS/*/* packages/centos6
160 cp rpmbuild/SRPMS/* packages/centos6
161 cp rpmbuild/SRPMS/* packages/centos6
161
162
162 docker-centos6:
163 docker-centos6:
163 mkdir -p packages/centos6
164 mkdir -p packages/centos6
164 contrib/dockerrpm centos6
165 contrib/dockerrpm centos6
165
166
166 .PHONY: help all local build doc clean install install-bin install-doc \
167 .PHONY: help all local build doc clean install install-bin install-doc \
167 install-home install-home-bin install-home-doc dist dist-notests tests \
168 install-home install-home-bin install-home-doc dist dist-notests tests \
168 update-pot fedora docker-fedora
169 update-pot fedora docker-fedora
@@ -1,592 +1,592 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 printf = eval('print')
16 printf = eval('print')
17 libdir_escape = 'unicode_escape'
17 libdir_escape = 'unicode_escape'
18 else:
18 else:
19 libdir_escape = 'string_escape'
19 libdir_escape = 'string_escape'
20 def b(s):
20 def b(s):
21 '''A helper function to emulate 2.6+ bytes literals using string
21 '''A helper function to emulate 2.6+ bytes literals using string
22 literals.'''
22 literals.'''
23 return s
23 return s
24 def printf(*args, **kwargs):
24 def printf(*args, **kwargs):
25 f = kwargs.get('file', sys.stdout)
25 f = kwargs.get('file', sys.stdout)
26 end = kwargs.get('end', '\n')
26 end = kwargs.get('end', '\n')
27 f.write(b(' ').join(args) + end)
27 f.write(b(' ').join(args) + end)
28
28
29 # Solaris Python packaging brain damage
29 # Solaris Python packaging brain damage
30 try:
30 try:
31 import hashlib
31 import hashlib
32 sha = hashlib.sha1()
32 sha = hashlib.sha1()
33 except ImportError:
33 except ImportError:
34 try:
34 try:
35 import sha
35 import sha
36 sha.sha # silence unused import warning
36 sha.sha # silence unused import warning
37 except ImportError:
37 except ImportError:
38 raise SystemExit(
38 raise SystemExit(
39 "Couldn't import standard hashlib (incomplete Python install).")
39 "Couldn't import standard hashlib (incomplete Python install).")
40
40
41 try:
41 try:
42 import zlib
42 import zlib
43 zlib.compressobj # silence unused import warning
43 zlib.compressobj # silence unused import warning
44 except ImportError:
44 except ImportError:
45 raise SystemExit(
45 raise SystemExit(
46 "Couldn't import standard zlib (incomplete Python install).")
46 "Couldn't import standard zlib (incomplete Python install).")
47
47
48 # The base IronPython distribution (as of 2.7.1) doesn't support bz2
48 # The base IronPython distribution (as of 2.7.1) doesn't support bz2
49 isironpython = False
49 isironpython = False
50 try:
50 try:
51 isironpython = (platform.python_implementation()
51 isironpython = (platform.python_implementation()
52 .lower().find("ironpython") != -1)
52 .lower().find("ironpython") != -1)
53 except AttributeError:
53 except AttributeError:
54 pass
54 pass
55
55
56 if isironpython:
56 if isironpython:
57 sys.stderr.write("warning: IronPython detected (no bz2 support)\n")
57 sys.stderr.write("warning: IronPython detected (no bz2 support)\n")
58 else:
58 else:
59 try:
59 try:
60 import bz2
60 import bz2
61 bz2.BZ2Compressor # silence unused import warning
61 bz2.BZ2Compressor # silence unused import warning
62 except ImportError:
62 except ImportError:
63 raise SystemExit(
63 raise SystemExit(
64 "Couldn't import standard bz2 (incomplete Python install).")
64 "Couldn't import standard bz2 (incomplete Python install).")
65
65
66 import os, subprocess, time
66 import os, subprocess, time
67 import re
67 import re
68 import shutil
68 import shutil
69 import tempfile
69 import tempfile
70 from distutils import log
70 from distutils import log
71 from distutils.core import setup, Command, Extension
71 from distutils.core import setup, Command, Extension
72 from distutils.dist import Distribution
72 from distutils.dist import Distribution
73 from distutils.command.build import build
73 from distutils.command.build import build
74 from distutils.command.build_ext import build_ext
74 from distutils.command.build_ext import build_ext
75 from distutils.command.build_py import build_py
75 from distutils.command.build_py import build_py
76 from distutils.command.install_scripts import install_scripts
76 from distutils.command.install_scripts import install_scripts
77 from distutils.spawn import spawn, find_executable
77 from distutils.spawn import spawn, find_executable
78 from distutils import cygwinccompiler
78 from distutils import cygwinccompiler
79 from distutils.errors import CCompilerError, DistutilsExecError
79 from distutils.errors import CCompilerError, DistutilsExecError
80 from distutils.sysconfig import get_python_inc, get_config_var
80 from distutils.sysconfig import get_python_inc, get_config_var
81 from distutils.version import StrictVersion
81 from distutils.version import StrictVersion
82
82
83 convert2to3 = '--c2to3' in sys.argv
83 convert2to3 = '--c2to3' in sys.argv
84 if convert2to3:
84 if convert2to3:
85 try:
85 try:
86 from distutils.command.build_py import build_py_2to3 as build_py
86 from distutils.command.build_py import build_py_2to3 as build_py
87 from lib2to3.refactor import get_fixers_from_package as getfixers
87 from lib2to3.refactor import get_fixers_from_package as getfixers
88 except ImportError:
88 except ImportError:
89 if sys.version_info[0] < 3:
89 if sys.version_info[0] < 3:
90 raise SystemExit("--c2to3 is only compatible with python3.")
90 raise SystemExit("--c2to3 is only compatible with python3.")
91 raise
91 raise
92 sys.path.append('contrib')
92 sys.path.append('contrib')
93 elif sys.version_info[0] >= 3:
93 elif sys.version_info[0] >= 3:
94 raise SystemExit("setup.py with python3 needs --c2to3 (experimental)")
94 raise SystemExit("setup.py with python3 needs --c2to3 (experimental)")
95
95
96 scripts = ['hg']
96 scripts = ['hg']
97 if os.name == 'nt':
97 if os.name == 'nt':
98 scripts.append('contrib/win32/hg.bat')
98 scripts.append('contrib/win32/hg.bat')
99
99
100 # simplified version of distutils.ccompiler.CCompiler.has_function
100 # simplified version of distutils.ccompiler.CCompiler.has_function
101 # that actually removes its temporary files.
101 # that actually removes its temporary files.
102 def hasfunction(cc, funcname):
102 def hasfunction(cc, funcname):
103 tmpdir = tempfile.mkdtemp(prefix='hg-install-')
103 tmpdir = tempfile.mkdtemp(prefix='hg-install-')
104 devnull = oldstderr = None
104 devnull = oldstderr = None
105 try:
105 try:
106 try:
106 try:
107 fname = os.path.join(tmpdir, 'funcname.c')
107 fname = os.path.join(tmpdir, 'funcname.c')
108 f = open(fname, 'w')
108 f = open(fname, 'w')
109 f.write('int main(void) {\n')
109 f.write('int main(void) {\n')
110 f.write(' %s();\n' % funcname)
110 f.write(' %s();\n' % funcname)
111 f.write('}\n')
111 f.write('}\n')
112 f.close()
112 f.close()
113 # Redirect stderr to /dev/null to hide any error messages
113 # Redirect stderr to /dev/null to hide any error messages
114 # from the compiler.
114 # from the compiler.
115 # This will have to be changed if we ever have to check
115 # This will have to be changed if we ever have to check
116 # for a function on Windows.
116 # for a function on Windows.
117 devnull = open('/dev/null', 'w')
117 devnull = open('/dev/null', 'w')
118 oldstderr = os.dup(sys.stderr.fileno())
118 oldstderr = os.dup(sys.stderr.fileno())
119 os.dup2(devnull.fileno(), sys.stderr.fileno())
119 os.dup2(devnull.fileno(), sys.stderr.fileno())
120 objects = cc.compile([fname], output_dir=tmpdir)
120 objects = cc.compile([fname], output_dir=tmpdir)
121 cc.link_executable(objects, os.path.join(tmpdir, "a.out"))
121 cc.link_executable(objects, os.path.join(tmpdir, "a.out"))
122 except Exception:
122 except Exception:
123 return False
123 return False
124 return True
124 return True
125 finally:
125 finally:
126 if oldstderr is not None:
126 if oldstderr is not None:
127 os.dup2(oldstderr, sys.stderr.fileno())
127 os.dup2(oldstderr, sys.stderr.fileno())
128 if devnull is not None:
128 if devnull is not None:
129 devnull.close()
129 devnull.close()
130 shutil.rmtree(tmpdir)
130 shutil.rmtree(tmpdir)
131
131
132 # py2exe needs to be installed to work
132 # py2exe needs to be installed to work
133 try:
133 try:
134 import py2exe
134 import py2exe
135 py2exe.Distribution # silence unused import warning
135 py2exe.Distribution # silence unused import warning
136 py2exeloaded = True
136 py2exeloaded = True
137 # import py2exe's patched Distribution class
137 # import py2exe's patched Distribution class
138 from distutils.core import Distribution
138 from distutils.core import Distribution
139 except ImportError:
139 except ImportError:
140 py2exeloaded = False
140 py2exeloaded = False
141
141
142 def runcmd(cmd, env):
142 def runcmd(cmd, env):
143 if sys.platform == 'plan9':
143 if sys.platform == 'plan9':
144 # subprocess kludge to work around issues in half-baked Python
144 # subprocess kludge to work around issues in half-baked Python
145 # ports, notably bichued/python:
145 # ports, notably bichued/python:
146 _, out, err = os.popen3(cmd)
146 _, out, err = os.popen3(cmd)
147 return str(out), str(err)
147 return str(out), str(err)
148 else:
148 else:
149 p = subprocess.Popen(cmd, stdout=subprocess.PIPE,
149 p = subprocess.Popen(cmd, stdout=subprocess.PIPE,
150 stderr=subprocess.PIPE, env=env)
150 stderr=subprocess.PIPE, env=env)
151 out, err = p.communicate()
151 out, err = p.communicate()
152 return out, err
152 return out, err
153
153
154 def runhg(cmd, env):
154 def runhg(cmd, env):
155 out, err = runcmd(cmd, env)
155 out, err = runcmd(cmd, env)
156 # If root is executing setup.py, but the repository is owned by
156 # If root is executing setup.py, but the repository is owned by
157 # another user (as in "sudo python setup.py install") we will get
157 # another user (as in "sudo python setup.py install") we will get
158 # trust warnings since the .hg/hgrc file is untrusted. That is
158 # trust warnings since the .hg/hgrc file is untrusted. That is
159 # fine, we don't want to load it anyway. Python may warn about
159 # fine, we don't want to load it anyway. Python may warn about
160 # a missing __init__.py in mercurial/locale, we also ignore that.
160 # a missing __init__.py in mercurial/locale, we also ignore that.
161 err = [e for e in err.splitlines()
161 err = [e for e in err.splitlines()
162 if not e.startswith(b('not trusting file')) \
162 if not e.startswith(b('not trusting file')) \
163 and not e.startswith(b('warning: Not importing')) \
163 and not e.startswith(b('warning: Not importing')) \
164 and not e.startswith(b('obsolete feature not enabled'))]
164 and not e.startswith(b('obsolete feature not enabled'))]
165 if err:
165 if err:
166 printf("stderr from '%s':" % (' '.join(cmd)), file=sys.stderr)
166 printf("stderr from '%s':" % (' '.join(cmd)), file=sys.stderr)
167 printf(b('\n').join([b(' ') + e for e in err]), file=sys.stderr)
167 printf(b('\n').join([b(' ') + e for e in err]), file=sys.stderr)
168 return ''
168 return ''
169 return out
169 return out
170
170
171 version = ''
171 version = ''
172
172
173 # Execute hg out of this directory with a custom environment which
173 # Execute hg out of this directory with a custom environment which
174 # includes the pure Python modules in mercurial/pure. We also take
174 # includes the pure Python modules in mercurial/pure. We also take
175 # care to not use any hgrc files and do no localization.
175 # care to not use any hgrc files and do no localization.
176 pypath = ['mercurial', os.path.join('mercurial', 'pure')]
176 pypath = ['mercurial', os.path.join('mercurial', 'pure')]
177 env = {'PYTHONPATH': os.pathsep.join(pypath),
177 env = {'PYTHONPATH': os.pathsep.join(pypath),
178 'HGRCPATH': '',
178 'HGRCPATH': '',
179 'LANGUAGE': 'C'}
179 'LANGUAGE': 'C'}
180 if 'LD_LIBRARY_PATH' in os.environ:
180 if 'LD_LIBRARY_PATH' in os.environ:
181 env['LD_LIBRARY_PATH'] = os.environ['LD_LIBRARY_PATH']
181 env['LD_LIBRARY_PATH'] = os.environ['LD_LIBRARY_PATH']
182 if 'SystemRoot' in os.environ:
182 if 'SystemRoot' in os.environ:
183 # Copy SystemRoot into the custom environment for Python 2.6
183 # Copy SystemRoot into the custom environment for Python 2.6
184 # under Windows. Otherwise, the subprocess will fail with
184 # under Windows. Otherwise, the subprocess will fail with
185 # error 0xc0150004. See: http://bugs.python.org/issue3440
185 # error 0xc0150004. See: http://bugs.python.org/issue3440
186 env['SystemRoot'] = os.environ['SystemRoot']
186 env['SystemRoot'] = os.environ['SystemRoot']
187
187
188 if os.path.isdir('.hg'):
188 if os.path.isdir('.hg'):
189 cmd = [sys.executable, 'hg', 'log', '-r', '.', '--template', '{tags}\n']
189 cmd = [sys.executable, 'hg', 'log', '-r', '.', '--template', '{tags}\n']
190 numerictags = [t for t in runhg(cmd, env).split() if t[0].isdigit()]
190 numerictags = [t for t in runhg(cmd, env).split() if t[0].isdigit()]
191 hgid = runhg([sys.executable, 'hg', 'id', '-i'], env).strip()
191 hgid = runhg([sys.executable, 'hg', 'id', '-i'], env).strip()
192 if numerictags: # tag(s) found
192 if numerictags: # tag(s) found
193 version = numerictags[-1]
193 version = numerictags[-1]
194 if hgid.endswith('+'): # propagate the dirty status to the tag
194 if hgid.endswith('+'): # propagate the dirty status to the tag
195 version += '+'
195 version += '+'
196 else: # no tag found
196 else: # no tag found
197 cmd = [sys.executable, 'hg', 'parents', '--template',
197 cmd = [sys.executable, 'hg', 'parents', '--template',
198 '{latesttag}+{latesttagdistance}-']
198 '{latesttag}+{latesttagdistance}-']
199 version = runhg(cmd, env) + hgid
199 version = runhg(cmd, env) + hgid
200 if version.endswith('+'):
200 if version.endswith('+'):
201 version += time.strftime('%Y%m%d')
201 version += time.strftime('%Y%m%d')
202 elif os.path.exists('.hg_archival.txt'):
202 elif os.path.exists('.hg_archival.txt'):
203 kw = dict([[t.strip() for t in l.split(':', 1)]
203 kw = dict([[t.strip() for t in l.split(':', 1)]
204 for l in open('.hg_archival.txt')])
204 for l in open('.hg_archival.txt')])
205 if 'tag' in kw:
205 if 'tag' in kw:
206 version = kw['tag']
206 version = kw['tag']
207 elif 'latesttag' in kw:
207 elif 'latesttag' in kw:
208 version = '%(latesttag)s+%(latesttagdistance)s-%(node).12s' % kw
208 version = '%(latesttag)s+%(latesttagdistance)s-%(node).12s' % kw
209 else:
209 else:
210 version = kw.get('node', '')[:12]
210 version = kw.get('node', '')[:12]
211
211
212 if version:
212 if version:
213 f = open("mercurial/__version__.py", "w")
213 f = open("mercurial/__version__.py", "w")
214 f.write('# this file is autogenerated by setup.py\n')
214 f.write('# this file is autogenerated by setup.py\n')
215 f.write('version = "%s"\n' % version)
215 f.write('version = "%s"\n' % version)
216 f.close()
216 f.close()
217
217
218
218
219 try:
219 try:
220 from mercurial import __version__
220 from mercurial import __version__
221 version = __version__.version
221 version = __version__.version
222 except ImportError:
222 except ImportError:
223 version = 'unknown'
223 version = 'unknown'
224
224
225 class hgbuild(build):
225 class hgbuild(build):
226 # Insert hgbuildmo first so that files in mercurial/locale/ are found
226 # Insert hgbuildmo first so that files in mercurial/locale/ are found
227 # when build_py is run next.
227 # when build_py is run next.
228 sub_commands = [('build_mo', None),
228 sub_commands = [('build_mo', None),
229
229
230 # We also need build_ext before build_py. Otherwise, when 2to3 is
230 # We also need build_ext before build_py. Otherwise, when 2to3 is
231 # called (in build_py), it will not find osutil & friends,
231 # called (in build_py), it will not find osutil & friends,
232 # thinking that those modules are global and, consequently, making
232 # thinking that those modules are global and, consequently, making
233 # a mess, now that all module imports are global.
233 # a mess, now that all module imports are global.
234
234
235 ('build_ext', build.has_ext_modules),
235 ('build_ext', build.has_ext_modules),
236 ] + build.sub_commands
236 ] + build.sub_commands
237
237
238 class hgbuildmo(build):
238 class hgbuildmo(build):
239
239
240 description = "build translations (.mo files)"
240 description = "build translations (.mo files)"
241
241
242 def run(self):
242 def run(self):
243 if not find_executable('msgfmt'):
243 if not find_executable('msgfmt'):
244 self.warn("could not find msgfmt executable, no translations "
244 self.warn("could not find msgfmt executable, no translations "
245 "will be built")
245 "will be built")
246 return
246 return
247
247
248 podir = 'i18n'
248 podir = 'i18n'
249 if not os.path.isdir(podir):
249 if not os.path.isdir(podir):
250 self.warn("could not find %s/ directory" % podir)
250 self.warn("could not find %s/ directory" % podir)
251 return
251 return
252
252
253 join = os.path.join
253 join = os.path.join
254 for po in os.listdir(podir):
254 for po in os.listdir(podir):
255 if not po.endswith('.po'):
255 if not po.endswith('.po'):
256 continue
256 continue
257 pofile = join(podir, po)
257 pofile = join(podir, po)
258 modir = join('locale', po[:-3], 'LC_MESSAGES')
258 modir = join('locale', po[:-3], 'LC_MESSAGES')
259 mofile = join(modir, 'hg.mo')
259 mofile = join(modir, 'hg.mo')
260 mobuildfile = join('mercurial', mofile)
260 mobuildfile = join('mercurial', mofile)
261 cmd = ['msgfmt', '-v', '-o', mobuildfile, pofile]
261 cmd = ['msgfmt', '-v', '-o', mobuildfile, pofile]
262 if sys.platform != 'sunos5':
262 if sys.platform != 'sunos5':
263 # msgfmt on Solaris does not know about -c
263 # msgfmt on Solaris does not know about -c
264 cmd.append('-c')
264 cmd.append('-c')
265 self.mkpath(join('mercurial', modir))
265 self.mkpath(join('mercurial', modir))
266 self.make_file([pofile], mobuildfile, spawn, (cmd,))
266 self.make_file([pofile], mobuildfile, spawn, (cmd,))
267
267
268
268
269 class hgdist(Distribution):
269 class hgdist(Distribution):
270 pure = 0
270 pure = 0
271
271
272 global_options = Distribution.global_options + \
272 global_options = Distribution.global_options + \
273 [('pure', None, "use pure (slow) Python "
273 [('pure', None, "use pure (slow) Python "
274 "code instead of C extensions"),
274 "code instead of C extensions"),
275 ('c2to3', None, "(experimental!) convert "
275 ('c2to3', None, "(experimental!) convert "
276 "code with 2to3"),
276 "code with 2to3"),
277 ]
277 ]
278
278
279 def has_ext_modules(self):
279 def has_ext_modules(self):
280 # self.ext_modules is emptied in hgbuildpy.finalize_options which is
280 # self.ext_modules is emptied in hgbuildpy.finalize_options which is
281 # too late for some cases
281 # too late for some cases
282 return not self.pure and Distribution.has_ext_modules(self)
282 return not self.pure and Distribution.has_ext_modules(self)
283
283
284 class hgbuildext(build_ext):
284 class hgbuildext(build_ext):
285
285
286 def build_extension(self, ext):
286 def build_extension(self, ext):
287 try:
287 try:
288 build_ext.build_extension(self, ext)
288 build_ext.build_extension(self, ext)
289 except CCompilerError:
289 except CCompilerError:
290 if not getattr(ext, 'optional', False):
290 if not getattr(ext, 'optional', False):
291 raise
291 raise
292 log.warn("Failed to build optional extension '%s' (skipping)",
292 log.warn("Failed to build optional extension '%s' (skipping)",
293 ext.name)
293 ext.name)
294
294
295 class hgbuildpy(build_py):
295 class hgbuildpy(build_py):
296 if convert2to3:
296 if convert2to3:
297 fixer_names = sorted(set(getfixers("lib2to3.fixes") +
297 fixer_names = sorted(set(getfixers("lib2to3.fixes") +
298 getfixers("hgfixes")))
298 getfixers("hgfixes")))
299
299
300 def finalize_options(self):
300 def finalize_options(self):
301 build_py.finalize_options(self)
301 build_py.finalize_options(self)
302
302
303 if self.distribution.pure:
303 if self.distribution.pure:
304 if self.py_modules is None:
304 if self.py_modules is None:
305 self.py_modules = []
305 self.py_modules = []
306 for ext in self.distribution.ext_modules:
306 for ext in self.distribution.ext_modules:
307 if ext.name.startswith("mercurial."):
307 if ext.name.startswith("mercurial."):
308 self.py_modules.append("mercurial.pure.%s" % ext.name[10:])
308 self.py_modules.append("mercurial.pure.%s" % ext.name[10:])
309 self.distribution.ext_modules = []
309 self.distribution.ext_modules = []
310 else:
310 else:
311 h = os.path.join(get_python_inc(), 'Python.h')
311 h = os.path.join(get_python_inc(), 'Python.h')
312 if not os.path.exists(h):
312 if not os.path.exists(h):
313 raise SystemExit('Python headers are required to build '
313 raise SystemExit('Python headers are required to build '
314 'Mercurial but weren\'t found in %s' % h)
314 'Mercurial but weren\'t found in %s' % h)
315
315
316 def find_modules(self):
316 def find_modules(self):
317 modules = build_py.find_modules(self)
317 modules = build_py.find_modules(self)
318 for module in modules:
318 for module in modules:
319 if module[0] == "mercurial.pure":
319 if module[0] == "mercurial.pure":
320 if module[1] != "__init__":
320 if module[1] != "__init__":
321 yield ("mercurial", module[1], module[2])
321 yield ("mercurial", module[1], module[2])
322 else:
322 else:
323 yield module
323 yield module
324
324
325 class buildhgextindex(Command):
325 class buildhgextindex(Command):
326 description = 'generate prebuilt index of hgext (for frozen package)'
326 description = 'generate prebuilt index of hgext (for frozen package)'
327 user_options = []
327 user_options = []
328 _indexfilename = 'hgext/__index__.py'
328 _indexfilename = 'hgext/__index__.py'
329
329
330 def initialize_options(self):
330 def initialize_options(self):
331 pass
331 pass
332
332
333 def finalize_options(self):
333 def finalize_options(self):
334 pass
334 pass
335
335
336 def run(self):
336 def run(self):
337 if os.path.exists(self._indexfilename):
337 if os.path.exists(self._indexfilename):
338 f = open(self._indexfilename, 'w')
338 f = open(self._indexfilename, 'w')
339 f.write('# empty\n')
339 f.write('# empty\n')
340 f.close()
340 f.close()
341
341
342 # here no extension enabled, disabled() lists up everything
342 # here no extension enabled, disabled() lists up everything
343 code = ('import pprint; from mercurial import extensions; '
343 code = ('import pprint; from mercurial import extensions; '
344 'pprint.pprint(extensions.disabled())')
344 'pprint.pprint(extensions.disabled())')
345 out, err = runcmd([sys.executable, '-c', code], env)
345 out, err = runcmd([sys.executable, '-c', code], env)
346 if err:
346 if err:
347 raise DistutilsExecError(err)
347 raise DistutilsExecError(err)
348
348
349 f = open(self._indexfilename, 'w')
349 f = open(self._indexfilename, 'w')
350 f.write('# this file is autogenerated by setup.py\n')
350 f.write('# this file is autogenerated by setup.py\n')
351 f.write('docs = ')
351 f.write('docs = ')
352 f.write(out)
352 f.write(out)
353 f.close()
353 f.close()
354
354
355 class buildhgexe(build_ext):
355 class buildhgexe(build_ext):
356 description = 'compile hg.exe from mercurial/exewrapper.c'
356 description = 'compile hg.exe from mercurial/exewrapper.c'
357
357
358 def build_extensions(self):
358 def build_extensions(self):
359 if os.name != 'nt':
359 if os.name != 'nt':
360 return
360 return
361 if isinstance(self.compiler, HackedMingw32CCompiler):
361 if isinstance(self.compiler, HackedMingw32CCompiler):
362 self.compiler.compiler_so = self.compiler.compiler # no -mdll
362 self.compiler.compiler_so = self.compiler.compiler # no -mdll
363 self.compiler.dll_libraries = [] # no -lmsrvc90
363 self.compiler.dll_libraries = [] # no -lmsrvc90
364 hv = sys.hexversion
364 hv = sys.hexversion
365 pythonlib = 'python%d%d' % (hv >> 24, (hv >> 16) & 0xff)
365 pythonlib = 'python%d%d' % (hv >> 24, (hv >> 16) & 0xff)
366 f = open('mercurial/hgpythonlib.h', 'wb')
366 f = open('mercurial/hgpythonlib.h', 'wb')
367 f.write('/* this file is autogenerated by setup.py */\n')
367 f.write('/* this file is autogenerated by setup.py */\n')
368 f.write('#define HGPYTHONLIB "%s"\n' % pythonlib)
368 f.write('#define HGPYTHONLIB "%s"\n' % pythonlib)
369 f.close()
369 f.close()
370 objects = self.compiler.compile(['mercurial/exewrapper.c'],
370 objects = self.compiler.compile(['mercurial/exewrapper.c'],
371 output_dir=self.build_temp)
371 output_dir=self.build_temp)
372 dir = os.path.dirname(self.get_ext_fullpath('dummy'))
372 dir = os.path.dirname(self.get_ext_fullpath('dummy'))
373 target = os.path.join(dir, 'hg')
373 target = os.path.join(dir, 'hg')
374 self.compiler.link_executable(objects, target,
374 self.compiler.link_executable(objects, target,
375 libraries=[],
375 libraries=[],
376 output_dir=self.build_temp)
376 output_dir=self.build_temp)
377
377
378 class hginstallscripts(install_scripts):
378 class hginstallscripts(install_scripts):
379 '''
379 '''
380 This is a specialization of install_scripts that replaces the @LIBDIR@ with
380 This is a specialization of install_scripts that replaces the @LIBDIR@ with
381 the configured directory for modules. If possible, the path is made relative
381 the configured directory for modules. If possible, the path is made relative
382 to the directory for scripts.
382 to the directory for scripts.
383 '''
383 '''
384
384
385 def initialize_options(self):
385 def initialize_options(self):
386 install_scripts.initialize_options(self)
386 install_scripts.initialize_options(self)
387
387
388 self.install_lib = None
388 self.install_lib = None
389
389
390 def finalize_options(self):
390 def finalize_options(self):
391 install_scripts.finalize_options(self)
391 install_scripts.finalize_options(self)
392 self.set_undefined_options('install',
392 self.set_undefined_options('install',
393 ('install_lib', 'install_lib'))
393 ('install_lib', 'install_lib'))
394
394
395 def run(self):
395 def run(self):
396 install_scripts.run(self)
396 install_scripts.run(self)
397
397
398 if (os.path.splitdrive(self.install_dir)[0] !=
398 if (os.path.splitdrive(self.install_dir)[0] !=
399 os.path.splitdrive(self.install_lib)[0]):
399 os.path.splitdrive(self.install_lib)[0]):
400 # can't make relative paths from one drive to another, so use an
400 # can't make relative paths from one drive to another, so use an
401 # absolute path instead
401 # absolute path instead
402 libdir = self.install_lib
402 libdir = self.install_lib
403 else:
403 else:
404 common = os.path.commonprefix((self.install_dir, self.install_lib))
404 common = os.path.commonprefix((self.install_dir, self.install_lib))
405 rest = self.install_dir[len(common):]
405 rest = self.install_dir[len(common):]
406 uplevel = len([n for n in os.path.split(rest) if n])
406 uplevel = len([n for n in os.path.split(rest) if n])
407
407
408 libdir = uplevel * ('..' + os.sep) + self.install_lib[len(common):]
408 libdir = uplevel * ('..' + os.sep) + self.install_lib[len(common):]
409
409
410 for outfile in self.outfiles:
410 for outfile in self.outfiles:
411 fp = open(outfile, 'rb')
411 fp = open(outfile, 'rb')
412 data = fp.read()
412 data = fp.read()
413 fp.close()
413 fp.close()
414
414
415 # skip binary files
415 # skip binary files
416 if b('\0') in data:
416 if b('\0') in data:
417 continue
417 continue
418
418
419 data = data.replace(b('@LIBDIR@'), libdir.encode(libdir_escape))
419 data = data.replace(b('@LIBDIR@'), libdir.encode(libdir_escape))
420 fp = open(outfile, 'wb')
420 fp = open(outfile, 'wb')
421 fp.write(data)
421 fp.write(data)
422 fp.close()
422 fp.close()
423
423
424 cmdclass = {'build': hgbuild,
424 cmdclass = {'build': hgbuild,
425 'build_mo': hgbuildmo,
425 'build_mo': hgbuildmo,
426 'build_ext': hgbuildext,
426 'build_ext': hgbuildext,
427 'build_py': hgbuildpy,
427 'build_py': hgbuildpy,
428 'build_hgextindex': buildhgextindex,
428 'build_hgextindex': buildhgextindex,
429 'install_scripts': hginstallscripts,
429 'install_scripts': hginstallscripts,
430 'build_hgexe': buildhgexe,
430 'build_hgexe': buildhgexe,
431 }
431 }
432
432
433 packages = ['mercurial', 'mercurial.hgweb', 'mercurial.httpclient',
433 packages = ['mercurial', 'mercurial.hgweb', 'mercurial.httpclient',
434 'hgext', 'hgext.convert', 'hgext.highlight', 'hgext.zeroconf',
434 'hgext', 'hgext.convert', 'hgext.highlight', 'hgext.zeroconf',
435 'hgext.largefiles']
435 'hgext.largefiles']
436
436
437 pymodules = []
437 pymodules = []
438
438
439 common_depends = ['mercurial/util.h']
439 common_depends = ['mercurial/util.h']
440
440
441 extmodules = [
441 extmodules = [
442 Extension('mercurial.base85', ['mercurial/base85.c'],
442 Extension('mercurial.base85', ['mercurial/base85.c'],
443 depends=common_depends),
443 depends=common_depends),
444 Extension('mercurial.bdiff', ['mercurial/bdiff.c'],
444 Extension('mercurial.bdiff', ['mercurial/bdiff.c'],
445 depends=common_depends),
445 depends=common_depends),
446 Extension('mercurial.diffhelpers', ['mercurial/diffhelpers.c'],
446 Extension('mercurial.diffhelpers', ['mercurial/diffhelpers.c'],
447 depends=common_depends),
447 depends=common_depends),
448 Extension('mercurial.mpatch', ['mercurial/mpatch.c'],
448 Extension('mercurial.mpatch', ['mercurial/mpatch.c'],
449 depends=common_depends),
449 depends=common_depends),
450 Extension('mercurial.parsers', ['mercurial/dirs.c',
450 Extension('mercurial.parsers', ['mercurial/dirs.c',
451 'mercurial/parsers.c',
451 'mercurial/parsers.c',
452 'mercurial/pathencode.c'],
452 'mercurial/pathencode.c'],
453 depends=common_depends),
453 depends=common_depends),
454 ]
454 ]
455
455
456 osutil_ldflags = []
456 osutil_ldflags = []
457
457
458 if sys.platform == 'darwin':
458 if sys.platform == 'darwin':
459 osutil_ldflags += ['-framework', 'ApplicationServices']
459 osutil_ldflags += ['-framework', 'ApplicationServices']
460
460
461 # disable osutil.c under windows + python 2.4 (issue1364)
461 # disable osutil.c under windows + python 2.4 (issue1364)
462 if sys.platform == 'win32' and sys.version_info < (2, 5, 0, 'final'):
462 if sys.platform == 'win32' and sys.version_info < (2, 5, 0, 'final'):
463 pymodules.append('mercurial.pure.osutil')
463 pymodules.append('mercurial.pure.osutil')
464 else:
464 else:
465 extmodules.append(Extension('mercurial.osutil', ['mercurial/osutil.c'],
465 extmodules.append(Extension('mercurial.osutil', ['mercurial/osutil.c'],
466 extra_link_args=osutil_ldflags,
466 extra_link_args=osutil_ldflags,
467 depends=common_depends))
467 depends=common_depends))
468
468
469 # the -mno-cygwin option has been deprecated for years
469 # the -mno-cygwin option has been deprecated for years
470 Mingw32CCompiler = cygwinccompiler.Mingw32CCompiler
470 Mingw32CCompiler = cygwinccompiler.Mingw32CCompiler
471
471
472 class HackedMingw32CCompiler(cygwinccompiler.Mingw32CCompiler):
472 class HackedMingw32CCompiler(cygwinccompiler.Mingw32CCompiler):
473 def __init__(self, *args, **kwargs):
473 def __init__(self, *args, **kwargs):
474 Mingw32CCompiler.__init__(self, *args, **kwargs)
474 Mingw32CCompiler.__init__(self, *args, **kwargs)
475 for i in 'compiler compiler_so linker_exe linker_so'.split():
475 for i in 'compiler compiler_so linker_exe linker_so'.split():
476 try:
476 try:
477 getattr(self, i).remove('-mno-cygwin')
477 getattr(self, i).remove('-mno-cygwin')
478 except ValueError:
478 except ValueError:
479 pass
479 pass
480
480
481 cygwinccompiler.Mingw32CCompiler = HackedMingw32CCompiler
481 cygwinccompiler.Mingw32CCompiler = HackedMingw32CCompiler
482
482
483 packagedata = {'mercurial': ['locale/*/LC_MESSAGES/hg.mo',
483 packagedata = {'mercurial': ['locale/*/LC_MESSAGES/hg.mo',
484 'help/*.txt']}
484 'help/*.txt']}
485
485
486 def ordinarypath(p):
486 def ordinarypath(p):
487 return p and p[0] != '.' and p[-1] != '~'
487 return p and p[0] != '.' and p[-1] != '~'
488
488
489 for root in ('templates',):
489 for root in ('templates',):
490 for curdir, dirs, files in os.walk(os.path.join('mercurial', root)):
490 for curdir, dirs, files in os.walk(os.path.join('mercurial', root)):
491 curdir = curdir.split(os.sep, 1)[1]
491 curdir = curdir.split(os.sep, 1)[1]
492 dirs[:] = filter(ordinarypath, dirs)
492 dirs[:] = filter(ordinarypath, dirs)
493 for f in filter(ordinarypath, files):
493 for f in filter(ordinarypath, files):
494 f = os.path.join(curdir, f)
494 f = os.path.join(curdir, f)
495 packagedata['mercurial'].append(f)
495 packagedata['mercurial'].append(f)
496
496
497 datafiles = []
497 datafiles = []
498 setupversion = version
498 setupversion = version
499 extra = {}
499 extra = {}
500
500
501 if py2exeloaded:
501 if py2exeloaded:
502 extra['console'] = [
502 extra['console'] = [
503 {'script':'hg',
503 {'script':'hg',
504 'copyright':'Copyright (C) 2005-2010 Matt Mackall and others',
504 'copyright':'Copyright (C) 2005-2010 Matt Mackall and others',
505 'product_version':version}]
505 'product_version':version}]
506 # sub command of 'build' because 'py2exe' does not handle sub_commands
506 # sub command of 'build' because 'py2exe' does not handle sub_commands
507 build.sub_commands.insert(0, ('build_hgextindex', None))
507 build.sub_commands.insert(0, ('build_hgextindex', None))
508
508
509 if os.name == 'nt':
509 if os.name == 'nt':
510 # Windows binary file versions for exe/dll files must have the
510 # Windows binary file versions for exe/dll files must have the
511 # form W.X.Y.Z, where W,X,Y,Z are numbers in the range 0..65535
511 # form W.X.Y.Z, where W,X,Y,Z are numbers in the range 0..65535
512 setupversion = version.split('+', 1)[0]
512 setupversion = version.split('+', 1)[0]
513
513
514 if sys.platform == 'darwin' and os.path.exists('/usr/bin/xcodebuild'):
514 if sys.platform == 'darwin' and os.path.exists('/usr/bin/xcodebuild'):
515 version = runcmd(['/usr/bin/xcodebuild', '-version'], {})[0].splitlines()
515 version = runcmd(['/usr/bin/xcodebuild', '-version'], {})[0].splitlines()
516 if version:
516 if version:
517 version = version[0]
517 version = version[0]
518 xcode4 = (version.startswith('Xcode') and
518 xcode4 = (version.startswith('Xcode') and
519 StrictVersion(version.split()[1]) >= StrictVersion('4.0'))
519 StrictVersion(version.split()[1]) >= StrictVersion('4.0'))
520 xcode51 = re.match(r'^Xcode\s+5\.1', version) is not None
520 xcode51 = re.match(r'^Xcode\s+5\.1', version) is not None
521 else:
521 else:
522 # xcodebuild returns empty on OS X Lion with XCode 4.3 not
522 # xcodebuild returns empty on OS X Lion with XCode 4.3 not
523 # installed, but instead with only command-line tools. Assume
523 # installed, but instead with only command-line tools. Assume
524 # that only happens on >= Lion, thus no PPC support.
524 # that only happens on >= Lion, thus no PPC support.
525 xcode4 = True
525 xcode4 = True
526 xcode51 = False
526 xcode51 = False
527
527
528 # XCode 4.0 dropped support for ppc architecture, which is hardcoded in
528 # XCode 4.0 dropped support for ppc architecture, which is hardcoded in
529 # distutils.sysconfig
529 # distutils.sysconfig
530 if xcode4:
530 if xcode4:
531 os.environ['ARCHFLAGS'] = ''
531 os.environ['ARCHFLAGS'] = ''
532
532
533 # XCode 5.1 changes clang such that it now fails to compile if the
533 # XCode 5.1 changes clang such that it now fails to compile if the
534 # -mno-fused-madd flag is passed, but the version of Python shipped with
534 # -mno-fused-madd flag is passed, but the version of Python shipped with
535 # OS X 10.9 Mavericks includes this flag. This causes problems in all
535 # OS X 10.9 Mavericks includes this flag. This causes problems in all
536 # C extension modules, and a bug has been filed upstream at
536 # C extension modules, and a bug has been filed upstream at
537 # http://bugs.python.org/issue21244. We also need to patch this here
537 # http://bugs.python.org/issue21244. We also need to patch this here
538 # so Mercurial can continue to compile in the meantime.
538 # so Mercurial can continue to compile in the meantime.
539 if xcode51:
539 if xcode51:
540 cflags = get_config_var('CFLAGS')
540 cflags = get_config_var('CFLAGS')
541 if cflags and re.search(r'-mno-fused-madd\b', cflags) is not None:
541 if cflags and re.search(r'-mno-fused-madd\b', cflags) is not None:
542 os.environ['CFLAGS'] = (
542 os.environ['CFLAGS'] = (
543 os.environ.get('CFLAGS', '') + ' -Qunused-arguments')
543 os.environ.get('CFLAGS', '') + ' -Qunused-arguments')
544
544
545 setup(name='mercurial',
545 setup(name='mercurial',
546 version=setupversion,
546 version=setupversion,
547 author='Matt Mackall and many others',
547 author='Matt Mackall and many others',
548 author_email='mercurial@selenic.com',
548 author_email='mercurial@selenic.com',
549 url='http://mercurial.selenic.com/',
549 url='http://mercurial.selenic.com/',
550 download_url='http://mercurial.selenic.com/release/',
550 download_url='http://mercurial.selenic.com/release/',
551 description=('Fast scalable distributed SCM (revision control, version '
551 description=('Fast scalable distributed SCM (revision control, version '
552 'control) system'),
552 'control) system'),
553 long_description=('Mercurial is a distributed SCM tool written in Python.'
553 long_description=('Mercurial is a distributed SCM tool written in Python.'
554 ' It is used by a number of large projects that require'
554 ' It is used by a number of large projects that require'
555 ' fast, reliable distributed revision control, such as '
555 ' fast, reliable distributed revision control, such as '
556 'Mozilla.'),
556 'Mozilla.'),
557 license='GNU GPLv2 or any later version',
557 license='GNU GPLv2 or any later version',
558 classifiers=[
558 classifiers=[
559 'Development Status :: 6 - Mature',
559 'Development Status :: 6 - Mature',
560 'Environment :: Console',
560 'Environment :: Console',
561 'Intended Audience :: Developers',
561 'Intended Audience :: Developers',
562 'Intended Audience :: System Administrators',
562 'Intended Audience :: System Administrators',
563 'License :: OSI Approved :: GNU General Public License (GPL)',
563 'License :: OSI Approved :: GNU General Public License (GPL)',
564 'Natural Language :: Danish',
564 'Natural Language :: Danish',
565 'Natural Language :: English',
565 'Natural Language :: English',
566 'Natural Language :: German',
566 'Natural Language :: German',
567 'Natural Language :: Italian',
567 'Natural Language :: Italian',
568 'Natural Language :: Japanese',
568 'Natural Language :: Japanese',
569 'Natural Language :: Portuguese (Brazilian)',
569 'Natural Language :: Portuguese (Brazilian)',
570 'Operating System :: Microsoft :: Windows',
570 'Operating System :: Microsoft :: Windows',
571 'Operating System :: OS Independent',
571 'Operating System :: OS Independent',
572 'Operating System :: POSIX',
572 'Operating System :: POSIX',
573 'Programming Language :: C',
573 'Programming Language :: C',
574 'Programming Language :: Python',
574 'Programming Language :: Python',
575 'Topic :: Software Development :: Version Control',
575 'Topic :: Software Development :: Version Control',
576 ],
576 ],
577 scripts=scripts,
577 scripts=scripts,
578 packages=packages,
578 packages=packages,
579 py_modules=pymodules,
579 py_modules=pymodules,
580 ext_modules=extmodules,
580 ext_modules=extmodules,
581 data_files=datafiles,
581 data_files=datafiles,
582 package_data=packagedata,
582 package_data=packagedata,
583 cmdclass=cmdclass,
583 cmdclass=cmdclass,
584 distclass=hgdist,
584 distclass=hgdist,
585 options={'py2exe': {'packages': ['hgext', 'email']},
585 options={'py2exe': {'packages': ['hgext', 'email']},
586 'bdist_mpkg': {'zipdist': True,
586 'bdist_mpkg': {'zipdist': False,
587 'license': 'COPYING',
587 'license': 'COPYING',
588 'readme': 'contrib/macosx/Readme.html',
588 'readme': 'contrib/macosx/Readme.html',
589 'welcome': 'contrib/macosx/Welcome.html',
589 'welcome': 'contrib/macosx/Welcome.html',
590 },
590 },
591 },
591 },
592 **extra)
592 **extra)
General Comments 0
You need to be logged in to leave comments. Login now