aboutsummaryrefslogtreecommitdiffstats
path: root/build/scripts/decimal_md5.py
diff options
context:
space:
mode:
authoralexv-smirnov <alex@ydb.tech>2023-06-13 11:05:01 +0300
committeralexv-smirnov <alex@ydb.tech>2023-06-13 11:05:01 +0300
commitbf0f13dd39ee3e65092ba3572bb5b1fcd125dcd0 (patch)
tree1d1df72c0541a59a81439842f46d95396d3e7189 /build/scripts/decimal_md5.py
parent8bfdfa9a9bd19bddbc58d888e180fbd1218681be (diff)
downloadydb-bf0f13dd39ee3e65092ba3572bb5b1fcd125dcd0.tar.gz
add ymake export to ydb
Diffstat (limited to 'build/scripts/decimal_md5.py')
-rw-r--r--build/scripts/decimal_md5.py79
1 files changed, 79 insertions, 0 deletions
diff --git a/build/scripts/decimal_md5.py b/build/scripts/decimal_md5.py
new file mode 100644
index 0000000000..e70ca80a09
--- /dev/null
+++ b/build/scripts/decimal_md5.py
@@ -0,0 +1,79 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+import hashlib
+import struct
+import sys
+import os
+import argparse
+
+
+def print_code(checksum, func_name):
+ if len(func_name) == 0: # safe fallback for old ya.make files
+ func_name = "DecimalMD5"
+ print 'const char* ' + func_name + '() {return "' + checksum + '";}'
+
+
+def ensure_paths_exist(paths):
+ bad_paths = sorted(
+ path for path in paths
+ if not os.path.exists(path)
+ )
+ if bad_paths:
+ print >> sys.stderr, "decimal_md5 inputs do not exist:"
+ for path in bad_paths:
+ print >> sys.stderr, path
+ sys.exit(1)
+
+
+def _update_digest_with_file_contents(digest, path, block_size=65535):
+ with open(path) as f:
+ while True:
+ block = f.read(block_size)
+ if not block:
+ break
+ digest.update(block)
+
+
+def main():
+ parser = argparse.ArgumentParser()
+ parser.add_argument("--fixed-output", help="don not calculate md5, use this value instead")
+ parser.add_argument("--lower-bits", help="use specified count of lower bits", type=int, default=32)
+ parser.add_argument("--source-root", help="arcadia source root")
+ parser.add_argument("--func-name", help="custom function name to be defined", default="DecimalMD5")
+ parser.add_argument("targets", nargs='*', default=['.'])
+
+ args = parser.parse_args()
+
+ abs_paths = [
+ os.path.join(args.source_root, target)
+ for target in args.targets
+ ]
+ ensure_paths_exist(abs_paths)
+
+ if args.fixed_output:
+ try:
+ bitmask = (1 << args.lower_bits) - 1
+ fmt = '{:0%dd}' % len(str(bitmask))
+ checksum = fmt.format(int(args.fixed_output) & bitmask)
+ except ValueError:
+ raise ValueError("decimal_md5: bad value passed via --fixed-output: %s" % args.fixed_output)
+ print_code(str(checksum), func_name=args.func_name)
+ return
+
+ md5 = hashlib.md5()
+ for path in abs_paths:
+ _update_digest_with_file_contents(md5, path)
+
+ md5_parts = struct.unpack('IIII', md5.digest())
+ md5_int = sum(part << (32 * n) for n, part in enumerate(md5_parts))
+ bitmask = (1 << args.lower_bits) - 1
+ fmt = '{:0%dd}' % len(str(bitmask))
+
+ checksum_str = fmt.format(md5_int & bitmask)
+ print_code(checksum_str, func_name=args.func_name)
+
+
+if __name__ == "__main__":
+ main()
+