Mercurial > hgrepos > Python > apps > py-cutils
comparison cutils/treesum.py @ 205:63088d3675bb
Add a "GENERATOR" line with control flats to treesum.py
| author | Franz Glasner <fzglas.hg@dom66.de> |
|---|---|
| date | Wed, 22 Jan 2025 17:45:37 +0100 |
| parents | 07f1d79e6674 |
| children | 73d22943da5a |
comparison
equal
deleted
inserted
replaced
| 204:07f1d79e6674 | 205:63088d3675bb |
|---|---|
| 73 "--full-mode", action="store_true", dest="metadata_full_mode", | 73 "--full-mode", action="store_true", dest="metadata_full_mode", |
| 74 help="Consider all mode bits as returned from stat(2) when " | 74 help="Consider all mode bits as returned from stat(2) when " |
| 75 "computing directory digests. " | 75 "computing directory digests. " |
| 76 "Note that mode bits on symbolic links itself are not " | 76 "Note that mode bits on symbolic links itself are not " |
| 77 "considered.") | 77 "considered.") |
| 78 gp.add_argument( | |
| 79 "--generator", choices=("normal", "full", "none"), | |
| 80 default="normal", | |
| 81 help="""Put a `GENERATOR' line into the output. | |
| 82 `full' prints full Python and OS/platform version information, | |
| 83 `normal' prints just whether Python 2 or Python 3 is used, and `none' | |
| 84 suppresses the output completely. The default is `normal'.""") | |
| 78 gp.add_argument( | 85 gp.add_argument( |
| 79 "--logical", "-L", dest="logical", action="store_true", | 86 "--logical", "-L", dest="logical", action="store_true", |
| 80 default=None, | 87 default=None, |
| 81 help="Follow symbolic links given on command line arguments." | 88 help="Follow symbolic links given on command line arguments." |
| 82 " Note that this is a different setting as to follow symbolic" | 89 " Note that this is a different setting as to follow symbolic" |
| 247 append_output=False, | 254 append_output=False, |
| 248 base64=False, | 255 base64=False, |
| 249 comment=[], | 256 comment=[], |
| 250 follow_directory_symlinks=False, | 257 follow_directory_symlinks=False, |
| 251 full_mode=False, | 258 full_mode=False, |
| 259 generator="normal", | |
| 252 logical=None, | 260 logical=None, |
| 253 minimal=None, | 261 minimal=None, |
| 254 mode=False, | 262 mode=False, |
| 255 mmap=None, | 263 mmap=None, |
| 256 mtime=False, | 264 mtime=False, |
| 263 algorithm=util.argv2algo(algorithm), | 271 algorithm=util.argv2algo(algorithm), |
| 264 append_output=append_output, | 272 append_output=append_output, |
| 265 base64=base64, | 273 base64=base64, |
| 266 comment=comment, | 274 comment=comment, |
| 267 follow_directory_symlinks=follow_directory_symlinks, | 275 follow_directory_symlinks=follow_directory_symlinks, |
| 276 generator=generator, | |
| 268 logical=logical, | 277 logical=logical, |
| 269 minimal=minimal, | 278 minimal=minimal, |
| 270 mmap=mmap, | 279 mmap=mmap, |
| 271 metadata_full_mode=full_mode, | 280 metadata_full_mode=full_mode, |
| 272 metadata_mode=mode, | 281 metadata_mode=mode, |
| 319 for d in opts.directories: | 328 for d in opts.directories: |
| 320 | 329 |
| 321 V1DirectoryTreesumGenerator( | 330 V1DirectoryTreesumGenerator( |
| 322 opts.algorithm, opts.mmap, opts.base64, | 331 opts.algorithm, opts.mmap, opts.base64, |
| 323 opts.logical, opts.follow_directory_symlinks, | 332 opts.logical, opts.follow_directory_symlinks, |
| 333 opts.generator, | |
| 324 opts.metadata_mode, | 334 opts.metadata_mode, |
| 325 opts.metadata_full_mode, | 335 opts.metadata_full_mode, |
| 326 opts.metadata_mtime, | 336 opts.metadata_mtime, |
| 327 opts.size_only, | 337 opts.size_only, |
| 328 opts.print_size, | 338 opts.print_size, |
| 333 | 343 |
| 334 class V1DirectoryTreesumGenerator(object): | 344 class V1DirectoryTreesumGenerator(object): |
| 335 | 345 |
| 336 def __init__(self, algorithm, use_mmap, use_base64, | 346 def __init__(self, algorithm, use_mmap, use_base64, |
| 337 handle_root_logical, follow_directory_symlinks, | 347 handle_root_logical, follow_directory_symlinks, |
| 348 with_generator, | |
| 338 with_metadata_mode, with_metadata_full_mode, | 349 with_metadata_mode, with_metadata_full_mode, |
| 339 with_metadata_mtime, size_only, print_size, utf8_mode, | 350 with_metadata_mtime, size_only, print_size, utf8_mode, |
| 340 minimal=None,): | 351 minimal=None,): |
| 341 super(V1DirectoryTreesumGenerator, self).__init__() | 352 super(V1DirectoryTreesumGenerator, self).__init__() |
| 342 self._algorithm = algorithm | 353 self._algorithm = algorithm |
| 343 self._use_mmap = use_mmap | 354 self._use_mmap = use_mmap |
| 344 self._use_base64 = use_base64 | 355 self._use_base64 = use_base64 |
| 345 self._handle_root_logical = handle_root_logical | 356 self._handle_root_logical = handle_root_logical |
| 346 self._follow_directory_symlinks = follow_directory_symlinks | 357 self._follow_directory_symlinks = follow_directory_symlinks |
| 358 self._with_generator = with_generator | |
| 347 self._with_metadata_mode = with_metadata_mode | 359 self._with_metadata_mode = with_metadata_mode |
| 348 self._with_metadata_full_mode = with_metadata_full_mode | 360 self._with_metadata_full_mode = with_metadata_full_mode |
| 349 self._with_metadata_mtime = with_metadata_mtime | 361 self._with_metadata_mtime = with_metadata_mtime |
| 350 self._size_only = size_only | 362 self._size_only = size_only |
| 351 self._print_size = print_size | 363 self._print_size = print_size |
| 362 self._outfp.resetdigest() | 374 self._outfp.resetdigest() |
| 363 self._outfp.write(format_bsd_line("VERSION", "1", None, False)) | 375 self._outfp.write(format_bsd_line("VERSION", "1", None, False)) |
| 364 self._outfp.write(format_bsd_line( | 376 self._outfp.write(format_bsd_line( |
| 365 "FSENCODING", util.n(walk.getfsencoding().upper()), None, False)) | 377 "FSENCODING", util.n(walk.getfsencoding().upper()), None, False)) |
| 366 self._outfp.flush() | 378 self._outfp.flush() |
| 379 | |
| 380 if self._with_generator == "none": | |
| 381 pass # do nothing | |
| 382 elif self._with_generator == "normal": | |
| 383 self._outfp.write(format_bsd_line( | |
| 384 "GENERATOR", None, b"PY2" if util.PY2 else b"PY3", False)) | |
| 385 elif self._with_generator == "full": | |
| 386 import platform | |
| 387 info = "%s %s, %s" % (platform.python_implementation(), | |
| 388 platform.python_version(), | |
| 389 platform.platform()) | |
| 390 self._outfp.write(format_bsd_line( | |
| 391 "GENERATOR", None, info.encode("utf-8"), False)) | |
| 392 else: | |
| 393 raise NotImplementedError( | |
| 394 "not implemented: %s" % (self._with_generator,)) | |
| 367 | 395 |
| 368 # | 396 # |
| 369 # Note: Given non-default flags that are relevant for | 397 # Note: Given non-default flags that are relevant for |
| 370 # directory traversal. | 398 # directory traversal. |
| 371 # | 399 # |
| 765 if what in (b"FSENCODING", b"ISOTIMESTAMP", b"FLAGS", b"VERSION", | 793 if what in (b"FSENCODING", b"ISOTIMESTAMP", b"FLAGS", b"VERSION", |
| 766 b"CRC32"): | 794 b"CRC32"): |
| 767 assert filename is None | 795 assert filename is None |
| 768 return util.interpolate_bytes(b"%s = %s%s", what, util.b(value), ls) | 796 return util.interpolate_bytes(b"%s = %s%s", what, util.b(value), ls) |
| 769 assert filename is not None | 797 assert filename is not None |
| 770 if what in (b"COMMENT", b"ERROR"): | 798 if what in (b"COMMENT", b"ERROR", b"GENERATOR"): |
| 771 return util.interpolate_bytes( | 799 return util.interpolate_bytes( |
| 772 b"%s (%s)%s", what, util.b(filename, "utf-8"), ls) | 800 b"%s (%s)%s", what, util.b(filename, "utf-8"), ls) |
| 773 if not isinstance(filename, bytes): | 801 if not isinstance(filename, bytes): |
| 774 filename = util.fsencode(filename) | 802 filename = util.fsencode(filename) |
| 775 if what == b"SIZE": | 803 if what == b"SIZE": |
| 798 | 826 |
| 799 """ | 827 """ |
| 800 | 828 |
| 801 PATTERN0 = re.compile(br"\A[ \t]*\r?\n\Z") # empty lines | 829 PATTERN0 = re.compile(br"\A[ \t]*\r?\n\Z") # empty lines |
| 802 PATTERN1 = re.compile(br"\A(VERSION|FSENCODING|FLAGS|TIMESTAMP|ISOTIMESTAMP|CRC32)[ \t]*=[ \t]*([^ \t]+)[ \t]*\r?\n\Z") # noqa: E501 line too long | 830 PATTERN1 = re.compile(br"\A(VERSION|FSENCODING|FLAGS|TIMESTAMP|ISOTIMESTAMP|CRC32)[ \t]*=[ \t]*([^ \t]+)[ \t]*\r?\n\Z") # noqa: E501 line too long |
| 803 PATTERN2 = re.compile(br"\A(ROOT|COMMENT|ERROR)[ \t]*\((.*)\)[ \t]*\r?\n\Z") # noqa: E501 line too long | 831 PATTERN2 = re.compile(br"\A(ROOT|COMMENT|ERROR|GENERATOR)[ \t]*\((.*)\)[ \t]*\r?\n\Z") # noqa: E501 line too long |
| 804 PATTERN3 = re.compile(br"\ASIZE[ \t]*\((.*)\)[ \t]*=[ \t]*(\d+)[ \t]*\r?\n\Z") # noqa: E501 line too long | 832 PATTERN3 = re.compile(br"\ASIZE[ \t]*\((.*)\)[ \t]*=[ \t]*(\d+)[ \t]*\r?\n\Z") # noqa: E501 line too long |
| 805 PATTERN4 = re.compile(br"\A([A-Za-z0-9_-]+)[ \t]*\((.*)\)[ \t]*=[ \t]*([A-Za-z0-9=+/]+)(,(\d+))?[ \t]*\r?\n\Z") # noqa: E501 line too long | 833 PATTERN4 = re.compile(br"\A([A-Za-z0-9_-]+)[ \t]*\((.*)\)[ \t]*=[ \t]*([A-Za-z0-9=+/]+)(,(\d+))?[ \t]*\r?\n\Z") # noqa: E501 line too long |
| 806 | 834 |
| 807 def __init__(self, _fp, _filename, _own_fp): | 835 def __init__(self, _fp, _filename, _own_fp): |
| 808 self._fp = _fp | 836 self._fp = _fp |
| 925 return (util.n(mo.group(1)), util.n(mo.group(2))) | 953 return (util.n(mo.group(1)), util.n(mo.group(2))) |
| 926 else: | 954 else: |
| 927 mo = self.PATTERN2.search(line) | 955 mo = self.PATTERN2.search(line) |
| 928 if mo: | 956 if mo: |
| 929 self._update_crc(line) | 957 self._update_crc(line) |
| 930 if mo.group(1) in (b"COMMENT", b"ERROR"): | 958 if mo.group(1) in (b"COMMENT", b"ERROR", b"GENERATOR"): |
| 931 return (util.u(mo.group(1)), util.u(mo.group(2), "utf-8")) | 959 return (util.u(mo.group(1)), util.u(mo.group(2), "utf-8")) |
| 932 elif mo.group(1) == b"ROOT": | 960 elif mo.group(1) == b"ROOT": |
| 933 return ("ROOT", mo.group(2)) | 961 return ("ROOT", mo.group(2)) |
| 934 assert False, line | 962 assert False, line |
| 935 else: | 963 else: |
