##// END OF EJS Templates
hghave: detect darcs client
Patrick Mezard -
r5410:2daecf3d default
parent child Browse files
Show More
@@ -1,144 +1,148 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
7 import os
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 ret = fh.close()
21 ret = fh.close()
22 return (ignorestatus or ret is None) and r.search(s)
22 return (ignorestatus or ret is None) and r.search(s)
23
23
24 def has_cvs():
24 def has_cvs():
25 return matchoutput('cvs --version 2>&1', r'Concurrent Versions System')
25 return matchoutput('cvs --version 2>&1', r'Concurrent Versions System')
26
26
27 def has_cvsps():
27 def has_cvsps():
28 return matchoutput('cvsps -h -q 2>&1', r'cvsps version', True)
28 return matchoutput('cvsps -h -q 2>&1', r'cvsps version', True)
29
29
30 def has_darcs():
31 return matchoutput('darcs', 'darcs version', True)
32
30 def has_eol_in_paths():
33 def has_eol_in_paths():
31 try:
34 try:
32 fd, path = tempfile.mkstemp(prefix=tempprefix, suffix='\n\r')
35 fd, path = tempfile.mkstemp(prefix=tempprefix, suffix='\n\r')
33 os.close(fd)
36 os.close(fd)
34 os.remove(path)
37 os.remove(path)
35 return True
38 return True
36 except:
39 except:
37 return False
40 return False
38
41
39 def has_executablebit():
42 def has_executablebit():
40 fd, path = tempfile.mkstemp(prefix=tempprefix)
43 fd, path = tempfile.mkstemp(prefix=tempprefix)
41 os.close(fd)
44 os.close(fd)
42 try:
45 try:
43 s = os.lstat(path).st_mode
46 s = os.lstat(path).st_mode
44 os.chmod(path, s | 0100)
47 os.chmod(path, s | 0100)
45 return (os.lstat(path).st_mode & 0100 != 0)
48 return (os.lstat(path).st_mode & 0100 != 0)
46 finally:
49 finally:
47 os.remove(path)
50 os.remove(path)
48
51
49 def has_fifo():
52 def has_fifo():
50 return hasattr(os, "mkfifo")
53 return hasattr(os, "mkfifo")
51
54
52 def has_hotshot():
55 def has_hotshot():
53 try:
56 try:
54 # hotshot.stats tests hotshot and many problematic dependencies
57 # hotshot.stats tests hotshot and many problematic dependencies
55 # like profile.
58 # like profile.
56 import hotshot.stats
59 import hotshot.stats
57 return True
60 return True
58 except ImportError:
61 except ImportError:
59 return False
62 return False
60
63
61 def has_lsprof():
64 def has_lsprof():
62 try:
65 try:
63 import _lsprof
66 import _lsprof
64 return True
67 return True
65 except ImportError:
68 except ImportError:
66 return False
69 return False
67
70
68 def has_git():
71 def has_git():
69 return matchoutput('git --version 2>&1', r'^git version')
72 return matchoutput('git --version 2>&1', r'^git version')
70
73
71 def has_svn():
74 def has_svn():
72 return matchoutput('svn --version 2>&1', r'^svn, version') and \
75 return matchoutput('svn --version 2>&1', r'^svn, version') and \
73 matchoutput('svnadmin --version 2>&1', r'^svnadmin, version')
76 matchoutput('svnadmin --version 2>&1', r'^svnadmin, version')
74
77
75 def has_svn_bindings():
78 def has_svn_bindings():
76 try:
79 try:
77 import svn.core
80 import svn.core
78 return True
81 return True
79 except ImportError:
82 except ImportError:
80 return False
83 return False
81
84
82 def has_symlink():
85 def has_symlink():
83 return hasattr(os, "symlink")
86 return hasattr(os, "symlink")
84
87
85 checks = {
88 checks = {
86 "cvs": (has_cvs, "cvs client"),
89 "cvs": (has_cvs, "cvs client"),
87 "cvsps": (has_cvsps, "cvsps utility"),
90 "cvsps": (has_cvsps, "cvsps utility"),
91 "darcs": (has_darcs, "darcs client"),
88 "eol-in-paths": (has_eol_in_paths, "end-of-lines in paths"),
92 "eol-in-paths": (has_eol_in_paths, "end-of-lines in paths"),
89 "execbit": (has_executablebit, "executable bit"),
93 "execbit": (has_executablebit, "executable bit"),
90 "fifo": (has_fifo, "named pipes"),
94 "fifo": (has_fifo, "named pipes"),
91 "git": (has_git, "git command line client"),
95 "git": (has_git, "git command line client"),
92 "hotshot": (has_hotshot, "python hotshot module"),
96 "hotshot": (has_hotshot, "python hotshot module"),
93 "lsprof": (has_lsprof, "python lsprof module"),
97 "lsprof": (has_lsprof, "python lsprof module"),
94 "svn": (has_svn, "subversion client and admin tools"),
98 "svn": (has_svn, "subversion client and admin tools"),
95 "svn-bindings": (has_svn_bindings, "subversion python bindings"),
99 "svn-bindings": (has_svn_bindings, "subversion python bindings"),
96 "symlink": (has_symlink, "symbolic links"),
100 "symlink": (has_symlink, "symbolic links"),
97 }
101 }
98
102
99 def list_features():
103 def list_features():
100 for name, feature in checks.iteritems():
104 for name, feature in checks.iteritems():
101 desc = feature[1]
105 desc = feature[1]
102 print name + ':', desc
106 print name + ':', desc
103
107
104 parser = optparse.OptionParser("%prog [options] [features]")
108 parser = optparse.OptionParser("%prog [options] [features]")
105 parser.add_option("--list-features", action="store_true",
109 parser.add_option("--list-features", action="store_true",
106 help="list available features")
110 help="list available features")
107 parser.add_option("-q", "--quiet", action="store_true",
111 parser.add_option("-q", "--quiet", action="store_true",
108 help="check features silently")
112 help="check features silently")
109
113
110 if __name__ == '__main__':
114 if __name__ == '__main__':
111 options, args = parser.parse_args()
115 options, args = parser.parse_args()
112 if options.list_features:
116 if options.list_features:
113 list_features()
117 list_features()
114 sys.exit(0)
118 sys.exit(0)
115
119
116 quiet = options.quiet
120 quiet = options.quiet
117
121
118 failures = 0
122 failures = 0
119
123
120 def error(msg):
124 def error(msg):
121 global failures
125 global failures
122 if not quiet:
126 if not quiet:
123 sys.stderr.write(msg + '\n')
127 sys.stderr.write(msg + '\n')
124 failures += 1
128 failures += 1
125
129
126 for feature in args:
130 for feature in args:
127 negate = feature.startswith('no-')
131 negate = feature.startswith('no-')
128 if negate:
132 if negate:
129 feature = feature[3:]
133 feature = feature[3:]
130
134
131 if feature not in checks:
135 if feature not in checks:
132 error('hghave: unknown feature: ' + feature)
136 error('hghave: unknown feature: ' + feature)
133 continue
137 continue
134
138
135 check, desc = checks[feature]
139 check, desc = checks[feature]
136 if not negate and not check():
140 if not negate and not check():
137 error('hghave: missing feature: ' + desc)
141 error('hghave: missing feature: ' + desc)
138 elif negate and check():
142 elif negate and check():
139 error('hghave: system supports %s' % desc)
143 error('hghave: system supports %s' % desc)
140
144
141 if failures != 0:
145 if failures != 0:
142 sys.exit(1)
146 sys.exit(1)
143
147
144
148
General Comments 0
You need to be logged in to leave comments. Login now