tfscript/tfscript/verify.py

105 lines
2.9 KiB
Python

"""Verify all the things that could go wrong."""
from tfscript import tftypes
def verifyConfig(cfg: dict) -> (dict, dict):
verifiedConfig = {}
errors = {}
warnings = {}
# Do defaults first
defaults = []
classList = [
'default',
'scout',
'soldier',
'pyro',
('demo','demoman'),
('engi','engineer'),
('heavy','heavyweapons'),
'medic',
'sniper',
'spy'
]
for isclass, class_ in enumerate(classList):
classCFG = None
className = class_
if isinstance(class_, str) and class_ in cfg:
classCFG = cfg.pop(class_)
elif isinstance(class_, tuple):
for tupClass in class_:
if tupClass in cfg:
classCFG = cfg.pop(tupClass)
className = class_[0]
break
if classCFG is None:
# Invalid class, this gets caught later.
# It may be less efficient this way, but
# it makes for more descriptive error messages
continue
classBinds = []
errMessages = []
warnMessages = []
for key, data in classCFG.items():
bind = tftypes.ScriptBind(key, data)
bind = bind.toTargetType()
if isclass:
classBinds.append(bind)
else:
defaults.append(bind)
errMessages.extend(bind.errors)
warnMessages.extend(bind.warnings)
if len(errMessages) > 0:
errors.update( {className: errMessages} )
if len(warnMessages) > 0:
warnings.update( {className: warnMessages} )
verifiedConfig.update({className: classBinds})
# Turn list into only strings by expanding tuples
for i, class_ in enumerate(classList):
if isinstance(class_, tuple):
classList.insert(i+1, class_[1])
classList.insert(i+1, class_[0])
classList.pop(i)
globalErrors = []
for remainingClass in cfg:
if remainingClass not in classList:
globalErrors.append(f'"{remainingClass}" is not a valid class')
else:
otherName = findTwin(remainingClass)
globalErrors.append(f'Conflicting names for section: "{remainingClass}" and "{otherName}"')
if len(globalErrors) > 0:
errors.update({'file': globalErrors})
if len(errors) > 0:
verifiedConfig.update({'errors': errors})
if len(warnings) > 0:
verifiedConfig.update({'warnings': warnings})
return verifiedConfig, defaults
def findTwin(className):
classDict = {
"demo": "demoman",
"engi": "engineer",
"heavy": "heavyweapons"
}
for className1, className2 in classDict.items():
if className == className1:
return className2
elif className == className2:
return className1
return None