# # bulkstamp.py: # Stamp versions on all files that can be found in a given tree. # # USAGE: python bulkstamp.py # # Example: python bulkstamp.py 103 ..\win32\Build\ desc.txt # # corresponds to the build number. It will be concatenated with # the major and minor version numbers found in the description file. # # Description information is pulled from an input text file with lines of # the form: # # # # For example: # # PyWinTypes.dll Common types for Python on Win32 # etc # # The product's name, major, and minor versions are specified as: # # name # major # minor # # The tags are case-sensitive. # # Any line beginning with "#" will be ignored. Empty lines are okay. # import sys import os import verstamp import fnmatch import win32api numStamped = 0 g_patterns = [ '*.dll', '*.pyd', '*.exe', '*.ocx', ] def walk(arg, dirname, names): global numStamped vars, debug, descriptions = arg for name in names: for pat in g_patterns: if fnmatch.fnmatch(name, pat): # Handle the "_d" thing. pathname = os.path.join(dirname, name) base, ext = os.path.splitext(name) if base[-2:]=='_d': name = base[:-2] + ext is_dll = ext.lower() != ".exe" if os.path.normcase(name) in descriptions: desc = descriptions[os.path.normcase(name)] try: verstamp.stamp(vars, pathname, desc, is_dll=is_dll) numStamped = numStamped + 1 except win32api.error as exc: print("Could not stamp", pathname, "Error", exc.winerror, "-", exc.strerror) else: print('WARNING: description not provided for:', name) # skip branding this - assume already branded or handled elsewhere # print "Stamped", pathname def load_descriptions(fname, vars): retvars = {} descriptions = { } lines = open(fname, 'r').readlines() for i in range(len(lines)): line = lines[i].strip() if line != '' and line[0] != '#': idx1 = line.find(' ') idx2 = line.find('\t') if idx1 == -1 or idx2 < idx1: idx1 = idx2 if idx1 == -1: print('ERROR: bad syntax in description file at line %d.' % (i+1)) sys.exit(1) key = line[:idx1] val = line[idx1:].strip() if key in vars: retvars[key] = val else: descriptions[key] = val if 'product' not in retvars: print('ERROR: description file is missing the product name.') sys.exit(1) if 'major' not in retvars: print('ERROR: description file is missing the major version number.') sys.exit(1) if 'minor' not in retvars: print('ERROR: description file is missing the minor version number.') sys.exit(1) return retvars, descriptions def scan(build, root, desc, **custom_vars ): global numStamped numStamped = 0 try: build = int(build) except ValueError: print('ERROR: build number is not a number: %s' % build) sys.exit(1) debug = 0 ### maybe fix this one day varList = ['major', 'minor', 'sub', 'company', 'copyright', 'trademarks', 'product'] vars, descriptions = load_descriptions(desc, varList) vars['build'] = build vars.update(custom_vars) arg = vars, debug, descriptions os.path.walk(root, walk, arg) print("Stamped %d files." % (numStamped)) if __name__ == '__main__': if len(sys.argv) != 4: print("ERROR: incorrect invocation. See script's header comments.") sys.exit(1) scan(*tuple(sys.argv[1:]))