普通文本  |  144行  |  3.13 KB

#!/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()