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