Mercurial > hgrepos > Python > apps > py-cutils
comparison cutils/treesum.py @ 178:dac26a2d9de5
Cleanup: remove non used walk-code
| author | Franz Glasner <fzglas.hg@dom66.de> |
|---|---|
| date | Sat, 11 Jan 2025 21:18:53 +0100 |
| parents | 089c40240061 |
| children | 53614a724bf0 |
comparison
equal
deleted
inserted
replaced
| 177:089c40240061 | 178:dac26a2d9de5 |
|---|---|
| 291 opts.size_only, | 291 opts.size_only, |
| 292 opts.print_size, | 292 opts.print_size, |
| 293 minimal=opts.minimal).generate( | 293 minimal=opts.minimal).generate( |
| 294 outfp, d, comment=opts.comment) | 294 outfp, d, comment=opts.comment) |
| 295 | 295 |
| 296 generate_treesum_for_directory( | |
| 297 outfp, d, opts.algorithm, opts.mmap, opts.base64, opts.logical, | |
| 298 opts.follow_directory_symlinks, | |
| 299 opts.metadata_mode, | |
| 300 opts.metadata_full_mode, | |
| 301 opts.metadata_mtime, | |
| 302 opts.size_only, | |
| 303 opts.print_size, | |
| 304 minimal=opts.minimal, | |
| 305 comment=opts.comment) | |
| 306 | |
| 307 | 296 |
| 308 class V1DirectoryTreesumGenerator(object): | 297 class V1DirectoryTreesumGenerator(object): |
| 309 | 298 |
| 310 def __init__(self, algorithm, use_mmap, use_base64, | 299 def __init__(self, algorithm, use_mmap, use_base64, |
| 311 handle_root_logical, follow_directory_symlinks, | 300 handle_root_logical, follow_directory_symlinks, |
| 529 self._outfp.write(format_bsd_line( | 518 self._outfp.write(format_bsd_line( |
| 530 self._algorithm[1], dir_dgst.digest(), opath, | 519 self._algorithm[1], dir_dgst.digest(), opath, |
| 531 self._use_base64)) | 520 self._use_base64)) |
| 532 self._outfp.flush() | 521 self._outfp.flush() |
| 533 return (dir_dgst.digest(), dir_size) | 522 return (dir_dgst.digest(), dir_size) |
| 534 | |
| 535 | |
| 536 def generate_treesum_for_directory( | |
| 537 outfp, root, algorithm, use_mmap, use_base64, handle_root_logical, | |
| 538 follow_directory_symlinks, with_metadata_mode, with_metadata_full_mode, | |
| 539 with_metadata_mtime, size_only, print_size, | |
| 540 minimal=None, comment=None): | |
| 541 """ | |
| 542 | |
| 543 :param outfp: a *binary* file with a "write()" and a "flush()" method | |
| 544 | |
| 545 """ | |
| 546 outfp.write(format_bsd_line("VERSION", "1", None, False)) | |
| 547 outfp.flush() | |
| 548 | |
| 549 # Note given non-default flags that are relevant for directory traversal | |
| 550 flags = [] | |
| 551 if with_metadata_full_mode: | |
| 552 flags.append("with-metadata-fullmode") | |
| 553 elif with_metadata_mode: | |
| 554 flags.append("with-metadata-mode") | |
| 555 if with_metadata_mtime: | |
| 556 flags.append("with-metadata-mtime") | |
| 557 if handle_root_logical: | |
| 558 flags.append("logical") | |
| 559 if follow_directory_symlinks: | |
| 560 flags.append("follow-directory-symlinks") | |
| 561 if size_only: | |
| 562 flags.append("size-only") | |
| 563 else: | |
| 564 if print_size: | |
| 565 flags.append("print-size") | |
| 566 if flags: | |
| 567 flags.sort() | |
| 568 outfp.write(format_bsd_line("FLAGS", ",".join(flags), None, False)) | |
| 569 outfp.flush() | |
| 570 | |
| 571 if minimal is None: | |
| 572 # Write execution timestamps in POSIX epoch and ISO format | |
| 573 ts = int(time.time()) | |
| 574 outfp.write(format_bsd_line("TIMESTAMP", ts, None, False)) | |
| 575 ts = (datetime.datetime.utcfromtimestamp(ts)).isoformat("T") | |
| 576 outfp.write(format_bsd_line("ISOTIMESTAMP", ts, None, False)) | |
| 577 outfp.flush() | |
| 578 | |
| 579 if comment: | |
| 580 for line in comment: | |
| 581 outfp.write(format_bsd_line("COMMENT", None, line, False)) | |
| 582 | |
| 583 if minimal is not None: | |
| 584 outfp.write( | |
| 585 format_bsd_line( | |
| 586 "ROOT", None, minimal if minimal else "", False)) | |
| 587 else: | |
| 588 outfp.write(format_bsd_line("ROOT", None, root, False)) | |
| 589 outfp.flush() | |
| 590 | |
| 591 dir_digests = {} | |
| 592 | |
| 593 if not handle_root_logical and os.path.islink(root): | |
| 594 linktgt = util.fsencode(os.readlink(root)) | |
| 595 linkdgst = algorithm[0]() | |
| 596 linkdgst.update( | |
| 597 util.interpolate_bytes(b"%d:%s,", len(linktgt), linktgt)) | |
| 598 dir_dgst = algorithm[0]() | |
| 599 dir_dgst.update(b"1:L,") | |
| 600 dir_dgst.update( | |
| 601 util.interpolate_bytes( | |
| 602 b"%d:%s,", len(linkdgst.digest()), linkdgst.digest())) | |
| 603 if size_only: | |
| 604 outfp.write( | |
| 605 format_bsd_line( | |
| 606 "SIZE", | |
| 607 None, | |
| 608 "./@", | |
| 609 False, | |
| 610 0)) | |
| 611 else: | |
| 612 outfp.write( | |
| 613 format_bsd_line( | |
| 614 algorithm[1], | |
| 615 dir_dgst.digest(), | |
| 616 "./@", | |
| 617 use_base64)) | |
| 618 outfp.flush() | |
| 619 return | |
| 620 | |
| 621 for top, fsobjects in walk.walk( | |
| 622 root, | |
| 623 follow_symlinks=follow_directory_symlinks): | |
| 624 dir_dgst = algorithm[0]() | |
| 625 dir_size = 0 | |
| 626 | |
| 627 for fso in fsobjects: | |
| 628 if fso.is_dir: | |
| 629 if fso.is_symlink and not follow_directory_symlinks: | |
| 630 linktgt = util.fsencode(os.readlink(fso.path)) | |
| 631 linkdgst = algorithm[0]() | |
| 632 linkdgst.update( | |
| 633 util.interpolate_bytes( | |
| 634 b"%d:%s,", len(linktgt), linktgt)) | |
| 635 dir_dgst.update(util.interpolate_bytes( | |
| 636 b"1:S,%d:%s,", len(fso.fsname), fso.fsname)) | |
| 637 # no mtime and no mode for symlinks | |
| 638 dir_dgst.update(util.interpolate_bytes( | |
| 639 b"%d:%s,", | |
| 640 len(linkdgst.digest()), linkdgst.digest())) | |
| 641 opath = "/".join(top) + "/" + fso.name if top else fso.name | |
| 642 if size_only: | |
| 643 outfp.write( | |
| 644 format_bsd_line( | |
| 645 "SIZE", | |
| 646 None, | |
| 647 "%s/./@" % (opath,), | |
| 648 False, | |
| 649 0)) | |
| 650 else: | |
| 651 outfp.write( | |
| 652 format_bsd_line( | |
| 653 algorithm[1], | |
| 654 linkdgst.digest(), | |
| 655 "%s/./@" % (opath,), | |
| 656 use_base64)) | |
| 657 outfp.flush() | |
| 658 continue | |
| 659 # fetch from dir_digests | |
| 660 dgst, dsz = dir_digests[top + (fso.name,)] | |
| 661 dir_size += dsz | |
| 662 dir_dgst.update(util.interpolate_bytes( | |
| 663 b"1:d,%d:%s,", len(fso.fsname), fso.fsname)) | |
| 664 dir_dgst.update(util.interpolate_bytes( | |
| 665 b"%d:%s,", len(dgst), dgst)) | |
| 666 if with_metadata_full_mode: | |
| 667 modestr = normalized_mode_str(fso.stat.st_mode) | |
| 668 if not isinstance(modestr, bytes): | |
| 669 modestr = modestr.encode("ascii") | |
| 670 dir_dgst.update(util.interpolate_bytes( | |
| 671 b"8:fullmode,%d:%s,", len(modestr), modestr)) | |
| 672 elif with_metadata_mode: | |
| 673 modestr = normalized_compatible_mode_str(fso.stat.st_mode) | |
| 674 if not isinstance(modestr, bytes): | |
| 675 modestr = modestr.encode("ascii") | |
| 676 dir_dgst.update(util.interpolate_bytes( | |
| 677 b"4:mode,%d:%s,", len(modestr), modestr)) | |
| 678 else: | |
| 679 dir_dgst.update(util.interpolate_bytes( | |
| 680 b"1:f,%d:%s,", len(fso.fsname), fso.fsname)) | |
| 681 dir_size += fso.stat.st_size | |
| 682 if with_metadata_mtime: | |
| 683 mtime = datetime.datetime.utcfromtimestamp( | |
| 684 int(fso.stat.st_mtime)) | |
| 685 mtime = mtime.isoformat("T") + "Z" | |
| 686 if not isinstance(mtime, bytes): | |
| 687 mtime = mtime.encode("ascii") | |
| 688 dir_dgst.update(util.interpolate_bytes( | |
| 689 b"5:mtime,%d:%s,", len(mtime), mtime)) | |
| 690 if with_metadata_full_mode: | |
| 691 modestr = normalized_mode_str(fso.stat.st_mode) | |
| 692 if not isinstance(modestr, bytes): | |
| 693 modestr = modestr.encode("ascii") | |
| 694 dir_dgst.update(util.interpolate_bytes( | |
| 695 b"8:fullmode,%d:%s,", len(modestr), modestr)) | |
| 696 elif with_metadata_mode: | |
| 697 modestr = normalized_compatible_mode_str(fso.stat.st_mode) | |
| 698 if not isinstance(modestr, bytes): | |
| 699 modestr = modestr.encode("ascii") | |
| 700 dir_dgst.update(util.interpolate_bytes( | |
| 701 b"4:mode,%d:%s,", len(modestr), modestr)) | |
| 702 if not size_only: | |
| 703 dgst = digest.compute_digest_file( | |
| 704 algorithm[0], fso.path, use_mmap=use_mmap) | |
| 705 dir_dgst.update(util.interpolate_bytes( | |
| 706 b"%d:%s,", len(dgst), dgst)) | |
| 707 opath = "/".join(top) + "/" + fso.name if top else fso.name | |
| 708 if size_only: | |
| 709 outfp.write( | |
| 710 format_bsd_line( | |
| 711 "SIZE", None, opath, False, fso.stat.st_size)) | |
| 712 else: | |
| 713 if print_size: | |
| 714 outfp.write( | |
| 715 format_bsd_line( | |
| 716 algorithm[1], dgst, opath, use_base64, | |
| 717 fso.stat.st_size)) | |
| 718 else: | |
| 719 outfp.write( | |
| 720 format_bsd_line( | |
| 721 algorithm[1], dgst, opath, use_base64)) | |
| 722 outfp.flush() | |
| 723 opath = "/".join(top) + "/" if top else "" | |
| 724 if size_only: | |
| 725 outfp.write(format_bsd_line( | |
| 726 "SIZE", None, opath, False, dir_size)) | |
| 727 else: | |
| 728 if print_size: | |
| 729 outfp.write(format_bsd_line( | |
| 730 algorithm[1], dir_dgst.digest(), opath, | |
| 731 use_base64, dir_size)) | |
| 732 else: | |
| 733 outfp.write(format_bsd_line( | |
| 734 algorithm[1], dir_dgst.digest(), opath, use_base64)) | |
| 735 outfp.flush() | |
| 736 dir_digests[top] = (dir_dgst.digest(), dir_size) | |
| 737 | 523 |
| 738 | 524 |
| 739 def normalized_compatible_mode_str(mode): | 525 def normalized_compatible_mode_str(mode): |
| 740 # XXX FIXME: Windows and "executable" | 526 # XXX FIXME: Windows and "executable" |
| 741 modebits = stat.S_IMODE(mode) | 527 modebits = stat.S_IMODE(mode) |
