##// END OF EJS Templates
hghave: update cvs112 description...
timeless -
r28756:45954a25 default
parent child Browse files
Show More
@@ -1,464 +1,464 b''
1 from __future__ import absolute_import
1 from __future__ import absolute_import
2
2
3 import errno
3 import errno
4 import os
4 import os
5 import re
5 import re
6 import socket
6 import socket
7 import stat
7 import stat
8 import subprocess
8 import subprocess
9 import sys
9 import sys
10 import tempfile
10 import tempfile
11
11
12 tempprefix = 'hg-hghave-'
12 tempprefix = 'hg-hghave-'
13
13
14 checks = {
14 checks = {
15 "true": (lambda: True, "yak shaving"),
15 "true": (lambda: True, "yak shaving"),
16 "false": (lambda: False, "nail clipper"),
16 "false": (lambda: False, "nail clipper"),
17 }
17 }
18
18
19 def check(name, desc):
19 def check(name, desc):
20 def decorator(func):
20 def decorator(func):
21 checks[name] = (func, desc)
21 checks[name] = (func, desc)
22 return func
22 return func
23 return decorator
23 return decorator
24
24
25 def checkfeatures(features):
25 def checkfeatures(features):
26 result = {
26 result = {
27 'error': [],
27 'error': [],
28 'missing': [],
28 'missing': [],
29 'skipped': [],
29 'skipped': [],
30 }
30 }
31
31
32 for feature in features:
32 for feature in features:
33 negate = feature.startswith('no-')
33 negate = feature.startswith('no-')
34 if negate:
34 if negate:
35 feature = feature[3:]
35 feature = feature[3:]
36
36
37 if feature not in checks:
37 if feature not in checks:
38 result['missing'].append(feature)
38 result['missing'].append(feature)
39 continue
39 continue
40
40
41 check, desc = checks[feature]
41 check, desc = checks[feature]
42 try:
42 try:
43 available = check()
43 available = check()
44 except Exception:
44 except Exception:
45 result['error'].append('hghave check failed: %s' % feature)
45 result['error'].append('hghave check failed: %s' % feature)
46 continue
46 continue
47
47
48 if not negate and not available:
48 if not negate and not available:
49 result['skipped'].append('missing feature: %s' % desc)
49 result['skipped'].append('missing feature: %s' % desc)
50 elif negate and available:
50 elif negate and available:
51 result['skipped'].append('system supports %s' % desc)
51 result['skipped'].append('system supports %s' % desc)
52
52
53 return result
53 return result
54
54
55 def require(features):
55 def require(features):
56 """Require that features are available, exiting if not."""
56 """Require that features are available, exiting if not."""
57 result = checkfeatures(features)
57 result = checkfeatures(features)
58
58
59 for missing in result['missing']:
59 for missing in result['missing']:
60 sys.stderr.write('skipped: unknown feature: %s\n' % missing)
60 sys.stderr.write('skipped: unknown feature: %s\n' % missing)
61 for msg in result['skipped']:
61 for msg in result['skipped']:
62 sys.stderr.write('skipped: %s\n' % msg)
62 sys.stderr.write('skipped: %s\n' % msg)
63 for msg in result['error']:
63 for msg in result['error']:
64 sys.stderr.write('%s\n' % msg)
64 sys.stderr.write('%s\n' % msg)
65
65
66 if result['missing']:
66 if result['missing']:
67 sys.exit(2)
67 sys.exit(2)
68
68
69 if result['skipped'] or result['error']:
69 if result['skipped'] or result['error']:
70 sys.exit(1)
70 sys.exit(1)
71
71
72 def matchoutput(cmd, regexp, ignorestatus=False):
72 def matchoutput(cmd, regexp, ignorestatus=False):
73 """Return the match object if cmd executes successfully and its output
73 """Return the match object if cmd executes successfully and its output
74 is matched by the supplied regular expression.
74 is matched by the supplied regular expression.
75 """
75 """
76 r = re.compile(regexp)
76 r = re.compile(regexp)
77 try:
77 try:
78 p = subprocess.Popen(
78 p = subprocess.Popen(
79 cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
79 cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
80 except OSError as e:
80 except OSError as e:
81 if e.errno != errno.ENOENT:
81 if e.errno != errno.ENOENT:
82 raise
82 raise
83 ret = -1
83 ret = -1
84 ret = p.wait()
84 ret = p.wait()
85 s = p.stdout.read()
85 s = p.stdout.read()
86 return (ignorestatus or not ret) and r.search(s)
86 return (ignorestatus or not ret) and r.search(s)
87
87
88 @check("baz", "GNU Arch baz client")
88 @check("baz", "GNU Arch baz client")
89 def has_baz():
89 def has_baz():
90 return matchoutput('baz --version 2>&1', r'baz Bazaar version')
90 return matchoutput('baz --version 2>&1', r'baz Bazaar version')
91
91
92 @check("bzr", "Canonical's Bazaar client")
92 @check("bzr", "Canonical's Bazaar client")
93 def has_bzr():
93 def has_bzr():
94 try:
94 try:
95 import bzrlib
95 import bzrlib
96 return bzrlib.__doc__ is not None
96 return bzrlib.__doc__ is not None
97 except ImportError:
97 except ImportError:
98 return False
98 return False
99
99
100 @check("bzr114", "Canonical's Bazaar client >= 1.14")
100 @check("bzr114", "Canonical's Bazaar client >= 1.14")
101 def has_bzr114():
101 def has_bzr114():
102 try:
102 try:
103 import bzrlib
103 import bzrlib
104 return (bzrlib.__doc__ is not None
104 return (bzrlib.__doc__ is not None
105 and bzrlib.version_info[:2] >= (1, 14))
105 and bzrlib.version_info[:2] >= (1, 14))
106 except ImportError:
106 except ImportError:
107 return False
107 return False
108
108
109 @check("cvs", "cvs client/server")
109 @check("cvs", "cvs client/server")
110 def has_cvs():
110 def has_cvs():
111 re = r'Concurrent Versions System.*?server'
111 re = r'Concurrent Versions System.*?server'
112 return matchoutput('cvs --version 2>&1', re) and not has_msys()
112 return matchoutput('cvs --version 2>&1', re) and not has_msys()
113
113
114 @check("cvs112", "cvs client/server >= 1.12")
114 @check("cvs112", "cvs client/server 1.12.* (not cvsnt)")
115 def has_cvs112():
115 def has_cvs112():
116 re = r'Concurrent Versions System \(CVS\) 1.12.*?server'
116 re = r'Concurrent Versions System \(CVS\) 1.12.*?server'
117 return matchoutput('cvs --version 2>&1', re) and not has_msys()
117 return matchoutput('cvs --version 2>&1', re) and not has_msys()
118
118
119 @check("darcs", "darcs client")
119 @check("darcs", "darcs client")
120 def has_darcs():
120 def has_darcs():
121 return matchoutput('darcs --version', r'2\.[2-9]', True)
121 return matchoutput('darcs --version', r'2\.[2-9]', True)
122
122
123 @check("mtn", "monotone client (>= 1.0)")
123 @check("mtn", "monotone client (>= 1.0)")
124 def has_mtn():
124 def has_mtn():
125 return matchoutput('mtn --version', r'monotone', True) and not matchoutput(
125 return matchoutput('mtn --version', r'monotone', True) and not matchoutput(
126 'mtn --version', r'monotone 0\.', True)
126 'mtn --version', r'monotone 0\.', True)
127
127
128 @check("eol-in-paths", "end-of-lines in paths")
128 @check("eol-in-paths", "end-of-lines in paths")
129 def has_eol_in_paths():
129 def has_eol_in_paths():
130 try:
130 try:
131 fd, path = tempfile.mkstemp(dir='.', prefix=tempprefix, suffix='\n\r')
131 fd, path = tempfile.mkstemp(dir='.', prefix=tempprefix, suffix='\n\r')
132 os.close(fd)
132 os.close(fd)
133 os.remove(path)
133 os.remove(path)
134 return True
134 return True
135 except (IOError, OSError):
135 except (IOError, OSError):
136 return False
136 return False
137
137
138 @check("execbit", "executable bit")
138 @check("execbit", "executable bit")
139 def has_executablebit():
139 def has_executablebit():
140 try:
140 try:
141 EXECFLAGS = stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH
141 EXECFLAGS = stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH
142 fh, fn = tempfile.mkstemp(dir='.', prefix=tempprefix)
142 fh, fn = tempfile.mkstemp(dir='.', prefix=tempprefix)
143 try:
143 try:
144 os.close(fh)
144 os.close(fh)
145 m = os.stat(fn).st_mode & 0o777
145 m = os.stat(fn).st_mode & 0o777
146 new_file_has_exec = m & EXECFLAGS
146 new_file_has_exec = m & EXECFLAGS
147 os.chmod(fn, m ^ EXECFLAGS)
147 os.chmod(fn, m ^ EXECFLAGS)
148 exec_flags_cannot_flip = ((os.stat(fn).st_mode & 0o777) == m)
148 exec_flags_cannot_flip = ((os.stat(fn).st_mode & 0o777) == m)
149 finally:
149 finally:
150 os.unlink(fn)
150 os.unlink(fn)
151 except (IOError, OSError):
151 except (IOError, OSError):
152 # we don't care, the user probably won't be able to commit anyway
152 # we don't care, the user probably won't be able to commit anyway
153 return False
153 return False
154 return not (new_file_has_exec or exec_flags_cannot_flip)
154 return not (new_file_has_exec or exec_flags_cannot_flip)
155
155
156 @check("icasefs", "case insensitive file system")
156 @check("icasefs", "case insensitive file system")
157 def has_icasefs():
157 def has_icasefs():
158 # Stolen from mercurial.util
158 # Stolen from mercurial.util
159 fd, path = tempfile.mkstemp(dir='.', prefix=tempprefix)
159 fd, path = tempfile.mkstemp(dir='.', prefix=tempprefix)
160 os.close(fd)
160 os.close(fd)
161 try:
161 try:
162 s1 = os.stat(path)
162 s1 = os.stat(path)
163 d, b = os.path.split(path)
163 d, b = os.path.split(path)
164 p2 = os.path.join(d, b.upper())
164 p2 = os.path.join(d, b.upper())
165 if path == p2:
165 if path == p2:
166 p2 = os.path.join(d, b.lower())
166 p2 = os.path.join(d, b.lower())
167 try:
167 try:
168 s2 = os.stat(p2)
168 s2 = os.stat(p2)
169 return s2 == s1
169 return s2 == s1
170 except OSError:
170 except OSError:
171 return False
171 return False
172 finally:
172 finally:
173 os.remove(path)
173 os.remove(path)
174
174
175 @check("fifo", "named pipes")
175 @check("fifo", "named pipes")
176 def has_fifo():
176 def has_fifo():
177 if getattr(os, "mkfifo", None) is None:
177 if getattr(os, "mkfifo", None) is None:
178 return False
178 return False
179 name = tempfile.mktemp(dir='.', prefix=tempprefix)
179 name = tempfile.mktemp(dir='.', prefix=tempprefix)
180 try:
180 try:
181 os.mkfifo(name)
181 os.mkfifo(name)
182 os.unlink(name)
182 os.unlink(name)
183 return True
183 return True
184 except OSError:
184 except OSError:
185 return False
185 return False
186
186
187 @check("killdaemons", 'killdaemons.py support')
187 @check("killdaemons", 'killdaemons.py support')
188 def has_killdaemons():
188 def has_killdaemons():
189 return True
189 return True
190
190
191 @check("cacheable", "cacheable filesystem")
191 @check("cacheable", "cacheable filesystem")
192 def has_cacheable_fs():
192 def has_cacheable_fs():
193 from mercurial import util
193 from mercurial import util
194
194
195 fd, path = tempfile.mkstemp(dir='.', prefix=tempprefix)
195 fd, path = tempfile.mkstemp(dir='.', prefix=tempprefix)
196 os.close(fd)
196 os.close(fd)
197 try:
197 try:
198 return util.cachestat(path).cacheable()
198 return util.cachestat(path).cacheable()
199 finally:
199 finally:
200 os.remove(path)
200 os.remove(path)
201
201
202 @check("lsprof", "python lsprof module")
202 @check("lsprof", "python lsprof module")
203 def has_lsprof():
203 def has_lsprof():
204 try:
204 try:
205 import _lsprof
205 import _lsprof
206 _lsprof.Profiler # silence unused import warning
206 _lsprof.Profiler # silence unused import warning
207 return True
207 return True
208 except ImportError:
208 except ImportError:
209 return False
209 return False
210
210
211 @check("gettext", "GNU Gettext (msgfmt)")
211 @check("gettext", "GNU Gettext (msgfmt)")
212 def has_gettext():
212 def has_gettext():
213 return matchoutput('msgfmt --version', 'GNU gettext-tools')
213 return matchoutput('msgfmt --version', 'GNU gettext-tools')
214
214
215 @check("git", "git command line client")
215 @check("git", "git command line client")
216 def has_git():
216 def has_git():
217 return matchoutput('git --version 2>&1', r'^git version')
217 return matchoutput('git --version 2>&1', r'^git version')
218
218
219 @check("docutils", "Docutils text processing library")
219 @check("docutils", "Docutils text processing library")
220 def has_docutils():
220 def has_docutils():
221 try:
221 try:
222 from docutils.core import publish_cmdline
222 from docutils.core import publish_cmdline
223 publish_cmdline # silence unused import
223 publish_cmdline # silence unused import
224 return True
224 return True
225 except ImportError:
225 except ImportError:
226 return False
226 return False
227
227
228 def getsvnversion():
228 def getsvnversion():
229 m = matchoutput('svn --version --quiet 2>&1', r'^(\d+)\.(\d+)')
229 m = matchoutput('svn --version --quiet 2>&1', r'^(\d+)\.(\d+)')
230 if not m:
230 if not m:
231 return (0, 0)
231 return (0, 0)
232 return (int(m.group(1)), int(m.group(2)))
232 return (int(m.group(1)), int(m.group(2)))
233
233
234 @check("svn15", "subversion client and admin tools >= 1.5")
234 @check("svn15", "subversion client and admin tools >= 1.5")
235 def has_svn15():
235 def has_svn15():
236 return getsvnversion() >= (1, 5)
236 return getsvnversion() >= (1, 5)
237
237
238 @check("svn13", "subversion client and admin tools >= 1.3")
238 @check("svn13", "subversion client and admin tools >= 1.3")
239 def has_svn13():
239 def has_svn13():
240 return getsvnversion() >= (1, 3)
240 return getsvnversion() >= (1, 3)
241
241
242 @check("svn", "subversion client and admin tools")
242 @check("svn", "subversion client and admin tools")
243 def has_svn():
243 def has_svn():
244 return matchoutput('svn --version 2>&1', r'^svn, version') and \
244 return matchoutput('svn --version 2>&1', r'^svn, version') and \
245 matchoutput('svnadmin --version 2>&1', r'^svnadmin, version')
245 matchoutput('svnadmin --version 2>&1', r'^svnadmin, version')
246
246
247 @check("svn-bindings", "subversion python bindings")
247 @check("svn-bindings", "subversion python bindings")
248 def has_svn_bindings():
248 def has_svn_bindings():
249 try:
249 try:
250 import svn.core
250 import svn.core
251 version = svn.core.SVN_VER_MAJOR, svn.core.SVN_VER_MINOR
251 version = svn.core.SVN_VER_MAJOR, svn.core.SVN_VER_MINOR
252 if version < (1, 4):
252 if version < (1, 4):
253 return False
253 return False
254 return True
254 return True
255 except ImportError:
255 except ImportError:
256 return False
256 return False
257
257
258 @check("p4", "Perforce server and client")
258 @check("p4", "Perforce server and client")
259 def has_p4():
259 def has_p4():
260 return (matchoutput('p4 -V', r'Rev\. P4/') and
260 return (matchoutput('p4 -V', r'Rev\. P4/') and
261 matchoutput('p4d -V', r'Rev\. P4D/'))
261 matchoutput('p4d -V', r'Rev\. P4D/'))
262
262
263 @check("symlink", "symbolic links")
263 @check("symlink", "symbolic links")
264 def has_symlink():
264 def has_symlink():
265 if getattr(os, "symlink", None) is None:
265 if getattr(os, "symlink", None) is None:
266 return False
266 return False
267 name = tempfile.mktemp(dir='.', prefix=tempprefix)
267 name = tempfile.mktemp(dir='.', prefix=tempprefix)
268 try:
268 try:
269 os.symlink(".", name)
269 os.symlink(".", name)
270 os.unlink(name)
270 os.unlink(name)
271 return True
271 return True
272 except (OSError, AttributeError):
272 except (OSError, AttributeError):
273 return False
273 return False
274
274
275 @check("hardlink", "hardlinks")
275 @check("hardlink", "hardlinks")
276 def has_hardlink():
276 def has_hardlink():
277 from mercurial import util
277 from mercurial import util
278 fh, fn = tempfile.mkstemp(dir='.', prefix=tempprefix)
278 fh, fn = tempfile.mkstemp(dir='.', prefix=tempprefix)
279 os.close(fh)
279 os.close(fh)
280 name = tempfile.mktemp(dir='.', prefix=tempprefix)
280 name = tempfile.mktemp(dir='.', prefix=tempprefix)
281 try:
281 try:
282 util.oslink(fn, name)
282 util.oslink(fn, name)
283 os.unlink(name)
283 os.unlink(name)
284 return True
284 return True
285 except OSError:
285 except OSError:
286 return False
286 return False
287 finally:
287 finally:
288 os.unlink(fn)
288 os.unlink(fn)
289
289
290 @check("tla", "GNU Arch tla client")
290 @check("tla", "GNU Arch tla client")
291 def has_tla():
291 def has_tla():
292 return matchoutput('tla --version 2>&1', r'The GNU Arch Revision')
292 return matchoutput('tla --version 2>&1', r'The GNU Arch Revision')
293
293
294 @check("gpg", "gpg client")
294 @check("gpg", "gpg client")
295 def has_gpg():
295 def has_gpg():
296 return matchoutput('gpg --version 2>&1', r'GnuPG')
296 return matchoutput('gpg --version 2>&1', r'GnuPG')
297
297
298 @check("unix-permissions", "unix-style permissions")
298 @check("unix-permissions", "unix-style permissions")
299 def has_unix_permissions():
299 def has_unix_permissions():
300 d = tempfile.mkdtemp(dir='.', prefix=tempprefix)
300 d = tempfile.mkdtemp(dir='.', prefix=tempprefix)
301 try:
301 try:
302 fname = os.path.join(d, 'foo')
302 fname = os.path.join(d, 'foo')
303 for umask in (0o77, 0o07, 0o22):
303 for umask in (0o77, 0o07, 0o22):
304 os.umask(umask)
304 os.umask(umask)
305 f = open(fname, 'w')
305 f = open(fname, 'w')
306 f.close()
306 f.close()
307 mode = os.stat(fname).st_mode
307 mode = os.stat(fname).st_mode
308 os.unlink(fname)
308 os.unlink(fname)
309 if mode & 0o777 != ~umask & 0o666:
309 if mode & 0o777 != ~umask & 0o666:
310 return False
310 return False
311 return True
311 return True
312 finally:
312 finally:
313 os.rmdir(d)
313 os.rmdir(d)
314
314
315 @check("unix-socket", "AF_UNIX socket family")
315 @check("unix-socket", "AF_UNIX socket family")
316 def has_unix_socket():
316 def has_unix_socket():
317 return getattr(socket, 'AF_UNIX', None) is not None
317 return getattr(socket, 'AF_UNIX', None) is not None
318
318
319 @check("root", "root permissions")
319 @check("root", "root permissions")
320 def has_root():
320 def has_root():
321 return getattr(os, 'geteuid', None) and os.geteuid() == 0
321 return getattr(os, 'geteuid', None) and os.geteuid() == 0
322
322
323 @check("pyflakes", "Pyflakes python linter")
323 @check("pyflakes", "Pyflakes python linter")
324 def has_pyflakes():
324 def has_pyflakes():
325 return matchoutput("sh -c \"echo 'import re' 2>&1 | pyflakes\"",
325 return matchoutput("sh -c \"echo 'import re' 2>&1 | pyflakes\"",
326 r"<stdin>:1: 're' imported but unused",
326 r"<stdin>:1: 're' imported but unused",
327 True)
327 True)
328
328
329 @check("pygments", "Pygments source highlighting library")
329 @check("pygments", "Pygments source highlighting library")
330 def has_pygments():
330 def has_pygments():
331 try:
331 try:
332 import pygments
332 import pygments
333 pygments.highlight # silence unused import warning
333 pygments.highlight # silence unused import warning
334 return True
334 return True
335 except ImportError:
335 except ImportError:
336 return False
336 return False
337
337
338 @check("outer-repo", "outer repo")
338 @check("outer-repo", "outer repo")
339 def has_outer_repo():
339 def has_outer_repo():
340 # failing for other reasons than 'no repo' imply that there is a repo
340 # failing for other reasons than 'no repo' imply that there is a repo
341 return not matchoutput('hg root 2>&1',
341 return not matchoutput('hg root 2>&1',
342 r'abort: no repository found', True)
342 r'abort: no repository found', True)
343
343
344 @check("ssl", "ssl module available")
344 @check("ssl", "ssl module available")
345 def has_ssl():
345 def has_ssl():
346 try:
346 try:
347 import ssl
347 import ssl
348 ssl.CERT_NONE
348 ssl.CERT_NONE
349 return True
349 return True
350 except ImportError:
350 except ImportError:
351 return False
351 return False
352
352
353 @check("sslcontext", "python >= 2.7.9 ssl")
353 @check("sslcontext", "python >= 2.7.9 ssl")
354 def has_sslcontext():
354 def has_sslcontext():
355 try:
355 try:
356 import ssl
356 import ssl
357 ssl.SSLContext
357 ssl.SSLContext
358 return True
358 return True
359 except (ImportError, AttributeError):
359 except (ImportError, AttributeError):
360 return False
360 return False
361
361
362 @check("defaultcacerts", "can verify SSL certs by system's CA certs store")
362 @check("defaultcacerts", "can verify SSL certs by system's CA certs store")
363 def has_defaultcacerts():
363 def has_defaultcacerts():
364 from mercurial import sslutil
364 from mercurial import sslutil
365 return sslutil._defaultcacerts() != '!'
365 return sslutil._defaultcacerts() != '!'
366
366
367 @check("windows", "Windows")
367 @check("windows", "Windows")
368 def has_windows():
368 def has_windows():
369 return os.name == 'nt'
369 return os.name == 'nt'
370
370
371 @check("system-sh", "system() uses sh")
371 @check("system-sh", "system() uses sh")
372 def has_system_sh():
372 def has_system_sh():
373 return os.name != 'nt'
373 return os.name != 'nt'
374
374
375 @check("serve", "platform and python can manage 'hg serve -d'")
375 @check("serve", "platform and python can manage 'hg serve -d'")
376 def has_serve():
376 def has_serve():
377 return os.name != 'nt' # gross approximation
377 return os.name != 'nt' # gross approximation
378
378
379 @check("test-repo", "running tests from repository")
379 @check("test-repo", "running tests from repository")
380 def has_test_repo():
380 def has_test_repo():
381 t = os.environ["TESTDIR"]
381 t = os.environ["TESTDIR"]
382 return os.path.isdir(os.path.join(t, "..", ".hg"))
382 return os.path.isdir(os.path.join(t, "..", ".hg"))
383
383
384 @check("tic", "terminfo compiler and curses module")
384 @check("tic", "terminfo compiler and curses module")
385 def has_tic():
385 def has_tic():
386 try:
386 try:
387 import curses
387 import curses
388 curses.COLOR_BLUE
388 curses.COLOR_BLUE
389 return matchoutput('test -x "`which tic`"', '')
389 return matchoutput('test -x "`which tic`"', '')
390 except ImportError:
390 except ImportError:
391 return False
391 return False
392
392
393 @check("msys", "Windows with MSYS")
393 @check("msys", "Windows with MSYS")
394 def has_msys():
394 def has_msys():
395 return os.getenv('MSYSTEM')
395 return os.getenv('MSYSTEM')
396
396
397 @check("aix", "AIX")
397 @check("aix", "AIX")
398 def has_aix():
398 def has_aix():
399 return sys.platform.startswith("aix")
399 return sys.platform.startswith("aix")
400
400
401 @check("osx", "OS X")
401 @check("osx", "OS X")
402 def has_osx():
402 def has_osx():
403 return sys.platform == 'darwin'
403 return sys.platform == 'darwin'
404
404
405 @check("docker", "docker support")
405 @check("docker", "docker support")
406 def has_docker():
406 def has_docker():
407 pat = r'A self-sufficient runtime for linux containers\.'
407 pat = r'A self-sufficient runtime for linux containers\.'
408 if matchoutput('docker --help', pat):
408 if matchoutput('docker --help', pat):
409 if 'linux' not in sys.platform:
409 if 'linux' not in sys.platform:
410 # TODO: in theory we should be able to test docker-based
410 # TODO: in theory we should be able to test docker-based
411 # package creation on non-linux using boot2docker, but in
411 # package creation on non-linux using boot2docker, but in
412 # practice that requires extra coordination to make sure
412 # practice that requires extra coordination to make sure
413 # $TESTTEMP is going to be visible at the same path to the
413 # $TESTTEMP is going to be visible at the same path to the
414 # boot2docker VM. If we figure out how to verify that, we
414 # boot2docker VM. If we figure out how to verify that, we
415 # can use the following instead of just saying False:
415 # can use the following instead of just saying False:
416 # return 'DOCKER_HOST' in os.environ
416 # return 'DOCKER_HOST' in os.environ
417 return False
417 return False
418
418
419 return True
419 return True
420 return False
420 return False
421
421
422 @check("debhelper", "debian packaging tools")
422 @check("debhelper", "debian packaging tools")
423 def has_debhelper():
423 def has_debhelper():
424 dpkg = matchoutput('dpkg --version',
424 dpkg = matchoutput('dpkg --version',
425 "Debian `dpkg' package management program")
425 "Debian `dpkg' package management program")
426 dh = matchoutput('dh --help',
426 dh = matchoutput('dh --help',
427 'dh is a part of debhelper.', ignorestatus=True)
427 'dh is a part of debhelper.', ignorestatus=True)
428 dh_py2 = matchoutput('dh_python2 --help',
428 dh_py2 = matchoutput('dh_python2 --help',
429 'other supported Python versions')
429 'other supported Python versions')
430 return dpkg and dh and dh_py2
430 return dpkg and dh and dh_py2
431
431
432 @check("absimport", "absolute_import in __future__")
432 @check("absimport", "absolute_import in __future__")
433 def has_absimport():
433 def has_absimport():
434 import __future__
434 import __future__
435 from mercurial import util
435 from mercurial import util
436 return util.safehasattr(__future__, "absolute_import")
436 return util.safehasattr(__future__, "absolute_import")
437
437
438 @check("py3k", "running with Python 3.x")
438 @check("py3k", "running with Python 3.x")
439 def has_py3k():
439 def has_py3k():
440 return 3 == sys.version_info[0]
440 return 3 == sys.version_info[0]
441
441
442 @check("py3exe", "a Python 3.x interpreter is available")
442 @check("py3exe", "a Python 3.x interpreter is available")
443 def has_python3exe():
443 def has_python3exe():
444 return 'PYTHON3' in os.environ
444 return 'PYTHON3' in os.environ
445
445
446 @check("pure", "running with pure Python code")
446 @check("pure", "running with pure Python code")
447 def has_pure():
447 def has_pure():
448 return any([
448 return any([
449 os.environ.get("HGMODULEPOLICY") == "py",
449 os.environ.get("HGMODULEPOLICY") == "py",
450 os.environ.get("HGTEST_RUN_TESTS_PURE") == "--pure",
450 os.environ.get("HGTEST_RUN_TESTS_PURE") == "--pure",
451 ])
451 ])
452
452
453 @check("slow", "allow slow tests")
453 @check("slow", "allow slow tests")
454 def has_slow():
454 def has_slow():
455 return os.environ.get('HGTEST_SLOW') == 'slow'
455 return os.environ.get('HGTEST_SLOW') == 'slow'
456
456
457 @check("hypothesis", "Hypothesis automated test generation")
457 @check("hypothesis", "Hypothesis automated test generation")
458 def has_hypothesis():
458 def has_hypothesis():
459 try:
459 try:
460 import hypothesis
460 import hypothesis
461 hypothesis.given
461 hypothesis.given
462 return True
462 return True
463 except ImportError:
463 except ImportError:
464 return False
464 return False
General Comments 0
You need to be logged in to leave comments. Login now