##// END OF EJS Templates
Fix how setup.py identifies the Mercurial version....
Jeremy Whitlock -
r8493:4c030ada default
parent child Browse files
Show More
@@ -1,260 +1,260 b''
1 1 #!/usr/bin/env python
2 2 #
3 3 # This is the mercurial setup script.
4 4 #
5 5 # 'python setup.py install', or
6 6 # 'python setup.py --help' for more options
7 7
8 8 import sys
9 9 if not hasattr(sys, 'version_info') or sys.version_info < (2, 3, 0, 'final'):
10 10 raise SystemExit("Mercurial requires python 2.3 or later.")
11 11
12 12 # Solaris Python packaging brain damage
13 13 try:
14 14 import hashlib
15 15 sha = hashlib.sha1()
16 16 except:
17 17 try:
18 18 import sha
19 19 except:
20 20 raise SystemExit(
21 21 "Couldn't import standard hashlib (incomplete Python install).")
22 22
23 23 try:
24 24 import zlib
25 25 except:
26 26 raise SystemExit(
27 27 "Couldn't import standard zlib (incomplete Python install).")
28 28
29 29 import os, time
30 30 import shutil
31 31 import tempfile
32 32 from distutils.core import setup, Extension
33 33 from distutils.dist import Distribution
34 34 from distutils.command.install_data import install_data
35 35 from distutils.command.build import build
36 36 from distutils.command.build_py import build_py
37 37 from distutils.spawn import spawn, find_executable
38 38 from distutils.ccompiler import new_compiler
39 39
40 40 extra = {}
41 41 scripts = ['hg']
42 42 if os.name == 'nt':
43 43 scripts.append('contrib/win32/hg.bat')
44 44
45 45 # simplified version of distutils.ccompiler.CCompiler.has_function
46 46 # that actually removes its temporary files.
47 47 def has_function(cc, funcname):
48 48 tmpdir = tempfile.mkdtemp(prefix='hg-install-')
49 49 devnull = oldstderr = None
50 50 try:
51 51 try:
52 52 fname = os.path.join(tmpdir, 'funcname.c')
53 53 f = open(fname, 'w')
54 54 f.write('int main(void) {\n')
55 55 f.write(' %s();\n' % funcname)
56 56 f.write('}\n')
57 57 f.close()
58 58 # Redirect stderr to /dev/null to hide any error messages
59 59 # from the compiler.
60 60 # This will have to be changed if we ever have to check
61 61 # for a function on Windows.
62 62 devnull = open('/dev/null', 'w')
63 63 oldstderr = os.dup(sys.stderr.fileno())
64 64 os.dup2(devnull.fileno(), sys.stderr.fileno())
65 65 objects = cc.compile([fname])
66 66 cc.link_executable(objects, os.path.join(tmpdir, "a.out"))
67 67 except:
68 68 return False
69 69 return True
70 70 finally:
71 71 if oldstderr is not None:
72 72 os.dup2(oldstderr, sys.stderr.fileno())
73 73 if devnull is not None:
74 74 devnull.close()
75 75 shutil.rmtree(tmpdir)
76 76
77 77 # py2exe needs to be installed to work
78 78 try:
79 79 import py2exe
80 80
81 81 # Help py2exe to find win32com.shell
82 82 try:
83 83 import modulefinder
84 84 import win32com
85 85 for p in win32com.__path__[1:]: # Take the path to win32comext
86 86 modulefinder.AddPackagePath("win32com", p)
87 87 pn = "win32com.shell"
88 88 __import__(pn)
89 89 m = sys.modules[pn]
90 90 for p in m.__path__[1:]:
91 91 modulefinder.AddPackagePath(pn, p)
92 92 except ImportError:
93 93 pass
94 94
95 95 extra['console'] = ['hg']
96 96
97 97 except ImportError:
98 98 pass
99 99
100 def getversion():
101 if not os.path.exists('.hg'):
102 return None # not in a repository
103
100 if os.path.exists('.hg'):
104 101 # execute hg out of this directory with a custom environment which
105 102 # includes the pure Python modules in mercurial/pure
106 103 pypath = os.environ.get('PYTHONPATH', '')
107 104 purepath = os.path.join('mercurial', 'pure')
108 105 os.environ['PYTHONPATH'] = os.pathsep.join(['mercurial', purepath, pypath])
109 106 os.environ['HGRCPATH'] = '' # do not read any config file
110 107 cmd = '%s hg id -it' % sys.executable
108 version = None
111 109
112 110 try:
113 111 l = os.popen(cmd).read().split()
114 112 except OSError, e:
115 113 print "warning: could not establish Mercurial version: %s" % e
116 114
117 115 os.environ['PYTHONPATH'] = pypath
118 116
119 117 while len(l) > 1 and l[-1][0].isalpha(): # remove non-numbered tags
120 118 l.pop()
121 119 if l:
122 120 version = l[-1] # latest tag or revision number
123 121 if version.endswith('+'):
124 122 version += time.strftime('%Y%m%d')
125 return version
126 123
127 version = getversion()
128 if version:
129 f = file("mercurial/__version__.py", "w")
130 f.write('# this file is autogenerated by setup.py\n')
131 f.write('version = "%s"\n' % version)
132 f.close()
133 else:
134 version = "unknown"
124 if version:
125 f = file("mercurial/__version__.py", "w")
126 f.write('# this file is autogenerated by setup.py\n')
127 f.write('version = "%s"\n' % version)
128 f.close()
129
130 try:
131 from mercurial import __version__
132 version = __version__.version
133 except ImportError:
134 version = 'unknown'
135 135
136 136 class install_package_data(install_data):
137 137 def finalize_options(self):
138 138 self.set_undefined_options('install',
139 139 ('install_lib', 'install_dir'))
140 140 install_data.finalize_options(self)
141 141
142 142 class build_mo(build):
143 143
144 144 description = "build translations (.mo files)"
145 145
146 146 def run(self):
147 147 if not find_executable('msgfmt'):
148 148 self.warn("could not find msgfmt executable, no translations "
149 149 "will be built")
150 150 return
151 151
152 152 podir = 'i18n'
153 153 if not os.path.isdir(podir):
154 154 self.warn("could not find %s/ directory" % podir)
155 155 return
156 156
157 157 join = os.path.join
158 158 for po in os.listdir(podir):
159 159 if not po.endswith('.po'):
160 160 continue
161 161 pofile = join(podir, po)
162 162 modir = join('locale', po[:-3], 'LC_MESSAGES')
163 163 mofile = join(modir, 'hg.mo')
164 164 cmd = ['msgfmt', '-v', '-o', mofile, pofile]
165 165 if sys.platform != 'sunos5':
166 166 # msgfmt on Solaris does not know about -c
167 167 cmd.append('-c')
168 168 self.mkpath(modir)
169 169 self.make_file([pofile], mofile, spawn, (cmd,))
170 170 self.distribution.data_files.append((join('mercurial', modir),
171 171 [mofile]))
172 172
173 173 build.sub_commands.append(('build_mo', None))
174 174
175 175 Distribution.pure = 0
176 176 Distribution.global_options.append(('pure', None, "use pure (slow) Python "
177 177 "code instead of C extensions"))
178 178
179 179 class hg_build_py(build_py):
180 180
181 181 def finalize_options(self):
182 182 build_py.finalize_options(self)
183 183
184 184 if self.distribution.pure:
185 185 if self.py_modules is None:
186 186 self.py_modules = []
187 187 for ext in self.distribution.ext_modules:
188 188 if ext.name.startswith("mercurial."):
189 189 self.py_modules.append("mercurial.pure.%s" % ext.name[10:])
190 190 self.distribution.ext_modules = []
191 191
192 192 def find_modules(self):
193 193 modules = build_py.find_modules(self)
194 194 for module in modules:
195 195 if module[0] == "mercurial.pure":
196 196 if module[1] != "__init__":
197 197 yield ("mercurial", module[1], module[2])
198 198 else:
199 199 yield module
200 200
201 201 cmdclass = {'install_data': install_package_data,
202 202 'build_mo': build_mo,
203 203 'build_py': hg_build_py}
204 204
205 205 ext_modules=[
206 206 Extension('mercurial.base85', ['mercurial/base85.c']),
207 207 Extension('mercurial.bdiff', ['mercurial/bdiff.c']),
208 208 Extension('mercurial.diffhelpers', ['mercurial/diffhelpers.c']),
209 209 Extension('mercurial.mpatch', ['mercurial/mpatch.c']),
210 210 Extension('mercurial.parsers', ['mercurial/parsers.c']),
211 211 ]
212 212
213 213 packages = ['mercurial', 'mercurial.hgweb', 'hgext', 'hgext.convert',
214 214 'hgext.highlight', 'hgext.zeroconf', ]
215 215
216 216 try:
217 217 import msvcrt
218 218 ext_modules.append(Extension('mercurial.osutil', ['mercurial/osutil.c']))
219 219 except ImportError:
220 220 pass
221 221
222 222 try:
223 223 import posix
224 224 ext_modules.append(Extension('mercurial.osutil', ['mercurial/osutil.c']))
225 225
226 226 if sys.platform == 'linux2' and os.uname()[2] > '2.6':
227 227 # The inotify extension is only usable with Linux 2.6 kernels.
228 228 # You also need a reasonably recent C library.
229 229 cc = new_compiler()
230 230 if has_function(cc, 'inotify_add_watch'):
231 231 ext_modules.append(Extension('hgext.inotify.linux._inotify',
232 232 ['hgext/inotify/linux/_inotify.c']))
233 233 packages.extend(['hgext.inotify', 'hgext.inotify.linux'])
234 234 except ImportError:
235 235 pass
236 236
237 237 datafiles = []
238 238 for root in ('templates', 'i18n'):
239 239 for dir, dirs, files in os.walk(root):
240 240 datafiles.append((os.path.join('mercurial', dir),
241 241 [os.path.join(dir, file_) for file_ in files]))
242 242
243 243 setup(name='mercurial',
244 244 version=version,
245 245 author='Matt Mackall',
246 246 author_email='mpm@selenic.com',
247 247 url='http://selenic.com/mercurial',
248 248 description='Scalable distributed SCM',
249 249 license='GNU GPL',
250 250 scripts=scripts,
251 251 packages=packages,
252 252 ext_modules=ext_modules,
253 253 data_files=datafiles,
254 254 cmdclass=cmdclass,
255 255 options=dict(py2exe=dict(packages=['hgext', 'email']),
256 256 bdist_mpkg=dict(zipdist=True,
257 257 license='COPYING',
258 258 readme='contrib/macosx/Readme.html',
259 259 welcome='contrib/macosx/Welcome.html')),
260 260 **extra)
General Comments 0
You need to be logged in to leave comments. Login now