##// END OF EJS Templates
hghave: add "absimport" feature to check "absolute_import" in __future__...
FUJIWARA Katsunori -
r19930:b8316878 default
parent child Browse files
Show More
@@ -1,321 +1,327
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_pyflakes():
236 def has_pyflakes():
237 return matchoutput("sh -c \"echo 'import re' 2>&1 | pyflakes\"",
237 return matchoutput("sh -c \"echo 'import re' 2>&1 | pyflakes\"",
238 r"<stdin>:1: 're' imported but unused",
238 r"<stdin>:1: 're' imported but unused",
239 True)
239 True)
240
240
241 def has_pygments():
241 def has_pygments():
242 try:
242 try:
243 import pygments
243 import pygments
244 return True
244 return True
245 except ImportError:
245 except ImportError:
246 return False
246 return False
247
247
248 def has_outer_repo():
248 def has_outer_repo():
249 # 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
250 return not matchoutput('hg root 2>&1',
250 return not matchoutput('hg root 2>&1',
251 r'abort: no repository found', True)
251 r'abort: no repository found', True)
252
252
253 def has_ssl():
253 def has_ssl():
254 try:
254 try:
255 import ssl
255 import ssl
256 import OpenSSL
256 import OpenSSL
257 OpenSSL.SSL.Context
257 OpenSSL.SSL.Context
258 return True
258 return True
259 except ImportError:
259 except ImportError:
260 return False
260 return False
261
261
262 def has_windows():
262 def has_windows():
263 return os.name == 'nt'
263 return os.name == 'nt'
264
264
265 def has_system_sh():
265 def has_system_sh():
266 return os.name != 'nt'
266 return os.name != 'nt'
267
267
268 def has_serve():
268 def has_serve():
269 return os.name != 'nt' # gross approximation
269 return os.name != 'nt' # gross approximation
270
270
271 def has_tic():
271 def has_tic():
272 return matchoutput('test -x "`which tic`"', '')
272 return matchoutput('test -x "`which tic`"', '')
273
273
274 def has_msys():
274 def has_msys():
275 return os.getenv('MSYSTEM')
275 return os.getenv('MSYSTEM')
276
276
277 def has_aix():
277 def has_aix():
278 return sys.platform.startswith("aix")
278 return sys.platform.startswith("aix")
279
279
280 def has_absimport():
281 import __future__
282 from mercurial import util
283 return util.safehasattr(__future__, "absolute_import")
284
280 checks = {
285 checks = {
281 "true": (lambda: True, "yak shaving"),
286 "true": (lambda: True, "yak shaving"),
282 "false": (lambda: False, "nail clipper"),
287 "false": (lambda: False, "nail clipper"),
283 "baz": (has_baz, "GNU Arch baz client"),
288 "baz": (has_baz, "GNU Arch baz client"),
284 "bzr": (has_bzr, "Canonical's Bazaar client"),
289 "bzr": (has_bzr, "Canonical's Bazaar client"),
285 "bzr114": (has_bzr114, "Canonical's Bazaar client >= 1.14"),
290 "bzr114": (has_bzr114, "Canonical's Bazaar client >= 1.14"),
286 "cacheable": (has_cacheable_fs, "cacheable filesystem"),
291 "cacheable": (has_cacheable_fs, "cacheable filesystem"),
287 "cvs": (has_cvs, "cvs client/server"),
292 "cvs": (has_cvs, "cvs client/server"),
288 "cvs112": (has_cvs112, "cvs client/server >= 1.12"),
293 "cvs112": (has_cvs112, "cvs client/server >= 1.12"),
289 "darcs": (has_darcs, "darcs client"),
294 "darcs": (has_darcs, "darcs client"),
290 "docutils": (has_docutils, "Docutils text processing library"),
295 "docutils": (has_docutils, "Docutils text processing library"),
291 "eol-in-paths": (has_eol_in_paths, "end-of-lines in paths"),
296 "eol-in-paths": (has_eol_in_paths, "end-of-lines in paths"),
292 "execbit": (has_executablebit, "executable bit"),
297 "execbit": (has_executablebit, "executable bit"),
293 "fifo": (has_fifo, "named pipes"),
298 "fifo": (has_fifo, "named pipes"),
294 "gettext": (has_gettext, "GNU Gettext (msgfmt)"),
299 "gettext": (has_gettext, "GNU Gettext (msgfmt)"),
295 "git": (has_git, "git command line client"),
300 "git": (has_git, "git command line client"),
296 "gpg": (has_gpg, "gpg client"),
301 "gpg": (has_gpg, "gpg client"),
297 "hardlink": (has_hardlink, "hardlinks"),
302 "hardlink": (has_hardlink, "hardlinks"),
298 "icasefs": (has_icasefs, "case insensitive file system"),
303 "icasefs": (has_icasefs, "case insensitive file system"),
299 "inotify": (has_inotify, "inotify extension support"),
304 "inotify": (has_inotify, "inotify extension support"),
300 "killdaemons": (has_killdaemons, 'killdaemons.py support'),
305 "killdaemons": (has_killdaemons, 'killdaemons.py support'),
301 "lsprof": (has_lsprof, "python lsprof module"),
306 "lsprof": (has_lsprof, "python lsprof module"),
302 "mtn": (has_mtn, "monotone client (>= 1.0)"),
307 "mtn": (has_mtn, "monotone client (>= 1.0)"),
303 "outer-repo": (has_outer_repo, "outer repo"),
308 "outer-repo": (has_outer_repo, "outer repo"),
304 "p4": (has_p4, "Perforce server and client"),
309 "p4": (has_p4, "Perforce server and client"),
305 "pyflakes": (has_pyflakes, "Pyflakes python linter"),
310 "pyflakes": (has_pyflakes, "Pyflakes python linter"),
306 "pygments": (has_pygments, "Pygments source highlighting library"),
311 "pygments": (has_pygments, "Pygments source highlighting library"),
307 "serve": (has_serve, "platform and python can manage 'hg serve -d'"),
312 "serve": (has_serve, "platform and python can manage 'hg serve -d'"),
308 "ssl": (has_ssl, "python >= 2.6 ssl module and python OpenSSL"),
313 "ssl": (has_ssl, "python >= 2.6 ssl module and python OpenSSL"),
309 "svn": (has_svn, "subversion client and admin tools"),
314 "svn": (has_svn, "subversion client and admin tools"),
310 "svn13": (has_svn13, "subversion client and admin tools >= 1.3"),
315 "svn13": (has_svn13, "subversion client and admin tools >= 1.3"),
311 "svn15": (has_svn15, "subversion client and admin tools >= 1.5"),
316 "svn15": (has_svn15, "subversion client and admin tools >= 1.5"),
312 "svn-bindings": (has_svn_bindings, "subversion python bindings"),
317 "svn-bindings": (has_svn_bindings, "subversion python bindings"),
313 "symlink": (has_symlink, "symbolic links"),
318 "symlink": (has_symlink, "symbolic links"),
314 "system-sh": (has_system_sh, "system() uses sh"),
319 "system-sh": (has_system_sh, "system() uses sh"),
315 "tic": (has_tic, "terminfo compiler"),
320 "tic": (has_tic, "terminfo compiler"),
316 "tla": (has_tla, "GNU Arch tla client"),
321 "tla": (has_tla, "GNU Arch tla client"),
317 "unix-permissions": (has_unix_permissions, "unix-style permissions"),
322 "unix-permissions": (has_unix_permissions, "unix-style permissions"),
318 "windows": (has_windows, "Windows"),
323 "windows": (has_windows, "Windows"),
319 "msys": (has_msys, "Windows with MSYS"),
324 "msys": (has_msys, "Windows with MSYS"),
320 "aix": (has_aix, "AIX"),
325 "aix": (has_aix, "AIX"),
326 "absimport": (has_absimport, "absolute_import in __future__"),
321 }
327 }
General Comments 0
You need to be logged in to leave comments. Login now