public static ImmutableSet<Path> createPackageLookupPathSet(IjModuleGraph moduleGraph) { ImmutableSet.Builder<Path> builder = ImmutableSet.builder(); for (IjModule module : moduleGraph.getModuleNodes()) { for (IjFolder folder : module.getFolders()) { if (!folder.getWantsPackagePrefix()) { continue; } Optional<Path> firstJavaFile = FluentIterable.from(folder.getInputs()) .filter( new Predicate<Path>() { @Override public boolean apply(Path input) { return input.getFileName().toString().endsWith(".java"); } }) .first(); if (firstJavaFile.isPresent()) { builder.add(firstJavaFile.get()); } } } return builder.build(); }
@Test public void testEmptyRootModule() throws Exception { Path baseTargetSrcFilePath = Paths.get("java/com/example/base/Base.java"); TargetNode<?> baseTargetNode = JavaLibraryBuilder.createBuilder( BuildTargetFactory.newInstance("//java/com/example/base:base")) .addSrc(baseTargetSrcFilePath) .build(); IjModuleGraph moduleGraph = IjModuleGraphTest.createModuleGraph(ImmutableSet.<TargetNode<?>>of(baseTargetNode)); IjProjectTemplateDataPreparer dataPreparer = new IjProjectTemplateDataPreparer(javaPackageFinder, moduleGraph, filesystem); assertThat( dataPreparer.getModulesToBeWritten(), containsInAnyOrder( IjModule.builder() .setModuleBasePath(Paths.get("java/com/example/base")) .setTargets(ImmutableSet.<TargetNode<?>>of(baseTargetNode)) .addFolders( IjFolder.builder() .setType(AbstractIjFolder.Type.SOURCE_FOLDER) .setPath(Paths.get("java/com/example/base")) .setInputs(ImmutableSortedSet.<Path>of(baseTargetSrcFilePath)) .setWantsPackagePrefix(true) .build()) .build(), IjModule.builder() .setModuleBasePath(Paths.get("")) .setTargets(ImmutableSet.<TargetNode<?>>of()) .build())); }
public ContentRoot getContentRoot(IjModule module) throws IOException { Path moduleBasePath = module.getModuleBasePath(); Path moduleLocation = module.getModuleImlFilePath(); final Path moduleLocationBasePath = (moduleLocation.getParent() == null) ? Paths.get("") : moduleLocation.getParent(); ImmutableSet<IjFolder> sourcesAndExcludes = FluentIterable.from(module.getFolders()).append(createExcludes(module)).toSet(); return createContentRoot(moduleBasePath, sourcesAndExcludes, moduleLocationBasePath); }
public static ImmutableSet<Path> createReferencedFolderPathsSet(ImmutableSet<IjModule> modules) { Set<Path> pathSet = new HashSet<>(); for (IjModule module : modules) { addPathAndParents(pathSet, module.getModuleBasePath()); for (IjFolder folder : module.getFolders()) { addPathAndParents(pathSet, folder.getPath()); } } return ImmutableSet.copyOf(pathSet); }
private static ImmutableSet<IjModule> createModulesToBeWritten(IjModuleGraph graph) { Path rootModuleBasePath = Paths.get(""); boolean hasRootModule = FluentIterable.from(graph.getModuleNodes()) .transform(IjModule.TO_MODULE_BASE_PATH) .contains(rootModuleBasePath); ImmutableSet<IjModule> supplementalModules = ImmutableSet.of(); if (!hasRootModule) { supplementalModules = ImmutableSet.of( IjModule.builder() .setModuleBasePath(rootModuleBasePath) .setTargets(ImmutableSet.<TargetNode<?>>of()) .build()); } return FluentIterable.from(graph.getModuleNodes()).append(supplementalModules).toSet(); }
public ImmutableSet<IjFolder> createExcludes(IjModule module) throws IOException { final ImmutableSet.Builder<IjFolder> excludesBuilder = ImmutableSet.builder(); final Path moduleBasePath = module.getModuleBasePath(); projectFilesystem.walkRelativeFileTree( moduleBasePath, new FileVisitor<Path>() { @Override public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException { // This is another module that's nested in this one. The entire subtree will be handled // When we create excludes for that module. if (filesystemTraversalBoundaryPaths.contains(dir) && !moduleBasePath.equals(dir)) { return FileVisitResult.SKIP_SUBTREE; } if (!referencedFolderPaths.contains(dir)) { excludesBuilder.add(new ExcludeFolder(dir)); return FileVisitResult.SKIP_SUBTREE; } return FileVisitResult.CONTINUE; } @Override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { return FileVisitResult.CONTINUE; } @Override public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException { return FileVisitResult.CONTINUE; } @Override public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException { return FileVisitResult.CONTINUE; } }); return excludesBuilder.build(); }
/** * @param targetGraph input graph. * @return module graph corresponding to the supplied {@link TargetGraph}. Multiple targets from * the same base path are mapped to a single module, therefore an IjModuleGraph edge exists * between two modules (Ma, Mb) if a TargetGraph edge existed between a pair of nodes (Ta, Tb) * and Ma contains Ta and Mb contains Tb. */ public static IjModuleGraph from( final TargetGraph targetGraph, final IjLibraryFactory libraryFactory, final IjModuleFactory moduleFactory) { final ImmutableMap<BuildTarget, IjModule> rulesToModules = createModules(targetGraph, moduleFactory); final ExportedDepsClosureResolver exportedDepsClosureResolver = new ExportedDepsClosureResolver(targetGraph); ImmutableMap.Builder<IjProjectElement, ImmutableMap<IjProjectElement, DependencyType>> depsBuilder = ImmutableMap.builder(); final Set<IjLibrary> referencedLibraries = new HashSet<>(); for (final IjModule module : FluentIterable.from(rulesToModules.values()).toSet()) { Map<IjProjectElement, DependencyType> moduleDeps = new HashMap<>(); for (Map.Entry<BuildTarget, DependencyType> entry : module.getDependencies().entrySet()) { BuildTarget depBuildTarget = entry.getKey(); DependencyType depType = entry.getValue(); ImmutableSet<IjProjectElement> depElements; if (depType.equals(DependencyType.COMPILED_SHADOW)) { TargetNode<?> targetNode = Preconditions.checkNotNull(targetGraph.get(depBuildTarget)); Optional<IjLibrary> library = libraryFactory.getLibrary(targetNode); if (library.isPresent()) { depElements = ImmutableSet.<IjProjectElement>of(library.get()); } else { depElements = ImmutableSet.of(); } } else { depElements = FluentIterable.from( exportedDepsClosureResolver.getExportedDepsClosure(depBuildTarget)) .append(depBuildTarget) .filter( new Predicate<BuildTarget>() { @Override public boolean apply(BuildTarget input) { // The exported deps closure can contain references back to targets // contained // in the module, so filter those out. TargetNode<?> targetNode = targetGraph.get(input); return !module.getTargets().contains(targetNode); } }) .transform( new Function<BuildTarget, IjProjectElement>() { @Nullable @Override public IjProjectElement apply(BuildTarget depTarget) { IjModule depModule = rulesToModules.get(depTarget); if (depModule != null) { return depModule; } TargetNode<?> targetNode = Preconditions.checkNotNull(targetGraph.get(depTarget)); IjLibrary library = libraryFactory.getLibrary(targetNode).orNull(); return library; } }) .filter(Predicates.notNull()) .toSet(); } for (IjProjectElement depElement : depElements) { Preconditions.checkState(!depElement.equals(module)); DependencyType.putWithMerge(moduleDeps, depElement, depType); } } if (!module.getExtraClassPathDependencies().isEmpty()) { IjLibrary extraClassPathLibrary = IjLibrary.builder() .setClassPaths(module.getExtraClassPathDependencies()) .setTargets(ImmutableSet.<TargetNode<?>>of()) .setName("library_" + module.getName() + "_extra_classpath") .build(); moduleDeps.put(extraClassPathLibrary, DependencyType.PROD); } referencedLibraries.addAll( FluentIterable.from(moduleDeps.keySet()).filter(IjLibrary.class).toSet()); depsBuilder.put(module, ImmutableMap.copyOf(moduleDeps)); } for (IjLibrary library : referencedLibraries) { depsBuilder.put(library, ImmutableMap.<IjProjectElement, DependencyType>of()); } return new IjModuleGraph(depsBuilder.build()); }
@Test @SuppressWarnings("unchecked") public void testDependencies() throws Exception { TargetNode<?> hamcrestTargetNode = PrebuiltJarBuilder.createBuilder( BuildTargetFactory.newInstance("//third-party/hamcrest:hamcrest")) .setBinaryJar(Paths.get("third-party/hamcrest/hamcrest.jar")) .build(); TargetNode<?> guavaTargetNode = PrebuiltJarBuilder.createBuilder( BuildTargetFactory.newInstance("//third-party/guava:guava")) .setBinaryJar(Paths.get("third-party/guava/guava.jar")) .build(); TargetNode<?> baseTargetNode = JavaLibraryBuilder.createBuilder( BuildTargetFactory.newInstance("//java/com/example/base:base")) .addDep(guavaTargetNode.getBuildTarget()) .addSrc(Paths.get("java/com/example/base/Base.java")) .build(); TargetNode<?> baseGenruleTarget = GenruleBuilder.newGenruleBuilder( BuildTargetFactory.newInstance("//java/com/example/base:genrule")) .build(); TargetNode<?> baseInlineTestsTargetNode = JavaLibraryBuilder.createBuilder( BuildTargetFactory.newInstance("//java/com/example/base:tests")) .addDep(hamcrestTargetNode.getBuildTarget()) .addSrc(Paths.get("java/com/example/base/TestBase.java")) .addSrcTarget(baseGenruleTarget.getBuildTarget()) .build(); TargetNode<?> baseTestsTargetNode = JavaTestBuilder.createBuilder( BuildTargetFactory.newInstance("//javatests/com/example/base:base")) .addDep(baseTargetNode.getBuildTarget()) .addDep(hamcrestTargetNode.getBuildTarget()) .addSrc(Paths.get("javatests/com/example/base/Base.java")) .build(); IjModuleGraph moduleGraph = IjModuleGraphTest.createModuleGraph( ImmutableSet.of( hamcrestTargetNode, guavaTargetNode, baseTargetNode, baseGenruleTarget, baseInlineTestsTargetNode, baseTestsTargetNode), ImmutableMap.<TargetNode<?>, Path>of( baseInlineTestsTargetNode, Paths.get("buck-out/baseInlineTests.jar")), Functions.constant(Optional.<Path>absent())); IjLibrary hamcrestLibrary = IjModuleGraphTest.getLibraryForTarget(moduleGraph, hamcrestTargetNode); IjLibrary guavaLibrary = IjModuleGraphTest.getLibraryForTarget(moduleGraph, guavaTargetNode); IjModule baseModule = IjModuleGraphTest.getModuleForTarget(moduleGraph, baseTargetNode); IjModule baseTestModule = IjModuleGraphTest.getModuleForTarget(moduleGraph, baseTestsTargetNode); IjProjectTemplateDataPreparer dataPreparer = new IjProjectTemplateDataPreparer(javaPackageFinder, moduleGraph, filesystem); assertEquals( IjModuleGraphTest.getModuleForTarget(moduleGraph, baseInlineTestsTargetNode), IjModuleGraphTest.getModuleForTarget(moduleGraph, baseTargetNode)); DependencyEntryData.Builder dependencyEntryBuilder = DependencyEntryData.builder().setExported(false); assertThat( dataPreparer.getDependencies(baseModule), contains( allOf( hasProperty("type", equalTo(IjDependencyListBuilder.Type.LIBRARY)), hasProperty( "data", equalTo( Optional.of( dependencyEntryBuilder .setName(guavaLibrary.getName()) .setScope(IjDependencyListBuilder.Scope.COMPILE) .build())))), allOf( hasProperty("type", equalTo(IjDependencyListBuilder.Type.LIBRARY)), hasProperty( "data", equalTo( Optional.of( dependencyEntryBuilder .setName(hamcrestLibrary.getName()) .setScope(IjDependencyListBuilder.Scope.COMPILE) .build())))), allOf(hasProperty("type", equalTo(IjDependencyListBuilder.Type.SOURCE_FOLDER))), allOf( hasProperty("type", equalTo(IjDependencyListBuilder.Type.LIBRARY)), hasProperty( "data", equalTo( Optional.of( DependencyEntryData.builder() .setExported(true) .setName("library_java_com_example_base_tests") .setScope(IjDependencyListBuilder.Scope.PROVIDED) .build())))))); assertThat( dataPreparer.getDependencies(baseTestModule), contains( allOf( hasProperty("type", equalTo(IjDependencyListBuilder.Type.MODULE)), hasProperty( "data", equalTo( Optional.of( dependencyEntryBuilder .setName(baseModule.getName()) .setScope(IjDependencyListBuilder.Scope.TEST) .build())))), allOf( hasProperty("type", equalTo(IjDependencyListBuilder.Type.LIBRARY)), hasProperty( "data", equalTo( Optional.of( dependencyEntryBuilder .setName(hamcrestLibrary.getName()) .setScope(IjDependencyListBuilder.Scope.TEST) .build())))), allOf(hasProperty("type", equalTo(IjDependencyListBuilder.Type.SOURCE_FOLDER))))); }