diff options
| author | Stijn Kuipers <stijnkuipers@gmail.com> | 2023-06-29 16:26:07 +0200 |
|---|---|---|
| committer | Stijn Kuipers <stijnkuipers@gmail.com> | 2023-06-29 16:26:07 +0200 |
| commit | fb5a321dd7c2848128b04b306f3e1e59c87a3f70 (patch) | |
| tree | a8ef6273f9f331ebb1971a9baf20a8c897955612 /sw/ideScripts/updatePaths.py | |
| parent | bae7568fd4dd0676b370be8548c7ec95d6521ba1 (diff) | |
| download | plinky-fb5a321dd7c2848128b04b306f3e1e59c87a3f70.tar.gz | |
Initial Filedump
Tadaaa!!
Diffstat (limited to 'sw/ideScripts/updatePaths.py')
| -rwxr-xr-x | sw/ideScripts/updatePaths.py | 273 |
1 files changed, 273 insertions, 0 deletions
diff --git a/sw/ideScripts/updatePaths.py b/sw/ideScripts/updatePaths.py new file mode 100755 index 0000000..7599f39 --- /dev/null +++ b/sw/ideScripts/updatePaths.py @@ -0,0 +1,273 @@ +''' +This script can be run to update paths to gcc, openOCD and other tools/files/folders. +Script verify and add data to 'buildData.json' file. +''' +import os +import shutil + +import utilities as utils +import updateBuildData as build +import updateTasks as tasks +import updateLaunchConfig as launch +import updateWorkspaceFile as workspaceFile + +__version__ = utils.__version__ + + +class UpdatePaths(): + def __init__(self): + self.bStr = build.BuildDataStrings() + + # list of paths with explanatory names and (optionally) default path + # keys must match with 'self.bStr.toolsPaths' list + self.pathsDescriptionsData = { + self.bStr.gccExePath: { + "name": "arm-none-eabi-gcc executable (arm-none-eabi-gcc.exe)", + "defaultPath": "arm-none-eabi-gcc"}, + self.bStr.buildToolsPath: { + "name": "make executable (make.exe)", + "defaultPath": "make"}, + self.bStr.openOcdPath: { + "name": "OpenOCD executable (openocd.exe)", + "defaultPath": "openocd"}, + self.bStr.openOcdInterfacePath: { + "name": "OpenOCD ST Link interface path ('stlink.cfg')", + "defaultPath": "./scripts/interface/stlink.cfg"}, + self.bStr.stm32SvdPath: { + "name": "STM target '*.svd' file (.../Keil*/CMSIS/SVD/STM32F0x1.svd)", + "defaultPath": None} + } + + def verifyToolsPaths(self, toolsPaths, request=False): + ''' + This function checks if paths in 'toolsPaths.json' are a valid paths. + If any path is not valid/missing, user is asked for update via updatePath(). + If 'request' is set to True, user is asked to update path even if it is a valid path. + + Returns updated valid tools paths. + ''' + for pathName in self.bStr.toolsPaths: + try: + mustBeUpdated = False + if pathName in toolsPaths: + # 'toolsPaths.json' keys are not lists. Always a plain path (string) + if not utils.pathExists(toolsPaths[pathName]): + mustBeUpdated = True + # path not valid, check if command + if utils.commandExists(toolsPaths[pathName]): + mustBeUpdated = False + + if mustBeUpdated: + if toolsPaths[pathName] != '': + # avoid reporting invalid file path, if there is an empty string + msg = "\n\nInvalid path detected in '" + pathName + "' key." + print(msg) + else: + if request: + msg = "\n\nValid path(s) for " + pathName + " detected: '" + toolsPaths[pathName] + "'." + msg += "\n\tUpdate? [y/n]: " + if utils.getYesNoAnswer(msg): + mustBeUpdated = True + + else: # this key is missing in toolsPaths.json! + mustBeUpdated = True + + if mustBeUpdated: + if pathName in self.bStr.derivedPaths: + continue + + elif pathName == self.bStr.openOcdConfig: + # get openOcdConfig - special handler + toolsPaths[pathName] = utils.getOpenOcdConfig(toolsPaths[self.bStr.openOcdPath]) + + elif pathName in self.pathsDescriptionsData: + name = self.pathsDescriptionsData[pathName]['name'] + defaultPath = self.pathsDescriptionsData[pathName]['defaultPath'] + toolsPaths[pathName] = self.updatePath(name, defaultPath) + + else: + toolsPaths[pathName] = self.updatePath(pathName, None) + + except Exception as err: + toolsPaths[pathName] = self.updatePath(pathName, None) + + for pathName in self.bStr.derivedPaths: + if pathName == self.bStr.pythonExec: + toolsPaths[self.bStr.pythonExec] = utils.getPython3Executable() + + elif pathName == self.bStr.gccInludePath: + toolsPaths[self.bStr.gccInludePath] = utils.getGccIncludePath(toolsPaths[self.bStr.gccExePath]) + + else: + errorMsg = "ideScripts design error: pathName '" + pathName + "' is in 'self.bStr.derivedPaths' list, " + errorMsg += "but no 'get()' handler is specified." + utils.printAndQuit(errorMsg) + + return toolsPaths + + def verifyTargetConfigurationPaths(self, buildData, request=False): + ''' + This function checks if 'buildData.json' contains targetConfiguration paths. + If any path is not valid/missing, user is asked for update via updatePath(). + If 'request' is set to True, user is asked to update path even if it is a valid path. + + Returns buildData with a valid, updated tools paths. + ''' + for pathName in self.bStr.targetConfigurationPaths: + mustBeUpdated = False + + if pathName in self.bStr.derivedPaths: + # derived paths, build later + continue + + if pathName not in buildData: + mustBeUpdated = True + + else: + if isinstance(buildData[pathName], list): + if not buildData[pathName]: + mustBeUpdated = True + else: + for path in buildData[pathName]: + if not utils.pathExists(path): + mustBeUpdated = True + break + + else: # not a list, a single path expected + if not utils.pathExists(buildData[pathName]): + mustBeUpdated = True + # path not valid, check if command + if utils.commandExists(buildData[pathName]): + mustBeUpdated = False + + if mustBeUpdated: + notify = True + # avoid reporting invalid file path, if there is an empty string/list + if isinstance(buildData[pathName], list): + if not buildData[pathName]: + notify = False + else: + if buildData[pathName] == '': + notify = False + + if notify: + msg = "\n\nInvalid path detected in 'buildData.json' '" + pathName + "' key." + print(msg) + else: + if request: + msg = "\n\nValid path(s) for " + pathName + " detected: '" + str(buildData[pathName]) + "'." + msg += "\n\tUpdate? [y/n]: " + if utils.getYesNoAnswer(msg): + mustBeUpdated = True + + if mustBeUpdated: + if pathName == self.bStr.openOcdConfig: + # get openOcdConfig - special handler + buildData[pathName] = utils.getOpenOcdConfig(buildData[self.bStr.openOcdPath]) + + elif pathName in self.bStr.derivedPaths: + name = self.bStr.derivedPaths[pathName]['name'] + defaultPath = self.bStr.derivedPaths[pathName]['defaultPath'] + buildData[pathName] = self.updatePath(name, defaultPath) + + else: + buildData[pathName] = self.updatePath(pathName, None) + + return buildData + + def copyTargetConfigurationFiles(self, buildData): + ''' + This function checks if paths to target configuration files listed in 'BuildDataStrings.targetConfigurationPaths' + are available, stored inside this workspace '.vscode' subfolder. Once this files are copied, paths are updated and + new buildData is returned. + + Paths are previously checked/updated in 'verifyTargetConfigurationPaths()' + ''' + for pathName in self.bStr.targetConfigurationPaths: + currentPaths = buildData[pathName] + + if isinstance(currentPaths, list): + isList = True + else: + isList = False + currentPaths = [currentPaths] + + newPaths = [] + for currentPath in currentPaths: + fileName = utils.getFileName(currentPath, withExtension=True) + fileInVsCodeFolder = os.path.join(utils.vsCodeFolderPath, fileName) + + if not utils.pathExists(fileInVsCodeFolder): + # file does not exist in '.vscode' folder + try: + newPath = shutil.copy(currentPath, utils.vsCodeFolderPath) + except Exception as err: + errorMsg = "Unable to copy file '" + fileName + "' to '.vscode' folder. Exception:\n" + str(err) + utils.printAndQuit(errorMsg) + + newPath = os.path.relpath(fileInVsCodeFolder) + newPath = utils.pathWithForwardSlashes(newPath) + newPaths.append(newPath) + + if isList: + buildData[pathName] = newPaths + else: + buildData[pathName] = newPaths[0] + + return buildData + + def updatePath(self, pathName, default): + ''' + This function is called when a path is detected as invalid or the user requests to update paths. + ''' + pathDefault = None + + # check if default is a path + if utils.pathExists(default): + pathDefault = default + + # not a path command, check if it's a command + elif utils.commandExists(default): + pathDefault = shutil.which(default) + + if pathDefault is not None: + msg = "\n\tDefault path to '" + pathName + "' detected at '" + pathDefault + "'\n\tUse this path? [y/n]: " + if utils.getYesNoAnswer(msg): + return pathDefault + + # default not detected or user wants custom path/command + newPath = utils.getUserPath(pathName) + return newPath + + +######################################################################################################################## +if __name__ == "__main__": + utils.verifyFolderStructure() + + paths = UpdatePaths() + bData = build.BuildData() + tasks = tasks.Tasks() + launch = launch.LaunchConfigurations() + wksFile = workspaceFile.UpdateWorkspaceFile() + + # update build data + buildData = bData.prepareBuildData(request=True) + bData.overwriteBuildDataFile(buildData) + + # update tasks + tasks.checkTasksFile() + tasksData = tasks.getTasksData() + tasksData = tasks.addAllTasks(tasksData) + tasks.overwriteTasksFile(tasksData) + + # update launch configurations + launch.checkLaunchFile() + launchData = launch.getLaunchData() + launchData = launch.addAllLaunchConfigurations(launchData) + launch.overwriteLaunchFile(launchData) + + # update workspace file with "cortex-debug" specifics + wksFile.checkWorkspaceFile() + wksData = wksFile.getWorkspaceFileData() + wksData = wksFile.addBuildDataToWorkspaceFile(wksData, buildData) + wksFile.overwriteWorkspaceFile(wksData) |
