Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-11-25 02:29:48

0001 #! /usr/bin/env python3
0002 
0003 from argparse import ArgumentParser, ArgumentDefaultsHelpFormatter
0004 import os
0005 import sys
0006 import re
0007 import shutil
0008 
0009 ccRE = re.compile (r'(\w+)\.cc')
0010 
0011 def extractBuildFilePiece (buildfile, copy, target = 'dummy'):
0012     """Extracts necessary piece of the buildfile.  Returns empty
0013     string if not found."""    
0014     try:
0015         build = open (buildfile, 'r')
0016     except:        
0017         raise RuntimeError("Could not open BuildFile '%s' for reading. Aboring." \
0018               % buildfile)
0019     # make my regex
0020     startBinRE = re.compile (r'<\s*bin\s+name=(\S+)')
0021     endBinRE   = re.compile (r'<\s*/bin>')
0022     exeNameRE  = re.compile (r'(\w+)\.exe')
0023     ccName = os.path.basename (copy)
0024     match = ccRE.match (ccName)
0025     if match:
0026         ccName = match.group (1)
0027     retval = ''
0028     foundBin = False
0029     for line in build:
0030         # Are we in the middle of copying what we need?
0031         if foundBin:
0032             retval += line
0033         # Are we copying what we need and reach the end?
0034         if foundBin and endBinRE.search (line):
0035             # all done
0036             break
0037         # Is this the start of a bin line with the right name?
0038         match = startBinRE.search (line)
0039         if match:
0040             # strip of .exe if it's there
0041             exeName = match.group (1)
0042             exeMatch = exeNameRE.search (exeName)
0043             if exeMatch:
0044                 exeName = exeMatch.group (1)
0045             if exeName == ccName:
0046                 foundBin = True
0047                 line = re.sub (exeName, target, line)
0048                 retval = line
0049     build.close()
0050     return retval
0051 
0052 
0053 def createBuildFile (buildfile):
0054     """Creates a BuildFile if one doesn't already exist"""
0055     if os.path.exists (buildfile):
0056         return
0057     build = open (buildfile, 'w')
0058     build.write ("<!-- -*- XML -*- -->\n\n<environment>\n\n</environment>\n")
0059     build.close()
0060 
0061 
0062 def addBuildPiece (targetBuild, buildPiece):
0063     """Adds needed piece for new executable.  Returns true upon
0064     success."""
0065     backup = targetBuild + ".bak"
0066     shutil.copyfile (targetBuild, backup)
0067     oldBuild = open (backup, 'r')
0068     newBuild = open (targetBuild, 'w')
0069     environRE = re.compile (r'<\s*environment')
0070     success = False
0071     for line in oldBuild:
0072         newBuild.write (line)
0073         if environRE.search (line):
0074             newBuild.write ('\n\n')
0075             newBuild.write (buildPiece)
0076             success = True
0077     oldBuild.close()
0078     newBuild.close()
0079     return success
0080         
0081 
0082 
0083 ########################
0084 ## ################## ##
0085 ## ## Main Program ## ##
0086 ## ################## ##
0087 ########################
0088 
0089 if __name__ == '__main__':
0090     # We need CMSSW to already be setup
0091     base         = os.environ.get ('CMSSW_BASE')
0092     release_base = os.environ.get ('CMSSW_RELEASE_BASE')
0093     if not base or not release_base:
0094         print("Error: You must have already setup a CMSSW release.  Aborting.")
0095         sys.exit()
0096     # setup the options
0097     parser = ArgumentParser(formatter_class=ArgumentDefaultsHelpFormatter, description='Creates new analysis code')
0098     parser.add_argument('--copy', dest='copy', type=str, default = 'blank',
0099                         help='Copies example. COPY should either be a file'
0100                         ' _or_ an example in PhysicsTools/FWLite/examples')
0101     parser.add_argument('--newPackage', dest='newPackage', action='store_true',
0102                         help='Will create Package/Subpackage folders if necessary')
0103     parser.add_argument('--toTest', dest='toTest', action='store_true',
0104                         help='Will create files in test/ instead of bin/')
0105     parser.add_argument("name", metavar="Package/SubPackage/name", type=str)
0106     options = parser.parse_args()
0107     # get the name of the copy file and make sure we can find everything
0108     copy = options.copy
0109     if not re.search ('\.cc$', copy):
0110         copy += '.cc'
0111     buildCopy = os.path.dirname (copy)
0112     if len (buildCopy):
0113         buildCopy += '/BuildFile'
0114     else:
0115         buildCopy = 'BuildFile'
0116     found = False
0117     searchList = ['',
0118                   base + "/src/PhysicsTools/FWLite/examples/",
0119                   release_base+ "/src/PhysicsTools/FWLite/examples/"]
0120     fullName  = ''
0121     fullBuild = ''
0122     for where in searchList:        
0123         name  = where + copy
0124         build = where + buildCopy
0125         # Is the copy file here
0126         if os.path.exists (name):
0127             # Yes.
0128             found = True
0129             # Is there a Buildfile too?
0130             if not os.path.exists (build):
0131                 print("Error: Found '%s', but no accompanying " % name, \
0132                       "Buildfile '%s'. Aborting" % build)
0133                 sys.exit()
0134             fullName = name
0135             fullBuild = build
0136             break
0137     if not found:
0138         print("Error: Did not find '%s' to copy.  Aborting." % copy)
0139         sys.exit()
0140     pieces = options.name.split('/')
0141     if len (pieces) != 3:
0142         print("Error: Need to provide 'Package/SubPackage/name'")
0143         sys.exit()    
0144     target = pieces[2]
0145     match = ccRE.match (target)
0146     if match:
0147         target = match.group (1)    
0148     buildPiece = extractBuildFilePiece (fullBuild, copy, target)
0149     if not buildPiece:
0150         print("Error: Could not extract necessary info from Buildfile. Aborting.")
0151         sys.exit()
0152     # print buildPiece
0153     firstDir  = base + '/src/' + pieces[0]
0154     secondDir = firstDir + '/' + pieces[1]
0155     if options.toTest:
0156         bin = '/test'
0157     else:
0158         bin = '/bin'
0159     if not os.path.exists (secondDir) and \
0160        not options.newPackage:
0161         raise RuntimeError("%s does not exist.  Use '--newPackage' to create" \
0162               % ("/".join (pieces[0:2]) ))
0163     dirList = [firstDir, secondDir, secondDir + bin]
0164     targetCC = dirList[2] + '/' + target + '.cc'
0165     targetBuild = dirList[2] + '/BuildFile'
0166     if os.path.exists (targetCC):
0167         print('Error: "%s" already exists.  Aborting.' % targetCC)
0168         sys.exit()
0169     # Start making directory structure
0170     for currDir in dirList:
0171         if not os.path.exists (currDir):
0172             os.mkdir (currDir)
0173     # copy the file over
0174     shutil.copyfile (fullName, targetCC)
0175     print("Copied:\n   %s\nto:\n   %s.\n" % (fullName, targetCC))
0176     createBuildFile (targetBuild)
0177     if extractBuildFilePiece (targetBuild, target):
0178         print("Buildfile already has '%s'.  Skipping" % target)
0179     else :
0180         # we don't already have a piece here
0181         if addBuildPiece (targetBuild, buildPiece):
0182             print("Added info to:\n   %s." % targetBuild)
0183         else:
0184             print("Unable to modify Buildfile.  Sorry.")