# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration # @file PyUtils.scripts.check_reflex # @purpose a script to check the definitions of (reflex) plugins # across multiple so-called 'rootmap' files # @author Sebastien Binet # @date February 2010 from __future__ import print_function __doc__ = """ a script to check the definitions of (reflex) plugins across multiple so-called 'rootmap' files """ __author__ = "Sebastien Binet" ### imports ------------------------------------------------------------------- import PyUtils.acmdlib as acmdlib @acmdlib.command(name='chk-rflx') @acmdlib.argument( '--capabilities', nargs='?', default=None, help="Dump the capabilities of a given library (ex: libAthenaServices.so)") @acmdlib.argument( '--dups', dest='chk_dups', default=None, help="Check if there is any duplicates among dictionaries for a given library") @acmdlib.argument( '--dump-content', action='store_true', default=False, help="Dump the content of all the known plugins (dicts. and components)") @acmdlib.argument( "--dso", dest = "dump_dso", action = "store_true", default = False, help = "Dump all the dsomap/rootmap files known to the Dso repository") @acmdlib.argument( "--libs", dest = "dump_libs", action = "store_true", default = False, help = "Dump all the libraries known to the Dso repository") @acmdlib.argument( "--check-dict-dups", action = "store_true", default = False, help = "Check if there is any duplicates among dictionaries") @acmdlib.argument( "--check-pf-dups", action = "store_true", default = False, help = "Check if there is any duplicates among components declared to the PluginSvc") @acmdlib.argument( "--check-all-dups", action = "store_true", default = False, help = "Check dictionaries *and* components") @acmdlib.argument( "--detailed-dump", action = "store_true", default = False, help = "Performs a detailed dump if duplicates are found") @acmdlib.argument( "--pedantic", action = "store_true", default = False, help = """Pedantic mode: if a component is found in 2 libraries which have the same name (usual case of a developer working on a (set of) package(s)), it is still being reported as being duplicated""") @acmdlib.argument( "-l", "--level", default = "INFO", help = "Logging level (aka verbosity)") def main(args): """a script to check the definitions of (reflex) plugins across multiple so-called 'rootmap' files """ exitcode = 0 print (":"*80) print ("::: chk-rflx :::") import os import PyUtils.Dso as Dso _suppression_dct = { 'TMath' : ('libCore.so', 'libMathCore.so'), 'string': ('libGaudiKernelDict.so', 'libCore.so', 'liblcg_PyCoolDict.so', 'libSTLAddRflx.so'), '__pf__::CNV_71_9631': ('libDataModelTestDataReadCnvPoolCnv.so', 'libDataModelTestDataWriteCnvPoolCnv.so',), '__pf__::CNV_71_9632': ('libDataModelTestDataReadCnvPoolCnv.so', 'libDataModelTestDataWriteCnvPoolCnv.so',), '__pf__::CNV_71_9633': ('libDataModelTestDataReadCnvPoolCnv.so', 'libDataModelTestDataWriteCnvPoolCnv.so',), '__pf__::CNV_71_9634': ('libDataModelTestDataReadCnvPoolCnv.so', 'libDataModelTestDataWriteCnvPoolCnv.so',), '__pf__::CNV_71_9639': ('libDataModelTestDataReadCnvPoolCnv.so', 'libDataModelTestDataWriteCnvPoolCnv.so',), ## FIXME !! this shouldn't be suppressed !! '__pf__::RootCollection': ('liblcg_RootCollection.so', 'libAthAnalysisTools.so',), ## !! } def print_db( db, detailedDump = False ): if detailedDump : fct = lambda x: x else: fct = os.path.basename keys = db.keys() keys.sort() for k in keys: print ("%s:" % k) libs = db[k] libs.sort() for lib in libs: print (" ",fct(lib)) return dsodb = Dso.DsoDb() if args.capabilities: libname = args.capabilities try: capabilities = dsodb.capabilities(libname) print ("::: capabilities of [%s]" % (libname,)) print (os.linesep.join([" %s"%c for c in capabilities])) except ValueError: exitcode = 1 pass if args.chk_dups: libname = args.chk_dups try: print ("::: checking duplicates for [%s]..." % (libname,)) dups = dsodb.duplicates(libname, pedantic=args.pedantic) for k in dups: print (" -",k) print (os.linesep.join([" %s"%v for v in dups[k]])) if len(dups.keys())>0: exitcode = 1 except ValueError: exitcode = 1 pass if args.dump_content: print ("::: dumping content of all known plugins...") entries = dsodb.content(pedantic=args.pedantic) print_db(entries, args.detailed_dump) print ("::: known entries:",len(entries.keys())) if args.dump_libs: print ("::: dumping all known libraries...") libs = dsodb.libs(detailedDump=args.detailed_dump) for lib in libs: print (" -",lib) print ("::: known libs:",len(libs)) if args.dump_dso: print ("::: dumping all known dso/rootmap files...") dso_files = [dso for dso in dsodb.dsoFiles] dso_files.sort() for dso_file in dso_files: if not args.detailed_dump: dso_file = os.path.basename(dso_file) print (" -",dso_file) print ("::: known dsos:",len(dso_files)) if args.check_dict_dups: print (":: checking dict. duplicates...") dups = dsodb.dictDuplicates(pedantic=args.pedantic) suppression_log = [] for k in dups: v = dups[k] # mark as error only if it isn't a known dup' if k in _suppression_dct: suppressed = [os.path.basename(ii) in _suppression_dct[k] for ii in v] if all(suppressed): suppression_log.append(k[:]) pass else: # that's a new one !! exitcode = 1 else: # that's a new one !! exitcode = 1 # print ("---> NOT ignoring [%s]" % (k,)) print_db(dups, args.detailed_dump) if len(suppression_log): print ("-"*40) print ("## ignoring the following dups':") for k in suppression_log: print (" -",k) print ("-"*40) print ("## all dups:",len(dups.keys())) print ("## dups:",len(dups.keys())-len(suppression_log)) if args.check_pf_dups: print ("::: checking (plugin factories) components dups...") dups = dsodb.pfDuplicates(pedantic=args.pedantic) suppression_log = [] for k in dups: v = dups[k] # mark as error only if it isn't a known dup' if k in _suppression_dct: suppressed = [os.path.basename(ii) in _suppression_dct[k] for ii in v] if all(suppressed): suppression_log.append(k[:]) pass else: # that's a new one !! exitcode = 1 else: # that's a new one !! exitcode = 1 # print ("---> NOT ignoring [%s]" % (k,)) print_db(dups, args.detailed_dump) if len(suppression_log): print ("-"*40) print ("## ignoring the following dups':") for k in suppression_log: print (" -",k) print ("-"*40) print ("## all dups:",len(dups.keys())) print ("## dups:",len(dups.keys())-len(suppression_log)) if args.check_all_dups: print ("::: checking all components dups...") dups = dsodb.pfDuplicates(pedantic=args.pedantic) dups.update(dsodb.dictDuplicates(pedantic=args.pedantic)) suppression_log = [] for k in dups: v = dups[k] # mark as error only if it isn't a known dup' if k in _suppression_dct: suppressed = [os.path.basename(ii) in _suppression_dct[k] for ii in v] if all(suppressed): suppression_log.append(k[:]) pass else: # that's a new one !! exitcode = 1 else: # that's a new one !! exitcode = 1 # print ("---> NOT ignoring [%s]" % (k,)) print_db(dups, args.detailed_dump) if len(suppression_log): print ("-"*40) print ("## ignoring the following dups':") for k in suppression_log: print (" -",k) print ("-"*40) print ("## all dups:",len(dups.keys())) print ("## dups:",len(dups.keys())-len(suppression_log)) if exitcode: print ("::: ERROR !!") else: print ("::: All good.") print (":"*80) return exitcode