Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:23:23

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