Package: bain-wizard-interpreter
BAIN Wizard InterpreterA BAIN Wizard Interpreter based onwizparsethat can
be used in various settings to run BAIN Wizard installers.Basic UsageThere are various way to use the interpreter.
The easiest way is to extends theWizardScriptRunnerand add the missing
functionalities that are mod-manager or game specific.
You can then useWizardScriptRunner.run()to execute a script, and everything will
be called when required.frompathlibimportPathfromtypingimportListfromwizard.managerimportSelectOptionfromwizard.scriptrunnerimportWizardScriptRunnerfromwizard.valueimportSubPackage,SubPackagesclassMySubPackage(SubPackage):"""Implement your own SubPackage."""_files:List[str]def__init__(self,name:str,files:List[str]):super().__init__(name)self._files=files@propertydeffiles(self):returniter(self._files)classMyRunner(WizardScriptRunner):"""Extends the runner and implement the missing methods."""# these are the methods you need to provide, see manager.ManagerModInterface# and manager.ManagerUserInterface for the documentation of each method## the WizardRunner class extends both interfaces and already implements many# functions, but you can always override themdefselectOne(self,description:str,options:List[SelectOption],default:SelectOption)->SelectOption:...defselectMany(self,description:str,options:List[SelectOption],default:List[SelectOption]=[],)->List[SelectOption]:...defcompareGameVersion(self,version:str)->int:...defcompareSEVersion(self,version:str)->int:...defcompareGEVersion(self,version:str)->int:...defcompareWBVersion(self,version:str)->int:...defdataFileExists(self,*filepaths:str)->bool:...defgetPluginLoadOrder(self,filename:str,fallback:int=-1)->int:...defgetPluginStatus(self,filename)->int:...defgetFilename(self,path:str)->str:...defgetFolder(self,path:str)->str:...# create the sub-packagessubpackages=SubPackages([MySubPackage(...)for...])# create the runnerrunner=MyRunner(subpackages)# run a script - use a Path() object, otherwise the string will be interpreted# as a scriptstatus,result=runner.run(Path("wizard.txt"))status# status of the executionresult.subpackages# list of selected sub-packagesresult.plugins# list of enabled pluginsresult.notes# list of notesresult.tweaks.disabled# list of disabled INI settingsresult.tweaks.modified# list of new or modified INI settingsHandling errorsIf an error occurs during the script execution, the interpreter will call
theWizardScriptRunner.error()function with the Python exception. By default, this
method re-raise the error, you can change it:deferror(self,exc:Exception):# handle the error...If this method returns,result.statuswill beWizardScriptRunnerStatus.ERROR.Extra featuresTheWizardScriptRunnerexposes a few extra features through methods that you can use
during the execution, e.g. inselectOne,selectMany,error,complete, etc.runner=WizardRunner(...)# abort the execution - Equivalent to a 'Cancel' keywordrunner.abort()# retrieve the current contextcontext=runner.context()# rewind to the given contextrunner.rewind(context)Therunner.abortandrunner.rewindmethod rely on exception to work, so these do
not return.DependencieswizparseThe code underwizard/antlr4is generated fromwizard/antlr4/wizard.g4from thewizparserepository.
To generate the file, you needantlr4, and you simply have to run:# IMPORTANT: use FORWARD SLASH (/) everywhere, otherwise it does not workjava-jarantlr-4.10.1-complete.jar-visitor-Dlanguage=Python3-o./wizard/antlr4./vendor/wizparse/wizards/wizard.g4Run testsTo run the tests, you need the Python 3 ANTLR4 runtime andpytest:pipinstallantlr4-python3-runtimepytestYou can then run the tests usingpytest.LICENSEUnless otherwise specified, the code in this repository is licensed under the MIT license.
SeeLICENSEfor the full text.Exceptions:The code inwizard/antlr4is generated from
thewizparserepository, so thewizparseLICENSE applies to it.The code invendor/wizparseis under thewizparseLICENSE.The files invendor/wizparse/testshave their own accompanying license. See thewizparserepository for more details.