def loadConfigurableDb(): ''' Equivalent to GaudiKernel.ConfigurableDb.loadConfigurableDb(), but does a deep search and executes the '*.confdb' files instead of importing them. ''' log = GaudiKernel.ConfigurableDb.log from os.path import join as path_join # look for the confdb files in all the reasonable places # - CMake builds confDbFiles = [] for path in sys.path: confDbFiles += [f for f in glob(path_join(path, '*', '*.confdb')) if os.path.isfile(f)] # - used projects and local merged file pathlist = os.getenv("LD_LIBRARY_PATH", "").split(os.pathsep) for path in filter(os.path.isdir, pathlist): confDbFiles += [f for f in [path_join(path, f) for f in os.listdir(path) if f.endswith('.confdb')]] # - load the confdb files for confDb in confDbFiles: log.debug( "\t-loading [%s]..." % confDb ) try: cfgDb._loadModule( confDb ) except Exception, err: # It may happen that the file is found but not completely # written, usually during parallel builds, but we do not care. log.warning( "Could not load file [%s] !", confDb ) log.warning( "Reason: %s", err )
def main(): from optparse import OptionParser parser = OptionParser(prog = os.path.basename(sys.argv[0]), usage = "%prog [options] <PackageName> [<Module1> ...]") parser.add_option("-o", "--output", action="store", type="string", help="output file for confDb data [default = '../genConf/<PackageName>_user_confDb.py'].") parser.add_option("-r", "--root", action="store", type="string", help="root directory of the python modules [default = '../python'].") parser.add_option("-v", "--verbose", action="store_true", help="print some debugging information") parser.add_option("--debug", action="store_true", help="print more debugging information") parser.add_option("--lockerpath", action="store", metavar = "DIRNAME", help="directory where to find the module 'locker'") parser.set_defaults(root = os.path.join("..","python")) opts, args = parser.parse_args() if opts.debug: log_level = logging.DEBUG elif opts.verbose: log_level = logging.VERBOSE else: log_level = logging.INFO logging.basicConfig(format = "%(levelname)s: %(message)s", stream = sys.stdout, level = log_level) if len(args) < 1: parser.error("PackageName is required") package_name = args.pop(0) usingConvention = False if not args: # use the conventional module name <package>.Configuration args = [package_name + ".Configuration"] usingConvention = True genConfDir = os.path.join("..", os.environ.get("CMTCONFIG", ""), "genConf") if not os.path.exists(genConfDir): genConfDir = os.path.join("..", "genConf") if not opts.output: outputfile = os.path.join(genConfDir, package_name + '_user.confdb') else: outputfile = opts.output # The locking ensures that nobody tries to modify the python.zip file while # we read it. dbLock = None if "GAUDI_BUILD_LOCK" in os.environ: if opts.lockerpath: sys.path.append(opts.lockerpath) # Get the LockFile class from the locker module in GaudiPolicy or use a fake # factory. try: from locker import LockFile except ImportError: def LockFile(*args, **kwargs): return None # obtain the lock dbLock = LockFile(os.environ["GAUDI_BUILD_LOCK"], temporary = True) # We can disable the error on missing configurables only if we can import Gaudi.Configurables # It must be done at this point because it may conflict with logging.basicConfig try: import Gaudi.Configurables Gaudi.Configurables.ignoreMissingConfigurables = True except: pass # load configurables database to avoid fake duplicates loadConfigurableDb() # ensure that local configurables are in the database try: # Add the local python directories to the python path to be able to import the local # configurables sys.path.insert(0, genConfDir) sys.path.insert(0, os.path.join("..", "python")) localConfDb = os.path.join(genConfDir, package_name, package_name + '.confdb') if os.path.exists(localConfDb): cfgDb._loadModule(localConfDb) # Extend the search path of the package module to find the configurables package_module = __import__(package_name) package_module.__path__.insert(0, os.path.join(genConfDir, package_name)) except: pass # ignore failures (not important) del dbLock # Now we can let the others operate on the install area python directory # Collecting ConfigurableUser specializations cus = {} for mod in args: lst = None try: lst = getConfigurableUsers(mod, root = opts.root, mayNotExist = usingConvention) except ImportError: import traceback logging.error("Cannot import module %r:\n%s", mod, traceback.format_exc().rstrip()) # I remove the trailing '\n' return 2 if lst: cus[mod] = lst # Add the configurables to the database as fake entries to avoid duplicates for m in lst: cfgDb.add(configurable = m, package = 'None', module = 'None', lib = 'None') elif not usingConvention: logging.warning("Specified module %r does not contain ConfigurableUser specializations", mod) if cus: logging.info("ConfigurableUser found:\n%s", pformat(cus)) # header output = """## -*- ascii -*- # db file automatically generated by %s on: %s """ % (parser.prog, time.asctime()) for mod in cus: for cu in cus[mod]: output += "%s %s %s\n" % (mod, 'None', cu) # trailer output += "## %s\n" % package_name elif usingConvention: logging.info("No ConfigurableUser found") output = ("# db file automatically generated by %s on: %s\n" "# No ConfigurableUser specialization in %s\n") % (parser.prog, time.asctime(), package_name) else: logging.error("No ConfigurableUser specialization found") return 1 # create the destination directory if not there output_dir = os.path.dirname(outputfile) try: logging.info("Creating directory %r", output_dir) os.makedirs(output_dir, 0755) except OSError, err: import errno if err.errno == errno.EEXIST: # somebody already - perhaps concurrently - created that dir. pass else: raise