comparison cutils/treesum.py @ 386:f045d46e9f3d

treesum: also collect the CRC checksum when reading .treesum files and test for them
author Franz Glasner <fzglas.hg@dom66.de>
date Sat, 17 May 2025 22:41:22 +0200
parents ea73723be05e
children
comparison
equal deleted inserted replaced
385:ea73723be05e 386:f045d46e9f3d
1933 else: 1933 else:
1934 reader = TreesumReader.from_path(fn) 1934 reader = TreesumReader.from_path(fn)
1935 1935
1936 with reader: 1936 with reader:
1937 root = generator = flags = fsencoding = algorithm = digest \ 1937 root = generator = flags = fsencoding = algorithm = digest \
1938 = size = None 1938 = size = crc_checksum = None
1939 errors = set() 1939 errors = set()
1940 comments = [] 1940 comments = []
1941 fnmatch_filters = [] 1941 fnmatch_filters = []
1942 in_block = False 1942 in_block = False
1943 block_no = 0 1943 block_no = 0
1947 raise ValueError( 1947 raise ValueError(
1948 "VERSION not yet handled: %r" % (record[1],)) 1948 "VERSION not yet handled: %r" % (record[1],))
1949 # start a new block 1949 # start a new block
1950 in_block = True 1950 in_block = True
1951 block_no += 1 1951 block_no += 1
1952 root = flags = algorithm = digest = size = None 1952 root = flags = algorithm = digest = size = \
1953 crc_checksum = None
1953 comments = [] 1954 comments = []
1954 elif record[0] == "GENERATOR": 1955 elif record[0] == "GENERATOR":
1955 generator = record[1] 1956 generator = record[1]
1956 elif record[0] == "FSENCODING": 1957 elif record[0] == "FSENCODING":
1957 fsencoding = record[1] 1958 fsencoding = record[1]
1968 elif record[0] in ("TIMESTAMP", "ISOTIMESTAMP"): 1969 elif record[0] in ("TIMESTAMP", "ISOTIMESTAMP"):
1969 pass 1970 pass
1970 elif record[0] == "ACCEPT-TREESUM": 1971 elif record[0] == "ACCEPT-TREESUM":
1971 pass 1972 pass
1972 elif record[0] == "CRC32": 1973 elif record[0] == "CRC32":
1973 pass 1974 crc_checksum = record[1]
1974 # in_block = False 1975 # in_block = False
1975 else: 1976 else:
1976 if not in_block: 1977 if not in_block:
1977 continue 1978 continue
1978 # digest line or size line 1979 # digest line or size line
1988 if not only_last_block: 1989 if not only_last_block:
1989 block_handler( 1990 block_handler(
1990 block_no, 1991 block_no,
1991 root, generator, fsencoding, flags, 1992 root, generator, fsencoding, flags,
1992 fnmatch_filters, 1993 fnmatch_filters,
1993 comments, errors, algorithm, digest, size) 1994 comments, errors, algorithm, digest, size,
1995 crc_checksum)
1994 root = generator = flags = fsencoding = algorithm \ 1996 root = generator = flags = fsencoding = algorithm \
1995 = digest = size = None 1997 = digest = size = None
1996 errors = set() 1998 errors = set()
1997 comments = [] 1999 comments = []
1998 in_block = False 2000 in_block = False
2000 if not in_block: 2002 if not in_block:
2001 if digest is not None or size is not None: 2003 if digest is not None or size is not None:
2002 block_handler( 2004 block_handler(
2003 block_no, 2005 block_no,
2004 root, generator, fsencoding, flags, fnmatch_filters, 2006 root, generator, fsencoding, flags, fnmatch_filters,
2005 comments, errors, algorithm, digest, size) 2007 comments, errors, algorithm, digest, size,
2008 crc_checksum)
2006 else: 2009 else:
2007 logging.warning("missing block end") 2010 logging.warning("missing block end")
2008 2011
2009 2012
2010 def print_block_data(block_no, tag, generator, fsencoding, flags, 2013 def print_block_data(block_no, tag, generator, fsencoding, flags,
2011 fnmatch_filters, comments, errors, 2014 fnmatch_filters, comments, errors,
2012 algorithm, digest, size): 2015 algorithm, digest, size,
2016 crc_checksum):
2013 digeststr = util.n(binascii.hexlify(digest)) if digest else "<no digest>" 2017 digeststr = util.n(binascii.hexlify(digest)) if digest else "<no digest>"
2014 sizestr = str(size) if size is not None else "<no size>" 2018 sizestr = str(size) if size is not None else "<no size>"
2015 print("BLOCK No %d:" % (block_no,)) 2019 print("BLOCK No %d:" % (block_no,))
2016 print(" Tag:", tag) 2020 print(" Tag:", tag)
2017 print(" FS-Encoding:", fsencoding) 2021 print(" FS-Encoding:", fsencoding)
2040 2044
2041 2045
2042 class TreesumInfo(object): 2046 class TreesumInfo(object):
2043 2047
2044 def __init__(self): 2048 def __init__(self):
2045 self._algorithm = self._digest = self._size = None 2049 self._algorithm = self._digest = self._size = self._crc_checksum = None
2046 2050
2047 def __call__(self, block_no, tag, generator, fsencoding, flags, 2051 def __call__(self, block_no, tag, generator, fsencoding, flags,
2048 fnmatch_filters, comments, errors, 2052 fnmatch_filters, comments, errors,
2049 algorithm, digest, size): 2053 algorithm, digest, size,
2054 crc_checksum):
2050 self._algorithm = algorithm 2055 self._algorithm = algorithm
2051 self._digest = digest 2056 self._digest = digest
2052 self._size = size 2057 self._size = size
2058 self._crc_checksum = crc_checksum # this is the hex-encoded value
2053 2059
2054 @property 2060 @property
2055 def algorithm(self): 2061 def algorithm(self):
2056 return self._algorithm 2062 return self._algorithm
2057 2063
2060 return self._digest 2066 return self._digest
2061 2067
2062 @property 2068 @property
2063 def size(self): 2069 def size(self):
2064 return self._size 2070 return self._size
2071
2072 @property
2073 def crc_checksum(self):
2074 if self._crc_checksum:
2075 return self._crc_checksum.upper()
2076 return self._crc_checksum
2065 2077
2066 @classmethod 2078 @classmethod
2067 def collect_last_from_file(cls, digest_file): 2079 def collect_last_from_file(cls, digest_file):
2068 info = cls() 2080 info = cls()
2069 get_infos_from_digestfile([digest_file], info, True) 2081 get_infos_from_digestfile([digest_file], info, True)