##// END OF EJS Templates
py3: use '%d' for os.stat_result.st_nlink instead of '%s'...
Pulkit Goyal -
r38383:06c85cbd default
parent child Browse files
Show More
@@ -1,177 +1,177 b''
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 binascii
28 import binascii
29 import glob
29 import glob
30 import hashlib
30 import hashlib
31 import optparse
31 import optparse
32 import os
32 import os
33 import re
33 import re
34 import sys
34 import sys
35
35
36 # Python 3 adapters
36 # Python 3 adapters
37 ispy3 = (sys.version_info[0] >= 3)
37 ispy3 = (sys.version_info[0] >= 3)
38 if ispy3:
38 if ispy3:
39 def iterbytes(s):
39 def iterbytes(s):
40 for i in range(len(s)):
40 for i in range(len(s)):
41 yield s[i:i + 1]
41 yield s[i:i + 1]
42 else:
42 else:
43 iterbytes = iter
43 iterbytes = iter
44
44
45 def visit(opts, filenames, outfile):
45 def visit(opts, filenames, outfile):
46 """Process filenames in the way specified in opts, writing output to
46 """Process filenames in the way specified in opts, writing output to
47 outfile."""
47 outfile."""
48 for f in sorted(filenames):
48 for f in sorted(filenames):
49 isstdin = f == '-'
49 isstdin = f == '-'
50 if not isstdin and not os.path.lexists(f):
50 if not isstdin and not os.path.lexists(f):
51 outfile.write(b'%s: file not found\n' % f.encode('utf-8'))
51 outfile.write(b'%s: file not found\n' % f.encode('utf-8'))
52 continue
52 continue
53 quiet = opts.quiet and not opts.recurse or isstdin
53 quiet = opts.quiet and not opts.recurse or isstdin
54 isdir = os.path.isdir(f)
54 isdir = os.path.isdir(f)
55 islink = os.path.islink(f)
55 islink = os.path.islink(f)
56 isfile = os.path.isfile(f) and not islink
56 isfile = os.path.isfile(f) and not islink
57 dirfiles = None
57 dirfiles = None
58 content = None
58 content = None
59 facts = []
59 facts = []
60 if isfile:
60 if isfile:
61 if opts.type:
61 if opts.type:
62 facts.append(b'file')
62 facts.append(b'file')
63 if any((opts.hexdump, opts.dump, opts.md5, opts.sha1, opts.sha256)):
63 if any((opts.hexdump, opts.dump, opts.md5, opts.sha1, opts.sha256)):
64 with open(f, 'rb') as fobj:
64 with open(f, 'rb') as fobj:
65 content = fobj.read()
65 content = fobj.read()
66 elif islink:
66 elif islink:
67 if opts.type:
67 if opts.type:
68 facts.append(b'link')
68 facts.append(b'link')
69 content = os.readlink(f)
69 content = os.readlink(f)
70 elif isstdin:
70 elif isstdin:
71 content = getattr(sys.stdin, 'buffer', sys.stdin).read()
71 content = getattr(sys.stdin, 'buffer', sys.stdin).read()
72 if opts.size:
72 if opts.size:
73 facts.append(b'size=%d' % len(content))
73 facts.append(b'size=%d' % len(content))
74 elif isdir:
74 elif isdir:
75 if opts.recurse or opts.type:
75 if opts.recurse or opts.type:
76 dirfiles = glob.glob(f + '/*')
76 dirfiles = glob.glob(f + '/*')
77 facts.append(b'directory with %d files' % len(dirfiles))
77 facts.append(b'directory with %d files' % len(dirfiles))
78 elif opts.type:
78 elif opts.type:
79 facts.append(b'type unknown')
79 facts.append(b'type unknown')
80 if not isstdin:
80 if not isstdin:
81 stat = os.lstat(f)
81 stat = os.lstat(f)
82 if opts.size and not isdir:
82 if opts.size and not isdir:
83 facts.append(b'size=%d' % stat.st_size)
83 facts.append(b'size=%d' % stat.st_size)
84 if opts.mode and not islink:
84 if opts.mode and not islink:
85 facts.append(b'mode=%o' % (stat.st_mode & 0o777))
85 facts.append(b'mode=%o' % (stat.st_mode & 0o777))
86 if opts.links:
86 if opts.links:
87 facts.append(b'links=%s' % stat.st_nlink)
87 facts.append(b'links=%d' % stat.st_nlink)
88 if opts.newer:
88 if opts.newer:
89 # mtime might be in whole seconds so newer file might be same
89 # mtime might be in whole seconds so newer file might be same
90 if stat.st_mtime >= os.stat(opts.newer).st_mtime:
90 if stat.st_mtime >= os.stat(opts.newer).st_mtime:
91 facts.append(b'newer than %s' % opts.newer)
91 facts.append(b'newer than %s' % opts.newer)
92 else:
92 else:
93 facts.append(b'older than %s' % opts.newer)
93 facts.append(b'older than %s' % opts.newer)
94 if opts.md5 and content is not None:
94 if opts.md5 and content is not None:
95 h = hashlib.md5(content)
95 h = hashlib.md5(content)
96 facts.append(b'md5=%s' % binascii.hexlify(h.digest())[:opts.bytes])
96 facts.append(b'md5=%s' % binascii.hexlify(h.digest())[:opts.bytes])
97 if opts.sha1 and content is not None:
97 if opts.sha1 and content is not None:
98 h = hashlib.sha1(content)
98 h = hashlib.sha1(content)
99 facts.append(b'sha1=%s' % binascii.hexlify(h.digest())[:opts.bytes])
99 facts.append(b'sha1=%s' % binascii.hexlify(h.digest())[:opts.bytes])
100 if opts.sha256 and content is not None:
100 if opts.sha256 and content is not None:
101 h = hashlib.sha256(content)
101 h = hashlib.sha256(content)
102 facts.append(b'sha256=%s' %
102 facts.append(b'sha256=%s' %
103 binascii.hexlify(h.digest())[:opts.bytes])
103 binascii.hexlify(h.digest())[:opts.bytes])
104 if isstdin:
104 if isstdin:
105 outfile.write(b', '.join(facts) + b'\n')
105 outfile.write(b', '.join(facts) + b'\n')
106 elif facts:
106 elif facts:
107 outfile.write(b'%s: %s\n' % (f.encode('utf-8'), b', '.join(facts)))
107 outfile.write(b'%s: %s\n' % (f.encode('utf-8'), b', '.join(facts)))
108 elif not quiet:
108 elif not quiet:
109 outfile.write(b'%s:\n' % f.encode('utf-8'))
109 outfile.write(b'%s:\n' % f.encode('utf-8'))
110 if content is not None:
110 if content is not None:
111 chunk = content
111 chunk = content
112 if not islink:
112 if not islink:
113 if opts.lines:
113 if opts.lines:
114 if opts.lines >= 0:
114 if opts.lines >= 0:
115 chunk = b''.join(chunk.splitlines(True)[:opts.lines])
115 chunk = b''.join(chunk.splitlines(True)[:opts.lines])
116 else:
116 else:
117 chunk = b''.join(chunk.splitlines(True)[opts.lines:])
117 chunk = b''.join(chunk.splitlines(True)[opts.lines:])
118 if opts.bytes:
118 if opts.bytes:
119 if opts.bytes >= 0:
119 if opts.bytes >= 0:
120 chunk = chunk[:opts.bytes]
120 chunk = chunk[:opts.bytes]
121 else:
121 else:
122 chunk = chunk[opts.bytes:]
122 chunk = chunk[opts.bytes:]
123 if opts.hexdump:
123 if opts.hexdump:
124 for i in range(0, len(chunk), 16):
124 for i in range(0, len(chunk), 16):
125 s = chunk[i:i + 16]
125 s = chunk[i:i + 16]
126 outfile.write(b'%04x: %-47s |%s|\n' %
126 outfile.write(b'%04x: %-47s |%s|\n' %
127 (i, b' '.join(
127 (i, b' '.join(
128 b'%02x' % ord(c) for c in iterbytes(s)),
128 b'%02x' % ord(c) for c in iterbytes(s)),
129 re.sub(b'[^ -~]', b'.', s)))
129 re.sub(b'[^ -~]', b'.', s)))
130 if opts.dump:
130 if opts.dump:
131 if not quiet:
131 if not quiet:
132 outfile.write(b'>>>\n')
132 outfile.write(b'>>>\n')
133 outfile.write(chunk)
133 outfile.write(chunk)
134 if not quiet:
134 if not quiet:
135 if chunk.endswith(b'\n'):
135 if chunk.endswith(b'\n'):
136 outfile.write(b'<<<\n')
136 outfile.write(b'<<<\n')
137 else:
137 else:
138 outfile.write(b'\n<<< no trailing newline\n')
138 outfile.write(b'\n<<< no trailing newline\n')
139 if opts.recurse and dirfiles:
139 if opts.recurse and dirfiles:
140 assert not isstdin
140 assert not isstdin
141 visit(opts, dirfiles, outfile)
141 visit(opts, dirfiles, outfile)
142
142
143 if __name__ == "__main__":
143 if __name__ == "__main__":
144 parser = optparse.OptionParser("%prog [options] [filenames]")
144 parser = optparse.OptionParser("%prog [options] [filenames]")
145 parser.add_option("-t", "--type", action="store_true",
145 parser.add_option("-t", "--type", action="store_true",
146 help="show file type (file or directory)")
146 help="show file type (file or directory)")
147 parser.add_option("-m", "--mode", action="store_true",
147 parser.add_option("-m", "--mode", action="store_true",
148 help="show file mode")
148 help="show file mode")
149 parser.add_option("-l", "--links", action="store_true",
149 parser.add_option("-l", "--links", action="store_true",
150 help="show number of links")
150 help="show number of links")
151 parser.add_option("-s", "--size", action="store_true",
151 parser.add_option("-s", "--size", action="store_true",
152 help="show size of file")
152 help="show size of file")
153 parser.add_option("-n", "--newer", action="store",
153 parser.add_option("-n", "--newer", action="store",
154 help="check if file is newer (or same)")
154 help="check if file is newer (or same)")
155 parser.add_option("-r", "--recurse", action="store_true",
155 parser.add_option("-r", "--recurse", action="store_true",
156 help="recurse into directories")
156 help="recurse into directories")
157 parser.add_option("-S", "--sha1", action="store_true",
157 parser.add_option("-S", "--sha1", action="store_true",
158 help="show sha1 hash of the content")
158 help="show sha1 hash of the content")
159 parser.add_option("", "--sha256", action="store_true",
159 parser.add_option("", "--sha256", action="store_true",
160 help="show sha256 hash of the content")
160 help="show sha256 hash of the content")
161 parser.add_option("-M", "--md5", action="store_true",
161 parser.add_option("-M", "--md5", action="store_true",
162 help="show md5 hash of the content")
162 help="show md5 hash of the content")
163 parser.add_option("-D", "--dump", action="store_true",
163 parser.add_option("-D", "--dump", action="store_true",
164 help="dump file content")
164 help="dump file content")
165 parser.add_option("-H", "--hexdump", action="store_true",
165 parser.add_option("-H", "--hexdump", action="store_true",
166 help="hexdump file content")
166 help="hexdump file content")
167 parser.add_option("-B", "--bytes", type="int",
167 parser.add_option("-B", "--bytes", type="int",
168 help="number of characters to dump")
168 help="number of characters to dump")
169 parser.add_option("-L", "--lines", type="int",
169 parser.add_option("-L", "--lines", type="int",
170 help="number of lines to dump")
170 help="number of lines to dump")
171 parser.add_option("-q", "--quiet", action="store_true",
171 parser.add_option("-q", "--quiet", action="store_true",
172 help="no default output")
172 help="no default output")
173 (opts, filenames) = parser.parse_args(sys.argv[1:])
173 (opts, filenames) = parser.parse_args(sys.argv[1:])
174 if not filenames:
174 if not filenames:
175 filenames = ['-']
175 filenames = ['-']
176
176
177 visit(opts, filenames, getattr(sys.stdout, 'buffer', sys.stdout))
177 visit(opts, filenames, getattr(sys.stdout, 'buffer', sys.stdout))
General Comments 0
You need to be logged in to leave comments. Login now