##// END OF EJS Templates
tests: make 'f' utility import hashlib unconditionally...
Yuya Nishihara -
r29233:318534bb default
parent child Browse files
Show More
@@ -1,164 +1,159
1 #!/usr/bin/env python
1 #!/usr/bin/env python
2
2
3 """
3 """
4 Utility for inspecting files in various ways.
4 Utility for inspecting files in various ways.
5
5
6 This tool is like the collection of tools found in a unix environment but are
6 This tool is like the collection of tools found in a unix environment but are
7 cross platform and stable and suitable for our needs in the test suite.
7 cross platform and stable and suitable for our needs in the test suite.
8
8
9 This can be used instead of tools like:
9 This can be used instead of tools like:
10 [
10 [
11 dd
11 dd
12 find
12 find
13 head
13 head
14 hexdump
14 hexdump
15 ls
15 ls
16 md5sum
16 md5sum
17 readlink
17 readlink
18 sha1sum
18 sha1sum
19 stat
19 stat
20 tail
20 tail
21 test
21 test
22 readlink.py
22 readlink.py
23 md5sum.py
23 md5sum.py
24 """
24 """
25
25
26 from __future__ import absolute_import
26 from __future__ import absolute_import
27
27
28 import glob
28 import glob
29 import hashlib
29 import optparse
30 import optparse
30 import os
31 import os
31 import re
32 import re
32 import sys
33 import sys
33
34
34 def visit(opts, filenames, outfile):
35 def visit(opts, filenames, outfile):
35 """Process filenames in the way specified in opts, writing output to
36 """Process filenames in the way specified in opts, writing output to
36 outfile."""
37 outfile."""
37 for f in sorted(filenames):
38 for f in sorted(filenames):
38 isstdin = f == '-'
39 isstdin = f == '-'
39 if not isstdin and not os.path.lexists(f):
40 if not isstdin and not os.path.lexists(f):
40 outfile.write('%s: file not found\n' % f)
41 outfile.write('%s: file not found\n' % f)
41 continue
42 continue
42 quiet = opts.quiet and not opts.recurse or isstdin
43 quiet = opts.quiet and not opts.recurse or isstdin
43 isdir = os.path.isdir(f)
44 isdir = os.path.isdir(f)
44 islink = os.path.islink(f)
45 islink = os.path.islink(f)
45 isfile = os.path.isfile(f) and not islink
46 isfile = os.path.isfile(f) and not islink
46 dirfiles = None
47 dirfiles = None
47 content = None
48 content = None
48 facts = []
49 facts = []
49 if isfile:
50 if isfile:
50 if opts.type:
51 if opts.type:
51 facts.append('file')
52 facts.append('file')
52 if opts.hexdump or opts.dump or opts.md5:
53 if opts.hexdump or opts.dump or opts.md5:
53 content = file(f, 'rb').read()
54 content = file(f, 'rb').read()
54 elif islink:
55 elif islink:
55 if opts.type:
56 if opts.type:
56 facts.append('link')
57 facts.append('link')
57 content = os.readlink(f)
58 content = os.readlink(f)
58 elif isstdin:
59 elif isstdin:
59 content = sys.stdin.read()
60 content = sys.stdin.read()
60 if opts.size:
61 if opts.size:
61 facts.append('size=%s' % len(content))
62 facts.append('size=%s' % len(content))
62 elif isdir:
63 elif isdir:
63 if opts.recurse or opts.type:
64 if opts.recurse or opts.type:
64 dirfiles = glob.glob(f + '/*')
65 dirfiles = glob.glob(f + '/*')
65 facts.append('directory with %s files' % len(dirfiles))
66 facts.append('directory with %s files' % len(dirfiles))
66 elif opts.type:
67 elif opts.type:
67 facts.append('type unknown')
68 facts.append('type unknown')
68 if not isstdin:
69 if not isstdin:
69 stat = os.lstat(f)
70 stat = os.lstat(f)
70 if opts.size and not isdir:
71 if opts.size and not isdir:
71 facts.append('size=%s' % stat.st_size)
72 facts.append('size=%s' % stat.st_size)
72 if opts.mode and not islink:
73 if opts.mode and not islink:
73 facts.append('mode=%o' % (stat.st_mode & 0o777))
74 facts.append('mode=%o' % (stat.st_mode & 0o777))
74 if opts.links:
75 if opts.links:
75 facts.append('links=%s' % stat.st_nlink)
76 facts.append('links=%s' % stat.st_nlink)
76 if opts.newer:
77 if opts.newer:
77 # mtime might be in whole seconds so newer file might be same
78 # mtime might be in whole seconds so newer file might be same
78 if stat.st_mtime >= os.stat(opts.newer).st_mtime:
79 if stat.st_mtime >= os.stat(opts.newer).st_mtime:
79 facts.append('newer than %s' % opts.newer)
80 facts.append('newer than %s' % opts.newer)
80 else:
81 else:
81 facts.append('older than %s' % opts.newer)
82 facts.append('older than %s' % opts.newer)
82 if opts.md5 and content is not None:
83 if opts.md5 and content is not None:
83 try:
84 h = hashlib.md5(content)
84 from hashlib import md5
85 facts.append('md5=%s' % h.hexdigest()[:opts.bytes])
85 except ImportError:
86 from md5 import md5
87 facts.append('md5=%s' % md5(content).hexdigest()[:opts.bytes])
88 if opts.sha1 and content is not None:
86 if opts.sha1 and content is not None:
89 try:
87 h = hashlib.sha1(content)
90 from hashlib import sha1
88 facts.append('sha1=%s' % h.hexdigest()[:opts.bytes])
91 except ImportError:
92 from sha import sha as sha1
93 facts.append('sha1=%s' % sha1(content).hexdigest()[:opts.bytes])
94 if isstdin:
89 if isstdin:
95 outfile.write(', '.join(facts) + '\n')
90 outfile.write(', '.join(facts) + '\n')
96 elif facts:
91 elif facts:
97 outfile.write('%s: %s\n' % (f, ', '.join(facts)))
92 outfile.write('%s: %s\n' % (f, ', '.join(facts)))
98 elif not quiet:
93 elif not quiet:
99 outfile.write('%s:\n' % f)
94 outfile.write('%s:\n' % f)
100 if content is not None:
95 if content is not None:
101 chunk = content
96 chunk = content
102 if not islink:
97 if not islink:
103 if opts.lines:
98 if opts.lines:
104 if opts.lines >= 0:
99 if opts.lines >= 0:
105 chunk = ''.join(chunk.splitlines(True)[:opts.lines])
100 chunk = ''.join(chunk.splitlines(True)[:opts.lines])
106 else:
101 else:
107 chunk = ''.join(chunk.splitlines(True)[opts.lines:])
102 chunk = ''.join(chunk.splitlines(True)[opts.lines:])
108 if opts.bytes:
103 if opts.bytes:
109 if opts.bytes >= 0:
104 if opts.bytes >= 0:
110 chunk = chunk[:opts.bytes]
105 chunk = chunk[:opts.bytes]
111 else:
106 else:
112 chunk = chunk[opts.bytes:]
107 chunk = chunk[opts.bytes:]
113 if opts.hexdump:
108 if opts.hexdump:
114 for i in range(0, len(chunk), 16):
109 for i in range(0, len(chunk), 16):
115 s = chunk[i:i + 16]
110 s = chunk[i:i + 16]
116 outfile.write('%04x: %-47s |%s|\n' %
111 outfile.write('%04x: %-47s |%s|\n' %
117 (i, ' '.join('%02x' % ord(c) for c in s),
112 (i, ' '.join('%02x' % ord(c) for c in s),
118 re.sub('[^ -~]', '.', s)))
113 re.sub('[^ -~]', '.', s)))
119 if opts.dump:
114 if opts.dump:
120 if not quiet:
115 if not quiet:
121 outfile.write('>>>\n')
116 outfile.write('>>>\n')
122 outfile.write(chunk)
117 outfile.write(chunk)
123 if not quiet:
118 if not quiet:
124 if chunk.endswith('\n'):
119 if chunk.endswith('\n'):
125 outfile.write('<<<\n')
120 outfile.write('<<<\n')
126 else:
121 else:
127 outfile.write('\n<<< no trailing newline\n')
122 outfile.write('\n<<< no trailing newline\n')
128 if opts.recurse and dirfiles:
123 if opts.recurse and dirfiles:
129 assert not isstdin
124 assert not isstdin
130 visit(opts, dirfiles, outfile)
125 visit(opts, dirfiles, outfile)
131
126
132 if __name__ == "__main__":
127 if __name__ == "__main__":
133 parser = optparse.OptionParser("%prog [options] [filenames]")
128 parser = optparse.OptionParser("%prog [options] [filenames]")
134 parser.add_option("-t", "--type", action="store_true",
129 parser.add_option("-t", "--type", action="store_true",
135 help="show file type (file or directory)")
130 help="show file type (file or directory)")
136 parser.add_option("-m", "--mode", action="store_true",
131 parser.add_option("-m", "--mode", action="store_true",
137 help="show file mode")
132 help="show file mode")
138 parser.add_option("-l", "--links", action="store_true",
133 parser.add_option("-l", "--links", action="store_true",
139 help="show number of links")
134 help="show number of links")
140 parser.add_option("-s", "--size", action="store_true",
135 parser.add_option("-s", "--size", action="store_true",
141 help="show size of file")
136 help="show size of file")
142 parser.add_option("-n", "--newer", action="store",
137 parser.add_option("-n", "--newer", action="store",
143 help="check if file is newer (or same)")
138 help="check if file is newer (or same)")
144 parser.add_option("-r", "--recurse", action="store_true",
139 parser.add_option("-r", "--recurse", action="store_true",
145 help="recurse into directories")
140 help="recurse into directories")
146 parser.add_option("-S", "--sha1", action="store_true",
141 parser.add_option("-S", "--sha1", action="store_true",
147 help="show sha1 hash of the content")
142 help="show sha1 hash of the content")
148 parser.add_option("-M", "--md5", action="store_true",
143 parser.add_option("-M", "--md5", action="store_true",
149 help="show md5 hash of the content")
144 help="show md5 hash of the content")
150 parser.add_option("-D", "--dump", action="store_true",
145 parser.add_option("-D", "--dump", action="store_true",
151 help="dump file content")
146 help="dump file content")
152 parser.add_option("-H", "--hexdump", action="store_true",
147 parser.add_option("-H", "--hexdump", action="store_true",
153 help="hexdump file content")
148 help="hexdump file content")
154 parser.add_option("-B", "--bytes", type="int",
149 parser.add_option("-B", "--bytes", type="int",
155 help="number of characters to dump")
150 help="number of characters to dump")
156 parser.add_option("-L", "--lines", type="int",
151 parser.add_option("-L", "--lines", type="int",
157 help="number of lines to dump")
152 help="number of lines to dump")
158 parser.add_option("-q", "--quiet", action="store_true",
153 parser.add_option("-q", "--quiet", action="store_true",
159 help="no default output")
154 help="no default output")
160 (opts, filenames) = parser.parse_args(sys.argv[1:])
155 (opts, filenames) = parser.parse_args(sys.argv[1:])
161 if not filenames:
156 if not filenames:
162 filenames = ['-']
157 filenames = ['-']
163
158
164 visit(opts, filenames, sys.stdout)
159 visit(opts, filenames, sys.stdout)
General Comments 0
You need to be logged in to leave comments. Login now