![]() |
|
|
Generated: 8 Jan 2009 |
00001 #!/usr/bin/env python 00002 00003 # @file: GaudiPolicy/cmt/fragments/merge_files.py 00004 # @purpose: merge_files <fragment> file into a 'per-project' <merged> file 00005 # @author: Sebastien Binet <binet@cern.ch> 00006 00007 import os 00008 import sys 00009 from datetime import datetime 00010 import locker 00011 00012 def mergeFiles( fragFileName, mergedFileName, commentChar, doMerge ): 00013 00014 isNewFile = not os.path.exists(mergedFileName) 00015 00016 # create an empty file if it does not exist 00017 # "append mode" ensures that, in case of two processes trying to 00018 # create the file, they do not truncate each other file 00019 if isNewFile: 00020 # check if the destination directory exists 00021 path_to_file = os.path.split(mergedFileName)[0] 00022 if not os.path.isdir(path_to_file): 00023 # if doesn't exist, create it 00024 os.makedirs(path_to_file) 00025 open(mergedFileName,'a') 00026 00027 mergedFile = open( mergedFileName, 'r+' ) 00028 00029 # locking file, gaining exclusive access to it 00030 lock = locker.lock( mergedFile ) 00031 try: 00032 00033 00034 startMark = "%s --Beg %s" % ( commentChar, 00035 os.path.basename(fragFileName) ) 00036 timeMark = "%s --Date inserted: %s" % ( commentChar, 00037 str(datetime.now()) ) 00038 endMark = "%s --End %s" % ( commentChar, 00039 os.path.basename(fragFileName) ) 00040 00041 newLines = [ ] 00042 skipBlock = False 00043 for line in mergedFile.readlines(): 00044 if line.startswith(startMark): 00045 skipBlock = True 00046 # remove all the empty lines occurring before the start mark 00047 while (len(newLines) > 0) and (newLines[-1].strip() == ''): 00048 newLines.pop() 00049 if not skipBlock: 00050 newLines.append(line) 00051 if line.startswith(endMark): 00052 skipBlock = False 00053 if skipBlock: 00054 print "WARNING: missing end mark ('%s')"%endMark 00055 00056 if doMerge: 00057 # I do not want to add 2 empty lines at the beginning of a file 00058 if not isNewFile: 00059 newLines.append('\n\n') 00060 newLines.append(startMark+'\n') 00061 newLines.append(timeMark+'\n') 00062 00063 for line in open( fragFileName, 'r' ).readlines(): 00064 newLines.append(line) 00065 00066 newLines.append(endMark+'\n') 00067 00068 mergedFile.seek(0) 00069 mergedFile.truncate(0) 00070 mergedFile.writelines(newLines) 00071 00072 finally: 00073 # unlock file 00074 locker.unlock( mergedFile ) 00075 00076 return 0 00077 00078 if __name__ == "__main__": 00079 00080 from optparse import OptionParser 00081 parser = OptionParser(usage="usage: %prog [options]") 00082 parser.add_option( 00083 "-i", 00084 "--input-file", 00085 dest = "fragFileName", 00086 default = None, 00087 help = "The path and name of the file one wants to merge into the 'master' one" 00088 ) 00089 parser.add_option( 00090 "-m", 00091 "--merged-file", 00092 dest = "mergedFileName", 00093 default = None, 00094 help = "The path and name of the 'master' file which will hold the content of all the other fragment files" 00095 ) 00096 parser.add_option( 00097 "-c", 00098 "--comment-char", 00099 dest = "commentChar", 00100 default = "#", 00101 help = "The type of the commenting character for the type of files at hand (this is an attempt at handling the largest possible use cases)" 00102 ) 00103 parser.add_option( 00104 "--do-merge", 00105 dest = "doMerge", 00106 action = "store_true", 00107 default = True, 00108 help = "Switch to actually carry on with the merging procedure" 00109 ) 00110 parser.add_option( 00111 "--un-merge", 00112 dest = "unMerge", 00113 action = "store_true", 00114 default = False, 00115 help = "Switch to remove our fragment file from the 'master' file" 00116 ) 00117 parser.add_option( 00118 "--stamp-dir", 00119 dest = "stampDir", 00120 action = "store", 00121 default = None, 00122 help = "Create the stamp file in the specified directory. If not specified" 00123 +" the directory of the source file is used." 00124 ) 00125 00126 (options, args) = parser.parse_args() 00127 00128 # ensure consistency... 00129 options.doMerge = not options.unMerge 00130 00131 # allow command line syntax as 00132 # merge_files.py [options] <fragment file> <merged file> 00133 if len(args) > 0 and args[0][0] != "-": options.fragFileName = args[0] 00134 if len(args) > 1 and args[1][0] != "-": options.mergedFileName = args[1] 00135 00136 sc = 1 00137 if not options.fragFileName or \ 00138 not options.mergedFileName : 00139 str(parser.print_help() or "") 00140 print "*** ERROR ***",sys.argv 00141 sys.exit(sc) 00142 pass 00143 00144 if options.stampDir is None: 00145 stampFileName = options.fragFileName + ".stamp" 00146 else: 00147 stampFileName = os.path.join(options.stampDir, 00148 os.path.basename(options.fragFileName) 00149 + ".stamp") 00150 try: 00151 sc = mergeFiles( options.fragFileName, options.mergedFileName, 00152 options.commentChar, 00153 doMerge = options.doMerge ) 00154 stamp = open( stampFileName, 'w' ) 00155 stamp.close() 00156 except IOError, err: 00157 print "ERROR:",err 00158 except Exception, err: 00159 print "ERROR:",err 00160 except: 00161 print "ERROR: unknown error !!" 00162 00163 sys.exit( sc )