Skip to content

Commit a2d77f2

Browse files
committed
Refactor edmCheckClassVersion
1 parent da9e5a1 commit a2d77f2

File tree

1 file changed

+106
-95
lines changed

1 file changed

+106
-95
lines changed

FWCore/Reflection/scripts/edmCheckClassVersion

Lines changed: 106 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -46,99 +46,110 @@ def checkDictionaries(name):
4646

4747
return missingDict
4848

49-
#Setup the options
50-
from argparse import ArgumentParser, ArgumentDefaultsHelpFormatter
51-
oparser = ArgumentParser(formatter_class=ArgumentDefaultsHelpFormatter)
52-
oparser.add_argument("-d","--check_dictionaries", dest="checkdict",action="store_true",default=False,
53-
help="check that all required dictionaries are loaded")
54-
oparser.add_argument("-l","--lib", dest="library", type=str,
55-
help="specify the library to load. If not set classes are found using the PluginManager")
56-
oparser.add_argument("-x","--xml_file", dest="xmlfile",default="./classes_def.xml", type=str,
57-
help="the classes_def.xml file to read")
58-
oparser.add_argument("-g","--generate_new",dest="generate", action="store_true",default=False,
59-
help="instead of issuing errors, generate a new classes_def.xml file.")
60-
61-
options=oparser.parse_args()
62-
63-
ClassesDefUtils.initROOT(options.library)
64-
if options.library is None and options.checkdict:
65-
print ("Dictionary checks require a specific library")
66-
67-
missingDict = 0
68-
69-
ClassesDefUtils.initCheckClass()
70-
71-
try:
72-
p = ClassesDefUtils.XmlParser(options.xmlfile)
73-
except RuntimeError as e:
74-
print(f"Parsing {options.xmlfile} failed: {e}")
75-
sys.exit(1)
76-
foundErrors = dict()
77-
for name,info in p.classes.items():
78-
errorCode,rootClassVersion,classChecksum = ClassesDefUtils.checkClass(name,info[ClassesDefUtils.XmlParser.classVersionIndex],info[ClassesDefUtils.XmlParser.versionsToChecksumIndex])
79-
if errorCode != ClassesDefUtils.noError:
80-
foundErrors[name]=(errorCode,classChecksum,rootClassVersion)
81-
if options.checkdict :
82-
missingDict += checkDictionaries(name)
83-
84-
foundRootDoesNotMatchError = False
85-
originalToNormalizedNames = dict()
86-
for name,retValues in foundErrors.items():
87-
origName = p.classes[name][ClassesDefUtils.XmlParser.originalNameIndex]
88-
originalToNormalizedNames[origName]=name
89-
code = retValues[0]
90-
classVersion = p.classes[name][ClassesDefUtils.XmlParser.classVersionIndex]
91-
classChecksum = retValues[1]
92-
rootClassVersion = retValues[2]
93-
if code == ClassesDefUtils.errorRootDoesNotMatchClassDef:
94-
foundRootDoesNotMatchError=True
95-
print ("error: for class '"+name+"' ROOT says the ClassVersion is "+str(rootClassVersion)+" but classes_def.xml says it is "+str(classVersion)+". Are you sure everything compiled correctly?")
96-
elif code == ClassesDefUtils.errorMustUpdateClassVersion and not options.generate:
97-
print ("error: class '"+name+"' has a different checksum for ClassVersion "+str(classVersion)+". Increment ClassVersion to "+str(classVersion+1)+" and assign it to checksum "+str(classChecksum))
98-
elif not options.generate:
99-
print ("error:class '"+name+"' needs to include the following as part of its 'class' declaration")
100-
print (' <version ClassVersion="'+str(classVersion)+'" checksum="'+str(classChecksum)+'"/>')
101-
102-
103-
if options.generate and not foundRootDoesNotMatchError and not missingDict:
104-
f = open(options.xmlfile)
105-
outFile = open('classes_def.xml.generated','w')
106-
out = ''
107-
for l in f.readlines():
108-
newLine = l
109-
if -1 != l.find('<class') and -1 != l.find('ClassVersion'):
110-
splitArgs = l.split('"')
111-
name = splitArgs[1]
112-
normName = originalToNormalizedNames.get(name,None)
113-
if normName is not None:
114-
indent = l.find('<')
115-
#this is a class with a problem
116-
classVersion = p.classes[normName][ClassesDefUtils.XmlParser.classVersionIndex]
117-
code,checksum,rootClassVersion = foundErrors[normName]
118-
hasNoSubElements = (-1 != l.find('/>'))
119-
if code == ClassesDefUtils.errorMustUpdateClassVersion:
120-
classVersion += 1
121-
parts = splitArgs[:]
122-
indexToClassVersion = 0
123-
for pt in parts:
124-
indexToClassVersion +=1
125-
if -1 != pt.find('ClassVersion'):
126-
break
127-
parts[indexToClassVersion]=str(classVersion)
128-
newLine = '"'.join(parts)
129-
130-
if hasNoSubElements:
131-
newLine = newLine.replace('/','')
132-
out +=newLine
133-
newLine =' '*indent+' <version ClassVersion="'+str(classVersion)+'" checksum="'+str(checksum)+'"/>\n'
134-
if hasNoSubElements:
135-
out += newLine
136-
newLine=' '*indent+'</class>\n'
137-
out +=newLine
138-
139-
outFile.writelines(out)
140-
141-
if (len(foundErrors)>0 and not options.generate) or (options.generate and foundRootDoesNotMatchError) or missingDict:
142-
import sys
143-
sys.exit(1)
49+
def checkClassDefinitions(classes, checkdict):
50+
missingDict = 0
51+
foundErrors = dict()
52+
for name,info in classes.items():
53+
errorCode,rootClassVersion,classChecksum = ClassesDefUtils.checkClass(name,info[ClassesDefUtils.XmlParser.classVersionIndex],info[ClassesDefUtils.XmlParser.versionsToChecksumIndex])
54+
if errorCode != ClassesDefUtils.noError:
55+
foundErrors[name]=(errorCode,classChecksum,rootClassVersion)
56+
if checkdict :
57+
missingDict += checkDictionaries(name)
58+
return (missingDict, foundErrors)
59+
60+
def checkErrors(foundErrors, classes, generate):
61+
foundRootDoesNotMatchError = False
62+
originalToNormalizedNames = dict()
63+
for name,retValues in foundErrors.items():
64+
origName = classes[name][ClassesDefUtils.XmlParser.originalNameIndex]
65+
originalToNormalizedNames[origName]=name
66+
code = retValues[0]
67+
classVersion = classes[name][ClassesDefUtils.XmlParser.classVersionIndex]
68+
classChecksum = retValues[1]
69+
rootClassVersion = retValues[2]
70+
if code == ClassesDefUtils.errorRootDoesNotMatchClassDef:
71+
foundRootDoesNotMatchError=True
72+
print ("error: for class '"+name+"' ROOT says the ClassVersion is "+str(rootClassVersion)+" but classes_def.xml says it is "+str(classVersion)+". Are you sure everything compiled correctly?")
73+
elif code == ClassesDefUtils.errorMustUpdateClassVersion and not generate:
74+
print ("error: class '"+name+"' has a different checksum for ClassVersion "+str(classVersion)+". Increment ClassVersion to "+str(classVersion+1)+" and assign it to checksum "+str(classChecksum))
75+
elif not generate:
76+
print ("error:class '"+name+"' needs to include the following as part of its 'class' declaration")
77+
print (' <version ClassVersion="'+str(classVersion)+'" checksum="'+str(classChecksum)+'"/>')
78+
return (foundRootDoesNotMatchError, originalToNormalizedNames)
79+
80+
81+
def generate(oldfile, newfile, originalToNormalizedNames, classes, foundErrors):
82+
with open(oldfile) as f, open(newfile, 'w') as outFile:
83+
out = ''
84+
for l in f.readlines():
85+
newLine = l
86+
if -1 != l.find('<class') and -1 != l.find('ClassVersion'):
87+
splitArgs = l.split('"')
88+
name = splitArgs[1]
89+
normName = originalToNormalizedNames.get(name,None)
90+
if normName is not None:
91+
indent = l.find('<')
92+
#this is a class with a problem
93+
classVersion = classes[normName][ClassesDefUtils.XmlParser.classVersionIndex]
94+
code,checksum,rootClassVersion = foundErrors[normName]
95+
hasNoSubElements = (-1 != l.find('/>'))
96+
if code == ClassesDefUtils.errorMustUpdateClassVersion:
97+
classVersion += 1
98+
parts = splitArgs[:]
99+
indexToClassVersion = 0
100+
for pt in parts:
101+
indexToClassVersion +=1
102+
if -1 != pt.find('ClassVersion'):
103+
break
104+
parts[indexToClassVersion]=str(classVersion)
105+
newLine = '"'.join(parts)
106+
107+
if hasNoSubElements:
108+
newLine = newLine.replace('/','')
109+
out +=newLine
110+
newLine =' '*indent+' <version ClassVersion="'+str(classVersion)+'" checksum="'+str(checksum)+'"/>\n'
111+
if hasNoSubElements:
112+
out += newLine
113+
newLine=' '*indent+'</class>\n'
114+
out +=newLine
115+
116+
outFile.writelines(out)
117+
118+
def main(args):
119+
ClassesDefUtils.initROOT(args.library)
120+
if args.library is None and args.checkdict:
121+
print ("Dictionary checks require a specific library")
122+
ClassesDefUtils.initCheckClass()
123+
124+
try:
125+
p = ClassesDefUtils.XmlParser(args.xmlfile)
126+
except RuntimeError as e:
127+
print(f"Parsing {args.xmlfile} failed: {e}")
128+
return(1)
129+
130+
(missingDict, foundErrors) = checkClassDefinitions(p.classes, args.checkdict)
131+
(foundRootDoesNotMatchError, originalToNormalizedNames) = checkErrors(foundErrors, p.classes, args.generate)
132+
133+
if (len(foundErrors)>0 and not args.generate) or (args.generate and foundRootDoesNotMatchError) or missingDict:
134+
return 1
135+
136+
if args.generate:
137+
generate(args.xmlfile, 'classes_def.xml.generated', originalToNormalizedNames, p.classes, foundErrors)
138+
139+
return 0
140+
141+
if __name__ == "__main__":
142+
from argparse import ArgumentParser, ArgumentDefaultsHelpFormatter
143+
parser = ArgumentParser(formatter_class=ArgumentDefaultsHelpFormatter)
144+
parser.add_argument("-d","--check_dictionaries", dest="checkdict",action="store_true",default=False,
145+
help="check that all required dictionaries are loaded")
146+
parser.add_argument("-l","--lib", dest="library", type=str,
147+
help="specify the library to load. If not set classes are found using the PluginManager")
148+
parser.add_argument("-x","--xml_file", dest="xmlfile",default="./classes_def.xml", type=str,
149+
help="the classes_def.xml file to read")
150+
parser.add_argument("-g","--generate_new",dest="generate", action="store_true",default=False,
151+
help="instead of issuing errors, generate a new classes_def.xml file.")
152+
153+
args = parser.parse_args()
154+
sys.exit(main(args))
144155

0 commit comments

Comments
 (0)