Gaudi Framework, version v23r4

Home   Generated: Mon Sep 17 2012

merge_files.py

Go to the documentation of this file.
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( fragFileNames, mergedFileName, commentChar, doMerge ):
00013 
00014     startMark = "%s --Beg " % commentChar
00015     timeMark  = "%s --Date inserted: %s" % (commentChar, datetime.now())
00016     endMark   = "%s --End " % commentChar
00017     nameOffset = len(startMark)
00018 
00019     basenames = map(os.path.basename, fragFileNames)
00020 
00021     isNewFile = not os.path.exists(mergedFileName)
00022 
00023     # create an empty file if it does not exist
00024     # "append mode" ensures that, in case of two processes trying to
00025     # create the file, they do not truncate each other file
00026     if isNewFile:
00027         # check if the destination directory exists
00028         path_to_file = os.path.split(mergedFileName)[0]
00029         if path_to_file and not os.path.isdir(path_to_file):
00030             # if doesn't exist, create it
00031             os.makedirs(path_to_file)
00032         open(mergedFileName,'a')
00033 
00034     mergedFile = open( mergedFileName, 'r+' )
00035 
00036     # locking file, gaining exclusive access to it
00037     lock = locker.lock( mergedFile )
00038     try:
00039 
00040         newLines = [ ]
00041         skipBlock = ""
00042         for line in mergedFile.readlines():
00043             if line.startswith(startMark) and line[nameOffset:].strip() in basenames:
00044                 skipBlock = endMark + line[nameOffset:].strip()
00045                 # remove all the empty lines occurring before the start mark
00046                 while (len(newLines) > 0) and (newLines[-1].strip() == ''):
00047                     newLines.pop()
00048             if not skipBlock:
00049                 newLines.append(line)
00050             if line.startswith(skipBlock):
00051                 skipBlock = ""
00052         if skipBlock:
00053             print "WARNING: missing end mark ('%s')" % skipBlock
00054 
00055         if doMerge:
00056             for f in fragFileNames:
00057                 # I do not want to add 2 empty lines at the beginning of a file
00058                 if newLines:
00059                     newLines.append('\n\n')
00060                 bf = os.path.basename(f)
00061                 newLines.append(startMark + bf + '\n')
00062                 newLines.append(timeMark + '\n')
00063                 fileData = open(f, 'r').read()
00064                 newLines.append(fileData)
00065                 if fileData and fileData[-1] != '\n':
00066                     newLines.append('\n')
00067                 newLines.append(endMark + bf + '\n')
00068 
00069         mergedFile.seek(0)
00070         mergedFile.truncate(0)
00071         mergedFile.writelines(newLines)
00072 
00073     finally:
00074         # unlock file
00075         locker.unlock( mergedFile )
00076 
00077     return 0
00078 
00079 if __name__ == "__main__":
00080 
00081     from optparse import OptionParser
00082     parser = OptionParser(usage="usage: %prog [options]")
00083     parser.add_option(
00084         "-i",
00085         "--input-file",
00086         action = "append",
00087         dest = "fragFileNames",
00088         default = [],
00089         help = "The path and name of the file one wants to merge into the 'master' one"
00090         )
00091     parser.add_option(
00092         "-m",
00093         "--merged-file",
00094         dest = "mergedFileName",
00095         default = None,
00096         help = "The path and name of the 'master' file which will hold the content of all the other fragment files"
00097         )
00098     parser.add_option(
00099         "-c",
00100         "--comment-char",
00101         dest = "commentChar",
00102         default = "#",
00103         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)"
00104         )
00105     parser.add_option(
00106         "--do-merge",
00107         dest = "doMerge",
00108         action = "store_true",
00109         default = True,
00110         help = "Switch to actually carry on with the merging procedure"
00111         )
00112     parser.add_option(
00113         "--un-merge",
00114         dest = "unMerge",
00115         action = "store_true",
00116         default = False,
00117         help = "Switch to remove our fragment file from the 'master' file"
00118         )
00119     parser.add_option(
00120         "--stamp-dir",
00121         dest = "stampDir",
00122         action = "store",
00123         default = None,
00124         help = "Create the stamp file in the specified directory. If not specified"
00125               +" the directory of the source file is used."
00126         )
00127     parser.add_option(
00128         "--no-stamp",
00129         action = "store_true",
00130         help = "Do no create stamp files."
00131         )
00132 
00133     (options, args) = parser.parse_args()
00134 
00135     # ensure consistency...
00136     options.doMerge = not options.unMerge
00137 
00138     # allow command line syntax as
00139     #   merge_files.py [options] <fragment file1> [<fragment file2>...] <merged file>
00140     if args:
00141         options.mergedFileName = args[-1]
00142         options.fragFileNames += args[:-1]
00143 
00144     sc = 1
00145     if not options.fragFileNames or \
00146        not options.mergedFileName :
00147         str(parser.print_help() or "")
00148         print "*** ERROR ***",sys.argv
00149         sys.exit(sc)
00150         pass
00151 
00152     if options.stampDir is None:
00153         stampFileName = lambda x: x + ".stamp"
00154     else:
00155         stampFileName = lambda x: os.path.join(options.stampDir,
00156                                                os.path.basename(x)
00157                                                + ".stamp")
00158     # Configure Python logging
00159     import logging
00160     logging.basicConfig(level = logging.INFO)
00161 
00162     if "GAUDI_BUILD_LOCK" in os.environ:
00163         globalLock = locker.LockFile(os.environ["GAUDI_BUILD_LOCK"], temporary =  True)
00164     else:
00165         globalLock = None
00166 
00167     if True: #try:
00168         sc = mergeFiles( options.fragFileNames, options.mergedFileName,
00169                          options.commentChar,
00170                          doMerge = options.doMerge )
00171         if not options.no_stamp:
00172             for stamp in map(stampFileName, options.fragFileNames):
00173                 open(stamp, 'w')
00174     #except IOError, err:
00175     #    print "ERROR:",err
00176     #except Exception, err:
00177     #    print "ERROR:",err
00178     #except:
00179     #    print "ERROR: unknown error !!"
00180 
00181     del globalLock
00182 
00183     sys.exit( sc )
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines

Generated at Mon Sep 17 2012 13:49:35 for Gaudi Framework, version v23r4 by Doxygen version 1.7.2 written by Dimitri van Heesch, © 1997-2004