tfscript/src/tfscript/verify.py

105 lines
2.9 KiB
Python
Raw Normal View History

2022-08-06 21:45:36 -04:00
"""Verify all the things that could go wrong."""
2022-09-17 14:07:44 -04:00
2022-08-25 20:34:38 -04:00
from tfscript import tftypes
2022-08-19 21:34:45 -04:00
def verifyConfig(cfg: dict) -> (dict, dict):
verifiedConfig = {}
2022-08-06 21:45:36 -04:00
2022-08-15 13:41:09 -04:00
errors = {}
2022-10-02 12:12:15 -04:00
warnings = {}
2022-08-06 21:45:36 -04:00
2022-09-04 09:26:22 -04:00
# Do defaults first
2022-08-21 21:21:41 -04:00
defaults = []
2022-08-06 21:45:36 -04:00
classList = [
2022-08-25 21:28:43 -04:00
'default',
2022-08-21 21:21:41 -04:00
'scout',
'soldier',
'pyro',
('demo','demoman'),
('engi','engineer'),
('heavy','heavyweapons'),
'medic',
'sniper',
'spy'
]
2022-08-06 21:45:36 -04:00
2022-09-04 09:26:22 -04:00
for isclass, class_ in enumerate(classList):
2022-08-25 21:28:43 -04:00
classCFG = None
2022-09-04 09:26:22 -04:00
className = class_
2022-08-25 21:28:43 -04:00
2022-09-04 09:26:22 -04:00
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)
2022-09-04 09:26:22 -04:00
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
2022-08-25 21:28:43 -04:00
2022-10-02 12:12:15 -04:00
classBinds = []
2022-08-15 13:41:09 -04:00
errMessages = []
2022-10-02 12:12:15 -04:00
warnMessages = []
for key, data in classCFG.items():
2022-10-02 12:12:15 -04:00
bind = tftypes.Bind(key, data)
2022-08-21 21:21:41 -04:00
2022-08-25 21:28:43 -04:00
bind = bind.toTargetType()
if isclass:
2022-08-21 21:21:41 -04:00
classBinds.append(bind)
2022-08-25 21:28:43 -04:00
else:
defaults.append(bind)
2022-08-21 21:21:41 -04:00
errMessages.extend(bind.errors)
2022-10-02 12:12:15 -04:00
warnMessages.extend(bind.warnings)
2022-08-21 21:21:41 -04:00
2022-08-15 13:41:09 -04:00
if len(errMessages) > 0:
errors.update( {className: errMessages} )
2022-10-02 12:12:15 -04:00
if len(warnMessages) > 0:
warnings.update( {className: warnMessages} )
2022-08-25 21:28:43 -04:00
2022-08-21 21:21:41 -04:00
verifiedConfig.update({className: classBinds})
# Turn list into only strings by expanding tuples
2022-09-04 09:26:22 -04:00
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)
2022-08-15 13:41:09 -04:00
globalErrors = []
for remainingClass in cfg:
if remainingClass not in classList:
2022-08-15 13:41:09 -04:00
globalErrors.append(f'"{remainingClass}" is not a valid class')
else:
otherName = findTwin(remainingClass)
2022-08-15 13:41:09 -04:00
globalErrors.append(f'Conflicting names for section: "{remainingClass}" and "{otherName}"')
if len(globalErrors) > 0:
2022-08-21 21:21:41 -04:00
errors.update({'file': globalErrors})
2022-08-06 21:45:36 -04:00
if len(errors) > 0:
2022-08-21 21:21:41 -04:00
verifiedConfig.update({'errors': errors})
2022-10-02 12:12:15 -04:00
if len(warnings) > 0:
verifiedConfig.update({'warnings': warnings})
2022-08-06 21:45:36 -04:00
return verifiedConfig, defaults
2022-08-06 21:45:36 -04:00
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