Exemplo n.º 1
0
    def __validateDependsOnLists(self):
        if len(self.targets) == 0:
            return True

        for currTarget in self.targets:
            normalizedName = target.normalizeName(currTarget.name)
            checkedDependencies = []
            for dependency in currTarget.dependsOn:
                normalizedDepedancy = target.normalizeName(dependency)
                if normalizedDepedancy == normalizedName:
                    logger.writeError("Target cannot depend on itself",
                                      currTarget.name, "", self.path)
                    return False
                if normalizedDepedancy in checkedDependencies:
                    logger.writeError(
                        "Target has duplicate dependency '" + dependency + "'",
                        currTarget.name, "", self.path)
                    return False
                if self.getTarget(dependency) is None:
                    logger.writeError(
                        "Target has non-existant dependency '" + dependency +
                        "'", currTarget.name, "", self.path)
                    return False
                checkedDependencies.append(normalizedDepedancy)

        path = [target.normalizeName(self.targets[0].name)]
        return self.__searchPathsForCycles(path)
Exemplo n.º 2
0
 def getTarget(self, targetName):
     normalizedTargetName = target.normalizeName(targetName)
     for currTarget in self.targets:
         if normalizedTargetName == target.normalizeName(currTarget.name):
             return currTarget
         for alias in currTarget.aliases:
             if normalizedTargetName == target.normalizeName(alias):
                 return currTarget
     return None
Exemplo n.º 3
0
 def getTarget(self, targetName):
     normalizedTargetName = target.normalizeName(targetName)
     for currTarget in self.targets:
         if normalizedTargetName == target.normalizeName(currTarget.name):
             return currTarget
         for alias in currTarget.aliases:
             if normalizedTargetName == target.normalizeName(alias):
                 return currTarget
     return None
Exemplo n.º 4
0
    def __addTarget(self, targets, lineCount=0):
        if targets.name == "" or targets.path == "":
            logger.writeError("New target started before previous was finished, all targets require atleast 'Name' and 'Path' to be declared", "", "", self.path, lineCount)
            return False

        for currTarget in self.targets:
            if target.normalizeName(targets.name) == target.normalizeName(currTarget.name):
                logger.writeError("Cannot have more than one project target by the same name", currTarget.name, "", self.path, lineCount)
                return False
        self.targets.append(targets)
        return True
Exemplo n.º 5
0
 def replaceTarget(self, newTarget):
     normalizedTargetName = target.normalizeName(newTarget.name)
     i = 0
     targetFound = False
     for currTarget in self.targets:
         if normalizedTargetName == target.normalizeName(currTarget.name):
             targetFound = True
             break
         i += 1
     if targetFound:
         self.targets[i] = newTarget
Exemplo n.º 6
0
 def replaceTarget(self, newTarget):
     normalizedTargetName = target.normalizeName(newTarget.name)
     i = 0
     targetFound = False
     for currTarget in self.targets:
         if normalizedTargetName == target.normalizeName(currTarget.name):
             targetFound = True
             break
         i += 1
     if targetFound:
         self.targets[i] = newTarget
Exemplo n.º 7
0
def getDependencies(path, name="", verbose=True):
    deps = []
    if not os.path.isdir(path):
        return None
    if not isCMakeProject(path):
        return None

    if verbose:
        logger.writeMessage("Analyzing CMake files for dependencies...", name)

    fileList = list()
    _findAllCMakeFiles(path, fileList)

    packageRegExp = re.compile(r"find_package\s*\((\s*[\w\.]+)\s*.*\)")
    #find_library(...) starts with a output variable then has two options
    # 1) the name of the library to search for
    # 2) "NAMES" followed by a list of possible library names
    #It can then be followed by possible paths and various tokens listed below
    #By using the first name in the list I should be to avoid any extra paths that may or may not exist and get
    #  the majority of library names right (since most examples I found were close to "OpenGL, OpenGL3.1, OpenGL, 3.2, etc"
    libraryRegExp = re.compile(r"find_library\s*\(\s*([^\)]+)\s*\)")
    libraryTokens = ['names', 'hints', 'paths', 'path_suffixes', 'doc', 'no_default_path', 'no_cmake_environment_path', 'no_cmake_path', 'no_system_environment_path', 'no_cmake_system_path', 'cmake_find_root_path_both', 'only_cmake_find_root_path',  'no_cmake_find_root_path']

    for name in fileList:
        try:
            cmakeFile = open(name, "r")
            for line in cmakeFile:
                match = packageRegExp.search(line)
                if match != None:
                    foundDep = target.normalizeName(match.group(1))
                    if not foundDep in deps:
                        deps.append(foundDep)

                ignoredFirstParam = False
                match = libraryRegExp.search(line)
                if match != None:
                    paramStr = match.group(1).strip()
                    paramList = paramStr.split(" ")
                    for param in paramList:
                        param = target.normalizeName(param)
                        if param != "":
                            if not ignoredFirstParam:
                                ignoredFirstParam = True
                                continue
                            if param in libraryTokens:
                                continue
                            foundDep = param
                            break
                    if not foundDep.startswith("${") and not foundDep in deps:
                        deps.append(foundDep)
                ignoredFirstParam = False
        finally:
            cmakeFile.close()
    return deps
Exemplo n.º 8
0
def getDependencies(path, name="", verbose=True):
    deps = []
    if not os.path.isdir(path) or not os.path.exists(
            os.path.join(path, "configure")):
        return None

    if verbose:
        logger.writeMessage("Analyzing 'configure --help' output", name)
    helpFileName = os.path.join(path, "configure_help.log")
    helpFile = open(helpFileName, "w")
    try:
        returnCode = utilityFunctions.executeSubProcess(
            "./configure --help", path, helpFile.fileno())
    finally:
        helpFile.close()
    if returnCode != 0:
        return None

    try:
        helpFile = open(helpFileName, "r")
        regexp = re.compile(
            r"--with-([a-zA-Z\-_]+)=(?:PREFIX|prefix|PATH|path|DIR|dir)")
        for line in helpFile:
            match = regexp.search(line)
            if match != None:
                foundDep = match.group(1)
                foundDep = target.normalizeName(foundDep)
                if not foundDep in deps:
                    deps.append(foundDep)
    finally:
        helpFile.close()

    return deps
Exemplo n.º 9
0
    def __addTarget(self, targets, lineCount=0):
        if targets.name == "" or targets.path == "":
            logger.writeError(
                "New target started before previous was finished, all targets require atleast 'Name' and 'Path' to be declared",
                "", "", self.path, lineCount)
            return False

        for currTarget in self.targets:
            if target.normalizeName(targets.name) == target.normalizeName(
                    currTarget.name):
                logger.writeError(
                    "Cannot have more than one project target by the same name",
                    currTarget.name, "", self.path, lineCount)
                return False
        self.targets.append(targets)
        return True
Exemplo n.º 10
0
def getDependencies(path, name="", verbose=True):
    deps = []
    if not os.path.isdir(path) or not os.path.exists(os.path.join(path, "configure")):
        return None

    if verbose:
        logger.writeMessage("Analyzing 'configure --help' output", name)
    helpFileName = os.path.join(path, "configure_help.log")
    helpFile = open(helpFileName, "w")
    try:
        returnCode = utilityFunctions.executeSubProcess("./configure --help", path, helpFile.fileno())
    finally:
        helpFile.close()
    if returnCode != 0:
        return None

    try:
        helpFile = open(helpFileName, "r")
        regexp = re.compile(r"--with-([a-zA-Z\-_]+)=(?:PREFIX|prefix|PATH|path|DIR|dir)")
        for line in helpFile:
            match = regexp.search(line)
            if match != None:
                foundDep = match.group(1)
                foundDep = target.normalizeName(foundDep)
                if not foundDep in deps:
                    deps.append(foundDep)
    finally:
        helpFile.close()

    return deps
Exemplo n.º 11
0
def getTarget(name, targetList, aliasToAdd = ""):
    normalizedTargetName = target.normalizeName(name)
    foundTarget = None
    for currTarget in targetList:
        if normalizedTargetName == target.normalizeName(currTarget.name):
            foundTarget = currTarget
            break
        for alias in currTarget.aliases:
            if normalizedTargetName == target.normalizeName(alias):
                foundTarget = currTarget
                break

    if foundTarget != None:
        if aliasToAdd != "" and not aliasToAdd in target.aliases:
            target.aliases.append(aliasToAdd)

    return foundTarget
Exemplo n.º 12
0
def getTarget(name, targetList, aliasToAdd=""):
    normalizedTargetName = target.normalizeName(name)
    foundTarget = None
    for currTarget in targetList:
        if normalizedTargetName == target.normalizeName(currTarget.name):
            foundTarget = currTarget
            break
        for alias in currTarget.aliases:
            if normalizedTargetName == target.normalizeName(alias):
                foundTarget = currTarget
                break

    if foundTarget != None:
        if aliasToAdd != "" and not aliasToAdd in target.aliases:
            target.aliases.append(aliasToAdd)

    return foundTarget
Exemplo n.º 13
0
 def __searchPathsForCycles(self, path):
     currTarget = self.getTarget(path[len(path)-1])
     for dependency in currTarget.dependsOn:
         normalizedDependency = target.normalizeName(dependency)
         if normalizedDependency in path:
             return False
         path.append(normalizedDependency)
         if not self.__searchPathsForCycles(path):
             return False
         path.pop()
     return True
Exemplo n.º 14
0
 def __searchPathsForCycles(self, path):
     currTarget = self.getTarget(path[len(path) - 1])
     for dependency in currTarget.dependsOn:
         normalizedDependency = target.normalizeName(dependency)
         if normalizedDependency in path:
             return False
         path.append(normalizedDependency)
         if not self.__searchPathsForCycles(path):
             return False
         path.pop()
     return True
Exemplo n.º 15
0
    def __validateDependsOnLists(self):
        if len(self.targets) == 0:
            return True

        for currTarget in self.targets:
            normalizedName = target.normalizeName(currTarget.name)
            checkedDependencies = []
            for dependency in currTarget.dependsOn:
                normalizedDepedancy = target.normalizeName(dependency)
                if normalizedDepedancy == normalizedName:
                    logger.writeError("Target cannot depend on itself", currTarget.name, "", self.path)
                    return False
                if normalizedDepedancy in checkedDependencies:
                    logger.writeError("Target has duplicate dependency '" + dependency + "'", currTarget.name, "", self.path)
                    return False
                if self.getTarget(dependency) is None:
                    logger.writeError("Target has non-existant dependency '" + dependency + "'", currTarget.name, "", self.path)
                    return False
                checkedDependencies.append(normalizedDepedancy)

        path = [target.normalizeName(self.targets[0].name)]
        return self.__searchPathsForCycles(path)
Exemplo n.º 16
0
    def read(self):
        if self.path == "":
            logger.writeError("No project file was specified")
            return False
        f = open(self.path, "r")
        try:
            currTarget = None
            lineCount = 0
            for currLine in f:
                lineCount += 1
                lastPackageLineNumber = 0
                currLine = str.strip(currLine)
                if (currLine == "") or currLine.startswith('#') or currLine.startswith('//'):
                    pass
                else:
                    colonIndex = currLine.find(":")
                    equalsIndex = currLine.find("=")

                    if (colonIndex == -1) and (equalsIndex == -1):
                        logger.writeError("Line could not be understood by project parser.  Lines can be comments, defines, or target information.", "", "", self.path, lineCount)
                        return False

                    if ((colonIndex == -1) and (equalsIndex != -1)) or\
                       ((colonIndex != -1) and (equalsIndex != -1) and (equalsIndex < colonIndex)):
                        currPair = currLine.split("=", 1)
                        currPair = currPair[0].strip(), currPair[1].strip()
                        currName = str.lower(currPair[0])
                        self.defines[currPair[0]] = currPair[1]
                    else:
                        currPair = currLine.split(":", 1)
                        currPair = currPair[0].strip(), currPair[1].strip()
                        currName = str.lower(currPair[0])

                        if (currName != "name") and (currTarget is None):
                            logger.writeError("'" + currPair[0] +  "' declared before 'name' in Project file", "", "", self.path, lineCount)
                            return False

                        if currName == "name":
                            lastPackageLineNumber = lineCount
                            if currTarget != None:
                                if not self.__addTarget(currTarget, lastPackageLineNumber):
                                    return False
                            currTarget = target.Target(currPair[1])
                        elif currName == "path":
                            if currTarget.path != "":
                                logger.writeError("Project targets can only have one 'Path' defined", "", "", self.path, lineCount)
                                return False
                            fullPath = os.path.abspath(currPair[1])
                            currTarget.origPath = fullPath
                            currTarget.path = fullPath
                        elif currName == "output":
                            if currTarget.outputPathSpecified:
                                logger.writeError("Project targets can only have one 'Output' defined", "", "", self.path, lineCount)
                                return False
                            currTarget.outputPath = currPair[1]
                            currTarget.outputPathSpecified = True
                        elif currName == "dependson":
                            if currTarget.dependsOn != []:
                                logger.writeError("Project targets can only have one 'DependsOn' defined (use a comma delimited list for multiple dependencies)", "", "", self.path, lineCount)
                                return False
                            if currPair[1] != "":
                                dependsOnList = utilityFunctions.stripItemsInList(currPair[1].split(","))
                                normalizedName = target.normalizeName(currTarget.name)
                                for dependency in dependsOnList:
                                    if not re.match(r'[\w\.+_\-]+$', dependency):
                                        logger.writeError("Dependancy name, '" + dependency + "', found with invalid character. Only alphanumeric is allowed.", currTarget.name, "", self.path, lineCount)
                                        return False
                                    if target.normalizeName(dependency) == normalizedName:
                                        logger.writeError("Project targets cannot depend on themselves", currTarget.name, "", self.path, lineCount)
                                        return False
                                currTarget.dependsOn = dependsOnList
                        elif currName == "aliases":
                            if currTarget.aliases != []:
                                logger.writeError("Project targets can only have one 'Aliases' defined (use a comma delimited list for multiple aliases)", "", "", self.path, lineCount)
                                return False
                            if currPair[1] != "":
                                aliases = utilityFunctions.stripItemsInList(currPair[1].split(","))
                                noralizedName = target.normalizeName(currTarget.name)
                                for alias in aliases:
                                    if target.normalizeName(alias) == normalizedName:
                                        logger.writeError("Project target alias cannot be same as its name", currTarget.name, "", self.path, lineCount)
                                        return False
                                currTarget.aliases = aliases
                        elif currName == "skipsteps" or currName == "skipstep":
                            if currTarget.skipSteps != []:
                                logger.writeError("Project targets can only have one 'SkipSteps' defined (use a comma delimited list for multiple steps)", "", "", self.path, lineCount)
                                return False
                            currTarget.skipSteps = utilityFunctions.stripItemsInList(str.lower(currPair[1]).split(","))
                        elif currName == "prefix":
                            if currTarget.prefix != "":
                                logger.writeError("Project targets can only have one 'Prefix' defined", "", "", self.path, lineCount)
                                return False
                            currTarget.prefix = currPair[1]
                        elif currName == "version":
                            if currTarget.version != "":
                                logger.writeError("Project targets can only have one 'Version' defined", "", "", self.path, lineCount)
                                return False
                            currTarget.version = currPair[1]
                        elif currName in commands.buildSteps:
                            if currTarget.findBuildStep(currName) != None:
                                logger.writeError("Project targets can only have one '" + currName + "' defined", "", "", self.path, lineCount)
                                return False
                            currTarget.buildSteps.append(commands.BuildStep(currName, currPair[1]))
                        else:
                            logger.writeError("Cannot understand given line: '" + currLine + "'", "", "", self.path, lineCount)
                            return False

            if not self.__addTarget(currTarget, lastPackageLineNumber):
                return False
        finally:
            f.close()
        return True
Exemplo n.º 17
0
def importTargets(options):
    logger.setLogger("console")

    finalTargets = []
    ignoredTargets = []
    partialImport = False
    fetchStep = commands.BuildStep("fetch", commands.__getFetchCommand(None))
    unpackStep = commands.BuildStep("unpack",
                                    commands.__getUnpackCommand(None))

    tempDir = tempfile.mkdtemp(prefix="mixdown-")
    options.downloadDir = os.path.join(tempDir, "mdDownloads")

    while len(options.targetsToImport) != 0:
        target = options.targetsToImport.pop(0)

        logger.writeMessage("Analyzing target...", target.name)
        logger.writeMessage("Extracting target...", target.name)

        target.outputPath = os.path.join(tempDir, target.name)
        target.currBuildStep = fetchStep
        if not commands.buildStepActor(target, options, None):
            utilityFunctions.removeDir(tempDir)
            return None, False
        target.currBuildStep = unpackStep
        if not commands.buildStepActor(target, options, None):
            utilityFunctions.removeDir(tempDir)
            return None, False

        #Generate build files and find possible dependencies
        possibleDeps = []
        if cmake.isCMakeProject(target.path):
            logger.writeMessage("CMake project found...", target.name)
            logger.writeMessage("Analyzing for dependencies...", target.name)
            possibleDeps = cmake.getDependencies(target.path, target.name)
        elif autoTools.isAutoToolsProject(target.path):
            logger.writeMessage("Auto Tools project found...", target.name)
            if not os.path.exists(os.path.join(target.path, "configure")):
                if not autoTools.generateConfigureFiles(
                        target.path, target.name):
                    utilityFunctions.removeDir(tempDir)
                    return None, False
            logger.writeMessage("Analyzing for dependencies...", target.name)
            possibleDeps = autoTools.getDependencies(target.path, target.name)
            if possibleDeps == None:
                target.comment = "Unable to parse 'configure --help' output. MixDown cannot determine dependencies for this target."
                logger.writeError(target.comment, target.name)
                partialImport = True
                possibleDeps = []
        elif make.isMakeProject(target.path):
            target.comment = "Make project found. MixDown cannot determine dependencies from Make projects."
            logger.writeError(target.comment, target.name)
            partialImport = True
        else:
            target.comment = "Unknown build system found.  MixDown cannot determine dependencies or build commands."
            logger.writeError(target.comment, target.name)
            partialImport = True

        #Find actual dependencies
        for possibleDependency in possibleDeps:
            if getTarget(possibleDependency,
                         finalTargets + options.targetsToImport):
                logger.writeMessage(
                    "Known dependency found (" + possibleDependency + ")",
                    target.name)
                target.dependsOn.append(possibleDependency)
                continue
            elif options.interactive and possibleDependency in ignoredTargets:
                logger.writeMessage(
                    "Previously ignored dependency found (" +
                    possibleDependency + ")", target.name)
                continue

            if searchForPossibleAliasInList(
                    possibleDependency, finalTargets + options.targetsToImport,
                    options.interactive):
                target.dependsOn.append(possibleDependency)
            elif not options.interactive:
                logger.writeMessage(
                    "Ignoring unknown dependency (" + possibleDependency + ")",
                    target.name)
            else:
                logger.writeMessage(
                    "Unknown dependency found (" + possibleDependency + ")",
                    target.name)
                userInput = raw_input(
                    possibleDependency +
                    ": Input location, target name, or blank to ignore:"
                ).strip()
                if userInput == "":
                    ignoredTargets.append(possibleDependency)
                elif os.path.isfile(userInput) or os.path.isdir(
                        userInput) or utilityFunctions.isURL(userInput):
                    name = target.targetPathToName(userInput)
                    if name == "":
                        return None, False
                    newTarget = target.Target(name, userInput)
                    options.targetsToImport.append(newTarget)
                    if target.normalizeName(
                            possibleDependency) != target.normalizeName(
                                userInput):
                        newTarget.aliases.append(possibleDependency)
                    target.dependsOn.append(possibleDependency)
                else:
                    aliasTarget = getTarget(
                        userInput, finalTargets + options.targetsToImport,
                        possibleDependency)
                    if aliasTarget != None:
                        logger.writeMessage("Alias added (" + userInput + ")",
                                            aliasTarget.name)
                        target.dependsOn.append(possibleDependency)
                    else:
                        aliasLocation = raw_input(
                            userInput +
                            ": Target name not found in any known targets.  Location of new target:"
                        ).strip()
                        if os.path.isfile(aliasLocation) or os.path.isdir(
                                aliasLocation) or utilityFunctions.isURL(
                                    aliasLocation):
                            name = target.targetPathToName(aliasLocation)
                            if name == "":
                                return None, False
                            newTarget = target.Target(name, aliasLocation)
                            notReviewedTargets.append(newTarget)
                            if target.normalizeName(possibleDependency
                                                    ) != target.normalizeName(
                                                        aliasLocation):
                                newTarget.aliases.append(possibleDependency)
                            target.dependsOn.append(possibleDependency)
                        else:
                            logger.writeError(
                                userInput + ": Alias location not understood.",
                                exitProgram=True)

        finalTargets.append(target)

    #Create project for targets
    projects = project.Project("ProjectNameNotDetermined", finalTargets)

    if not projects.examine(options):
        logger.writeError("Project failed examination", exitProgram=True)
    if not projects.validate(options):
        logger.writeError("Project failed validation", exitProgram=True)

    mainTargetPath = projects.targets[0].origPath
    if utilityFunctions.isURL(mainTargetPath):
        mainTargetPath = utilityFunctions.URLToFilename(mainTargetPath)
    mainTargetName, mainTargetVersion = utilityFunctions.splitFileName(
        mainTargetPath)
    if mainTargetVersion != "":
        projects.name = mainTargetName + "-" + mainTargetVersion
    else:
        projects.name = mainTargetName
    projects.path = projects.name + ".md"

    for target in projects.targets:
        target.outputPath = ""

    if projects.examine(options):
        logger.writeMessage("\nFinal targets...\n\n" + str(projects))
        projects.write()

    utilityFunctions.removeDir(tempDir)
    return projects, partialImport
Exemplo n.º 18
0
    def read(self):
        if self.path == "":
            logger.writeError("No project file was specified")
            return False
        f = open(self.path, "r")
        try:
            currTarget = None
            lineCount = 0
            for currLine in f:
                lineCount += 1
                lastPackageLineNumber = 0
                currLine = str.strip(currLine)
                if (currLine == ""
                    ) or currLine.startswith('#') or currLine.startswith('//'):
                    pass
                else:
                    colonIndex = currLine.find(":")
                    equalsIndex = currLine.find("=")

                    if (colonIndex == -1) and (equalsIndex == -1):
                        logger.writeError(
                            "Line could not be understood by project parser.  Lines can be comments, defines, or target information.",
                            "", "", self.path, lineCount)
                        return False

                    if ((colonIndex == -1) and (equalsIndex != -1)) or\
                       ((colonIndex != -1) and (equalsIndex != -1) and (equalsIndex < colonIndex)):
                        currPair = currLine.split("=", 1)
                        currPair = currPair[0].strip(), currPair[1].strip()
                        currName = str.lower(currPair[0])
                        self.defines[currPair[0]] = currPair[1]
                    else:
                        currPair = currLine.split(":", 1)
                        currPair = currPair[0].strip(), currPair[1].strip()
                        currName = str.lower(currPair[0])

                        if (currName != "name") and (currTarget is None):
                            logger.writeError(
                                "'" + currPair[0] +
                                "' declared before 'name' in Project file", "",
                                "", self.path, lineCount)
                            return False

                        if currName == "name":
                            lastPackageLineNumber = lineCount
                            if currTarget != None:
                                if not self.__addTarget(
                                        currTarget, lastPackageLineNumber):
                                    return False
                            currTarget = target.Target(currPair[1])
                        elif currName == "path":
                            if currTarget.path != "":
                                logger.writeError(
                                    "Project targets can only have one 'Path' defined",
                                    "", "", self.path, lineCount)
                                return False
                            fullPath = os.path.abspath(currPair[1])
                            currTarget.origPath = fullPath
                            currTarget.path = fullPath
                        elif currName == "output":
                            if currTarget.outputPathSpecified:
                                logger.writeError(
                                    "Project targets can only have one 'Output' defined",
                                    "", "", self.path, lineCount)
                                return False
                            currTarget.outputPath = currPair[1]
                            currTarget.outputPathSpecified = True
                        elif currName == "dependson":
                            if currTarget.dependsOn != []:
                                logger.writeError(
                                    "Project targets can only have one 'DependsOn' defined (use a comma delimited list for multiple dependencies)",
                                    "", "", self.path, lineCount)
                                return False
                            if currPair[1] != "":
                                dependsOnList = utilityFunctions.stripItemsInList(
                                    currPair[1].split(","))
                                normalizedName = target.normalizeName(
                                    currTarget.name)
                                for dependency in dependsOnList:
                                    if not re.match(r'[\w\.+_\-]+$',
                                                    dependency):
                                        logger.writeError(
                                            "Dependancy name, '" + dependency +
                                            "', found with invalid character. Only alphanumeric is allowed.",
                                            currTarget.name, "", self.path,
                                            lineCount)
                                        return False
                                    if target.normalizeName(
                                            dependency) == normalizedName:
                                        logger.writeError(
                                            "Project targets cannot depend on themselves",
                                            currTarget.name, "", self.path,
                                            lineCount)
                                        return False
                                currTarget.dependsOn = dependsOnList
                        elif currName == "aliases":
                            if currTarget.aliases != []:
                                logger.writeError(
                                    "Project targets can only have one 'Aliases' defined (use a comma delimited list for multiple aliases)",
                                    "", "", self.path, lineCount)
                                return False
                            if currPair[1] != "":
                                aliases = utilityFunctions.stripItemsInList(
                                    currPair[1].split(","))
                                noralizedName = target.normalizeName(
                                    currTarget.name)
                                for alias in aliases:
                                    if target.normalizeName(
                                            alias) == normalizedName:
                                        logger.writeError(
                                            "Project target alias cannot be same as its name",
                                            currTarget.name, "", self.path,
                                            lineCount)
                                        return False
                                currTarget.aliases = aliases
                        elif currName == "skipsteps" or currName == "skipstep":
                            if currTarget.skipSteps != []:
                                logger.writeError(
                                    "Project targets can only have one 'SkipSteps' defined (use a comma delimited list for multiple steps)",
                                    "", "", self.path, lineCount)
                                return False
                            currTarget.skipSteps = utilityFunctions.stripItemsInList(
                                str.lower(currPair[1]).split(","))
                        elif currName == "prefix":
                            if currTarget.prefix != "":
                                logger.writeError(
                                    "Project targets can only have one 'Prefix' defined",
                                    "", "", self.path, lineCount)
                                return False
                            currTarget.prefix = currPair[1]
                        elif currName == "version":
                            if currTarget.version != "":
                                logger.writeError(
                                    "Project targets can only have one 'Version' defined",
                                    "", "", self.path, lineCount)
                                return False
                            currTarget.version = currPair[1]
                        elif currName in commands.buildSteps:
                            if currTarget.findBuildStep(currName) != None:
                                logger.writeError(
                                    "Project targets can only have one '" +
                                    currName + "' defined", "", "", self.path,
                                    lineCount)
                                return False
                            currTarget.buildSteps.append(
                                commands.BuildStep(currName, currPair[1]))
                        else:
                            logger.writeError(
                                "Cannot understand given line: '" + currLine +
                                "'", "", "", self.path, lineCount)
                            return False

            if not self.__addTarget(currTarget, lastPackageLineNumber):
                return False
        finally:
            f.close()
        return True
Exemplo n.º 19
0
def importTargets(options):
    logger.setLogger("console")

    finalTargets = []
    ignoredTargets = []
    partialImport = False
    fetchStep = commands.BuildStep("fetch", commands.__getFetchCommand(None))
    unpackStep = commands.BuildStep("unpack", commands.__getUnpackCommand(None))

    tempDir = tempfile.mkdtemp(prefix="mixdown-")
    options.downloadDir = os.path.join(tempDir, "mdDownloads")

    while len(options.targetsToImport) != 0:
        target = options.targetsToImport.pop(0)

        logger.writeMessage("Analyzing target...", target.name)
        logger.writeMessage("Extracting target...", target.name)

        target.outputPath = os.path.join(tempDir, target.name)
        target.currBuildStep = fetchStep
        if not commands.buildStepActor(target, options, None):
            utilityFunctions.removeDir(tempDir)
            return None, False
        target.currBuildStep = unpackStep
        if not commands.buildStepActor(target, options, None):
            utilityFunctions.removeDir(tempDir)
            return None, False

        #Generate build files and find possible dependencies
        possibleDeps = []
        if cmake.isCMakeProject(target.path):
            logger.writeMessage("CMake project found...", target.name)
            logger.writeMessage("Analyzing for dependencies...", target.name)
            possibleDeps = cmake.getDependencies(target.path, target.name)
        elif autoTools.isAutoToolsProject(target.path):
            logger.writeMessage("Auto Tools project found...", target.name)
            if not os.path.exists(os.path.join(target.path, "configure")):
                if not autoTools.generateConfigureFiles(target.path, target.name):
                    utilityFunctions.removeDir(tempDir)
                    return None, False
            logger.writeMessage("Analyzing for dependencies...", target.name)
            possibleDeps = autoTools.getDependencies(target.path, target.name)
            if possibleDeps == None:
                target.comment = "Unable to parse 'configure --help' output. MixDown cannot determine dependencies for this target."
                logger.writeError(target.comment, target.name)
                partialImport = True
                possibleDeps = []
        elif make.isMakeProject(target.path):
            target.comment = "Make project found. MixDown cannot determine dependencies from Make projects."
            logger.writeError(target.comment, target.name)
            partialImport = True
        else:
            target.comment = "Unknown build system found.  MixDown cannot determine dependencies or build commands."
            logger.writeError(target.comment, target.name)
            partialImport = True

        #Find actual dependencies
        for possibleDependency in possibleDeps:
            if getTarget(possibleDependency, finalTargets + options.targetsToImport):
                logger.writeMessage("Known dependency found (" + possibleDependency + ")", target.name)
                target.dependsOn.append(possibleDependency)
                continue
            elif options.interactive and possibleDependency in ignoredTargets:
                logger.writeMessage("Previously ignored dependency found (" + possibleDependency + ")", target.name)
                continue

            if searchForPossibleAliasInList(possibleDependency, finalTargets + options.targetsToImport, options.interactive):
                target.dependsOn.append(possibleDependency)
            elif not options.interactive:
                logger.writeMessage("Ignoring unknown dependency (" + possibleDependency + ")", target.name)
            else:
                logger.writeMessage("Unknown dependency found (" + possibleDependency + ")", target.name)
                userInput = raw_input(possibleDependency + ": Input location, target name, or blank to ignore:").strip()
                if userInput == "":
                    ignoredTargets.append(possibleDependency)
                elif os.path.isfile(userInput) or os.path.isdir(userInput) or utilityFunctions.isURL(userInput):
                    name = target.targetPathToName(userInput)
                    if name == "":
                        return None, False
                    newTarget = target.Target(name, userInput)
                    options.targetsToImport.append(newTarget)
                    if target.normalizeName(possibleDependency) != target.normalizeName(userInput):
                        newTarget.aliases.append(possibleDependency)
                    target.dependsOn.append(possibleDependency)
                else:
                    aliasTarget = getTarget(userInput, finalTargets + options.targetsToImport, possibleDependency)
                    if aliasTarget != None:
                        logger.writeMessage("Alias added (" + userInput + ")", aliasTarget.name)
                        target.dependsOn.append(possibleDependency)
                    else:
                        aliasLocation = raw_input(userInput + ": Target name not found in any known targets.  Location of new target:").strip()
                        if os.path.isfile(aliasLocation) or os.path.isdir(aliasLocation) or utilityFunctions.isURL(aliasLocation):
                            name = target.targetPathToName(aliasLocation)
                            if name == "":
                                return None, False
                            newTarget = target.Target(name, aliasLocation)
                            notReviewedTargets.append(newTarget)
                            if target.normalizeName(possibleDependency) != target.normalizeName(aliasLocation):
                                newTarget.aliases.append(possibleDependency)
                            target.dependsOn.append(possibleDependency)
                        else:
                            logger.writeError(userInput + ": Alias location not understood.", exitProgram=True)

        finalTargets.append(target)

    #Create project for targets
    projects = project.Project("ProjectNameNotDetermined", finalTargets)

    if not projects.examine(options):
        logger.writeError("Project failed examination", exitProgram=True)
    if not projects.validate(options):
        logger.writeError("Project failed validation", exitProgram=True)

    mainTargetPath = projects.targets[0].origPath
    if utilityFunctions.isURL(mainTargetPath):
        mainTargetPath = utilityFunctions.URLToFilename(mainTargetPath)
    mainTargetName, mainTargetVersion = utilityFunctions.splitFileName(mainTargetPath)
    if mainTargetVersion != "":
        projects.name = mainTargetName + "-" + mainTargetVersion
    else:
        projects.name = mainTargetName
    projects.path = projects.name + ".md"

    for target in projects.targets:
        target.outputPath = ""

    if projects.examine(options):
        logger.writeMessage("\nFinal targets...\n\n" + str(projects))
        projects.write()

    utilityFunctions.removeDir(tempDir)
    return projects, partialImport