Beispiel #1
0
    def restoreOriginalMakefile(self):
        '''
        Check wether current 'Makefile' has print capabilities. If it has, this means it was already altered by this script.
        If it was, replace it with backup copy: 'Makefile.backup'.
        If it does not have print capabilities, it is assumed 'Makefile' was regenerated with CubeMX
        tool - print function is added and backup file is overwritten with this new 'Makefile'.

        At the end, fresh 'Makefile' with print function should be available.
        '''
        if utils.pathExists(utils.makefilePath):
            # Makefile exists, check if it is original (no print capabilities)
            if self.hasPrintCapabilities(utils.makefilePath):
                # Makefile exists, already modified
                if utils.pathExists(utils.makefileBackupPath):
                    # can original file be restored from backup file?
                    if self.hasPrintCapabilities(utils.makefileBackupPath):
                        errorMsg = "Both, 'Makefile' and 'Makefile.backup' exists, but they are both modified!\n"
                        errorMsg += "Did you manually delete, replace or modify any of Makefiles?\n"
                        errorMsg += "-> Delete all Makefiles and regenerate with CubeMX."
                        utils.printAndQuit(errorMsg)
                    else:
                        # original will be restored from backup file
                        print(
                            "Existing 'Makefile' file will be restored from 'Makefile.backup'."
                        )
                        utils.copyAndRename(utils.makefileBackupPath,
                                            utils.makefilePath)
                else:
                    errorMsg = "'Makefile.backup' does not exist, while 'Makefile' was already modified!\n"
                    errorMsg += "Did you manually delete, replace or modify any of Makefiles?\n"
                    errorMsg += "-> Delete all Makefiles and regenerate with CubeMX."
                    utils.printAndQuit(errorMsg)
            else:
                print("Existing 'Makefile' file found (original).")
                utils.copyAndRename(utils.makefilePath,
                                    utils.makefileBackupPath)
        elif utils.pathExists(utils.makefileBackupPath):
            # Makefile does not exist, but Makefile.backup does
            if self.hasPrintCapabilities(utils.makefileBackupPath):
                errorMsg = "'Makefile.backup' exists, but is already modified!\n"
                errorMsg += "Did you manually delete, replace or modify any of Makefiles?\n"
                errorMsg += "-> Delete all Makefiles and regenerate with CubeMX."
                utils.printAndQuit(errorMsg)
            else:
                # original will be restored from backup file
                print(
                    "'Makefile' file will be restored from 'Makefile.backup'.")
                utils.copyAndRename(utils.makefileBackupPath,
                                    utils.makefilePath)
        else:
            errorMsg = "No Makefiles available, unable to proceed!\n"
            errorMsg += "-> Regenerate with CubeMX."
            utils.printAndQuit(errorMsg)

        self.addMakefileCustomFunctions(pathToMakefile=utils.makefilePath)
Beispiel #2
0
    def checkTasksFile(self):
        '''
        Check if 'tasks.json' file exists. If it does, check if it is a valid JSON file.
        If it doesn't exist, create new according to template.
        '''
        if utils.pathExists(utils.tasksPath):
            # file exists, check if it loads OK
            try:
                with open(utils.tasksPath, 'r') as tasksFile:
                    json.load(tasksFile)

                    print("Existing 'tasks.json' file found.")
                    return

            except Exception as err:
                errorMsg = "Invalid 'tasks.json' file. Creating backup and new one.\n"
                errorMsg += "Possible cause: invalid json format or comments (not supported by this scripts). Error:\n"
                errorMsg += str(err)
                print(errorMsg)

                utils.copyAndRename(utils.tasksPath, utils.tasksBackupPath)

                self.createTasksFile()

        else:  # 'tasks.json' file does not exist jet, create it according to template string
            self.createTasksFile()
Beispiel #3
0
    def restoreOriginalMakefile(self):
        '''
        Check wether current 'Makefile' has print capabilities. If it has, this means it was already altered by this script.
        If it was, replace it with backup copy: 'Makefile.backup'.
        If it does not have prin capabilities, is is assumed 'Makefile' was regenerated with CubeMX tool - print function is added and backup file is overwritten with this new 'Makefile'.
        At the end, add 'print-variable' capabilities
        '''
        if utils.pathExists(utils.makefileBackupPath):
            # Makefile.backup exists, check if it is original (no print capabilities)
            if self.hasPrintCapabilities(
                    pathToMakefile=utils.makefileBackupPath):
                errorMsg = "Makefile.backup exist, but looks like it was already modified!\n"
                errorMsg += "Did you manually delete, replace or modify any of Makefiles? "
                errorMsg += "Delete all Makefiles and regenerate with CubeMX."
                utils.printAndQuit(errorMsg)

            else:  # OK - seems like original Makefile, replace Makefile with Makefile.backup, add print capabilities
                utils.copyAndRename(utils.makefileBackupPath,
                                    utils.makefilePath)

        else:  # Makefile.backup does not exist, check if current Makefile has print capabilities.
            if self.hasPrintCapabilities(pathToMakefile=utils.makefilePath):
                errorMsg = "Looks like Makefile was already modified! Makefile.backup does not exist.\n"
                errorMsg += "Did you manually delete, replace or modify any of Makefiles? "
                errorMsg += "Delete all Makefiles and regenerate with CubeMX."
                utils.printAndQuit(errorMsg)

            else:  # Makefile looks like an original one. Create a backup copy and add print capabilities
                utils.copyAndRename(utils.makefilePath,
                                    utils.makefileBackupPath)

        self.addMakefileCustomFunctions(pathToMakefile=utils.makefilePath)
Beispiel #4
0
    def checkToolsPathFile(self):
        '''
        Returns True if 'toolsPaths.json' file exists and is a valid JSON file.
        If it doesn't exist, delete it and return False.
        '''
        if utils.pathExists(utils.toolsPaths):
            # file exists, check if it loads OK
            try:
                with open(utils.toolsPaths, 'r') as toolsFileHandler:
                    data = json.load(toolsFileHandler)
                    print("Valid 'toolsPaths.json' file found.")
                return True

            except Exception as err:
                errorMsg = "Invalid 'toolsPaths.json' file. Error:\n" + str(
                    err)
                print(errorMsg)

                try:
                    os.remove(utils.toolsPaths)
                    errorMsg = "\tDeleted. New 'toolsPaths.json' will be created on first valid user paths update."
                    print(errorMsg)
                except Exception as err:
                    errorMsg = "\tError deleting 'toolsPaths.json'. Error:\n" + str(
                        err)
                    print(errorMsg)
                return False

        else:  # toolsPaths.json does not exist
            return False
    def checkCPropertiesFile(self):
        '''
        Check if 'c_cpp_properties.json' file exists. If it does, check if it is a valid JSON file.
        If it doesn't exist, create new according to template.
        '''
        if utils.pathExists(utils.cPropertiesPath):
            # file exists, check if it loads OK
            try:
                with open(utils.cPropertiesPath, 'r') as cPropertiesFile:
                    currentData = json.load(cPropertiesFile)
                    # this is a valid json file
                    print("Existing valid 'c_cpp_properties.json' file found.")

                # merge current 'c_cpp_properties.json' with its template
                templateData = json.loads(tmpStr.c_cpp_template)
                dataToWrite = utils.mergeCurrentDataWithTemplate(currentData, templateData)
                dataToWrite = json.dumps(dataToWrite, indent=4, sort_keys=False)
                with open(utils.cPropertiesPath, 'w') as cPropertiesFile:
                    cPropertiesFile.write(dataToWrite)
                    print("\tKeys updated according to the template.")
                return

            except Exception as err:
                errorMsg = "Invalid 'c_cpp_properties.json' file. Creating backup and new one.\n"
                errorMsg += "Possible cause: invalid json format or comments (not supported by this scripts). Error:\n"
                errorMsg += str(err)
                print(errorMsg)

                utils.copyAndRename(utils.cPropertiesPath, utils.cPropertiesBackupPath)

                self.createCPropertiesFile()

        else:  # 'c_cpp_properties.json' file does not exist jet, create it according to template string
            self.createCPropertiesFile()
    def checkBuildDataFile(self):
        '''
        This function makes sure 'buildData.json' is available. 
        If existing 'buildData.json' file is a valid JSON, it returns immediately. 
        If it is not a valid JSON file OR it does not exist, new 'buildData.json' file is created from template.

        Note: There is no backup file for buildData.json, since it is always regenerated on Update task.
        '''
        if utils.pathExists(utils.buildDataPath):
            # file exists, check if it loads OK
            try:
                with open(utils.buildDataPath, 'r') as buildDataFileHandler:
                    json.load(buildDataFileHandler)
                    print("Valid 'buildData.json' file found.")

                return

            except Exception as err:
                errorMsg = "Invalid 'buildData.json' file. Error:\n" + str(err)
                print(errorMsg)

                try:
                    os.remove(utils.buildDataPath)
                    msg = "\tDeleted. New 'buildData.json' will be created on first workspace update."
                    print(msg)
                except Exception as err:
                    errorMsg = "Error deleting 'buildData.json'. Error:\n" + str(
                        err)
                    utils.printAndQuit(errorMsg)

        # else: buildData.json does not exist
        self.createBuildDataFile()
Beispiel #7
0
    def checkToolsPathFile(self):
        '''
        Returns True if 'toolsPaths.json' file exists and is a valid JSON file.
        If it is not a valid JSON, delete it and return False.
        '''
        if utils.pathExists(utils.toolsPaths):
            # file exists, check if it loads OK
            try:
                with open(utils.toolsPaths, 'r') as toolsFileHandler:
                    json.load(toolsFileHandler)
                    print("Valid 'toolsPaths.json' file found. " +
                          utils.toolsPaths)
                return True

            except Exception as err:
                errorMsg = "Invalid 'toolsPaths.json' file. Error:\n" + str(
                    err)
                print(errorMsg)

                try:
                    os.remove(utils.toolsPaths)
                    msg = "\tDeleted. New 'toolsPaths.json' will be created on first workspace update."
                    print(msg)
                except Exception as err:
                    errorMsg = "Error deleting 'toolsPaths.json'. Error:\n" + str(
                        err)
                    utils.printAndQuit(errorMsg)

        # else: toolsPaths.json does not exist
        return False
Beispiel #8
0
 def checkMakefileFile(self):
     '''
     Check if 'Makefile' file exists. If it doesn't, report as error.
     '''
     if not utils.pathExists(utils.makefilePath):
         errorMsg = "Makefile does not exist! Did CubeMX generated Makefile?\n"
         errorMsg += "File name must be 'Makefile'."
         utils.printAndQuit(errorMsg)
Beispiel #9
0
    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
Beispiel #10
0
    def updatePath(self, pathName, default):
        '''
        This function is called when a path is detected as invalid or the user requests to update paths.
        '''
        # check if default path is command
        pathDefault = None
        if utils.commandExists(default):
            pathDefault = shutil.which(default)
        # if not a command, check if it's a path
        elif utils.pathExists(default):
            pathDefault = 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
    def prepareBuildData(self, request=False):
        '''
        This function is used in all 'update*.py' scripts and makes sure, that 'toolsPaths.json' and 'buildData.json' with a 
        valid tools/target cofniguration paths exist. Invalid paths are updated (requested from the user).
        Returns available, valid build data.

        Note: tools paths listed in 'BuildDataStrings.toolsPaths' are stored in system local 'toolsPaths.json' file, and are 
        copied (overwritten) to 'buildData.json' on first 'Update' task run. This makes it possible for multiple code contributors.
        '''
        paths = pth.UpdatePaths()

        self.checkBuildDataFile()
        buildData = self.getBuildData()

        if self.checkToolsPathFile():  # a valid toolsPaths.json exists
            toolsPathsData = self.getToolsPathsData()

        else:
            # no valid data from 'toolsPaths.json' file
            # try to get data from current 'buildData.json' - backward compatibility for paths that already exist in 'buildData.json'
            toolsPathsData = json.loads(tmpStr.toolsPathsTemplate)
            for path in self.bStr.toolsPaths:
                if path in buildData:
                    if utils.pathExists(buildData[path]):
                        toolsPathsData[path] = buildData[path]

        # update/overwrite tools paths file. Don't mind if paths are already valid.
        toolsPathsData = paths.verifyToolsPaths(toolsPathsData, request)
        self.createUserToolsFile(toolsPathsData)

        buildData = self.addToolsPathsToBuildData(buildData, toolsPathsData)

        templateBuildData = json.loads(tmpStr.buildDataTemplate)
        buildData = utils.mergeCurrentDataWithTemplate(buildData,
                                                       templateBuildData)

        buildData = paths.verifyTargetConfigurationPaths(buildData, request)
        buildData = paths.copyTargetConfigurationFiles(buildData)

        return buildData
Beispiel #12
0
    def checkWorkspaceFile(self):
        '''
        Check if workspace '*.code-workspace' file exists. If it does, check if it is a valid JSON file.
        If it doesn't exist report error and quit.
        '''
        workspaceFiles = utils.getCodeWorkspaces()
        if len(workspaceFiles) == 1:
            _, fileName = os.path.split(workspaceFiles[0])
            workspaceFileName, _ = os.path.splitext(fileName)
            if utils.pathExists(utils.workspaceFilePath):
                # file exists, check if it loads OK
                try:
                    with open(utils.workspaceFilePath, 'r') as workspaceFile:
                        workspaceFileData = json.load(workspaceFile)

                        print("Existing " + workspaceFileName + " file found.")

                except Exception as err:
                    errorMsg = "Invalid " + workspaceFileName + " file.\n"
                    errorMsg += "Possible cause: invalid json format or comments (not supported by this scripts). Error:\n"
                    errorMsg += str(err)
                    print(errorMsg)
Beispiel #13
0
    def checkBuildDataFile(self):
        '''
        Check if 'buildData.json' file exists. If it does, check if it is a valid JSON file.
        If it doesn't exist, create new according to template.
        '''
        if utils.pathExists(utils.buildDataPath):
            # file exists, check if it loads OK
            try:
                with open(utils.buildDataPath, 'r') as buildDataFile:
                    data = json.load(buildDataFile)

                    print("Existing 'buildData.json' file found.")

            except Exception as err:
                errorMsg = "Invalid 'buildData.json' file. Creating new one. Error:\n"
                errorMsg += "Possible cause: invalid json format or comments (not supported by this scripts). Error:\n"
                errorMsg += str(err)
                print(errorMsg)

                self.createBuildDataFile()

        else:  # 'buildData.json' file does not exist jet, create it according to template string
            self.createBuildDataFile()
Beispiel #14
0
    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
Beispiel #15
0
    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
Beispiel #16
0
    def verifyExistingPaths(self, buildData, request=False):
        '''
        This function checks if configuration paths (not workspace sources) from 'buildData.json' are valid paths.
        Common configuration paths are previoulsy fetched from 'toolsPaths.json'.
        If any path is not valid/missing, user is asked for update via updatePath().

        Returns updated valid paths.
        '''
        for pathName in self.bStr.configurationPaths:
            mustBeUpdated = False
            try:
                isPathValid = False
                if pathName in buildData:
                    pathToCheck = buildData[pathName]
                    if isinstance(pathToCheck, list):
                        for path in pathToCheck:
                            if not utils.pathExists(path):
                                break
                        else:
                            isPathValid = True
                    else:  # not a list, a single path expected
                        if utils.pathExists(pathToCheck):
                            isPathValid = True
                        else:
                            # path not valid, check if command
                            if utils.commandExists(pathToCheck):
                                isPathValid = True

                if isPathValid:
                    if request:  # if the user made the path verification request
                        msg = "\n\nValid paths for " + pathName + " detected: '" + str(pathToCheck) + "'.\n\tUpdate? [y/n]: "
                        if utils.getYesNoAnswer(msg):
                            mustBeUpdated = True
                else:
                    # non-valid path, must be updated
                    mustBeUpdated = True

                if mustBeUpdated:
                    if pathName in [self.bStr.pythonExec, self.bStr.gccInludePath]:
                        # derived paths, build later
                        continue

                    elif pathName in self.toolsList:
                        name = self.toolsList[pathName]["name"]
                        defaultPath = self.toolsList[pathName]["defaultPath"]
                        buildData[pathName] = self.updatePath(name, defaultPath)

                    # handle special paths cases - custom get() handlers
                    elif pathName == self.bStr.openOcdInterfacePath:
                        buildData[pathName] = utils.getOpenOcdInterface(buildData[self.bStr.openOcdPath])

                    elif pathName == self.bStr.openOcdConfig:
                        # get openOcdConfig
                        buildData[self.bStr.openOcdConfig] = utils.getOpenOcdConfig(buildData[self.bStr.openOcdInterfacePath])

                    # basic path question, default name
                    else:
                        buildData[pathName] = self.updatePath(pathName, None)

            except Exception as err:
                buildData[pathName] = self.updatePath(pathName, None)

        # get gccIncludePath
        buildData[self.bStr.gccInludePath] = utils.getGccIncludePath(buildData[self.bStr.gccExePath])
        # get python3 executable
        buildData[self.bStr.pythonExec] = utils.getPython3Executable()

        return buildData