##// END OF EJS Templates
tests: 'hghave tic' also requires curses support in Python...
Mads Kiilerich -
r20304:e457321a default
parent child Browse files
Show More
@@ -1,335 +1,340 b''
1 import os, stat, socket
1 import os, stat, socket
2 import re
2 import re
3 import sys
3 import sys
4 import tempfile
4 import tempfile
5
5
6 tempprefix = 'hg-hghave-'
6 tempprefix = 'hg-hghave-'
7
7
8 def matchoutput(cmd, regexp, ignorestatus=False):
8 def matchoutput(cmd, regexp, ignorestatus=False):
9 """Return True if cmd executes successfully and its output
9 """Return True if cmd executes successfully and its output
10 is matched by the supplied regular expression.
10 is matched by the supplied regular expression.
11 """
11 """
12 r = re.compile(regexp)
12 r = re.compile(regexp)
13 fh = os.popen(cmd)
13 fh = os.popen(cmd)
14 s = fh.read()
14 s = fh.read()
15 try:
15 try:
16 ret = fh.close()
16 ret = fh.close()
17 except IOError:
17 except IOError:
18 # Happen in Windows test environment
18 # Happen in Windows test environment
19 ret = 1
19 ret = 1
20 return (ignorestatus or ret is None) and r.search(s)
20 return (ignorestatus or ret is None) and r.search(s)
21
21
22 def has_baz():
22 def has_baz():
23 return matchoutput('baz --version 2>&1', r'baz Bazaar version')
23 return matchoutput('baz --version 2>&1', r'baz Bazaar version')
24
24
25 def has_bzr():
25 def has_bzr():
26 try:
26 try:
27 import bzrlib
27 import bzrlib
28 return bzrlib.__doc__ is not None
28 return bzrlib.__doc__ is not None
29 except ImportError:
29 except ImportError:
30 return False
30 return False
31
31
32 def has_bzr114():
32 def has_bzr114():
33 try:
33 try:
34 import bzrlib
34 import bzrlib
35 return (bzrlib.__doc__ is not None
35 return (bzrlib.__doc__ is not None
36 and bzrlib.version_info[:2] >= (1, 14))
36 and bzrlib.version_info[:2] >= (1, 14))
37 except ImportError:
37 except ImportError:
38 return False
38 return False
39
39
40 def has_cvs():
40 def has_cvs():
41 re = r'Concurrent Versions System.*?server'
41 re = r'Concurrent Versions System.*?server'
42 return matchoutput('cvs --version 2>&1', re) and not has_msys()
42 return matchoutput('cvs --version 2>&1', re) and not has_msys()
43
43
44 def has_cvs112():
44 def has_cvs112():
45 re = r'Concurrent Versions System \(CVS\) 1.12.*?server'
45 re = r'Concurrent Versions System \(CVS\) 1.12.*?server'
46 return matchoutput('cvs --version 2>&1', re) and not has_msys()
46 return matchoutput('cvs --version 2>&1', re) and not has_msys()
47
47
48 def has_darcs():
48 def has_darcs():
49 return matchoutput('darcs --version', r'2\.[2-9]', True)
49 return matchoutput('darcs --version', r'2\.[2-9]', True)
50
50
51 def has_mtn():
51 def has_mtn():
52 return matchoutput('mtn --version', r'monotone', True) and not matchoutput(
52 return matchoutput('mtn --version', r'monotone', True) and not matchoutput(
53 'mtn --version', r'monotone 0\.', True)
53 'mtn --version', r'monotone 0\.', True)
54
54
55 def has_eol_in_paths():
55 def has_eol_in_paths():
56 try:
56 try:
57 fd, path = tempfile.mkstemp(dir='.', prefix=tempprefix, suffix='\n\r')
57 fd, path = tempfile.mkstemp(dir='.', prefix=tempprefix, suffix='\n\r')
58 os.close(fd)
58 os.close(fd)
59 os.remove(path)
59 os.remove(path)
60 return True
60 return True
61 except (IOError, OSError):
61 except (IOError, OSError):
62 return False
62 return False
63
63
64 def has_executablebit():
64 def has_executablebit():
65 try:
65 try:
66 EXECFLAGS = stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH
66 EXECFLAGS = stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH
67 fh, fn = tempfile.mkstemp(dir='.', prefix=tempprefix)
67 fh, fn = tempfile.mkstemp(dir='.', prefix=tempprefix)
68 try:
68 try:
69 os.close(fh)
69 os.close(fh)
70 m = os.stat(fn).st_mode & 0777
70 m = os.stat(fn).st_mode & 0777
71 new_file_has_exec = m & EXECFLAGS
71 new_file_has_exec = m & EXECFLAGS
72 os.chmod(fn, m ^ EXECFLAGS)
72 os.chmod(fn, m ^ EXECFLAGS)
73 exec_flags_cannot_flip = ((os.stat(fn).st_mode & 0777) == m)
73 exec_flags_cannot_flip = ((os.stat(fn).st_mode & 0777) == m)
74 finally:
74 finally:
75 os.unlink(fn)
75 os.unlink(fn)
76 except (IOError, OSError):
76 except (IOError, OSError):
77 # we don't care, the user probably won't be able to commit anyway
77 # we don't care, the user probably won't be able to commit anyway
78 return False
78 return False
79 return not (new_file_has_exec or exec_flags_cannot_flip)
79 return not (new_file_has_exec or exec_flags_cannot_flip)
80
80
81 def has_icasefs():
81 def has_icasefs():
82 # Stolen from mercurial.util
82 # Stolen from mercurial.util
83 fd, path = tempfile.mkstemp(dir='.', prefix=tempprefix)
83 fd, path = tempfile.mkstemp(dir='.', prefix=tempprefix)
84 os.close(fd)
84 os.close(fd)
85 try:
85 try:
86 s1 = os.stat(path)
86 s1 = os.stat(path)
87 d, b = os.path.split(path)
87 d, b = os.path.split(path)
88 p2 = os.path.join(d, b.upper())
88 p2 = os.path.join(d, b.upper())
89 if path == p2:
89 if path == p2:
90 p2 = os.path.join(d, b.lower())
90 p2 = os.path.join(d, b.lower())
91 try:
91 try:
92 s2 = os.stat(p2)
92 s2 = os.stat(p2)
93 return s2 == s1
93 return s2 == s1
94 except OSError:
94 except OSError:
95 return False
95 return False
96 finally:
96 finally:
97 os.remove(path)
97 os.remove(path)
98
98
99 def has_inotify():
99 def has_inotify():
100 try:
100 try:
101 import hgext.inotify.linux.watcher
101 import hgext.inotify.linux.watcher
102 except ImportError:
102 except ImportError:
103 return False
103 return False
104 name = tempfile.mktemp(dir='.', prefix=tempprefix)
104 name = tempfile.mktemp(dir='.', prefix=tempprefix)
105 sock = socket.socket(socket.AF_UNIX)
105 sock = socket.socket(socket.AF_UNIX)
106 try:
106 try:
107 sock.bind(name)
107 sock.bind(name)
108 except socket.error:
108 except socket.error:
109 return False
109 return False
110 sock.close()
110 sock.close()
111 os.unlink(name)
111 os.unlink(name)
112 return True
112 return True
113
113
114 def has_fifo():
114 def has_fifo():
115 if getattr(os, "mkfifo", None) is None:
115 if getattr(os, "mkfifo", None) is None:
116 return False
116 return False
117 name = tempfile.mktemp(dir='.', prefix=tempprefix)
117 name = tempfile.mktemp(dir='.', prefix=tempprefix)
118 try:
118 try:
119 os.mkfifo(name)
119 os.mkfifo(name)
120 os.unlink(name)
120 os.unlink(name)
121 return True
121 return True
122 except OSError:
122 except OSError:
123 return False
123 return False
124
124
125 def has_killdaemons():
125 def has_killdaemons():
126 return True
126 return True
127
127
128 def has_cacheable_fs():
128 def has_cacheable_fs():
129 from mercurial import util
129 from mercurial import util
130
130
131 fd, path = tempfile.mkstemp(dir='.', prefix=tempprefix)
131 fd, path = tempfile.mkstemp(dir='.', prefix=tempprefix)
132 os.close(fd)
132 os.close(fd)
133 try:
133 try:
134 return util.cachestat(path).cacheable()
134 return util.cachestat(path).cacheable()
135 finally:
135 finally:
136 os.remove(path)
136 os.remove(path)
137
137
138 def has_lsprof():
138 def has_lsprof():
139 try:
139 try:
140 import _lsprof
140 import _lsprof
141 return True
141 return True
142 except ImportError:
142 except ImportError:
143 return False
143 return False
144
144
145 def has_gettext():
145 def has_gettext():
146 return matchoutput('msgfmt --version', 'GNU gettext-tools')
146 return matchoutput('msgfmt --version', 'GNU gettext-tools')
147
147
148 def has_git():
148 def has_git():
149 return matchoutput('git --version 2>&1', r'^git version')
149 return matchoutput('git --version 2>&1', r'^git version')
150
150
151 def has_docutils():
151 def has_docutils():
152 try:
152 try:
153 from docutils.core import publish_cmdline
153 from docutils.core import publish_cmdline
154 return True
154 return True
155 except ImportError:
155 except ImportError:
156 return False
156 return False
157
157
158 def getsvnversion():
158 def getsvnversion():
159 m = matchoutput('svn --version --quiet 2>&1', r'^(\d+)\.(\d+)')
159 m = matchoutput('svn --version --quiet 2>&1', r'^(\d+)\.(\d+)')
160 if not m:
160 if not m:
161 return (0, 0)
161 return (0, 0)
162 return (int(m.group(1)), int(m.group(2)))
162 return (int(m.group(1)), int(m.group(2)))
163
163
164 def has_svn15():
164 def has_svn15():
165 return getsvnversion() >= (1, 5)
165 return getsvnversion() >= (1, 5)
166
166
167 def has_svn13():
167 def has_svn13():
168 return getsvnversion() >= (1, 3)
168 return getsvnversion() >= (1, 3)
169
169
170 def has_svn():
170 def has_svn():
171 return matchoutput('svn --version 2>&1', r'^svn, version') and \
171 return matchoutput('svn --version 2>&1', r'^svn, version') and \
172 matchoutput('svnadmin --version 2>&1', r'^svnadmin, version')
172 matchoutput('svnadmin --version 2>&1', r'^svnadmin, version')
173
173
174 def has_svn_bindings():
174 def has_svn_bindings():
175 try:
175 try:
176 import svn.core
176 import svn.core
177 version = svn.core.SVN_VER_MAJOR, svn.core.SVN_VER_MINOR
177 version = svn.core.SVN_VER_MAJOR, svn.core.SVN_VER_MINOR
178 if version < (1, 4):
178 if version < (1, 4):
179 return False
179 return False
180 return True
180 return True
181 except ImportError:
181 except ImportError:
182 return False
182 return False
183
183
184 def has_p4():
184 def has_p4():
185 return (matchoutput('p4 -V', r'Rev\. P4/') and
185 return (matchoutput('p4 -V', r'Rev\. P4/') and
186 matchoutput('p4d -V', r'Rev\. P4D/'))
186 matchoutput('p4d -V', r'Rev\. P4D/'))
187
187
188 def has_symlink():
188 def has_symlink():
189 if getattr(os, "symlink", None) is None:
189 if getattr(os, "symlink", None) is None:
190 return False
190 return False
191 name = tempfile.mktemp(dir='.', prefix=tempprefix)
191 name = tempfile.mktemp(dir='.', prefix=tempprefix)
192 try:
192 try:
193 os.symlink(".", name)
193 os.symlink(".", name)
194 os.unlink(name)
194 os.unlink(name)
195 return True
195 return True
196 except (OSError, AttributeError):
196 except (OSError, AttributeError):
197 return False
197 return False
198
198
199 def has_hardlink():
199 def has_hardlink():
200 from mercurial import util
200 from mercurial import util
201 fh, fn = tempfile.mkstemp(dir='.', prefix=tempprefix)
201 fh, fn = tempfile.mkstemp(dir='.', prefix=tempprefix)
202 os.close(fh)
202 os.close(fh)
203 name = tempfile.mktemp(dir='.', prefix=tempprefix)
203 name = tempfile.mktemp(dir='.', prefix=tempprefix)
204 try:
204 try:
205 try:
205 try:
206 util.oslink(fn, name)
206 util.oslink(fn, name)
207 os.unlink(name)
207 os.unlink(name)
208 return True
208 return True
209 except OSError:
209 except OSError:
210 return False
210 return False
211 finally:
211 finally:
212 os.unlink(fn)
212 os.unlink(fn)
213
213
214 def has_tla():
214 def has_tla():
215 return matchoutput('tla --version 2>&1', r'The GNU Arch Revision')
215 return matchoutput('tla --version 2>&1', r'The GNU Arch Revision')
216
216
217 def has_gpg():
217 def has_gpg():
218 return matchoutput('gpg --version 2>&1', r'GnuPG')
218 return matchoutput('gpg --version 2>&1', r'GnuPG')
219
219
220 def has_unix_permissions():
220 def has_unix_permissions():
221 d = tempfile.mkdtemp(dir='.', prefix=tempprefix)
221 d = tempfile.mkdtemp(dir='.', prefix=tempprefix)
222 try:
222 try:
223 fname = os.path.join(d, 'foo')
223 fname = os.path.join(d, 'foo')
224 for umask in (077, 007, 022):
224 for umask in (077, 007, 022):
225 os.umask(umask)
225 os.umask(umask)
226 f = open(fname, 'w')
226 f = open(fname, 'w')
227 f.close()
227 f.close()
228 mode = os.stat(fname).st_mode
228 mode = os.stat(fname).st_mode
229 os.unlink(fname)
229 os.unlink(fname)
230 if mode & 0777 != ~umask & 0666:
230 if mode & 0777 != ~umask & 0666:
231 return False
231 return False
232 return True
232 return True
233 finally:
233 finally:
234 os.rmdir(d)
234 os.rmdir(d)
235
235
236 def has_root():
236 def has_root():
237 return getattr(os, 'geteuid', None) and os.geteuid() == 0
237 return getattr(os, 'geteuid', None) and os.geteuid() == 0
238
238
239 def has_pyflakes():
239 def has_pyflakes():
240 return matchoutput("sh -c \"echo 'import re' 2>&1 | pyflakes\"",
240 return matchoutput("sh -c \"echo 'import re' 2>&1 | pyflakes\"",
241 r"<stdin>:1: 're' imported but unused",
241 r"<stdin>:1: 're' imported but unused",
242 True)
242 True)
243
243
244 def has_pygments():
244 def has_pygments():
245 try:
245 try:
246 import pygments
246 import pygments
247 return True
247 return True
248 except ImportError:
248 except ImportError:
249 return False
249 return False
250
250
251 def has_outer_repo():
251 def has_outer_repo():
252 # failing for other reasons than 'no repo' imply that there is a repo
252 # failing for other reasons than 'no repo' imply that there is a repo
253 return not matchoutput('hg root 2>&1',
253 return not matchoutput('hg root 2>&1',
254 r'abort: no repository found', True)
254 r'abort: no repository found', True)
255
255
256 def has_ssl():
256 def has_ssl():
257 try:
257 try:
258 import ssl
258 import ssl
259 import OpenSSL
259 import OpenSSL
260 OpenSSL.SSL.Context
260 OpenSSL.SSL.Context
261 return True
261 return True
262 except ImportError:
262 except ImportError:
263 return False
263 return False
264
264
265 def has_windows():
265 def has_windows():
266 return os.name == 'nt'
266 return os.name == 'nt'
267
267
268 def has_system_sh():
268 def has_system_sh():
269 return os.name != 'nt'
269 return os.name != 'nt'
270
270
271 def has_serve():
271 def has_serve():
272 return os.name != 'nt' # gross approximation
272 return os.name != 'nt' # gross approximation
273
273
274 def has_tic():
274 def has_tic():
275 return matchoutput('test -x "`which tic`"', '')
275 try:
276 import curses
277 curses.COLOR_BLUE
278 return matchoutput('test -x "`which tic`"', '')
279 except ImportError:
280 return False
276
281
277 def has_msys():
282 def has_msys():
278 return os.getenv('MSYSTEM')
283 return os.getenv('MSYSTEM')
279
284
280 def has_aix():
285 def has_aix():
281 return sys.platform.startswith("aix")
286 return sys.platform.startswith("aix")
282
287
283 def has_absimport():
288 def has_absimport():
284 import __future__
289 import __future__
285 from mercurial import util
290 from mercurial import util
286 return util.safehasattr(__future__, "absolute_import")
291 return util.safehasattr(__future__, "absolute_import")
287
292
288 def has_py3k():
293 def has_py3k():
289 return 3 == sys.version_info[0]
294 return 3 == sys.version_info[0]
290
295
291 checks = {
296 checks = {
292 "true": (lambda: True, "yak shaving"),
297 "true": (lambda: True, "yak shaving"),
293 "false": (lambda: False, "nail clipper"),
298 "false": (lambda: False, "nail clipper"),
294 "baz": (has_baz, "GNU Arch baz client"),
299 "baz": (has_baz, "GNU Arch baz client"),
295 "bzr": (has_bzr, "Canonical's Bazaar client"),
300 "bzr": (has_bzr, "Canonical's Bazaar client"),
296 "bzr114": (has_bzr114, "Canonical's Bazaar client >= 1.14"),
301 "bzr114": (has_bzr114, "Canonical's Bazaar client >= 1.14"),
297 "cacheable": (has_cacheable_fs, "cacheable filesystem"),
302 "cacheable": (has_cacheable_fs, "cacheable filesystem"),
298 "cvs": (has_cvs, "cvs client/server"),
303 "cvs": (has_cvs, "cvs client/server"),
299 "cvs112": (has_cvs112, "cvs client/server >= 1.12"),
304 "cvs112": (has_cvs112, "cvs client/server >= 1.12"),
300 "darcs": (has_darcs, "darcs client"),
305 "darcs": (has_darcs, "darcs client"),
301 "docutils": (has_docutils, "Docutils text processing library"),
306 "docutils": (has_docutils, "Docutils text processing library"),
302 "eol-in-paths": (has_eol_in_paths, "end-of-lines in paths"),
307 "eol-in-paths": (has_eol_in_paths, "end-of-lines in paths"),
303 "execbit": (has_executablebit, "executable bit"),
308 "execbit": (has_executablebit, "executable bit"),
304 "fifo": (has_fifo, "named pipes"),
309 "fifo": (has_fifo, "named pipes"),
305 "gettext": (has_gettext, "GNU Gettext (msgfmt)"),
310 "gettext": (has_gettext, "GNU Gettext (msgfmt)"),
306 "git": (has_git, "git command line client"),
311 "git": (has_git, "git command line client"),
307 "gpg": (has_gpg, "gpg client"),
312 "gpg": (has_gpg, "gpg client"),
308 "hardlink": (has_hardlink, "hardlinks"),
313 "hardlink": (has_hardlink, "hardlinks"),
309 "icasefs": (has_icasefs, "case insensitive file system"),
314 "icasefs": (has_icasefs, "case insensitive file system"),
310 "inotify": (has_inotify, "inotify extension support"),
315 "inotify": (has_inotify, "inotify extension support"),
311 "killdaemons": (has_killdaemons, 'killdaemons.py support'),
316 "killdaemons": (has_killdaemons, 'killdaemons.py support'),
312 "lsprof": (has_lsprof, "python lsprof module"),
317 "lsprof": (has_lsprof, "python lsprof module"),
313 "mtn": (has_mtn, "monotone client (>= 1.0)"),
318 "mtn": (has_mtn, "monotone client (>= 1.0)"),
314 "outer-repo": (has_outer_repo, "outer repo"),
319 "outer-repo": (has_outer_repo, "outer repo"),
315 "p4": (has_p4, "Perforce server and client"),
320 "p4": (has_p4, "Perforce server and client"),
316 "pyflakes": (has_pyflakes, "Pyflakes python linter"),
321 "pyflakes": (has_pyflakes, "Pyflakes python linter"),
317 "pygments": (has_pygments, "Pygments source highlighting library"),
322 "pygments": (has_pygments, "Pygments source highlighting library"),
318 "root": (has_root, "root permissions"),
323 "root": (has_root, "root permissions"),
319 "serve": (has_serve, "platform and python can manage 'hg serve -d'"),
324 "serve": (has_serve, "platform and python can manage 'hg serve -d'"),
320 "ssl": (has_ssl, "python >= 2.6 ssl module and python OpenSSL"),
325 "ssl": (has_ssl, "python >= 2.6 ssl module and python OpenSSL"),
321 "svn": (has_svn, "subversion client and admin tools"),
326 "svn": (has_svn, "subversion client and admin tools"),
322 "svn13": (has_svn13, "subversion client and admin tools >= 1.3"),
327 "svn13": (has_svn13, "subversion client and admin tools >= 1.3"),
323 "svn15": (has_svn15, "subversion client and admin tools >= 1.5"),
328 "svn15": (has_svn15, "subversion client and admin tools >= 1.5"),
324 "svn-bindings": (has_svn_bindings, "subversion python bindings"),
329 "svn-bindings": (has_svn_bindings, "subversion python bindings"),
325 "symlink": (has_symlink, "symbolic links"),
330 "symlink": (has_symlink, "symbolic links"),
326 "system-sh": (has_system_sh, "system() uses sh"),
331 "system-sh": (has_system_sh, "system() uses sh"),
327 "tic": (has_tic, "terminfo compiler"),
332 "tic": (has_tic, "terminfo compiler and curses module"),
328 "tla": (has_tla, "GNU Arch tla client"),
333 "tla": (has_tla, "GNU Arch tla client"),
329 "unix-permissions": (has_unix_permissions, "unix-style permissions"),
334 "unix-permissions": (has_unix_permissions, "unix-style permissions"),
330 "windows": (has_windows, "Windows"),
335 "windows": (has_windows, "Windows"),
331 "msys": (has_msys, "Windows with MSYS"),
336 "msys": (has_msys, "Windows with MSYS"),
332 "aix": (has_aix, "AIX"),
337 "aix": (has_aix, "AIX"),
333 "absimport": (has_absimport, "absolute_import in __future__"),
338 "absimport": (has_absimport, "absolute_import in __future__"),
334 "py3k": (has_py3k, "running with Python 3.x"),
339 "py3k": (has_py3k, "running with Python 3.x"),
335 }
340 }
General Comments 0
You need to be logged in to leave comments. Login now