forked from mapstruct/mapstruct
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
mapstruct#1420 Add support for Gradle incremental annotation processi…
…ng (mapstruct#1971) * Add relevant file in META-INF * Add integration test with Gradle test kit dependencies * Test with Gradle 5 and Gradle 6
- Loading branch information
Showing
10 changed files
with
302 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
159 changes: 159 additions & 0 deletions
159
...grationtest/src/test/java/org/mapstruct/itest/tests/GradleIncrementalCompilationTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,159 @@ | ||
/* | ||
* Copyright MapStruct Authors. | ||
* | ||
* Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 | ||
*/ | ||
package org.mapstruct.itest.tests; | ||
|
||
import static org.gradle.testkit.runner.TaskOutcome.SUCCESS; | ||
import static org.gradle.testkit.runner.TaskOutcome.UP_TO_DATE; | ||
import static org.hamcrest.core.StringContains.containsString; | ||
import static org.junit.Assert.assertEquals; | ||
import static org.junit.Assert.assertThat; | ||
|
||
import java.io.File; | ||
import java.io.IOException; | ||
import java.nio.charset.Charset; | ||
import java.nio.file.Path; | ||
import java.nio.file.Paths; | ||
import java.util.ArrayList; | ||
import java.util.Arrays; | ||
import java.util.List; | ||
|
||
import org.apache.commons.io.FileUtils; | ||
import org.gradle.testkit.runner.BuildResult; | ||
import org.gradle.testkit.runner.GradleRunner; | ||
import org.gradle.testkit.runner.TaskOutcome; | ||
import org.junit.Before; | ||
import org.junit.BeforeClass; | ||
import org.junit.Rule; | ||
import org.junit.Test; | ||
import org.junit.rules.TemporaryFolder; | ||
import org.junit.runner.RunWith; | ||
import org.junit.runners.Parameterized; | ||
import org.junit.runners.Parameterized.Parameters; | ||
|
||
/** | ||
* <p>This is supposed to be run from the mapstruct root project folder. | ||
* Otherwise, use <code>-Dmapstruct_root=path_to_project</code>. | ||
*/ | ||
@RunWith( Parameterized.class ) | ||
public class GradleIncrementalCompilationTest { | ||
private static Path rootPath; | ||
private static String projectDir = "integrationtest/src/test/resources/gradleIncrementalCompilationTest"; | ||
private static String compileTaskName = "compileJava"; | ||
|
||
@Rule | ||
public final TemporaryFolder testBuildDir = new TemporaryFolder(); | ||
@Rule | ||
public final TemporaryFolder testProjectDir = new TemporaryFolder(); | ||
|
||
private String gradleVersion; | ||
private GradleRunner runner; | ||
private File sourceDirectory; | ||
private List<String> compileArgs; // Gradle compile task arguments | ||
|
||
public GradleIncrementalCompilationTest(String gradleVersion) { | ||
this.gradleVersion = gradleVersion; | ||
} | ||
|
||
@Parameters( name = "Gradle {0}" ) | ||
public static List<String> gradleVersions() { | ||
return Arrays.asList( "5.0", "6.0" ); | ||
} | ||
|
||
private void replaceInFile(File file, CharSequence target, CharSequence replacement) throws IOException { | ||
String content = FileUtils.readFileToString( file, Charset.defaultCharset() ); | ||
FileUtils.writeStringToFile( file, content.replace( target, replacement ), Charset.defaultCharset() ); | ||
} | ||
|
||
private GradleRunner getRunner(String... additionalArguments) { | ||
List<String> fullArguments = new ArrayList<String>( compileArgs ); | ||
fullArguments.addAll( Arrays.asList( additionalArguments ) ); | ||
return runner.withArguments( fullArguments ); | ||
} | ||
|
||
private void assertCompileOutcome(BuildResult result, TaskOutcome outcome) { | ||
assertEquals( outcome, result.task( ":" + compileTaskName ).getOutcome() ); | ||
} | ||
|
||
private void assertRecompiled(BuildResult result, int recompiledCount) { | ||
assertCompileOutcome( result, recompiledCount > 0 ? SUCCESS : UP_TO_DATE ); | ||
assertThat( | ||
result.getOutput(), | ||
containsString( String.format( "Incremental compilation of %d classes completed", recompiledCount ) ) ); | ||
} | ||
|
||
private List<String> buildCompileArgs() { | ||
// Make Gradle use the temporary build folder by overriding the buildDir property | ||
String buildDirPropertyArg = "-PbuildDir=" + testBuildDir.getRoot().getAbsolutePath(); | ||
|
||
// Inject the path to the folder containing the mapstruct-processor JAR | ||
String jarDirectoryArg = "-PmapstructRootPath=" + rootPath.toString(); | ||
return Arrays.asList( compileTaskName, buildDirPropertyArg, jarDirectoryArg ); | ||
} | ||
|
||
@BeforeClass | ||
public static void setupClass() throws Exception { | ||
rootPath = Paths.get( System.getProperty( "mapstruct_root", "." ) ).toAbsolutePath(); | ||
} | ||
|
||
@Before | ||
public void setup() throws IOException { | ||
// Copy test project files to the temp dir | ||
Path gradleProjectPath = rootPath.resolve( projectDir ); | ||
FileUtils.copyDirectory( gradleProjectPath.toFile(), testProjectDir.getRoot() ); | ||
compileArgs = buildCompileArgs(); | ||
sourceDirectory = new File( testProjectDir.getRoot(), "src/main/java" ); | ||
runner = GradleRunner.create().withGradleVersion( gradleVersion ).withProjectDir( testProjectDir.getRoot() ); | ||
} | ||
|
||
@Test | ||
public void testBuildSucceeds() throws IOException { | ||
// Make sure the test build setup actually compiles | ||
BuildResult buildResult = getRunner().build(); | ||
assertCompileOutcome( buildResult, SUCCESS ); | ||
} | ||
|
||
@Test | ||
public void testUpToDate() throws IOException { | ||
getRunner().build(); | ||
BuildResult secondBuildResult = getRunner().build(); | ||
assertCompileOutcome( secondBuildResult, UP_TO_DATE ); | ||
} | ||
|
||
@Test | ||
public void testChangeConstant() throws IOException { | ||
getRunner().build(); | ||
// Change return value in class Target | ||
File targetFile = new File( sourceDirectory, "org/mapstruct/itest/gradle/model/Target.java" ); | ||
replaceInFile( targetFile, "original", "changed" ); | ||
BuildResult secondBuildResult = getRunner( "--info" ).build(); | ||
|
||
// 3 classes should be recompiled: Target -> TestMapper -> TestMapperImpl | ||
assertRecompiled( secondBuildResult, 3 ); | ||
} | ||
|
||
@Test | ||
public void testChangeTargetField() throws IOException { | ||
getRunner().build(); | ||
// Change target field in mapper interface | ||
File mapperFile = new File( sourceDirectory, "org/mapstruct/itest/gradle/lib/TestMapper.java" ); | ||
replaceInFile( mapperFile, "field", "otherField" ); | ||
BuildResult secondBuildResult = getRunner( "--info" ).build(); | ||
|
||
// 2 classes should be recompiled: TestMapper -> TestMapperImpl | ||
assertRecompiled( secondBuildResult, 2 ); | ||
} | ||
|
||
@Test | ||
public void testChangeUnrelatedFile() throws IOException { | ||
getRunner().build(); | ||
File unrelatedFile = new File( sourceDirectory, "org/mapstruct/itest/gradle/lib/UnrelatedComponent.java" ); | ||
replaceInFile( unrelatedFile, "true", "false" ); | ||
BuildResult secondBuildResult = getRunner( "--info" ).build(); | ||
|
||
// Only the UnrelatedComponent class should be recompiled | ||
assertRecompiled( secondBuildResult, 1 ); | ||
} | ||
} |
29 changes: 29 additions & 0 deletions
29
integrationtest/src/test/resources/gradleIncrementalCompilationTest/build.gradle
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
plugins { | ||
id 'java' | ||
} | ||
|
||
if (!project.hasProperty('mapstructRootPath')) | ||
throw new IllegalArgumentException("Missing required property: mapstructRootPath") | ||
|
||
repositories { | ||
jcenter() | ||
mavenLocal() | ||
flatDir { | ||
dirs "${mapstructRootPath}/processor/target" | ||
dirs "${mapstructRootPath}/core/target" | ||
} | ||
} | ||
|
||
// Extract version and artifactId values | ||
def apPom = new XmlParser().parse(file("${mapstructRootPath}/processor/pom.xml")) | ||
ext.apArtifactId = apPom.artifactId[0].text() | ||
ext.apVersion = apPom.parent[0].version[0].text() | ||
|
||
def libPom = new XmlParser().parse(file("${mapstructRootPath}/core/pom.xml")) | ||
ext.libArtifactId = libPom.artifactId[0].text() | ||
ext.libVersion = libPom.parent[0].version[0].text() | ||
|
||
dependencies { | ||
annotationProcessor name: "${apArtifactId}-${apVersion}" | ||
implementation name: "${libArtifactId}-${libVersion}" | ||
} |
1 change: 1 addition & 0 deletions
1
integrationtest/src/test/resources/gradleIncrementalCompilationTest/settings.gradle
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
rootProject.name = 'gradle-incremental-compilation-test' |
19 changes: 19 additions & 0 deletions
19
...leIncrementalCompilationTest/src/main/java/org/mapstruct/itest/gradle/lib/TestMapper.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
/* | ||
* Copyright MapStruct Authors. | ||
* | ||
* Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 | ||
*/ | ||
package org.mapstruct.itest.gradle.lib; | ||
|
||
import org.mapstruct.Mapper; | ||
import org.mapstruct.Mapping; | ||
import org.mapstruct.ReportingPolicy; | ||
|
||
import org.mapstruct.itest.gradle.model.Target; | ||
import org.mapstruct.itest.gradle.model.Source; | ||
|
||
@Mapper(unmappedTargetPolicy = ReportingPolicy.IGNORE) | ||
public interface TestMapper { | ||
@Mapping(source = "value", target = "field") | ||
public Target toTarget(Source source); | ||
} |
12 changes: 12 additions & 0 deletions
12
...entalCompilationTest/src/main/java/org/mapstruct/itest/gradle/lib/UnrelatedComponent.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
/* | ||
* Copyright MapStruct Authors. | ||
* | ||
* Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 | ||
*/ | ||
package org.mapstruct.itest.gradle.lib; | ||
|
||
public class UnrelatedComponent { | ||
public boolean unrelatedMethod() { | ||
return true; | ||
} | ||
} |
18 changes: 18 additions & 0 deletions
18
...adleIncrementalCompilationTest/src/main/java/org/mapstruct/itest/gradle/model/Source.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
/* | ||
* Copyright MapStruct Authors. | ||
* | ||
* Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 | ||
*/ | ||
package org.mapstruct.itest.gradle.model; | ||
|
||
public class Source { | ||
private int value; | ||
|
||
public void setValue(int value) { | ||
this.value = value; | ||
} | ||
|
||
public int getValue() { | ||
return value; | ||
} | ||
} |
31 changes: 31 additions & 0 deletions
31
...adleIncrementalCompilationTest/src/main/java/org/mapstruct/itest/gradle/model/Target.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
/* | ||
* Copyright MapStruct Authors. | ||
* | ||
* Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 | ||
*/ | ||
package org.mapstruct.itest.gradle.model; | ||
|
||
public class Target { | ||
private String field = getDefaultValue(); | ||
private String otherField; | ||
|
||
public void setField(String field) { | ||
this.field = field; | ||
} | ||
|
||
public String getField() { | ||
return field; | ||
} | ||
|
||
public void setOtherField(String otherField) { | ||
this.otherField = otherField; | ||
} | ||
|
||
public String getOtherField() { | ||
return otherField; | ||
} | ||
|
||
public String getDefaultValue() { | ||
return "original"; | ||
} | ||
} |
1 change: 1 addition & 0 deletions
1
processor/src/main/resources/META-INF/gradle/incremental.annotation.processors
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
org.mapstruct.ap.MappingProcessor,isolating |