public int createIntellijProject( File jsonTempFile, ProcessExecutor processExecutor, boolean generateMinimalProject, PrintStream stdOut, PrintStream stdErr) throws IOException { List<Module> modules = createModulesForProjectConfigs(); writeJsonConfig(jsonTempFile, modules); List<String> modifiedFiles = Lists.newArrayList(); // Process the JSON config to generate the .xml and .iml files for IntelliJ. ExitCodeAndOutput result = processJsonConfig(jsonTempFile, generateMinimalProject); if (result.exitCode != 0) { return result.exitCode; } else { // intellij.py writes the list of modified files to stdout, so parse stdout and add the // resulting file paths to the modifiedFiles list. Iterable<String> paths = Splitter.on('\n').trimResults().omitEmptyStrings().split(result.stdOut); Iterables.addAll(modifiedFiles, paths); } // Write out the project.properties files. List<String> modifiedPropertiesFiles = generateProjectDotPropertiesFiles(modules); modifiedFiles.addAll(modifiedPropertiesFiles); // Write out the .idea/compiler.xml file (the .idea/ directory is guaranteed to exist). CompilerXml compilerXml = new CompilerXml(modules); final String pathToCompilerXml = ".idea/compiler.xml"; File compilerXmlFile = projectFilesystem.getFileForRelativePath(pathToCompilerXml); if (compilerXml.write(compilerXmlFile)) { modifiedFiles.add(pathToCompilerXml); } // If the user specified a post-processing script, then run it. if (pathToPostProcessScript.isPresent()) { String pathToScript = pathToPostProcessScript.get(); Process process = Runtime.getRuntime().exec(new String[] {pathToScript}); ProcessExecutor.Result postProcessResult = processExecutor.execute(process); int postProcessExitCode = postProcessResult.getExitCode(); if (postProcessExitCode != 0) { return postProcessExitCode; } } // If any files have been modified by `buck project`, then list them for the user. if (!modifiedFiles.isEmpty()) { SortedSet<String> modifiedFilesInSortedForder = Sets.newTreeSet(modifiedFiles); stdOut.printf("MODIFIED FILES:\n%s\n", Joiner.on('\n').join(modifiedFilesInSortedForder)); } // Blit stderr from intellij.py to parent stderr. stdErr.print(result.stdErr); return 0; }
/** * If the source paths specified contains one source path to a non-generated file then we should * return the correct source tmp corresponding to that non-generated source path. Especially when * the generated file comes first in the ordered set. */ @Test public void testMixedSourceFile() { String pathToGenFile = (GEN_DIR + "/com/facebook/GeneratedFile.java"); String pathToNonGenFile1 = ("package/src/SourceFile1.java"); String pathToNonGenFile2 = ("package/src-gen/SourceFile2.java"); ImmutableSortedSet<String> javaSrcs = ImmutableSortedSet.of(pathToGenFile, pathToNonGenFile1, pathToNonGenFile2); File parentFile1 = createMock(File.class); expect(parentFile1.getName()).andReturn("src"); expect(parentFile1.getPath()).andReturn("package/src"); File sourceFile1 = createMock(File.class); expect(sourceFile1.getParentFile()).andReturn(parentFile1); File parentFile2 = createMock(File.class); expect(parentFile2.getName()).andReturn("src"); expect(parentFile2.getPath()).andReturn("package/src-gen"); File sourceFile2 = createMock(File.class); expect(sourceFile2.getParentFile()).andReturn(parentFile2); DefaultJavaPackageFinder defaultJavaPackageFinder = createMock(DefaultJavaPackageFinder.class); expect(defaultJavaPackageFinder.getPathsFromRoot()).andReturn(pathsFromRoot).times(2); expect(defaultJavaPackageFinder.getPathElements()).andReturn(pathElements).times(2); ProjectFilesystem projectFilesystem = createMock(ProjectFilesystem.class); expect(projectFilesystem.getFileForRelativePath(pathToNonGenFile1)).andReturn(sourceFile1); expect(projectFilesystem.getFileForRelativePath(pathToNonGenFile2)).andReturn(sourceFile2); JavaLibraryRule javaLibraryRule = new FakeJavaLibraryRule(new BuildTarget("//foo", "bar")).setJavaSrcs(javaSrcs); Object[] mocks = new Object[] { parentFile1, sourceFile1, parentFile2, sourceFile2, defaultJavaPackageFinder, projectFilesystem }; replay(mocks); ImmutableSet<String> result = TestCommand.getPathToSourceFolders( javaLibraryRule, Optional.of(defaultJavaPackageFinder), projectFilesystem); assertEquals( "The non-generated source files are under two different source folders.", ImmutableSet.of("package/src-gen/", "package/src/"), result); verify(mocks); }
/** * Finds the build file responsible for the given {@link Path} and invalidates all of the cached * rules dependent on it. * * @param path A {@link Path} "contained" within the build file to find and invalidate. */ private void invalidateContainingBuildFile(Path path) throws IOException { String packageBuildFilePath = buildFileTreeCache .getInput() .getBasePathOfAncestorTarget( projectFilesystem.getProjectRoot().toPath().relativize(path).toString()); invalidateDependents( projectFilesystem .getFileForRelativePath(packageBuildFilePath + '/' + BuckConstant.BUILD_RULES_FILE_NAME) .toPath()); }
/** * If the source paths specified are all for non-generated files then we should return the correct * source tmp corresponding to a non-generated source path. */ @Test public void testNonGeneratedSourceFile() { String pathToNonGenFile = "package/src/SourceFile1.java"; assertFalse(JavaTestRule.isGeneratedFile(pathToNonGenFile)); ImmutableSortedSet<String> javaSrcs = ImmutableSortedSet.of(pathToNonGenFile); JavaLibraryRule javaLibraryRule = new FakeJavaLibraryRule(new BuildTarget("//foo", "bar")).setJavaSrcs(javaSrcs); File parentFile = createMock(File.class); expect(parentFile.getName()).andReturn("src"); expect(parentFile.getPath()).andReturn("package/src"); File sourceFile = createMock(File.class); expect(sourceFile.getParentFile()).andReturn(parentFile); DefaultJavaPackageFinder defaultJavaPackageFinder = createMock(DefaultJavaPackageFinder.class); expect(defaultJavaPackageFinder.getPathsFromRoot()).andReturn(pathsFromRoot); expect(defaultJavaPackageFinder.getPathElements()).andReturn(pathElements); ProjectFilesystem projectFilesystem = createMock(ProjectFilesystem.class); expect(projectFilesystem.getFileForRelativePath(pathToNonGenFile)).andReturn(sourceFile); Object[] mocks = new Object[] {parentFile, sourceFile, defaultJavaPackageFinder, projectFilesystem}; replay(mocks); ImmutableSet<String> result = TestCommand.getPathToSourceFolders( javaLibraryRule, Optional.of(defaultJavaPackageFinder), projectFilesystem); assertEquals( "All non-generated source files are under one source tmp.", ImmutableSet.of("package/src/"), result); verify(mocks); }
public int createIntellijProject(File jsonTempFile, PrintStream stdOut) throws IOException { List<Module> modules = createModulesForProjectConfigs(); writeJsonConfig(jsonTempFile, modules); List<String> modifiedFiles = Lists.newArrayList(); // Process the JSON config to generate the .xml and .iml files for IntelliJ. ExitCodeAndStdOut result = processJsonConfig(jsonTempFile); if (result.exitCode != 0) { return result.exitCode; } else { // intellij.py writes the list of modified files to stdout, so parse stdout and add the // resulting file paths to the modifiedFiles list. Iterable<String> paths = Splitter.on('\n').trimResults().omitEmptyStrings().split(result.stdOut); Iterables.addAll(modifiedFiles, paths); } // Write out the project.properties files. List<String> modifiedPropertiesFiles = generateProjectDotPropertiesFiles(modules); modifiedFiles.addAll(modifiedPropertiesFiles); // Write out the .idea/compiler.xml file (the .idea/ directory is guaranteed to exist). CompilerXml compilerXml = new CompilerXml(modules); final String pathToCompilerXml = ".idea/compiler.xml"; File compilerXmlFile = projectFilesystem.getFileForRelativePath(pathToCompilerXml); if (compilerXml.write(compilerXmlFile)) { modifiedFiles.add(pathToCompilerXml); } // If any files have been modified by `buck project`, then list them for the user. if (!modifiedFiles.isEmpty()) { SortedSet<String> modifiedFilesInSortedForder = Sets.newTreeSet(modifiedFiles); stdOut.printf("MODIFIED FILES:\n%s\n", Joiner.on('\n').join(modifiedFilesInSortedForder)); } return 0; }