Skip to content
This repository was archived by the owner on Jun 30, 2025. It is now read-only.

Commit c85e3ac

Browse files
committed
Fix bugs in support for directory-based idea projects
Two issues have arisen in our support for directory based idea projects: * We regressed on issue #28, once again requiring the user import the 'idea' plugin * Issue #53: correctness depends on plugin ordering This PR fixes both by only updating compiler.xml after the project is evaluated, and using default values for sourceOutputDir/sourceTestOutputDir if the IDEA plugin has not been applied.
1 parent f0afed4 commit c85e3ac

File tree

2 files changed

+160
-11
lines changed

2 files changed

+160
-11
lines changed

src/main/groovy/org/inferred/gradle/ProcessorsPlugin.groovy

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -111,15 +111,17 @@ class ProcessorsPlugin implements Plugin<Project> {
111111
})
112112
})
113113

114-
// If the project uses .idea directory structure, update compiler.xml directly
115-
File ideaCompilerXml = project.file('.idea/compiler.xml')
116-
if (ideaCompilerXml.isFile()) {
117-
Node parsedProjectXml = (new XmlParser()).parse(ideaCompilerXml)
118-
updateIdeaCompilerConfiguration(project, parsedProjectXml)
119-
ideaCompilerXml.withWriter { writer ->
120-
XmlNodePrinter nodePrinter = new XmlNodePrinter(new PrintWriter(writer))
121-
nodePrinter.setPreserveWhitespace(true)
122-
nodePrinter.print(parsedProjectXml)
114+
project.afterEvaluate {
115+
// If the project uses .idea directory structure, update compiler.xml directly
116+
File ideaCompilerXml = project.file('.idea/compiler.xml')
117+
if (ideaCompilerXml.isFile()) {
118+
Node parsedProjectXml = (new XmlParser()).parse(ideaCompilerXml)
119+
updateIdeaCompilerConfiguration(project, parsedProjectXml)
120+
ideaCompilerXml.withWriter { writer ->
121+
XmlNodePrinter nodePrinter = new XmlNodePrinter(new PrintWriter(writer))
122+
nodePrinter.setPreserveWhitespace(true)
123+
nodePrinter.print(parsedProjectXml)
124+
}
123125
}
124126
}
125127

@@ -203,11 +205,18 @@ class ProcessorsPlugin implements Plugin<Project> {
203205
new Node(compilerConfiguration, "annotationProcessing")
204206
}
205207

208+
def outputDir = 'generated_src'
209+
def testOutputDir = 'generated_testSrc'
210+
if (project.hasProperty('idea')) {
211+
outputDir = project.idea.processors.outputDir
212+
testOutputDir = project.idea.processors.testOutputDir
213+
}
214+
206215
compilerConfiguration.annotationProcessing.replaceNode{
207216
annotationProcessing() {
208217
profile(default: 'true', name: 'Default', enabled: 'true') {
209-
sourceOutputDir(name: project.idea.processors.outputDir)
210-
sourceTestOutputDir(name: project.idea.processors.testOutputDir)
218+
sourceOutputDir(name: outputDir)
219+
sourceTestOutputDir(name: testOutputDir)
211220
outputRelativeToContentRoot(value: 'true')
212221
processorPath(useClasspath: 'true')
213222
}

src/test/groovy/org/inferred/gradle/ProcessorsPluginFunctionalTest.groovy

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -657,6 +657,54 @@ public class ProcessorsPluginFunctionalTest {
657657
assertEquals(expected, xml)
658658
}
659659

660+
@Test
661+
public void testUserSpecifiedDirectoriesUsedInIdeaCompilerXml() throws IOException {
662+
buildFile << """
663+
apply plugin: 'java'
664+
apply plugin: 'idea'
665+
apply plugin: 'org.inferred.processors'
666+
667+
idea.processors {
668+
outputDir = 'foo'
669+
testOutputDir = 'bar'
670+
}
671+
"""
672+
673+
new File(testProjectDir.newFolder('.idea'), 'compiler.xml') << """
674+
<?xml version="1.0" encoding="UTF-8"?>
675+
<project version="4">
676+
<component name="CompilerConfiguration">
677+
<annotationProcessing/>
678+
</component>
679+
</project>
680+
""".trim()
681+
682+
File testProjectDirRoot = testProjectDir.getRoot()
683+
GradleRunner.create()
684+
.withProjectDir(testProjectDirRoot)
685+
.withArguments("idea", "--stacktrace")
686+
.build()
687+
688+
def xml = testProjectDirRoot.toPath().resolve(".idea/compiler.xml").toFile().text.trim()
689+
690+
def expected = """
691+
<project version="4">
692+
<component name="CompilerConfiguration">
693+
<annotationProcessing>
694+
<profile default="true" name="Default" enabled="true">
695+
<sourceOutputDir name="foo"/>
696+
<sourceTestOutputDir name="bar"/>
697+
<outputRelativeToContentRoot value="true"/>
698+
<processorPath useClasspath="true"/>
699+
</profile>
700+
</annotationProcessing>
701+
</component>
702+
</project>
703+
""".stripIndent().trim()
704+
705+
assertEquals(expected, xml)
706+
}
707+
660708
@Test
661709
public void testOnlyApplyToSubProject() {
662710
testProjectDir.newFolder("projectA")
@@ -745,6 +793,98 @@ public class ProcessorsPluginFunctionalTest {
745793
assertAutoValueInFile(new File(runner.projectDir, ".factorypath"))
746794
}
747795

796+
/** @see https://github.com/palantir/gradle-processors/issues/28 */
797+
@Test
798+
public void testIdeaCompilerConfigurationUpdatedWithoutNeedToApplyIdeaPlugin() throws IOException {
799+
buildFile << """
800+
apply plugin: 'java'
801+
apply plugin: 'org.inferred.processors'
802+
"""
803+
804+
new File(testProjectDir.newFolder('.idea'), 'compiler.xml') << """
805+
<?xml version="1.0" encoding="UTF-8"?>
806+
<project version="4">
807+
<component name="CompilerConfiguration">
808+
<annotationProcessing/>
809+
</component>
810+
</project>
811+
""".trim()
812+
813+
File testProjectDirRoot = testProjectDir.getRoot()
814+
GradleRunner.create()
815+
.withProjectDir(testProjectDirRoot)
816+
.withArguments("tasks", "--stacktrace")
817+
.build()
818+
819+
def xml = testProjectDirRoot.toPath().resolve(".idea/compiler.xml").toFile().text.trim()
820+
821+
def expected = """
822+
<project version="4">
823+
<component name="CompilerConfiguration">
824+
<annotationProcessing>
825+
<profile default="true" name="Default" enabled="true">
826+
<sourceOutputDir name="generated_src"/>
827+
<sourceTestOutputDir name="generated_testSrc"/>
828+
<outputRelativeToContentRoot value="true"/>
829+
<processorPath useClasspath="true"/>
830+
</profile>
831+
</annotationProcessing>
832+
</component>
833+
</project>
834+
""".stripIndent().trim()
835+
836+
assertEquals(expected, xml)
837+
}
838+
839+
/** @see https://github.com/palantir/gradle-processors/issues/53 */
840+
@Test
841+
public void testCompilerXmlModificationWhenIdeaPluginImportedLast() throws IOException {
842+
buildFile << """
843+
apply plugin: 'java'
844+
apply plugin: 'org.inferred.processors'
845+
apply plugin: 'idea'
846+
847+
idea.processors {
848+
outputDir = 'foo'
849+
testOutputDir = 'bar'
850+
}
851+
"""
852+
853+
new File(testProjectDir.newFolder('.idea'), 'compiler.xml') << """
854+
<?xml version="1.0" encoding="UTF-8"?>
855+
<project version="4">
856+
<component name="CompilerConfiguration">
857+
<annotationProcessing/>
858+
</component>
859+
</project>
860+
""".trim()
861+
862+
File testProjectDirRoot = testProjectDir.getRoot()
863+
GradleRunner.create()
864+
.withProjectDir(testProjectDirRoot)
865+
.withArguments("idea", "--stacktrace")
866+
.build()
867+
868+
def xml = testProjectDirRoot.toPath().resolve(".idea/compiler.xml").toFile().text.trim()
869+
870+
def expected = """
871+
<project version="4">
872+
<component name="CompilerConfiguration">
873+
<annotationProcessing>
874+
<profile default="true" name="Default" enabled="true">
875+
<sourceOutputDir name="foo"/>
876+
<sourceTestOutputDir name="bar"/>
877+
<outputRelativeToContentRoot value="true"/>
878+
<processorPath useClasspath="true"/>
879+
</profile>
880+
</annotationProcessing>
881+
</component>
882+
</project>
883+
""".stripIndent().trim()
884+
885+
assertEquals(expected, xml)
886+
}
887+
748888
private void assertAutoValueInFile(File file) {
749889
if (!file.any { it.contains("auto-value-1.0.jar") }) {
750890
println "====== $file.name ============================================================"

0 commit comments

Comments
 (0)