def main(argv): manifestPath = op.expanduser(argv[1]) moduleDepPath = op.expanduser(argv[2]) otbDir = op.expanduser(argv[3]) appManifest = argv[4] csvAppDepends = argv[5] #app_dir = op.join(otbDir,"Applications") # Standard Manifest parsing, extract simple and full dependencies [groups, moduleList, sourceList] = manifestParser.parseManifest(manifestPath) depList = manifestParser.parseDependList(moduleDepPath) fullDepList = manifestParser.buildFullDep(depList) [appGroups, appModuleList, appSourceList] = manifestParser.parseManifest(appManifest) # add application sources to sourceList for item in appSourceList: sourceList[item] = appSourceList[item] appDependsList = manifestParser.buildSimpleDep(otbDir, appModuleList, sourceList) #manifestParser.printDepList(appDependsList) manifestParser.outputCSVEdgeList(appDependsList, csvAppDepends)
def main(argv): manifestPath = op.expanduser(argv[1]) moduleDepPath = op.expanduser(argv[2]) otbDir = op.expanduser(argv[3]) appManifest = argv[4] csvAppDepends = argv[5] #app_dir = op.join(otbDir,"Applications") # Standard Manifest parsing, extract simple and full dependencies [groups,moduleList,sourceList] = manifestParser.parseManifest(manifestPath) depList = manifestParser.parseDependList(moduleDepPath) fullDepList = manifestParser.buildFullDep(depList) [appGroups,appModuleList,appSourceList] = manifestParser.parseManifest(appManifest) # add application sources to sourceList for item in appSourceList: sourceList[item] = appSourceList[item] appDependsList = manifestParser.buildSimpleDep(otbDir,appModuleList,sourceList) #manifestParser.printDepList(appDependsList) manifestParser.outputCSVEdgeList(appDependsList,csvAppDepends)
def main(argv): manifestPath = op.expanduser(argv[1]) moduleDepPath = op.expanduser(argv[2]) otbDir = op.expanduser(argv[3]) exManifest = argv[4] csvExDepends = argv[5] # Standard Manifest parsing, extract simple and full dependencies [groups,moduleList,sourceList] = manifestParser.parseManifest(manifestPath) depList = manifestParser.parseDependList(moduleDepPath) fullDepList = manifestParser.buildFullDep(depList) [exGroups,exModuleList,exSourceList] = manifestParser.parseManifest(exManifest) exDependsList = manifestParser.buildSimpleDep(otbDir,exModuleList,sourceList) # clean the dependencies : remove modules already in fullDepList cleanDepList = {} for mod in exDependsList: cleanDepList[mod] = {} for dep in exDependsList[mod]: if not dep in fullDepList[mod]: cleanDepList[mod][dep] = 1 #manifestParser.printDepList(exDependsList) manifestParser.outputCSVEdgeList(cleanDepList,csvExDepends)
def main(argv): manifestPath = op.expanduser(argv[1]) moduleDepPath = op.expanduser(argv[2]) otbDir = op.expanduser(argv[3]) outManifest = argv[4] if len(argv) >= 6: csvTestDepends = argv[5] else: csvTestDepends = None testing_dir = op.join(otbDir, "Testing") # Standard Manifest parsing, extract simple and full dependencies [groups, moduleList, sourceList] = manifestParser.parseManifest(manifestPath) depList = manifestParser.parseDependList(moduleDepPath) fullDepList = manifestParser.buildFullDep(depList) # make sure every module is in depList and fullDepList (even if it has no dependencies) for mod in moduleList: if not depList.has_key(mod): depList[mod] = {} if not fullDepList.has_key(mod): fullDepList[mod] = {} OldFolderPartition = buildOldFolderPartition(moduleList) testCxx = {} outFD = open(outManifest, 'wb') outFD.write( "# Monolithic path, Current dir, group name, module name, subDir name, comment\n" ) # parse all cxx test files : analyse them and extract their dependencies for (d, f) in codeParser.FindBinaries(testing_dir): fullPath = op.join(d, f) shortPath = fullPath.replace(otbDir, '.') # skip Testing/Utilities , will not be used anymore if shortPath.startswith("./Testing/Utilities/"): continue moduleDestination = "TBD" groupDestination = "TBD" res = parseTestCxx(fullPath) if res["isTestDriver"]: # no need to dispatch test drivers, they can be generated again continue [testDepList, thirdPartyDep] = getTestDependencies(res["includes"], sourceList) # try to clean the dependency list (remove inherited modules) ignoreModules = ["ImageIO", "VectorDataIO", "TestKernel"] cleanTestDepList = [] depListToRemove = [] for dep1 in testDepList: # register the "from" field testDepList[dep1]["from"] = shortPath for dep2 in testDepList: if dep2 == dep1: continue # avoid IO modules to 'eat' usefull dependencies if dep1 in ignoreModules: continue if (dep2 in fullDepList[dep1]) and \ (not dep2 in depListToRemove): depListToRemove.append(dep2) for dep in testDepList: if not dep in depListToRemove: cleanTestDepList.append(dep) # build all dependencies of the test testFullDepList = [] for dep in testDepList: for subDep in fullDepList[dep]: if not subDep in testFullDepList: testFullDepList.append(subDep) # start guessing luckyGuess = None guessStep = 1 # try to get the list of module used to partition the corresponding source directory guessModules = [] guessSourceDir = op.split(shortPath.replace("./Testing", "."))[0] if OldFolderPartition.has_key(guessSourceDir): guessModules = OldFolderPartition[guessSourceDir].keys() # special case for Testing/Application -> ApplicationEngine if guessSourceDir == "./Applications": guessModules.append("ApplicationEngine") # first filter : find modules that appear in cleanTestDepList and in guessModules overlappingModules = [] for dep in cleanTestDepList: if dep in guessModules: overlappingModules.append(dep) if len(overlappingModules) == 1: luckyGuess = overlappingModules[0] # second filter : find the source file with the closest name if not luckyGuess: guessStep += 1 [matchFile, matchPercent] = findClosestSourceName(f, sourceList) if (sourceList[matchFile] in testDepList) and (matchPercent > 50.0): luckyGuess = sourceList[matchFile] elif (sourceList[matchFile] in testFullDepList) and (matchPercent > 70.0): luckyGuess = sourceList[matchFile] # third filter : ThirdParty if not luckyGuess: guessStep += 1 if guessSourceDir == "./Utilities" or len(testDepList) == 0: groupDestination = "ThirdParty" if len(thirdPartyDep) == 1: luckyGuess = thirdPartyDep[0] # fourth filter : if there is only one dependency in cleanTestDepList : take it if not luckyGuess: guessStep += 1 if len(cleanTestDepList) == 1: luckyGuess = cleanTestDepList[0] # fifth filter : separate IO test from non-IO test if not luckyGuess: guessStep += 1 if (f.find("Reader") >= 0) or (f.find("Reading") >= 0) or \ (f.find("Write") >= 0) or (f.find("Writing") >= 0) or \ (f.find("ImageIO") >= 0) or (guessSourceDir == "./Code/IO"): # remove non-IO deps from cleanTestDepList and look what's left ioCleanDep = [] for dep in cleanTestDepList: if manifestParser.getGroup(dep, groups) == "IO": ioCleanDep.append(dep) # ImageIO should be low priority compared to other IO modules if (len(ioCleanDep) == 2) and ("ImageIO" in ioCleanDep): ioCleanDep.remove("ImageIO") if len(ioCleanDep) == 1: luckyGuess = ioCleanDep[0] else: # remove non-IO deps from cleanTestDepList and look what's left nonIOcleanDep = [] for dep in cleanTestDepList: if manifestParser.getGroup(dep, groups) != "IO": nonIOcleanDep.append(dep) if len(nonIOcleanDep) == 1: luckyGuess = nonIOcleanDep[0] elif len(nonIOcleanDep) == 2: # compare the 2 possible modules based on their group groupAandB = [ manifestParser.getGroup(nonIOcleanDep[0], groups), manifestParser.getGroup(nonIOcleanDep[1], groups) ] levelAandB = [0, 0] for idx in [0, 1]: if groupAandB[idx] == "Core": levelAandB[idx] = 1 elif groupAandB[idx] == "Filtering": levelAandB[idx] = 2 else: levelAandB[idx] = 3 if levelAandB[0] > levelAandB[1]: luckyGuess = nonIOcleanDep[0] if levelAandB[0] < levelAandB[1]: luckyGuess = nonIOcleanDep[1] if luckyGuess: moduleDestination = luckyGuess else: pass #print f + " -> " + str(testDepList) #print f + " -> "+ matchFile + " ( " + str(matchPercent) + "% )" # if module is found and not group, deduce group if groupDestination == "TBD" and moduleDestination != "TBD": groupDestination = manifestParser.getGroup(moduleDestination, groups) if not res["hasMain"]: # manually add dependency to TestKernel for cxx using a test driver # the include to otbTestMain.h header is not located in the cxx testDepList["TestKernel"] = { "from": shortPath, "to": "./Code/Testing/otbTestMain.h" } testCxx[shortPath] = { "depList": testDepList, "thirdPartyDep": thirdPartyDep, "group": groupDestination, "module": moduleDestination } outFD.write(shortPath + "," + op.basename(op.dirname(shortPath)) + "," + groupDestination + "," + moduleDestination + ",test,\n") outFD.close() # sum all test dependencies in every module allTestDepends = gatherTestDepends(testCxx, fullDepList) # clean the test depends (i.e. ImageIO is dragged by TestKernel) cleanTestDepends = {} for mod in allTestDepends: cleanTestDepends[mod] = {} for dep1 in allTestDepends[mod]: isClean = True for dep2 in allTestDepends[mod]: if dep1 == dep2: continue if dep1 in fullDepList[dep2]: isClean = False break if isClean: cleanTestDepends[mod][dep1] = 1 if csvTestDepends: manifestParser.outputCSVEdgeList(cleanTestDepends, csvTestDepends)
def main(argv): manifestPath = op.expanduser(argv[1]) moduleDepPath = op.expanduser(argv[2]) otbDir = op.expanduser(argv[3]) outManifest = argv[4] if len(argv) >= 6: csvTestDepends = argv[5] else: csvTestDepends = None testing_dir = op.join(otbDir, "Testing") # Standard Manifest parsing, extract simple and full dependencies [groups, moduleList, sourceList] = manifestParser.parseManifest(manifestPath) depList = manifestParser.parseDependList(moduleDepPath) fullDepList = manifestParser.buildFullDep(depList) # make sure every module is in depList and fullDepList (even if it has no dependencies) for mod in moduleList: if not depList.has_key(mod): depList[mod] = {} if not fullDepList.has_key(mod): fullDepList[mod] = {} OldFolderPartition = buildOldFolderPartition(moduleList) testCxx = {} outFD = open(outManifest, "wb") outFD.write("# Monolithic path, Current dir, group name, module name, subDir name, comment\n") # parse all cxx test files : analyse them and extract their dependencies for (d, f) in codeParser.FindBinaries(testing_dir): fullPath = op.join(d, f) shortPath = fullPath.replace(otbDir, ".") # skip Testing/Utilities , will not be used anymore if shortPath.startswith("./Testing/Utilities/"): continue moduleDestination = "TBD" groupDestination = "TBD" res = parseTestCxx(fullPath) if res["isTestDriver"]: # no need to dispatch test drivers, they can be generated again continue [testDepList, thirdPartyDep] = getTestDependencies(res["includes"], sourceList) # try to clean the dependency list (remove inherited modules) ignoreModules = ["ImageIO", "VectorDataIO", "TestKernel"] cleanTestDepList = [] depListToRemove = [] for dep1 in testDepList: # register the "from" field testDepList[dep1]["from"] = shortPath for dep2 in testDepList: if dep2 == dep1: continue # avoid IO modules to 'eat' usefull dependencies if dep1 in ignoreModules: continue if (dep2 in fullDepList[dep1]) and (not dep2 in depListToRemove): depListToRemove.append(dep2) for dep in testDepList: if not dep in depListToRemove: cleanTestDepList.append(dep) # build all dependencies of the test testFullDepList = [] for dep in testDepList: for subDep in fullDepList[dep]: if not subDep in testFullDepList: testFullDepList.append(subDep) # start guessing luckyGuess = None guessStep = 1 # try to get the list of module used to partition the corresponding source directory guessModules = [] guessSourceDir = op.split(shortPath.replace("./Testing", "."))[0] if OldFolderPartition.has_key(guessSourceDir): guessModules = OldFolderPartition[guessSourceDir].keys() # special case for Testing/Application -> ApplicationEngine if guessSourceDir == "./Applications": guessModules.append("ApplicationEngine") # first filter : find modules that appear in cleanTestDepList and in guessModules overlappingModules = [] for dep in cleanTestDepList: if dep in guessModules: overlappingModules.append(dep) if len(overlappingModules) == 1: luckyGuess = overlappingModules[0] # second filter : find the source file with the closest name if not luckyGuess: guessStep += 1 [matchFile, matchPercent] = findClosestSourceName(f, sourceList) if (sourceList[matchFile] in testDepList) and (matchPercent > 50.0): luckyGuess = sourceList[matchFile] elif (sourceList[matchFile] in testFullDepList) and (matchPercent > 70.0): luckyGuess = sourceList[matchFile] # third filter : ThirdParty if not luckyGuess: guessStep += 1 if guessSourceDir == "./Utilities" or len(testDepList) == 0: groupDestination = "ThirdParty" if len(thirdPartyDep) == 1: luckyGuess = thirdPartyDep[0] # fourth filter : if there is only one dependency in cleanTestDepList : take it if not luckyGuess: guessStep += 1 if len(cleanTestDepList) == 1: luckyGuess = cleanTestDepList[0] # fifth filter : separate IO test from non-IO test if not luckyGuess: guessStep += 1 if ( (f.find("Reader") >= 0) or (f.find("Reading") >= 0) or (f.find("Write") >= 0) or (f.find("Writing") >= 0) or (f.find("ImageIO") >= 0) or (guessSourceDir == "./Code/IO") ): # remove non-IO deps from cleanTestDepList and look what's left ioCleanDep = [] for dep in cleanTestDepList: if manifestParser.getGroup(dep, groups) == "IO": ioCleanDep.append(dep) # ImageIO should be low priority compared to other IO modules if (len(ioCleanDep) == 2) and ("ImageIO" in ioCleanDep): ioCleanDep.remove("ImageIO") if len(ioCleanDep) == 1: luckyGuess = ioCleanDep[0] else: # remove non-IO deps from cleanTestDepList and look what's left nonIOcleanDep = [] for dep in cleanTestDepList: if manifestParser.getGroup(dep, groups) != "IO": nonIOcleanDep.append(dep) if len(nonIOcleanDep) == 1: luckyGuess = nonIOcleanDep[0] elif len(nonIOcleanDep) == 2: # compare the 2 possible modules based on their group groupAandB = [ manifestParser.getGroup(nonIOcleanDep[0], groups), manifestParser.getGroup(nonIOcleanDep[1], groups), ] levelAandB = [0, 0] for idx in [0, 1]: if groupAandB[idx] == "Core": levelAandB[idx] = 1 elif groupAandB[idx] == "Filtering": levelAandB[idx] = 2 else: levelAandB[idx] = 3 if levelAandB[0] > levelAandB[1]: luckyGuess = nonIOcleanDep[0] if levelAandB[0] < levelAandB[1]: luckyGuess = nonIOcleanDep[1] if luckyGuess: moduleDestination = luckyGuess else: pass # print f + " -> " + str(testDepList) # print f + " -> "+ matchFile + " ( " + str(matchPercent) + "% )" # if module is found and not group, deduce group if groupDestination == "TBD" and moduleDestination != "TBD": groupDestination = manifestParser.getGroup(moduleDestination, groups) if not res["hasMain"]: # manually add dependency to TestKernel for cxx using a test driver # the include to otbTestMain.h header is not located in the cxx testDepList["TestKernel"] = {"from": shortPath, "to": "./Code/Testing/otbTestMain.h"} testCxx[shortPath] = { "depList": testDepList, "thirdPartyDep": thirdPartyDep, "group": groupDestination, "module": moduleDestination, } outFD.write( shortPath + "," + op.basename(op.dirname(shortPath)) + "," + groupDestination + "," + moduleDestination + ",test,\n" ) outFD.close() # sum all test dependencies in every module allTestDepends = gatherTestDepends(testCxx, fullDepList) # clean the test depends (i.e. ImageIO is dragged by TestKernel) cleanTestDepends = {} for mod in allTestDepends: cleanTestDepends[mod] = {} for dep1 in allTestDepends[mod]: isClean = True for dep2 in allTestDepends[mod]: if dep1 == dep2: continue if dep1 in fullDepList[dep2]: isClean = False break if isClean: cleanTestDepends[mod][dep1] = 1 if csvTestDepends: manifestParser.outputCSVEdgeList(cleanTestDepends, csvTestDepends)
def main(argv): otbDir = op.abspath(argv[1]) targetModule = argv[2] targetGroup = "TBD" if targetModule.count('/') == 1: pos = targetModule.find('/') targetGroup = targetModule[0:pos] targetModule = targetModule[pos+1:] if targetModule == "": print "Wrong module name, check input argument : "+argv[2] if targetGroup == "": print "Wrong group name, check input argument : "+argv[2] print "Target module: "+targetGroup+"/"+targetModule srcFiles = [] for item in argv[3:]: src = item if not src.startswith("Modules/"): src = "Modules/"+src if op.isfile(op.join(otbDir,src)): srcFiles.append(src.strip('./')) else: print "Input source file not found, will be skipped : "+src # First, analyse current OTB tree, retrieve : # - module list # - group vs module association modulesRoot = op.join(otbDir,"Modules") [depList, optDepList, testDepList] = sourceAPI.parseOTBModuleCmake(modulesRoot) #fullDepList = manifestParser.buildFullDep(depList) #oldCleanDepList = sourceAPI.cleanDepList(depList,fullDepList) [groups,moduleList,sourceList,testList] = sourceAPI.parseModuleRoot(modulesRoot) # DEBUG #manifestParser.printDepList(depList) #print str(moduleList) # Second, operate the move if targetModule in moduleList: targetGroup = manifestParser.getGroup(targetModule,groups) else: if targetGroup == 'TBD': print "Error : group name must be specified for new modules (use group/module syntax)" return 1 destinationPrefix = op.join(targetGroup,targetModule) for srcFile in srcFiles: cleanFile = srcFile.strip('./') words = cleanFile.split('/') srcMod = words[2] srcGrp = words[1] targetFile = cleanFile.replace(srcGrp+'/'+srcMod,destinationPrefix,1) targetPath = op.join(otbDir,op.dirname(targetFile)) if not op.isdir(targetPath): os.makedirs(targetPath) shutil.move(op.join(otbDir,cleanFile),targetPath) # Compute new modules dependencies [newGroups,newModuleList,newSourceList,newTestList] = sourceAPI.parseModuleRoot(modulesRoot) newDepList = sourceAPI.buildModularDep(otbDir,newModuleList,newSourceList) newTestDepList = sourceAPI.buildModularDep(otbDir,newTestList,newSourceList) # compute full dependencies newFullDepList = manifestParser.buildFullDep(newDepList) # detect cyclic dependencies cyclicDependentModules = [] for mod in newFullDepList.keys(): if mod in newFullDepList[mod]: if not mod in cyclicDependentModules: cyclicDependentModules.append(mod) if len(cyclicDependentModules) > 0: print "Check for cyclic dependency : Failed" for m in cyclicDependentModules: cycle = sourceAPI.getCyclicDep(m,newDepList) print "Cycle for module "+m+": "+str(cycle) if len(cycle) > 0: a = m for c in cycle: b = c print a+" -> "+b+": " for dep in newDepList[a][b]: print "\t"+dep["from"]+" -> "+dep["to"] a = c #manifestParser.printDepList(newDepList,cyclicDependentModules) return 1 else: print "Check for cyclic dependency : Passed" # fix srcList and test declaration os.chdir(otbDir) for srcFile in srcFiles: cleanFile = srcFile.strip('./') words = cleanFile.split('/') srcMod = words[2] srcGrp = words[1] srcSub = words[3] targetFile = cleanFile.replace(srcGrp+"/"+srcMod,destinationPrefix,1) # call hg rename -A call(["hg","rename","-A",cleanFile,targetFile]) # - for input files in 'src' : adapt OTBModule_SRC if srcSub == "src" and len(words) == 5: # remove entry in previous module removed = [op.basename(srcFile)] added = [] cmakelistPath = op.join(modulesRoot,srcGrp,srcMod,srcSub,"CMakeLists.txt") # Check that there are some source file remaining in src dir source_files = filter(os.path.isfile, glob.glob(op.join(modulesRoot,srcGrp,srcMod,srcSub)+'/*.c*')) if len(source_files) >0 : sourceAPI.updateSourceList(cmakelistPath,"OTB"+srcMod+"_SRC",added,removed) else: # There are no more sources here, the whole src module can be removed print "Removing "+srcSub+" dir in "+srcGrp+"/"+srcMod+", since it does not contain source files anymore" call(["hg","remove",op.join(modulesRoot,srcGrp,srcMod,srcSub)+"/*"]) # add entry in target module removed = [] added = [op.basename(srcFile)] cmakelistPath = op.join(modulesRoot,destinationPrefix,srcSub,"CMakeLists.txt") if not op.exists(cmakelistPath): sourceAPI.initializeSrcCMakeLists(cmakelistPath,targetModule) call(["hg","add",cmakelistPath.replace(otbDir,".")]) sourceAPI.updateSourceList(cmakelistPath,"OTB"+targetModule+"_SRC",added,removed) # -for input files in 'app' if srcSub == "app" and len(words) == 5: cmakelistPath = op.join(modulesRoot,srcGrp,srcMod,srcSub,"CMakeLists.txt") nextCmakelistPath = op.join(modulesRoot,destinationPrefix,srcSub,"CMakeLists.txt") if not op.exists(nextCmakelistPath): sourceAPI.initializeAppCMakeLists(nextCmakelistPath,targetModule) call(["hg","add",nextCmakelistPath.replace(otbDir,".")]) # move the 'otb_create_application' bloc appName = sourceAPI.moveAppBloc(cmakelistPath,nextCmakelistPath,op.basename(srcFile)) source_files = filter(os.path.isfile, glob.glob(op.join(modulesRoot,srcGrp,srcMod,srcSub)+'/*.c*')) if len(source_files) == 0 : # There are no more sources here, the whole src module can be removed print "Removing "+srcSub+" dir in "+srcGrp+"/"+srcMod+", since it does not contain source files anymore" call(["hg","remove",op.join(modulesRoot,srcGrp,srcMod,srcSub)+"/*"]) # move tests testCmakelistPath = op.join(modulesRoot,srcGrp,srcMod,"test","CMakeLists.txt") nextTestCmakelistPath = op.join(modulesRoot,destinationPrefix,"test","CMakeLists.txt") appTestBlocs = {} if op.exists(testCmakelistPath): appTestBlocs = sourceAPI.extractAppTestBlocs(testCmakelistPath,appName) if len(appTestBlocs) > 0: if not op.exists(nextTestCmakelistPath): if not op.exists(op.dirname(nextTestCmakelistPath)): os.makedirs(op.dirname(nextTestCmakelistPath)) fd = open(nextTestCmakelistPath,'w') fd.write("otb_module_test()\n") fd.write("\n") fd.close() call(["hg","add",nextTestCmakelistPath.replace(otbDir,".")]) fd = open(nextTestCmakelistPath,'a') fd.write("#----------- "+appName+" TESTS ----------------\n") for tname in appTestBlocs: fd.writelines(appTestBlocs[tname]) fd.write("\n") fd.close() if srcSub == "test" and len(words) == 5: # analyse test res = createTestManifest.parseTestCxx(op.join(otbDir,targetFile)) if res["hasMain"]: print "Test with main ("+targetFile+") : not handled for now" else: # remove entry in previous module source list removed = [op.basename(srcFile)] added = [] oldCmakelistPath = op.join(modulesRoot,op.join(srcGrp,op.join(srcMod,"test/CMakeLists.txt"))) oldTestDriverPath = op.join(modulesRoot,op.join(srcGrp,op.join(srcMod,"test/otb"+srcMod+"TestDriver.cxx"))) sourceAPI.updateSourceList(oldCmakelistPath,"OTB"+srcMod+"Tests",added,removed) # add entry in target module source list removed = [] added = [op.basename(srcFile)] cmakelistPath = op.join(modulesRoot,op.join(destinationPrefix,"test/CMakeLists.txt")) testDriverPath = op.join(modulesRoot,op.join(destinationPrefix,"test/otb"+targetModule+"TestDriver.cxx")) if not op.exists(cmakelistPath): # there was no test before : initialize CMakeLists.txt sourceAPI.initializeTestCMakeLists(cmakelistPath,targetModule) call(["hg","add",cmakelistPath.replace(otbDir,".")]) if not op.exists(testDriverPath): # there was no test before : initialize test driver sourceAPI.initializeTestDriver(testDriverPath) call(["hg","add",testDriverPath.replace(otbDir,".")]) sourceAPI.updateSourceList(cmakelistPath,"OTB"+targetModule+"Tests",added,removed) # - move test declaration testCode = dispatchTests.findTestFromExe(oldCmakelistPath,"otb"+srcMod+"TestDriver","",res["testFunctions"],'otb_') # get set_test_properties() testProp = dispatchTests.findTestProperties(oldCmakelistPath,testCode.keys()) print "Found "+str(len(testCode))+" tests to move" sourceAPI.moveTestCode(oldCmakelistPath,cmakelistPath,testCode,testProp) for mod in newModuleList: curGroup = manifestParser.getGroup(mod,newGroups) # fix the otb-module.cmake cmake_module_path = op.join(modulesRoot,op.join(curGroup,op.join(mod,"otb-module.cmake"))) cmakel_module_path = op.join(modulesRoot,op.join(curGroup,op.join(mod,"CMakeLists.txt"))) if (not op.exists(cmake_module_path)) and (mod == targetModule): # initialize new otb-module.cmake if new module sourceAPI.initializeOTBModuleCmake(cmake_module_path,mod) with_lib = False if op.exists(op.join(curGroup,op.join(mod,"src"))): with_lib = True sourceAPI.initializeOTBModuleCMakeLists(cmakel_module_path,mod,with_lib) call(["hg","add",cmakel_module_path.replace(otbDir,".")]) call(["hg","add",cmake_module_path.replace(otbDir,".")]) # - fix the target_link_libraries src_dir = op.join(modulesRoot,curGroup,mod,"src") sub_src_CMakeList = op.join(modulesRoot,op.join(curGroup,op.join(mod,"src/CMakeLists.txt"))) # Update the module dependencies print "Updating module dependencies ..." count = updateModuleDependencies.update(otbDir) print str(count)+" modules were updated" # Update the module test driver print "Updating test drivers ..." count = updateTestDrivers.update(otbDir) print str(count)+" files updated" # Update the group declaration in doxygen print "Updating doxygen group declaration ..." updateDoxyGroup.update(otbDir) # TODO : hg commit by the user print "\nTo commit those changes, run: hg commit -m \"ENH: Automatic move of files to module "+targetGroup+"/"+targetModule+"\"\n" print "It is advised to run updateModuleDependencies.py script beforehand.\n"
def main(argv): otbDir = op.abspath(argv[1]) targetModule = argv[2] targetGroup = "TBD" if targetModule.count('/') == 1: pos = targetModule.find('/') targetGroup = targetModule[0:pos] targetModule = targetModule[pos + 1:] if targetModule == "": print "Wrong module name, check input argument : " + argv[2] if targetGroup == "": print "Wrong group name, check input argument : " + argv[2] print "Target module: " + targetGroup + "/" + targetModule srcFiles = [] for item in argv[3:]: src = item if not src.startswith("Modules/"): src = "Modules/" + src if op.isfile(op.join(otbDir, src)): srcFiles.append(src.strip('./')) else: print "Input source file not found, will be skipped : " + src # First, analyse current OTB tree, retrieve : # - module list # - group vs module association modulesRoot = op.join(otbDir, "Modules") [depList, optDepList, testDepList] = sourceAPI.parseOTBModuleCmake(modulesRoot) #fullDepList = manifestParser.buildFullDep(depList) #oldCleanDepList = sourceAPI.cleanDepList(depList,fullDepList) [groups, moduleList, sourceList, testList] = sourceAPI.parseModuleRoot(modulesRoot) # DEBUG #manifestParser.printDepList(depList) #print str(moduleList) # Second, operate the move if targetModule in moduleList: targetGroup = manifestParser.getGroup(targetModule, groups) else: if targetGroup == 'TBD': print "Error : group name must be specified for new modules (use group/module syntax)" return 1 destinationPrefix = op.join(targetGroup, targetModule) for srcFile in srcFiles: cleanFile = srcFile.strip('./') words = cleanFile.split('/') srcMod = words[2] srcGrp = words[1] targetFile = cleanFile.replace(srcGrp + '/' + srcMod, destinationPrefix, 1) targetPath = op.join(otbDir, op.dirname(targetFile)) if not op.isdir(targetPath): os.makedirs(targetPath) shutil.move(op.join(otbDir, cleanFile), targetPath) # Compute new modules dependencies [newGroups, newModuleList, newSourceList, newTestList] = sourceAPI.parseModuleRoot(modulesRoot) newDepList = sourceAPI.buildModularDep(otbDir, newModuleList, newSourceList) newTestDepList = sourceAPI.buildModularDep(otbDir, newTestList, newSourceList) # compute full dependencies newFullDepList = manifestParser.buildFullDep(newDepList) # detect cyclic dependencies cyclicDependentModules = [] for mod in newFullDepList.keys(): if mod in newFullDepList[mod]: if not mod in cyclicDependentModules: cyclicDependentModules.append(mod) if len(cyclicDependentModules) > 0: print "Check for cyclic dependency : Failed" for m in cyclicDependentModules: cycle = sourceAPI.getCyclicDep(m, newDepList) print "Cycle for module " + m + ": " + str(cycle) if len(cycle) > 0: a = m for c in cycle: b = c print a + " -> " + b + ": " for dep in newDepList[a][b]: print "\t" + dep["from"] + " -> " + dep["to"] a = c #manifestParser.printDepList(newDepList,cyclicDependentModules) return 1 else: print "Check for cyclic dependency : Passed" # fix srcList and test declaration os.chdir(otbDir) for srcFile in srcFiles: cleanFile = srcFile.strip('./') words = cleanFile.split('/') srcMod = words[2] srcGrp = words[1] srcSub = words[3] targetFile = cleanFile.replace(srcGrp + "/" + srcMod, destinationPrefix, 1) # call hg rename -A call(["hg", "rename", "-A", cleanFile, targetFile]) # - for input files in 'src' : adapt OTBModule_SRC if srcSub == "src" and len(words) == 5: # remove entry in previous module removed = [op.basename(srcFile)] added = [] cmakelistPath = op.join(modulesRoot, srcGrp, srcMod, srcSub, "CMakeLists.txt") # Check that there are some source file remaining in src dir source_files = filter( os.path.isfile, glob.glob( op.join(modulesRoot, srcGrp, srcMod, srcSub) + '/*.c*')) if len(source_files) > 0: sourceAPI.updateSourceList(cmakelistPath, "OTB" + srcMod + "_SRC", added, removed) else: # There are no more sources here, the whole src module can be removed print "Removing " + srcSub + " dir in " + srcGrp + "/" + srcMod + ", since it does not contain source files anymore" call([ "hg", "remove", op.join(modulesRoot, srcGrp, srcMod, srcSub) + "/*" ]) # add entry in target module removed = [] added = [op.basename(srcFile)] cmakelistPath = op.join(modulesRoot, destinationPrefix, srcSub, "CMakeLists.txt") if not op.exists(cmakelistPath): sourceAPI.initializeSrcCMakeLists(cmakelistPath, targetModule) call(["hg", "add", cmakelistPath.replace(otbDir, ".")]) sourceAPI.updateSourceList(cmakelistPath, "OTB" + targetModule + "_SRC", added, removed) # -for input files in 'app' if srcSub == "app" and len(words) == 5: cmakelistPath = op.join(modulesRoot, srcGrp, srcMod, srcSub, "CMakeLists.txt") nextCmakelistPath = op.join(modulesRoot, destinationPrefix, srcSub, "CMakeLists.txt") if not op.exists(nextCmakelistPath): sourceAPI.initializeAppCMakeLists(nextCmakelistPath, targetModule) call(["hg", "add", nextCmakelistPath.replace(otbDir, ".")]) # move the 'otb_create_application' bloc appName = sourceAPI.moveAppBloc(cmakelistPath, nextCmakelistPath, op.basename(srcFile)) source_files = filter( os.path.isfile, glob.glob( op.join(modulesRoot, srcGrp, srcMod, srcSub) + '/*.c*')) if len(source_files) == 0: # There are no more sources here, the whole src module can be removed print "Removing " + srcSub + " dir in " + srcGrp + "/" + srcMod + ", since it does not contain source files anymore" call([ "hg", "remove", op.join(modulesRoot, srcGrp, srcMod, srcSub) + "/*" ]) # move tests testCmakelistPath = op.join(modulesRoot, srcGrp, srcMod, "test", "CMakeLists.txt") nextTestCmakelistPath = op.join(modulesRoot, destinationPrefix, "test", "CMakeLists.txt") appTestBlocs = {} if op.exists(testCmakelistPath): appTestBlocs = sourceAPI.extractAppTestBlocs( testCmakelistPath, appName) if len(appTestBlocs) > 0: if not op.exists(nextTestCmakelistPath): if not op.exists(op.dirname(nextTestCmakelistPath)): os.makedirs(op.dirname(nextTestCmakelistPath)) fd = open(nextTestCmakelistPath, 'w') fd.write("otb_module_test()\n") fd.write("\n") fd.close() call([ "hg", "add", nextTestCmakelistPath.replace(otbDir, ".") ]) fd = open(nextTestCmakelistPath, 'a') fd.write("#----------- " + appName + " TESTS ----------------\n") for tname in appTestBlocs: fd.writelines(appTestBlocs[tname]) fd.write("\n") fd.close() if srcSub == "test" and len(words) == 5: # analyse test res = createTestManifest.parseTestCxx(op.join(otbDir, targetFile)) if res["hasMain"]: print "Test with main (" + targetFile + ") : not handled for now" else: # remove entry in previous module source list removed = [op.basename(srcFile)] added = [] oldCmakelistPath = op.join( modulesRoot, op.join(srcGrp, op.join(srcMod, "test/CMakeLists.txt"))) oldTestDriverPath = op.join( modulesRoot, op.join( srcGrp, op.join(srcMod, "test/otb" + srcMod + "TestDriver.cxx"))) sourceAPI.updateSourceList(oldCmakelistPath, "OTB" + srcMod + "Tests", added, removed) # add entry in target module source list removed = [] added = [op.basename(srcFile)] cmakelistPath = op.join( modulesRoot, op.join(destinationPrefix, "test/CMakeLists.txt")) testDriverPath = op.join( modulesRoot, op.join(destinationPrefix, "test/otb" + targetModule + "TestDriver.cxx")) if not op.exists(cmakelistPath): # there was no test before : initialize CMakeLists.txt sourceAPI.initializeTestCMakeLists(cmakelistPath, targetModule) call(["hg", "add", cmakelistPath.replace(otbDir, ".")]) if not op.exists(testDriverPath): # there was no test before : initialize test driver sourceAPI.initializeTestDriver(testDriverPath) call(["hg", "add", testDriverPath.replace(otbDir, ".")]) sourceAPI.updateSourceList(cmakelistPath, "OTB" + targetModule + "Tests", added, removed) # - move test declaration testCode = dispatchTests.findTestFromExe( oldCmakelistPath, "otb" + srcMod + "TestDriver", "", res["testFunctions"], 'otb_') # get set_test_properties() testProp = dispatchTests.findTestProperties( oldCmakelistPath, testCode.keys()) print "Found " + str(len(testCode)) + " tests to move" sourceAPI.moveTestCode(oldCmakelistPath, cmakelistPath, testCode, testProp) for mod in newModuleList: curGroup = manifestParser.getGroup(mod, newGroups) # fix the otb-module.cmake cmake_module_path = op.join( modulesRoot, op.join(curGroup, op.join(mod, "otb-module.cmake"))) cmakel_module_path = op.join( modulesRoot, op.join(curGroup, op.join(mod, "CMakeLists.txt"))) if (not op.exists(cmake_module_path)) and (mod == targetModule): # initialize new otb-module.cmake if new module sourceAPI.initializeOTBModuleCmake(cmake_module_path, mod) with_lib = False if op.exists(op.join(curGroup, op.join(mod, "src"))): with_lib = True sourceAPI.initializeOTBModuleCMakeLists(cmakel_module_path, mod, with_lib) call(["hg", "add", cmakel_module_path.replace(otbDir, ".")]) call(["hg", "add", cmake_module_path.replace(otbDir, ".")]) # - fix the target_link_libraries src_dir = op.join(modulesRoot, curGroup, mod, "src") sub_src_CMakeList = op.join( modulesRoot, op.join(curGroup, op.join(mod, "src/CMakeLists.txt"))) # Update the module dependencies print "Updating module dependencies ..." count = updateModuleDependencies.update(otbDir) print str(count) + " modules were updated" # Update the module test driver print "Updating test drivers ..." count = updateTestDrivers.update(otbDir) print str(count) + " files updated" # Update the group declaration in doxygen print "Updating doxygen group declaration ..." updateDoxyGroup.update(otbDir) # TODO : hg commit by the user print "\nTo commit those changes, run: hg commit -m \"ENH: Automatic move of files to module " + targetGroup + "/" + targetModule + "\"\n" print "It is advised to run updateModuleDependencies.py script beforehand.\n"
def main(argv): manifestPath = op.expanduser(argv[1]) moduleDepPath = op.expanduser(argv[2]) otbDir = op.expanduser(argv[3]) outManifest = argv[4] example_dir = op.join(otbDir, "Examples") # Standard Manifest parsing, extract simple and full dependencies [groups, moduleList, sourceList] = manifestParser.parseManifest(manifestPath) depList = manifestParser.parseDependList(moduleDepPath) fullDepList = manifestParser.buildFullDep(depList) # make sure every module is in depList and fullDepList (even if it has no dependencies) for mod in moduleList: if not depList.has_key(mod): depList[mod] = {} if not fullDepList.has_key(mod): fullDepList[mod] = {} depListPerGroup = manifestParser.findGroupDeps(groups, depList) OldFolderPartition = createTestManifest.buildOldFolderPartition(moduleList) exampleCxx = {} outFD = open(outManifest, 'wb') outFD.write( "# Monolithic path, Current dir, group name, module name, subDir name, comment\n" ) # parse all cxx test files : analyse them and extract their dependencies for (d, f) in codeParser.FindBinaries(example_dir): fullPath = op.join(d, f) shortPath = fullPath.replace(otbDir, '.') moduleDestination = "TBD" groupDestination = "TBD" res = createTestManifest.parseTestCxx(fullPath) if res["isTestDriver"]: # no need to dispatch test drivers, they can be generated again continue [exampleDepList, thirdPartyDep ] = createTestManifest.getTestDependencies(res["includes"], sourceList) # if no dependency found, at least put Common if len(exampleDepList) == 0: exampleDepList["Common"] = {"to": "unkown_source"} # try to clean the dependency list (remove inherited modules) ignoreModules = ["ImageIO", "VectorDataIO", "TestKernel"] cleanExampleDepList = [] depListToRemove = [] for dep1 in exampleDepList: # register the "from" field exampleDepList[dep1]["from"] = shortPath for dep2 in exampleDepList: if dep2 == dep1: continue # avoid IO modules to 'eat' usefull dependencies if dep1 in ignoreModules: continue if (dep2 in fullDepList[dep1]) and \ (not dep2 in depListToRemove): depListToRemove.append(dep2) for dep in exampleDepList: if not dep in depListToRemove: cleanExampleDepList.append(dep) # build all dependencies of the test exampleFullDepList = [] for dep in exampleDepList: for subDep in fullDepList[dep]: if not subDep in exampleFullDepList: exampleFullDepList.append(subDep) # start guessing luckyGuess = None guessStep = 1 # try to get the list of module used to partition the corresponding source directory guessModules = [] guessSourceDir = op.split(shortPath.replace("./Examples", "./Code"))[0] if OldFolderPartition.has_key(guessSourceDir): guessModules = OldFolderPartition[guessSourceDir].keys() # special case for Examples/Application -> ApplicationEngine if guessSourceDir == "./Application": guessModules.append("ApplicationEngine") # first filter : find modules that appear in cleanExampleDepList and in guessModules overlappingModules = [] for dep in cleanExampleDepList: if dep in guessModules: overlappingModules.append(dep) if len(overlappingModules) == 1: luckyGuess = overlappingModules[0] # second filter : find the source file with the closest name if not luckyGuess: guessStep += 1 [matchFile, matchPercent ] = createTestManifest.findClosestSourceName(f, sourceList) if (sourceList[matchFile] in exampleDepList) and (matchPercent > 50.0): luckyGuess = sourceList[matchFile] elif (sourceList[matchFile] in exampleFullDepList) and (matchPercent > 70.0): luckyGuess = sourceList[matchFile] # third guess : # Constrain the search : if the folder containing the test corresponds # to a group name, limit the search to the modules in this group # Also, separate IO examples from non-IO examples if not luckyGuess: folderName = op.basename(d) if folderName == "Classification": folderName = "Learning" if folderName in groups: groupDestination = folderName exampleSmallerDepList = {} for dep in exampleDepList: if groupDestination != "TBD": if dep in groups[groupDestination]: exampleSmallerDepList[dep] = 1 else: if not dep in groups["IO"]: exampleSmallerDepList[dep] = 1 if len(exampleSmallerDepList) == 1: luckyGuess = exampleSmallerDepList.keys()[0] elif len(exampleSmallerDepList) > 1: # filter again to get top-level dependencies doubleCleanDepList = [] depListToRemove = [] for dep1 in exampleSmallerDepList: for dep2 in exampleSmallerDepList: if dep2 == dep1: continue if (dep2 in fullDepList[dep1]) and \ (not dep2 in depListToRemove): depListToRemove.append(dep2) for dep in exampleSmallerDepList: if not dep in depListToRemove: doubleCleanDepList.append(dep) if len(doubleCleanDepList) == 1: luckyGuess = doubleCleanDepList[0] elif len(exampleSmallerDepList) == 0: # No dependence in guessed group # choose the most probable module in that group for mod in moduleList: if mod.startswith(folderName) and ( mod in groups[groupDestination]): luckyGuess = mod break # fourth filter : if there is only one dependency in cleanExampleDepList : take it if not luckyGuess: guessStep += 1 if len(cleanExampleDepList) == 1: luckyGuess = cleanExampleDepList[0] # DEBUG if not luckyGuess: print shortPath + " : " + str(exampleDepList.keys()) print shortPath + " : " + str(exampleSmallerDepList.keys()) luckyGuess = "TBD" if luckyGuess: moduleDestination = luckyGuess else: pass #print f + " -> " + str(exampleDepList) #print f + " -> "+ matchFile + " ( " + str(matchPercent) + "% )" # if module is found and not group, deduce group if groupDestination == "TBD" and moduleDestination != "TBD": groupDestination = manifestParser.getGroup(moduleDestination, groups) exampleCxx[shortPath] = { "depList": exampleDepList, "thirdPartyDep": thirdPartyDep, "group": groupDestination, "module": moduleDestination } outFD.write(shortPath + "," + op.basename(op.dirname(shortPath)) + "," + groupDestination + "," + moduleDestination + ",example,\n") outFD.close()
def main(argv): manifestPath = op.expanduser(argv[1]) moduleDepPath = op.expanduser(argv[2]) otbDir = op.expanduser(argv[3]) outManifest = argv[4] example_dir = op.join(otbDir,"Examples") # Standard Manifest parsing, extract simple and full dependencies [groups,moduleList,sourceList] = manifestParser.parseManifest(manifestPath) depList = manifestParser.parseDependList(moduleDepPath) fullDepList = manifestParser.buildFullDep(depList) # make sure every module is in depList and fullDepList (even if it has no dependencies) for mod in moduleList: if not depList.has_key(mod): depList[mod] = {} if not fullDepList.has_key(mod): fullDepList[mod] = {} depListPerGroup = manifestParser.findGroupDeps(groups,depList) OldFolderPartition = createTestManifest.buildOldFolderPartition(moduleList) exampleCxx = {} outFD = open(outManifest,'wb') outFD.write("# Monolithic path, Current dir, group name, module name, subDir name, comment\n") # parse all cxx test files : analyse them and extract their dependencies for (d,f) in codeParser.FindBinaries(example_dir): fullPath = op.join(d,f) shortPath = fullPath.replace(otbDir,'.') moduleDestination = "TBD" groupDestination = "TBD" res = createTestManifest.parseTestCxx(fullPath) if res["isTestDriver"]: # no need to dispatch test drivers, they can be generated again continue [exampleDepList,thirdPartyDep] = createTestManifest.getTestDependencies(res["includes"],sourceList) # if no dependency found, at least put Common if len(exampleDepList) == 0: exampleDepList["Common"] = {"to":"unkown_source"} # try to clean the dependency list (remove inherited modules) ignoreModules = ["ImageIO","VectorDataIO","TestKernel"] cleanExampleDepList = [] depListToRemove = [] for dep1 in exampleDepList: # register the "from" field exampleDepList[dep1]["from"] = shortPath for dep2 in exampleDepList: if dep2 == dep1: continue # avoid IO modules to 'eat' usefull dependencies if dep1 in ignoreModules: continue if (dep2 in fullDepList[dep1]) and \ (not dep2 in depListToRemove): depListToRemove.append(dep2) for dep in exampleDepList: if not dep in depListToRemove: cleanExampleDepList.append(dep) # build all dependencies of the test exampleFullDepList = [] for dep in exampleDepList: for subDep in fullDepList[dep]: if not subDep in exampleFullDepList: exampleFullDepList.append(subDep) # start guessing luckyGuess = None guessStep = 1 # try to get the list of module used to partition the corresponding source directory guessModules = [] guessSourceDir = op.split(shortPath.replace("./Examples","./Code"))[0] if OldFolderPartition.has_key(guessSourceDir): guessModules = OldFolderPartition[guessSourceDir].keys() # special case for Examples/Application -> ApplicationEngine if guessSourceDir == "./Application": guessModules.append("ApplicationEngine") # first filter : find modules that appear in cleanExampleDepList and in guessModules overlappingModules = [] for dep in cleanExampleDepList: if dep in guessModules: overlappingModules.append(dep) if len(overlappingModules) == 1: luckyGuess = overlappingModules[0] # second filter : find the source file with the closest name if not luckyGuess: guessStep += 1 [matchFile, matchPercent] = createTestManifest.findClosestSourceName(f,sourceList) if (sourceList[matchFile] in exampleDepList) and (matchPercent > 50.0): luckyGuess = sourceList[matchFile] elif (sourceList[matchFile] in exampleFullDepList) and (matchPercent > 70.0): luckyGuess = sourceList[matchFile] # third guess : # Constrain the search : if the folder containing the test corresponds # to a group name, limit the search to the modules in this group # Also, separate IO examples from non-IO examples if not luckyGuess: folderName = op.basename(d) if folderName == "Classification": folderName = "Learning" if folderName in groups: groupDestination = folderName exampleSmallerDepList = {} for dep in exampleDepList: if groupDestination != "TBD": if dep in groups[groupDestination]: exampleSmallerDepList[dep] = 1 else: if not dep in groups["IO"]: exampleSmallerDepList[dep] = 1 if len(exampleSmallerDepList) == 1: luckyGuess = exampleSmallerDepList.keys()[0] elif len(exampleSmallerDepList) > 1: # filter again to get top-level dependencies doubleCleanDepList = [] depListToRemove = [] for dep1 in exampleSmallerDepList: for dep2 in exampleSmallerDepList: if dep2 == dep1: continue if (dep2 in fullDepList[dep1]) and \ (not dep2 in depListToRemove): depListToRemove.append(dep2) for dep in exampleSmallerDepList: if not dep in depListToRemove: doubleCleanDepList.append(dep) if len(doubleCleanDepList) == 1: luckyGuess = doubleCleanDepList[0] elif len(exampleSmallerDepList) == 0: # No dependence in guessed group # choose the most probable module in that group for mod in moduleList: if mod.startswith(folderName) and (mod in groups[groupDestination]): luckyGuess = mod break # fourth filter : if there is only one dependency in cleanExampleDepList : take it if not luckyGuess: guessStep += 1 if len(cleanExampleDepList) == 1: luckyGuess = cleanExampleDepList[0] # DEBUG if not luckyGuess: print shortPath+" : "+str(exampleDepList.keys()) print shortPath+" : "+str(exampleSmallerDepList.keys()) luckyGuess = "TBD" if luckyGuess: moduleDestination = luckyGuess else: pass #print f + " -> " + str(exampleDepList) #print f + " -> "+ matchFile + " ( " + str(matchPercent) + "% )" # if module is found and not group, deduce group if groupDestination == "TBD" and moduleDestination != "TBD": groupDestination = manifestParser.getGroup(moduleDestination,groups) exampleCxx[shortPath] = {"depList":exampleDepList , "thirdPartyDep":thirdPartyDep, "group":groupDestination, "module":moduleDestination} outFD.write(shortPath+","+op.basename(op.dirname(shortPath))+","+groupDestination+","+moduleDestination+",example,\n") outFD.close()