comparison shasum.py @ 47:5bec7a5d894a

Allow internal output redirection: print() always to explicitely given file objects
author Franz Glasner <fzglas.hg@dom66.de>
date Wed, 19 Jan 2022 09:14:34 +0100
parents b25ef7293bf2
children 58d5a0b6e5b3
comparison
equal deleted inserted replaced
46:dc198b661149 47:5bec7a5d894a
95 sys.exit(64) # :manpage:`sysexits(3)` EX_USAGE 95 sys.exit(64) # :manpage:`sysexits(3)` EX_USAGE
96 96
97 if not opts.algorithm: 97 if not opts.algorithm:
98 opts.algorithm = argv2algo("1") 98 opts.algorithm = argv2algo("1")
99 99
100 opts.dest = None
101
100 return shasum(opts) 102 return shasum(opts)
101 103
102 104
103 def gen_opts(files=[], algorithm="SHA1", bsd=False, text_mode=False, 105 def gen_opts(files=[], algorithm="SHA1", bsd=False, text_mode=False,
104 checklist=False, check=False): 106 checklist=False, check=False, dest=None):
105 if text_mode: 107 if text_mode:
106 raise ValueError("text mode not supported") 108 raise ValueError("text mode not supported")
107 if checklist and check: 109 if checklist and check:
108 raise ValueError("only one of `checklist' or `check' is allowed") 110 raise ValueError("only one of `checklist' or `check' is allowed")
109 opts = argparse.Namespace(files=files, 111 opts = argparse.Namespace(files=files,
110 algorithm=(algotag2algotype(algorithm), 112 algorithm=(algotag2algotype(algorithm),
111 algorithm), 113 algorithm),
112 bsd=bsd, 114 bsd=bsd,
113 checklist=checklist, 115 checklist=checklist,
114 check=check, 116 check=check,
115 text_mode=False) 117 text_mode=False,
118 dest=dest)
116 return opts 119 return opts
117 120
118 121
119 def shasum(opts): 122 def shasum(opts):
120 if opts.check: 123 if opts.check:
143 None, 146 None,
144 opts.algorithm[1], 147 opts.algorithm[1],
145 True) 148 True)
146 else: 149 else:
147 for fn in opts.files: 150 for fn in opts.files:
148 out(sys.stdout, 151 out(opts.dest or sys.stdout,
149 compute_digest_file(opts.algorithm[0], fn), 152 compute_digest_file(opts.algorithm[0], fn),
150 fn, 153 fn,
151 opts.algorithm[1], 154 opts.algorithm[1],
152 True) 155 True)
153 return 0 156 return 0
154 157
155 158
156 def verify_digests_with_checklist(opts): 159 def verify_digests_with_checklist(opts):
160 dest = opts.dest or sys.stdout
157 exit_code = 0 161 exit_code = 0
158 if not opts.files or (len(opts.files) == 1 and opts.files[0] == '-'): 162 if not opts.files or (len(opts.files) == 1 and opts.files[0] == '-'):
159 if PY2: 163 if PY2:
160 if sys.platform == "win32": 164 if sys.platform == "win32":
161 import os, msvcrt # noqa: E401 165 import os, msvcrt # noqa: E401
164 else: 168 else:
165 source = sys.stdin.buffer 169 source = sys.stdin.buffer
166 pl = get_parsed_digest_line_from_checklist(opts.checklist, opts, None) 170 pl = get_parsed_digest_line_from_checklist(opts.checklist, opts, None)
167 if pl is None: 171 if pl is None:
168 exit_code = 1 172 exit_code = 1
169 print("-: MISSING") 173 print("-: MISSING", file=dest)
170 else: 174 else:
171 tag, algo, cl_filename, cl_digest = pl 175 tag, algo, cl_filename, cl_digest = pl
172 computed_digest = compute_digest_stream(algo, source) 176 computed_digest = compute_digest_stream(algo, source)
173 if cl_digest.lower() == computed_digest.lower(): 177 if cl_digest.lower() == computed_digest.lower():
174 res = "OK" 178 res = "OK"
175 else: 179 else:
176 res = "FAILED" 180 res = "FAILED"
177 exit_code = 1 181 exit_code = 1
178 print("{}: {}: {}".format(tag, "-", res)) 182 print("{}: {}: {}".format(tag, "-", res), file=dest)
179 else: 183 else:
180 for fn in opts.files: 184 for fn in opts.files:
181 pl = get_parsed_digest_line_from_checklist(opts.checklist, opts, fn) 185 pl = get_parsed_digest_line_from_checklist(opts.checklist, opts, fn)
182 if pl is None: 186 if pl is None:
183 print("{}: MISSING".format(fn)) 187 print("{}: MISSING".format(fn), file=dest)
184 exit_code = 1 188 exit_code = 1
185 else: 189 else:
186 tag, algo, cl_filename, cl_digest = pl 190 tag, algo, cl_filename, cl_digest = pl
187 computed_digest = compute_digest_file(algo, fn) 191 computed_digest = compute_digest_file(algo, fn)
188 if cl_digest.lower() == computed_digest.lower(): 192 if cl_digest.lower() == computed_digest.lower():
189 res = "OK" 193 res = "OK"
190 else: 194 else:
191 exit_code = 1 195 exit_code = 1
192 res = "FAILED" 196 res = "FAILED"
193 print("{}: {}: {}".format(tag, fn, res)) 197 print("{}: {}: {}".format(tag, fn, res), file=dest)
194 return exit_code 198 return exit_code
195 199
196 200
197 def verify_digests_from_files(opts): 201 def verify_digests_from_files(opts):
202 dest = opts.dest or sys.stdout
198 exit_code = 0 203 exit_code = 0
199 if not opts.files or (len(opts.files) == 1 and opts.files[0] == '-'): 204 if not opts.files or (len(opts.files) == 1 and opts.files[0] == '-'):
200 for checkline in sys.stdin: 205 for checkline in sys.stdin:
201 if not checkline: 206 if not checkline:
202 continue 207 continue
203 r, fn, tag = handle_checkline(opts, checkline) 208 r, fn, tag = handle_checkline(opts, checkline)
204 print("{}: {}: {}".format(tag, fn, r.upper())) 209 print("{}: {}: {}".format(tag, fn, r.upper()), file=dest)
205 if r != "ok" and exit_code == 0: 210 if r != "ok" and exit_code == 0:
206 exit_code = 1 211 exit_code = 1
207 else: 212 else:
208 for fn in opts.files: 213 for fn in opts.files:
209 with io.open(fn, "rt", encoding="utf-8") as checkfile: 214 with io.open(fn, "rt", encoding="utf-8") as checkfile:
210 for checkline in checkfile: 215 for checkline in checkfile:
211 if not checkline: 216 if not checkline:
212 continue 217 continue
213 r, fn, tag = handle_checkline(opts, checkline) 218 r, fn, tag = handle_checkline(opts, checkline)
214 print("{}: {}: {}".format(tag, fn, r.upper())) 219 print("{}: {}: {}".format(tag, fn, r.upper()), file=dest)
215 if r != "ok" and exit_code == 0: 220 if r != "ok" and exit_code == 0:
216 exit_code = 1 221 exit_code = 1
217 return exit_code 222 return exit_code
218 223
219 224