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