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