Mercurial > hgrepos > Python > apps > py-cutils
comparison cutils/treesum.py @ 173:e081b6ee5570
treesum.py now runs on Python3.4 also: use a workaround for its missing byte % formatting.
No extra module is required for it to run using sha SHA and SHA-2 family of
digests.
| author | Franz Glasner <fzglas.hg@dom66.de> |
|---|---|
| date | Fri, 10 Jan 2025 12:46:44 +0100 |
| parents | 804a823c63f5 |
| children | fc1055878775 |
comparison
equal
deleted
inserted
replaced
| 172:804a823c63f5 | 173:e081b6ee5570 |
|---|---|
| 339 dir_digests = {} | 339 dir_digests = {} |
| 340 | 340 |
| 341 if not handle_root_logical and os.path.islink(root): | 341 if not handle_root_logical and os.path.islink(root): |
| 342 linktgt = util.fsencode(os.readlink(root)) | 342 linktgt = util.fsencode(os.readlink(root)) |
| 343 linkdgst = algorithm[0]() | 343 linkdgst = algorithm[0]() |
| 344 linkdgst.update(b"%d:%s," % (len(linktgt), linktgt)) | 344 linkdgst.update( |
| 345 util.interpolate_bytes(b"%d:%s,", len(linktgt), linktgt)) | |
| 345 dir_dgst = algorithm[0]() | 346 dir_dgst = algorithm[0]() |
| 346 dir_dgst.update(b"1:L,") | 347 dir_dgst.update(b"1:L,") |
| 347 dir_dgst.update( | 348 dir_dgst.update( |
| 348 b"%d:%s," % (len(linkdgst.digest()), linkdgst.digest())) | 349 util.interpolate_bytes( |
| 350 b"%d:%s,", len(linkdgst.digest()), linkdgst.digest())) | |
| 349 if size_only: | 351 if size_only: |
| 350 outfp.write( | 352 outfp.write( |
| 351 format_bsd_line( | 353 format_bsd_line( |
| 352 "SIZE", | 354 "SIZE", |
| 353 None, | 355 None, |
| 373 for fso in fsobjects: | 375 for fso in fsobjects: |
| 374 if fso.is_dir: | 376 if fso.is_dir: |
| 375 if fso.is_symlink and not follow_directory_symlinks: | 377 if fso.is_symlink and not follow_directory_symlinks: |
| 376 linktgt = util.fsencode(os.readlink(fso.path)) | 378 linktgt = util.fsencode(os.readlink(fso.path)) |
| 377 linkdgst = algorithm[0]() | 379 linkdgst = algorithm[0]() |
| 378 linkdgst.update(b"%d:%s," % (len(linktgt), linktgt)) | 380 linkdgst.update( |
| 379 dir_dgst.update(b"1:S,%d:%s," | 381 util.interpolate_bytes( |
| 380 % (len(fso.fsname), fso.fsname)) | 382 b"%d:%s,", len(linktgt), linktgt)) |
| 383 dir_dgst.update(util.interpolate_bytes( | |
| 384 b"1:S,%d:%s,", len(fso.fsname), fso.fsname)) | |
| 381 # no mtime and no mode for symlinks | 385 # no mtime and no mode for symlinks |
| 382 dir_dgst.update( | 386 dir_dgst.update(util.interpolate_bytes( |
| 383 b"%d:%s," | 387 b"%d:%s,", |
| 384 % (len(linkdgst.digest()), linkdgst.digest())) | 388 len(linkdgst.digest()), linkdgst.digest())) |
| 385 opath = "/".join(top) + "/" + fso.name if top else fso.name | 389 opath = "/".join(top) + "/" + fso.name if top else fso.name |
| 386 if size_only: | 390 if size_only: |
| 387 outfp.write( | 391 outfp.write( |
| 388 format_bsd_line( | 392 format_bsd_line( |
| 389 "SIZE", | 393 "SIZE", |
| 401 outfp.flush() | 405 outfp.flush() |
| 402 continue | 406 continue |
| 403 # fetch from dir_digests | 407 # fetch from dir_digests |
| 404 dgst, dsz = dir_digests[top + (fso.name,)] | 408 dgst, dsz = dir_digests[top + (fso.name,)] |
| 405 dir_size += dsz | 409 dir_size += dsz |
| 406 dir_dgst.update(b"1:d,%d:%s," % (len(fso.fsname), fso.fsname)) | 410 dir_dgst.update(util.interpolate_bytes( |
| 407 dir_dgst.update(b"%d:%s," % (len(dgst), dgst)) | 411 b"1:d,%d:%s,", len(fso.fsname), fso.fsname)) |
| 412 dir_dgst.update(util.interpolate_bytes( | |
| 413 b"%d:%s,", len(dgst), dgst)) | |
| 408 if with_metadata_full_mode: | 414 if with_metadata_full_mode: |
| 409 modestr = normalized_mode_str(fso.stat.st_mode) | 415 modestr = normalized_mode_str(fso.stat.st_mode) |
| 410 if not isinstance(modestr, bytes): | 416 if not isinstance(modestr, bytes): |
| 411 modestr = modestr.encode("ascii") | 417 modestr = modestr.encode("ascii") |
| 412 dir_dgst.update(b"8:fullmode,%d:%s," | 418 dir_dgst.update(util.interpolate_bytes( |
| 413 % (len(modestr), modestr)) | 419 b"8:fullmode,%d:%s,", len(modestr), modestr)) |
| 414 elif with_metadata_mode: | 420 elif with_metadata_mode: |
| 415 modestr = normalized_compatible_mode_str(fso.stat.st_mode) | 421 modestr = normalized_compatible_mode_str(fso.stat.st_mode) |
| 416 if not isinstance(modestr, bytes): | 422 if not isinstance(modestr, bytes): |
| 417 modestr = modestr.encode("ascii") | 423 modestr = modestr.encode("ascii") |
| 418 dir_dgst.update(b"4:mode,%d:%s," % (len(modestr), modestr)) | 424 dir_dgst.update(util.interpolate_bytes( |
| 425 b"4:mode,%d:%s,", len(modestr), modestr)) | |
| 419 else: | 426 else: |
| 420 dir_dgst.update(b"1:f,%d:%s," % (len(fso.fsname), fso.fsname)) | 427 dir_dgst.update(util.interpolate_bytes( |
| 428 b"1:f,%d:%s,", len(fso.fsname), fso.fsname)) | |
| 421 dir_size += fso.stat.st_size | 429 dir_size += fso.stat.st_size |
| 422 if with_metadata_mtime: | 430 if with_metadata_mtime: |
| 423 mtime = datetime.datetime.utcfromtimestamp( | 431 mtime = datetime.datetime.utcfromtimestamp( |
| 424 int(fso.stat.st_mtime)) | 432 int(fso.stat.st_mtime)) |
| 425 mtime = mtime.isoformat("T") + "Z" | 433 mtime = mtime.isoformat("T") + "Z" |
| 426 if not isinstance(mtime, bytes): | 434 if not isinstance(mtime, bytes): |
| 427 mtime = mtime.encode("ascii") | 435 mtime = mtime.encode("ascii") |
| 428 dir_dgst.update(b"5:mtime,%d:%s," % (len(mtime), mtime)) | 436 dir_dgst.update(util.interpolate_bytes( |
| 437 b"5:mtime,%d:%s,", len(mtime), mtime)) | |
| 429 if with_metadata_full_mode: | 438 if with_metadata_full_mode: |
| 430 modestr = normalized_mode_str(fso.stat.st_mode) | 439 modestr = normalized_mode_str(fso.stat.st_mode) |
| 431 if not isinstance(modestr, bytes): | 440 if not isinstance(modestr, bytes): |
| 432 modestr = modestr.encode("ascii") | 441 modestr = modestr.encode("ascii") |
| 433 dir_dgst.update(b"8:fullmode,%d:%s," | 442 dir_dgst.update(util.interpolate_bytes( |
| 434 % (len(modestr), modestr)) | 443 b"8:fullmode,%d:%s,", len(modestr), modestr)) |
| 435 elif with_metadata_mode: | 444 elif with_metadata_mode: |
| 436 modestr = normalized_compatible_mode_str(fso.stat.st_mode) | 445 modestr = normalized_compatible_mode_str(fso.stat.st_mode) |
| 437 if not isinstance(modestr, bytes): | 446 if not isinstance(modestr, bytes): |
| 438 modestr = modestr.encode("ascii") | 447 modestr = modestr.encode("ascii") |
| 439 dir_dgst.update(b"4:mode,%d:%s," % (len(modestr), modestr)) | 448 dir_dgst.update(util.interpolate_bytes( |
| 449 b"4:mode,%d:%s,", len(modestr), modestr)) | |
| 440 if not size_only: | 450 if not size_only: |
| 441 dgst = digest.compute_digest_file( | 451 dgst = digest.compute_digest_file( |
| 442 algorithm[0], fso.path, use_mmap=use_mmap) | 452 algorithm[0], fso.path, use_mmap=use_mmap) |
| 443 dir_dgst.update(b"%d:%s," % (len(dgst), dgst)) | 453 dir_dgst.update(util.interpolate_bytes( |
| 454 b"%d:%s,", len(dgst), dgst)) | |
| 444 opath = "/".join(top) + "/" + fso.name if top else fso.name | 455 opath = "/".join(top) + "/" + fso.name if top else fso.name |
| 445 if size_only: | 456 if size_only: |
| 446 outfp.write( | 457 outfp.write( |
| 447 format_bsd_line( | 458 format_bsd_line( |
| 448 "SIZE", None, opath, False, fso.stat.st_size)) | 459 "SIZE", None, opath, False, fso.stat.st_size)) |
| 494 else os.linesep.encode("utf-8") | 505 else os.linesep.encode("utf-8") |
| 495 if not isinstance(what, bytes): | 506 if not isinstance(what, bytes): |
| 496 what = what.encode("ascii") | 507 what = what.encode("ascii") |
| 497 if what == b"TIMESTAMP": | 508 if what == b"TIMESTAMP": |
| 498 assert filename is None | 509 assert filename is None |
| 499 return b"TIMESTAMP = %d%s" % (value, ls) | 510 return util.interpolate_bytes(b"TIMESTAMP = %d%s", value, ls) |
| 500 if what in (b"ISOTIMESTAMP", b"FLAGS", b"VERSION"): | 511 if what in (b"ISOTIMESTAMP", b"FLAGS", b"VERSION"): |
| 501 assert filename is None | 512 assert filename is None |
| 502 if not isinstance(value, bytes): | 513 if not isinstance(value, bytes): |
| 503 value = value.encode("ascii") | 514 value = value.encode("ascii") |
| 504 return b"%s = %s%s" % (what, value, ls) | 515 return util.interpolate_bytes(b"%s = %s%s", what, value, ls) |
| 505 assert filename is not None | 516 assert filename is not None |
| 506 if what == b"COMMENT": | 517 if what == b"COMMENT": |
| 507 if not isinstance(filename, bytes): | 518 if not isinstance(filename, bytes): |
| 508 filename = filename.encode("utf-8") | 519 filename = filename.encode("utf-8") |
| 509 return b"COMMENT (%s)%s" % (filename, ls) | 520 return util.interpolate_bytes(b"COMMENT (%s)%s", filename, ls) |
| 510 if not isinstance(filename, bytes): | 521 if not isinstance(filename, bytes): |
| 511 filename = util.fsencode(filename) | 522 filename = util.fsencode(filename) |
| 512 if what == b"SIZE": | 523 if what == b"SIZE": |
| 513 return b"SIZE (%s) = %d%s" % (filename, size, ls) | 524 return util.interpolate_bytes(b"SIZE (%s) = %d%s", filename, size, ls) |
| 514 if value is None: | 525 if value is None: |
| 515 return b"%s (%s)%s" % (what, filename, ls) | 526 return util.interpolate_bytes(b"%s (%s)%s", what, filename, ls) |
| 516 if use_base64: | 527 if use_base64: |
| 517 value = base64.b64encode(value) | 528 value = base64.b64encode(value) |
| 518 else: | 529 else: |
| 519 value = binascii.hexlify(value) | 530 value = binascii.hexlify(value) |
| 520 if filename != b"./@": | 531 if filename != b"./@": |
| 521 filename = util.normalize_filename(filename, True) | 532 filename = util.normalize_filename(filename, True) |
| 522 if size is None: | 533 if size is None: |
| 523 return b"%s (%s) = %s%s" % (what, filename, value, ls) | 534 return util.interpolate_bytes( |
| 535 b"%s (%s) = %s%s", what, filename, value, ls) | |
| 524 else: | 536 else: |
| 525 return b"%s (%s) = %s,%d%s" % (what, filename, value, size, ls) | 537 return util.interpolate_bytes( |
| 538 b"%s (%s) = %s,%d%s", what, filename, value, size, ls) | |
| 526 | 539 |
| 527 | 540 |
| 528 if __name__ == "__main__": | 541 if __name__ == "__main__": |
| 529 sys.exit(main()) | 542 sys.exit(main()) |
