Home | History | Annotate | Download | only in build
      1 #!/usr/bin/env python
      2 
      3 import datetime
      4 import os
      5 import re
      6 import sys
      7 import subprocess
      8 
      9 try:
     10     import hashlib
     11     sha1 = hashlib.sha1
     12 except ImportError, e:
     13     import sha
     14     sha1 = sha.sha
     15 
     16 def get_repo_revision(repo_dir):
     17     if not os.path.exists(os.path.join(repo_dir, '.git')):
     18         return 'Unknown (not git)'
     19 
     20     # Get the HEAD revision
     21     proc = subprocess.Popen(['git', 'log', '-1', '--format=%H'],
     22                             stdout=subprocess.PIPE,
     23                             stderr=subprocess.PIPE,
     24                             cwd=repo_dir)
     25     out, err = proc.communicate()
     26     proc.wait()
     27 
     28     rev_sha1 = out.strip()
     29 
     30     # Working Directory Modified
     31     proc = subprocess.Popen(['git', 'status'],
     32                             stdout=subprocess.PIPE,
     33                             stderr=subprocess.PIPE,
     34                             cwd=repo_dir)
     35     out, err = proc.communicate()
     36     proc.wait()
     37 
     38     if out.find('(working directory clean)') == -1:
     39       mod = ' modified'
     40     else:
     41       mod = ''
     42 
     43     return rev_sha1 + mod + ' (git)'
     44 
     45 def compute_sha1(path, global_hasher = None):
     46     f = open(path, 'rb')
     47     hasher = sha1()
     48     while True:
     49         buf = f.read(512)
     50         hasher.update(buf)
     51         if global_hasher:
     52             global_hasher.update(buf)
     53         if len(buf) < 512:
     54             break
     55     f.close()
     56     return hasher.hexdigest()
     57 
     58 def compute_sha1_list(paths):
     59     hasher = sha1()
     60     sha1sums = []
     61     for path in paths:
     62         sha1sums.append(compute_sha1(path, hasher))
     63     return (hasher.hexdigest(), sha1sums)
     64 
     65 def quote_str(s):
     66     result = '"'
     67     for c in s:
     68         if c == '\\':
     69             result += '\\\\'
     70         elif c == '\r':
     71             result += '\\r'
     72         elif c == '\n':
     73             result += '\\n'
     74         elif c == '\t':
     75             result += '\\t'
     76         elif c == '\"':
     77             result += '\\"'
     78         elif c == '\'':
     79             result += '\\\''
     80         else:
     81             result += c
     82     result += '"'
     83     return result
     84 
     85 def main():
     86     # Check Argument
     87     if len(sys.argv) < 2:
     88         print >> sys.stderr, 'USAGE:', sys.argv[0], '[REPO] [LIBs]'
     89         sys.exit(1)
     90 
     91     # Record Build Time
     92     build_time = datetime.datetime.now().strftime('%Y/%m/%d %H:%M:%S')
     93 
     94     # Repository Directory (For build revision)
     95     repo_dir = sys.argv[1]
     96     build_rev = get_repo_revision(repo_dir)
     97 
     98     # Compute SHA1
     99     lib_list = list(set(sys.argv[2:]))
    100     lib_list.sort()
    101     build_sha1, sha1sum_list = compute_sha1_list(lib_list)
    102 
    103     # Build file list string
    104     lib_list_str = ''
    105     for i, path in enumerate(lib_list):
    106         lib_list_str += '   %s %s\n' % (sha1sum_list[i], path)
    107 
    108     # Print the automatically generated code
    109     print """/* Automatically generated file (DON'T MODIFY) */
    110 
    111 /* Repository directory: %s */
    112 
    113 /* File list:
    114 %s*/
    115 
    116 #ifdef __cplusplus
    117 extern "C" {
    118 #endif
    119 
    120 char const *bccGetBuildTime() {
    121   return %s;
    122 }
    123 
    124 char const *bccGetBuildRev() {
    125   return %s;
    126 }
    127 
    128 char const *bccGetBuildSHA1() {
    129   return %s;
    130 }
    131 
    132 #ifdef __cplusplus
    133 }
    134 #endif
    135 
    136 """ % (os.path.abspath(repo_dir),
    137        lib_list_str,
    138        quote_str(build_time),
    139        quote_str(build_rev),
    140        quote_str(build_sha1))
    141 
    142 if __name__ == '__main__':
    143     main()
    144