summaryrefslogtreecommitdiff
path: root/sw/ideScripts/updatePaths.py
diff options
context:
space:
mode:
Diffstat (limited to 'sw/ideScripts/updatePaths.py')
-rwxr-xr-xsw/ideScripts/updatePaths.py273
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)