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)
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
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
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
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
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
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
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
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
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
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
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
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)
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
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
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
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