#!/usr/bin/env python import datetime import os import re import sys import subprocess try: import hashlib sha1 = hashlib.sha1 except ImportError, e: import sha sha1 = sha.sha def get_repo_revision(repo_dir): if not os.path.exists(os.path.join(repo_dir, '.git')): return 'Unknown (not git)' # Get the HEAD revision proc = subprocess.Popen(['git', 'log', '-1', '--format=%H'], stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=repo_dir) out, err = proc.communicate() proc.wait() rev_sha1 = out.strip() # Working Directory Modified proc = subprocess.Popen(['git', 'status'], stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=repo_dir) out, err = proc.communicate() proc.wait() if out.find('(working directory clean)') == -1: mod = ' modified' else: mod = '' return rev_sha1 + mod + ' (git)' def compute_sha1(path, global_hasher = None): f = open(path, 'rb') hasher = sha1() while True: buf = f.read(512) hasher.update(buf) if global_hasher: global_hasher.update(buf) if len(buf) < 512: break f.close() return hasher.hexdigest() def compute_sha1_list(paths): hasher = sha1() sha1sums = [] for path in paths: sha1sums.append(compute_sha1(path, hasher)) return (hasher.hexdigest(), sha1sums) def quote_str(s): result = '"' for c in s: if c == '\\': result += '\\\\' elif c == '\r': result += '\\r' elif c == '\n': result += '\\n' elif c == '\t': result += '\\t' elif c == '\"': result += '\\"' elif c == '\'': result += '\\\'' else: result += c result += '"' return result def main(): # Check Argument if len(sys.argv) < 2: print >> sys.stderr, 'USAGE:', sys.argv[0], '[REPO] [LIBs]' sys.exit(1) # Record Build Time build_time = datetime.datetime.now().strftime('%Y/%m/%d %H:%M:%S') # Repository Directory (For build revision) repo_dir = sys.argv[1] build_rev = get_repo_revision(repo_dir) # Compute SHA1 lib_list = list(set(sys.argv[2:])) lib_list.sort() build_sha1, sha1sum_list = compute_sha1_list(lib_list) # Build file list string lib_list_str = '' for i, path in enumerate(lib_list): lib_list_str += ' %s %s\n' % (sha1sum_list[i], path) # Print the automatically generated code print """/* Automatically generated file (DON'T MODIFY) */ /* Repository directory: %s */ /* File list: %s*/ #ifdef __cplusplus extern "C" { #endif char const *bccGetBuildTime() { return %s; } char const *bccGetBuildRev() { return %s; } char const *bccGetBuildSHA1() { return %s; } #ifdef __cplusplus } #endif """ % (os.path.abspath(repo_dir), lib_list_str, quote_str(build_time), quote_str(build_rev), quote_str(build_sha1)) if __name__ == '__main__': main()