Back to home page

Project CMSSW displayed by LXR

 
 

    


Warning, /Utilities/ReleaseScripts/scripts/MakeBuildSet is written in an unsupported language. File is not indexed.

0001 #! /usr/bin/env python3
0002 from __future__ import print_function
0003 #pylint: disable-msg=W0403
0004 """
0005 MakeBuildSet - utilizes dependency discovery mechanism for Partial Releases.
0006 
0007 1 July 2008   - with -n option (test mode) does not reuse or save cached data
0008               - products dependencies are now taken into consideration
0009 """
0010 
0011 __revision__ = "$Id: MakeBuildSet,v 1.8 2009/07/02 16:39:24 muzaffar Exp $"
0012 __version__  = "$Revision: 1.8 $"
0013 
0014 import os
0015 import sys
0016 import getopt
0017 import re
0018 
0019 __version__ = __version__.replace("$","").replace("Revision: ","")
0020 programPath = os.path.dirname( os.path.realpath(sys.argv[0] ) ) 
0021 programName = os.path.basename( sys.argv[0] )
0022 
0023 packageListInFile     = ""
0024 dependencyAnalysisDir = ""
0025 outputFormats         = ["packages", "lcg", "tools"]
0026 outputFormat          = "packages"
0027 dependencyTypes       = ["binary", "source", "combined"]
0028 dependencyType        = "binary"
0029 dropPluginDeps        = 0
0030 dropAllPluginDeps     = 0
0031 dropTests             = 1
0032 
0033 ##############################################################
0034 # Internal utility functions:
0035 
0036 def usage():
0037     """
0038     Prints out usage help
0039     """
0040     # Require minimum arguments and use options only to
0041     # override the defaults
0042     print ("""
0043 USAGE:
0044     """ + programName + """ -d <dir> [OPTIONS] [<package>]+
0045 OPTIONS:
0046    -d <dir>     - Required: get dependency information from directory <dir>,
0047                   There should be at least dependencies.txt and products.txt
0048                   files exist under this directory
0049    -f <file>    - Optional: read list of packages from <file>.
0050    -o <format>  - Optional: <format> = [ """ + " | ".join(outputFormats) + """ | all ]
0051                   Default value is '""" + outputFormats[0] + """'.
0052    -D <dependency>
0053                 - Optional: <dependency> = [ """ + " | ".join(dependencyTypes) + """ ]
0054                   Default value is '""" + dependencyTypes[0] + """'
0055    -p           - Optional: drop products generated from plugins directories
0056    -P           - Optional: drop all plugins even generated from
0057                   <subsystem>/<package>/[src|bin|test] directories
0058    -T           - Optional: do not drop products generated from test directories.
0059                   NOTE: if -P is used then plugins generated from test area
0060                   will be excluded
0061    -h           - Optional: print this help and exit.
0062    -v           - Optional: display version number.
0063 """)
0064 
0065 def usageError ( message, programName) :
0066     """
0067     usageError:
0068       Call it to quit in case of usage error
0069     """
0070     print ("Usage error: ", message, \
0071           "\nTry \'" + programName + " -h\' for help")
0072     sys.exit ( 2 )
0073 
0074     
0075 ##############################################################
0076 # Interface functions:
0077 def readPackageFromFile(pkfile):
0078     cache = {}
0079     f = open(pkfile)
0080     blankLine = re.compile('^\s*(#.*|)$')
0081     for line in f.readlines():
0082         line = line.strip()
0083         if blankLine.match(line):
0084             continue
0085         else:
0086            cache[line]=1
0087     f.close()
0088     return cache
0089         
0090 def readProductsInfo(productFile):
0091     cache = {}
0092     prods=open(productFile)
0093     comment= re.compile("^\s*(#.*|)$")
0094     parts  = re.compile("^([^:]+):([^:]+):([^:]+):([^:]+)$")
0095     for line in prods.readlines():
0096         line = line.strip()
0097         if comment.match(line):
0098             continue
0099         result = parts.match(line)
0100         if result:
0101             prodFrom = result.group(1)
0102             typeName = result.group(2)
0103             dirPath  = result.group(3)
0104             prodName = result.group(4)
0105             cache[prodName]={}
0106             cache[prodName]["FROM"] = prodFrom
0107             cache[prodName]["TYPE"] = typeName
0108             cache[prodName]["PATH"] = dirPath
0109     prods.close()
0110     return cache
0111 
0112 def excludeProducts(lookup,match,cache,maps):
0113     for p in cache.keys():
0114         if cache[p][lookup] == match:
0115             maps[p]=1
0116 
0117 def addDependencies(packages, dependencies):
0118     cache              = {}
0119     for t in outputFormats:
0120         cache[t] = {}
0121     for p in packages.keys():
0122         addDependency(p,"packages",dependencies,cache)
0123     return cache
0124 
0125 def addDependency(p,scope,dependencies,cache):
0126     if p in cache[scope]:
0127         return
0128     cache[scope][p]=1
0129     if p in dependencies[scope]:
0130         for d in dependencies[scope][p].keys():
0131             if d in dependencies["tools"]:
0132                 cache["tools"][d]=1
0133                 continue
0134             xscope = "lcg"
0135             if not d in dependencies[xscope]:
0136                 xscope = "packages"
0137             addDependency(d,xscope,dependencies,cache)
0138             
0139 def readIgnominyDependencyDB(igFile,droppedProducts,packages):
0140     dependencies = {}
0141     for t in outputFormats:
0142         dependencies[t] = {}
0143     inBlock    = 0
0144     inPackage  = 0
0145     skipProduct = 0
0146     pname          = re.compile("^(.*?)_(.*)")
0147     beginBlock     = re.compile("^# Direct\s+" + dependencyType + "\s+dependencies")
0148     endBlock       = re.compile('^############################*')
0149     packageEntry   = re.compile('^(\S+)(\s+.+|):')
0150     requiresEntry  = re.compile('^\s+(\S+)\s*$')
0151     tools          = re.compile('^(tools|System)/(.+)\s*$',re.IGNORECASE)
0152     lcgProject     = re.compile('^((CORAL|SEAL|POOL)/([^/]+))(/src|)',re.IGNORECASE)
0153     extraEntry     = re.compile('^(.+)/(plugins|test|bin)\s*')
0154     f = open(igFile)
0155     for line in f.readlines():
0156         if inBlock:
0157             if endBlock.match(line):
0158                 inBlock = 0
0159                 return dependencies
0160             else:
0161                 if inPackage:
0162                     result=requiresEntry.match(line)
0163                     if result:
0164                         if not skipProduct:
0165                             requires=result.group(0).strip()
0166                             if pname.match(requires):
0167                                 continue
0168                             if dependencyType != "binary" and extraEntry.match(requires):
0169                                 continue
0170                             lcg = ""
0171                             res = lcgProject.match (requires)
0172                             if res:
0173                                 lcg = res.group(2).lower()
0174                                 requires = res.group(1)
0175                                 dependencies["tools"][lcg]=1
0176                             else:
0177                                 res = tools.match (requires)
0178                                 if res:
0179                                      requires = res.group(2).lower()
0180                                      dependencies["tools"][requires]=1
0181                             if currentPackage in dependencies["packages"]:
0182                                 dependencies["packages"][currentPackage][requires]=1
0183                                 if lcg:
0184                                      dependencies["packages"][currentPackage][lcg]=1
0185                             else:
0186                                  dependencies["lcg"][currentPackage][requires]=1
0187                     else:
0188                         inPackage=0
0189                 else:
0190                     result = packageEntry.match(line)
0191                     if result:
0192                         inPackage = 1
0193                         skipProduct = 0
0194                         currentPackage = result.group(1)
0195                         if currentPackage == "(UNKNOWN)":
0196                            skipProduct = 1
0197                            continue
0198                         res = lcgProject.match(currentPackage)
0199                         if res:
0200                             dependencies["tools"][res.group(2).lower()]=1
0201                             currentPackage = res.group(1)
0202                             if not currentPackage in dependencies["lcg"]:
0203                                 dependencies["lcg"][currentPackage]={}
0204                             continue
0205                         res = tools.match (currentPackage)
0206                         if res:
0207                             currentPackage = res.group(2).lower()
0208                             dependencies["tools"][currentPackage]=1
0209                             skipProduct = 1
0210                             continue
0211                         prodname=currentPackage.replace("/","")
0212                         pkg = 1
0213                         res = pname.match(currentPackage)
0214                         if res:
0215                             pkg = 0
0216                             currentPackage = res.group(1)
0217                             prodname = res.group(2)
0218                         elif dependencyType != "binary":
0219                             res = extraEntry.match(currentPackage)
0220                             if res:
0221                                 if res.group(2) == "test" and dropTests:
0222                                     skipProduct = 1
0223                                     continue
0224                                 elif res.group(2) == "plugins" and dropPluginDeps:
0225                                     skipProduct = 1
0226                                     continue
0227                                 else:
0228                                     pkg = 0
0229                                     currentPackage = res.group(1)
0230                                     prodname = currentPackage.replace("/","")
0231                         if (not pkg) or (not currentPackage in packages):
0232                             if prodname in droppedProducts:
0233                                  skipProduct = 1
0234                                  continue
0235                         if not currentPackage in dependencies["packages"]:
0236                             dependencies["packages"][currentPackage]={}
0237         else:
0238             if beginBlock.match(line):
0239                 inBlock = 1
0240     f.close()
0241     return dependencies
0242         
0243 ###############################################################
0244 # Here real action starts:
0245 
0246 # Handle options and arguments:
0247 try:
0248     opts, args = getopt.getopt( sys.argv[1:], "hpPTvf:D:d:o:" )
0249 
0250 except getopt.error:
0251     usageError( sys.exc_info()[1], programName)
0252 
0253 # process verbosity options separately before anything else. 
0254 
0255 for o, a in opts:
0256     if o == "-v":
0257         print (__version__)
0258         sys.exit()
0259     if o == "-h":
0260         usage()
0261         sys.exit()
0262     if o == "-f":
0263         packageListInFile = a
0264         if not os.path.isfile(a):
0265             usageError( "file '" + a + "' does not exist!", programName)
0266     if o == "-o":
0267         outputFormat = a
0268         if a != "all" and not a in outputFormats:
0269             usageError( "unknown output format: '" + a + "'.", programName)        
0270     if o == "-D":
0271         dependencyType = a
0272         if not a in dependencyTypes:
0273             usageError( "unknown ignominy generated dependency type: '" + a + "'.", programName)        
0274     if o == "-d":
0275         if not os.path.isdir(a):
0276             usageError( "directory '" + a + "' does not exist!", programName)
0277         dependencyAnalysisDir = a
0278     if o == "-p":
0279         dropPluginDeps = 1
0280     if o == "-P":
0281         dropAllPluginDeps = 1
0282         dropPluginDeps = 1
0283     if o == "-T":
0284         dropTests = 0
0285 
0286 if dependencyAnalysisDir == "":
0287      usageError( "missing ignominy analysis directory which should contain at least products.txt and dependencies.txt files.", programName)
0288 
0289 # Add packages from file: 
0290 packages = {}
0291 if (packageListInFile):
0292     packages = readPackageFromFile(packageListInFile)
0293 # Add extra packages passed via command-line
0294 for p in args[0:]:
0295     packages[p]=1
0296     
0297 if not len(packages.keys()):
0298     print ("""
0299 ERROR: You should use either '-f <file>' command-line option
0300        to provide the list of packages to look for OR provide
0301        a <space> separated list of package at the end of command-line
0302 """)
0303     sys.exit(2)
0304 
0305 # Read Product information dumped by ignominy in products.txt file
0306 productCache = readProductsInfo(os.path.join(dependencyAnalysisDir, "products.txt"))
0307 
0308 # Exclude test and plugins products if requested via command-line
0309 droppedProducts={}
0310 if dropTests:
0311     excludeProducts("FROM","TEST",productCache,droppedProducts)
0312 if dropAllPluginDeps:
0313     excludeProducts("FROM","PLUGINS",productCache,droppedProducts)
0314     excludeProducts("TYPE","PLUGINS",productCache,droppedProducts)
0315 elif dropPluginDeps:
0316     excludeProducts("FROM","PLUGINS",productCache,droppedProducts)
0317 
0318 # Get dependency info:
0319 dependencies = readIgnominyDependencyDB(os.path.join(dependencyAnalysisDir,"dependencies.txt"),droppedProducts,packages)
0320 
0321 # Cleanup, this information is not needed after this
0322 droppedProducts={}
0323 
0324 myPackages = addDependencies(packages, dependencies)
0325 
0326 # Cleanup, no more needed dependencies information
0327 dependencies = {}
0328 
0329 # Print output and finish:
0330 pitems = []
0331 if outputFormat != "all":
0332     outputFormats = [outputFormat]
0333 for item in outputFormats:
0334     pkg = sorted(myPackages[item].keys())
0335     for p in pkg:
0336         print (p)
0337 
0338 sys.exit()