From 2afc27a462504cf3ea240b4c5a1049339941938a Mon Sep 17 00:00:00 2001 From: Yan Zhulanow Date: Wed, 22 Feb 2017 05:12:25 +0300 Subject: [PATCH] Initial implementation of kapt for Maven (KT-14478) --- libraries/pom.xml | 1 + .../pom.xml | 178 ++++++++++++++++ .../kotlin/maven/K2JVMCompileMojo.java | 25 ++- .../kotlin/maven/KotlinTestCompileMojo.java | 11 + .../kapt/AnnotationProcessingManager.java | 191 ++++++++++++++++++ .../maven/kapt/KaptJVMCompilerMojo.java | 183 +++++++++++++++++ .../kotlin/maven/kapt/KaptOption.java | 48 +++++ .../maven/kapt/KaptTestJvmCompilerMojo.java | 90 +++++++++ 8 files changed, 723 insertions(+), 4 deletions(-) create mode 100755 libraries/tools/kotlin-annotation-processing-maven/pom.xml create mode 100644 libraries/tools/kotlin-maven-plugin/src/main/java/org/jetbrains/kotlin/maven/kapt/AnnotationProcessingManager.java create mode 100644 libraries/tools/kotlin-maven-plugin/src/main/java/org/jetbrains/kotlin/maven/kapt/KaptJVMCompilerMojo.java create mode 100644 libraries/tools/kotlin-maven-plugin/src/main/java/org/jetbrains/kotlin/maven/kapt/KaptOption.java create mode 100644 libraries/tools/kotlin-maven-plugin/src/main/java/org/jetbrains/kotlin/maven/kapt/KaptTestJvmCompilerMojo.java diff --git a/libraries/pom.xml b/libraries/pom.xml index ba346994c2e..a4ec559507f 100644 --- a/libraries/pom.xml +++ b/libraries/pom.xml @@ -105,6 +105,7 @@ tools/kotlin-js-tests tools/kotlin-js-tests-junit tools/kotlin-annotation-processing + tools/kotlin-annotation-processing-maven tools/kotlin-allopen tools/kotlin-maven-allopen tools/kotlin-noarg diff --git a/libraries/tools/kotlin-annotation-processing-maven/pom.xml b/libraries/tools/kotlin-annotation-processing-maven/pom.xml new file mode 100755 index 00000000000..c6977b95173 --- /dev/null +++ b/libraries/tools/kotlin-annotation-processing-maven/pom.xml @@ -0,0 +1,178 @@ + + + + 4.0.0 + + 3.0.4 + ${basedir}/../../../plugins/kapt3/src + ${basedir}/target/src/main/kotlin + ${basedir}/target/src/test/kotlin + ${basedir}/target/resource + + + + org.jetbrains.kotlin + kotlin-project + 1.1-SNAPSHOT + ../../pom.xml + + + kotlin-annotation-processing-maven + jar + + Annotation Processor wrapper for Kotlin Maven plugin + + + + jetbrains-utils + http://repository.jetbrains.com/utils + + + + + + org.jetbrains.kotlin + kotlin-stdlib + ${project.version} + + + org.jetbrains.kotlin + kotlin-compiler + ${project.version} + provided + + + org.jetbrains.kotlin + gradle-api + 1.6 + provided + + + com.android.tools.build + gradle + 1.1.0 + provided + + + + + ${annotation-processing.target-src} + ${annotation-processing.target-src-test} + + + ${annotation-processing.target-resource} + + + + + + maven-resources-plugin + 3.0.0 + + + copy-sources + validate + + copy-resources + + + ${annotation-processing.target-src} + + ${annotation-processing.src} + + + + + copy-resources + validate + + copy-resources + + + ${annotation-processing.target-resource}/META-INF + + ${annotation-processing.src}/META-INF + + + + + + + kotlin-maven-plugin + org.jetbrains.kotlin + ${project.version} + + ${env.JDK_18} + + ${basedir}/kotlinAnnotation + + + + + + compile + compile + compile + + + ${annotation-processing.target-src} + + + + + + test-compile + test-compile + test-compile + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.6 + 1.6 + + + + maven-failsafe-plugin + 2.6 + + + + integration-test + verify + + + + + + + + + + tools_jar_profile + + false + + kotlin-annotation-processing-maven-build.txt + + + + ${env.JDK_18}/lib/tools.jar + + + + com.sun + tools + 1.8.0 + system + ${toolsjar} + + + + + diff --git a/libraries/tools/kotlin-maven-plugin/src/main/java/org/jetbrains/kotlin/maven/K2JVMCompileMojo.java b/libraries/tools/kotlin-maven-plugin/src/main/java/org/jetbrains/kotlin/maven/K2JVMCompileMojo.java index a96681fbca6..7d9cdde02c9 100644 --- a/libraries/tools/kotlin-maven-plugin/src/main/java/org/jetbrains/kotlin/maven/K2JVMCompileMojo.java +++ b/libraries/tools/kotlin-maven-plugin/src/main/java/org/jetbrains/kotlin/maven/K2JVMCompileMojo.java @@ -17,16 +17,15 @@ package org.jetbrains.kotlin.maven; import org.apache.maven.plugin.MojoExecutionException; -import org.apache.maven.plugins.annotations.LifecyclePhase; -import org.apache.maven.plugins.annotations.Mojo; -import org.apache.maven.plugins.annotations.Parameter; -import org.apache.maven.plugins.annotations.ResolutionScope; +import org.apache.maven.plugins.annotations.*; import org.apache.maven.project.MavenProject; import org.jetbrains.annotations.NotNull; import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments; import org.jetbrains.kotlin.cli.jvm.K2JVMCompiler; +import org.jetbrains.kotlin.maven.kapt.AnnotationProcessingManager; import java.io.File; +import java.util.ArrayList; import java.util.List; import static com.intellij.openapi.util.text.StringUtil.join; @@ -83,6 +82,24 @@ public class K2JVMCompileMojo extends KotlinCompileMojoBase getSourceFilePaths() { + List paths = super.getSourceFilePaths(); + + File sourcesDir = AnnotationProcessingManager.getGeneratedSourcesDirectory(project, getSourceSetName()); + if (sourcesDir.isDirectory()) { + paths = new ArrayList(paths); + paths.add(sourcesDir.getAbsolutePath()); + } + + return paths; + } + + @NotNull + protected String getSourceSetName() { + return AnnotationProcessingManager.COMPILE_SOURCE_SET_NAME; + } + @Override protected void configureSpecificCompilerArguments(@NotNull K2JVMCompilerArguments arguments) throws MojoExecutionException { arguments.destination = output; diff --git a/libraries/tools/kotlin-maven-plugin/src/main/java/org/jetbrains/kotlin/maven/KotlinTestCompileMojo.java b/libraries/tools/kotlin-maven-plugin/src/main/java/org/jetbrains/kotlin/maven/KotlinTestCompileMojo.java index 1d6cab86764..692e87d9be0 100644 --- a/libraries/tools/kotlin-maven-plugin/src/main/java/org/jetbrains/kotlin/maven/KotlinTestCompileMojo.java +++ b/libraries/tools/kotlin-maven-plugin/src/main/java/org/jetbrains/kotlin/maven/KotlinTestCompileMojo.java @@ -25,6 +25,8 @@ import org.apache.maven.plugins.annotations.ResolutionScope; import org.apache.maven.project.MavenProject; import org.jetbrains.annotations.NotNull; import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments; +import org.jetbrains.kotlin.maven.kapt.AnnotationProcessingManager; +import org.jetbrains.kotlin.maven.kapt.KaptTestJvmCompilerMojo; import java.util.List; @@ -33,6 +35,10 @@ import java.util.List; * * @noinspection UnusedDeclaration */ + +/** Note! + * Please change {@link KaptTestJvmCompilerMojo} as well as it was majorly copied from this file. */ + @Mojo(name = "test-compile", defaultPhase = LifecyclePhase.TEST_COMPILE, requiresDependencyResolution = ResolutionScope.TEST @@ -95,4 +101,9 @@ public class KotlinTestCompileMojo extends K2JVMCompileMojo { protected List getRelatedSourceRoots(MavenProject project) { return project.getTestCompileSourceRoots(); } + + @NotNull + protected String getSourceSetName() { + return AnnotationProcessingManager.TEST_SOURCE_SET_NAME; + } } diff --git a/libraries/tools/kotlin-maven-plugin/src/main/java/org/jetbrains/kotlin/maven/kapt/AnnotationProcessingManager.java b/libraries/tools/kotlin-maven-plugin/src/main/java/org/jetbrains/kotlin/maven/kapt/AnnotationProcessingManager.java new file mode 100644 index 00000000000..d2ea8728d41 --- /dev/null +++ b/libraries/tools/kotlin-maven-plugin/src/main/java/org/jetbrains/kotlin/maven/kapt/AnnotationProcessingManager.java @@ -0,0 +1,191 @@ +package org.jetbrains.kotlin.maven.kapt; + +import org.apache.maven.artifact.Artifact; +import org.apache.maven.artifact.DefaultArtifact; +import org.apache.maven.artifact.handler.ArtifactHandler; +import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager; +import org.apache.maven.artifact.resolver.ArtifactResolutionRequest; +import org.apache.maven.artifact.resolver.ArtifactResolutionResult; +import org.apache.maven.artifact.resolver.ResolutionErrorHandler; +import org.apache.maven.artifact.versioning.VersionRange; +import org.apache.maven.execution.MavenSession; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.compiler.DependencyCoordinate; +import org.apache.maven.project.MavenProject; +import org.apache.maven.repository.RepositorySystem; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.util.*; + +public class AnnotationProcessingManager { + private final ArtifactHandlerManager artifactHandlerManager; + private final MavenSession session; + private final MavenProject project; + private final RepositorySystem repositorySystem; + private final ResolutionErrorHandler resolutionErrorHandler; + + AnnotationProcessingManager(@NotNull ArtifactHandlerManager artifactHandlerManager, + @NotNull MavenSession session, + @NotNull MavenProject project, + @NotNull RepositorySystem repositorySystem, + @NotNull ResolutionErrorHandler resolutionErrorHandler) { + this.artifactHandlerManager = artifactHandlerManager; + this.session = session; + this.project = project; + this.repositorySystem = repositorySystem; + this.resolutionErrorHandler = resolutionErrorHandler; + } + + private final static DependencyCoordinate KAPT_DEPENDENCY = new DependencyCoordinate(); + + public final static String COMPILE_SOURCE_SET_NAME = "compile"; + public final static String TEST_SOURCE_SET_NAME = "test"; + + static { + KAPT_DEPENDENCY.setGroupId("org.jetbrains.kotlin"); + KAPT_DEPENDENCY.setArtifactId("kotlin-annotation-processing-maven"); + try { + KAPT_DEPENDENCY.setVersion(getMavenPluginVersion()); + } + catch (MojoExecutionException e) { + throw new RuntimeException(e); + } + } + + @NotNull + public static File getGeneratedSourcesDirectory(@NotNull MavenProject project, @NotNull String sourceSetName) { + return new File(getTargetDirectory(project), "generated-sources/kapt/" + sourceSetName); + } + + @NotNull + static File getStubsDirectory(@NotNull MavenProject project, @NotNull String sourceSetName) { + return new File(getTargetDirectory(project), "kaptStubs/" + sourceSetName); + } + + @NotNull + static File getGeneratedClassesDirectory(@NotNull MavenProject project, @NotNull String sourceSetName) { + if (sourceSetName.equals(COMPILE_SOURCE_SET_NAME)) { + return new File(project.getModel().getBuild().getOutputDirectory()); + } + else if (sourceSetName.equals(TEST_SOURCE_SET_NAME)) { + return new File(project.getModel().getBuild().getTestOutputDirectory()); + } + else { + throw new IllegalArgumentException("'" + COMPILE_SOURCE_SET_NAME + "' or '" + + TEST_SOURCE_SET_NAME + "' expected"); + } + } + + @NotNull + private static File getTargetDirectory(@NotNull MavenProject project) { + return new File(project.getModel().getBuild().getDirectory()); + } + + @NotNull + ResolvedArtifacts resolveAnnotationProcessors(@Nullable List aptDependencies) throws Exception { + if (aptDependencies == null) { + aptDependencies = Collections.emptyList(); + } + + Set requiredArtifacts = new LinkedHashSet(); + + requiredArtifacts.add(getArtifact(artifactHandlerManager, KAPT_DEPENDENCY)); + + for (DependencyCoordinate dependency : aptDependencies) { + requiredArtifacts.add(getArtifact(artifactHandlerManager, dependency)); + } + + ArtifactResolutionRequest request = new ArtifactResolutionRequest() + .setArtifact(requiredArtifacts.iterator().next()) + .setResolveRoot(true) + .setResolveTransitively(true) + .setArtifactDependencies(requiredArtifacts) + .setLocalRepository(session.getLocalRepository()) + .setRemoteRepositories(project.getRemoteArtifactRepositories()); + + ArtifactResolutionResult resolutionResult = repositorySystem.resolve(request); + resolutionErrorHandler.throwErrors(request, resolutionResult); + + if (resolutionResult == null || resolutionResult.getArtifacts() == null) { + throw new IllegalStateException("Annotation processing artifacts were not resolved."); + } + + List apClasspath = new ArrayList(resolutionResult.getArtifacts().size()); + String kaptCompilerPluginArtifact = null; + + for (Artifact artifact : resolutionResult.getArtifacts()) { + if (artifact == null) { + continue; + } + + if (artifact.getGroupId().equals(KAPT_DEPENDENCY.getGroupId()) + && artifact.getArtifactId().equals(KAPT_DEPENDENCY.getArtifactId())) { + kaptCompilerPluginArtifact = artifact.getFile().getAbsolutePath(); + } + else { + apClasspath.add(artifact.getFile().getAbsolutePath()); + } + } + + if (kaptCompilerPluginArtifact == null) { + throw new IllegalStateException("Kapt compiler plugin artifact was not resolved."); + } + + return new ResolvedArtifacts(apClasspath, kaptCompilerPluginArtifact); + } + + @NotNull + private Artifact getArtifact( + @NotNull ArtifactHandlerManager artifactHandlerManager, + @NotNull DependencyCoordinate dependency) throws Exception { + ArtifactHandler handler = artifactHandlerManager.getArtifactHandler(dependency.getType()); + + return new DefaultArtifact( + dependency.getGroupId(), + dependency.getArtifactId(), + VersionRange.createFromVersionSpec(dependency.getVersion()), + Artifact.SCOPE_RUNTIME, + dependency.getType(), + dependency.getClassifier(), + handler, + false); + } + + @NotNull + private static String getMavenPluginVersion() throws MojoExecutionException { + ClassLoader classLoader = AnnotationProcessingManager.class.getClassLoader(); + InputStream pomPropertiesIs = classLoader.getResourceAsStream( + "META-INF/maven/org.jetbrains.kotlin/kotlin-maven-plugin/pom.properties"); + if (pomPropertiesIs == null) { + throw new MojoExecutionException("Can't resolve the version of kotlin-maven-plugin"); + } + + Properties properties = new Properties(); + try { + properties.load(pomPropertiesIs); + } + catch (IOException e) { + throw new MojoExecutionException("Error while reading kotlin-maven-plugin/pom.properties", e); + } + + return properties.getProperty("version"); + } + + class ResolvedArtifacts { + @NotNull + final List annotationProcessingClasspath; + + @NotNull + final String kaptCompilerPluginArtifact; + + ResolvedArtifacts(@NotNull List annotationProcessingClasspath, + @NotNull String kaptCompilerPluginArtifact) { + this.annotationProcessingClasspath = annotationProcessingClasspath; + this.kaptCompilerPluginArtifact = kaptCompilerPluginArtifact; + } + } +} diff --git a/libraries/tools/kotlin-maven-plugin/src/main/java/org/jetbrains/kotlin/maven/kapt/KaptJVMCompilerMojo.java b/libraries/tools/kotlin-maven-plugin/src/main/java/org/jetbrains/kotlin/maven/kapt/KaptJVMCompilerMojo.java new file mode 100644 index 00000000000..cc477ac1e4d --- /dev/null +++ b/libraries/tools/kotlin-maven-plugin/src/main/java/org/jetbrains/kotlin/maven/kapt/KaptJVMCompilerMojo.java @@ -0,0 +1,183 @@ +package org.jetbrains.kotlin.maven.kapt; + +import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager; +import org.apache.maven.artifact.resolver.ResolutionErrorHandler; +import org.apache.maven.execution.MavenSession; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.compiler.DependencyCoordinate; +import org.apache.maven.plugins.annotations.*; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments; +import org.jetbrains.kotlin.maven.K2JVMCompileMojo; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +import static org.jetbrains.kotlin.maven.kapt.AnnotationProcessingManager.getGeneratedClassesDirectory; +import static org.jetbrains.kotlin.maven.kapt.AnnotationProcessingManager.getGeneratedSourcesDirectory; +import static org.jetbrains.kotlin.maven.kapt.AnnotationProcessingManager.getStubsDirectory; + +/** @noinspection UnusedDeclaration */ +@Mojo(name = "kapt", defaultPhase = LifecyclePhase.PROCESS_SOURCES, requiresDependencyResolution = ResolutionScope.COMPILE) +public class KaptJVMCompilerMojo extends K2JVMCompileMojo { + @Parameter + private String[] annotationProcessors; + + @Parameter + private List annotationProcessorPaths; + + @Parameter + private boolean useLightAnalysis = true; + + @Parameter + private boolean correctErrorTypes = false; + + // Components for AnnotationProcessingManager + + @Component + private ArtifactHandlerManager artifactHandlerManager; + + @Parameter( defaultValue = "${session}", readonly = true, required = true ) + private MavenSession session; + + @Component + private ResolutionErrorHandler resolutionErrorHandler; + + private AnnotationProcessingManager cachedAnnotationProcessingManager; + + private AnnotationProcessingManager getAnnotationProcessingManager() { + if (cachedAnnotationProcessingManager != null) { + return cachedAnnotationProcessingManager; + } + + cachedAnnotationProcessingManager = new AnnotationProcessingManager( + artifactHandlerManager, session, project, system, resolutionErrorHandler); + return cachedAnnotationProcessingManager; + } + + @NotNull + private List getKaptOptions( + @NotNull K2JVMCompilerArguments arguments, + @NotNull AnnotationProcessingManager.ResolvedArtifacts resolvedArtifacts + ) { + List options = new ArrayList(); + + options.add(new KaptOption("aptOnly", true)); + options.add(new KaptOption("useLightAnalysis", useLightAnalysis)); + options.add(new KaptOption("correctErrorTypes", correctErrorTypes)); + options.add(new KaptOption("processors", annotationProcessors)); + + if (arguments.verbose) { + options.add(new KaptOption("verbose", true)); + } + + for (String entry : resolvedArtifacts.annotationProcessingClasspath) { + options.add(new KaptOption("apclasspath", entry)); + } + + String sourceSetName = getSourceSetName(); + File sourcesDirectory = getGeneratedSourcesDirectory(project, sourceSetName); + File classesDirectory = getGeneratedClassesDirectory(project, sourceSetName); + File stubsDirectory = getStubsDirectory(project, sourceSetName); + + addKaptSourcesDirectory(sourcesDirectory.getPath()); + + mkdirsSafe(sourcesDirectory); + mkdirsSafe(classesDirectory); + mkdirsSafe(stubsDirectory); + + options.add(new KaptOption("sources", sourcesDirectory.getAbsolutePath())); + options.add(new KaptOption("classes", classesDirectory.getAbsolutePath())); + options.add(new KaptOption("stubs", stubsDirectory.getAbsolutePath())); + + return options; + } + + protected void addKaptSourcesDirectory(@NotNull String path) { + project.addCompileSourceRoot(path); + } + + private void mkdirsSafe(@NotNull File directory) { + if (!directory.mkdirs()) { + getLog().warn("Unable to create directory " + directory); + } + } + + @Override + protected void configureSpecificCompilerArguments(@NotNull K2JVMCompilerArguments arguments) throws MojoExecutionException { + super.configureSpecificCompilerArguments(arguments); + + AnnotationProcessingManager.ResolvedArtifacts resolvedArtifacts; + + try { + resolvedArtifacts = getAnnotationProcessingManager().resolveAnnotationProcessors(annotationProcessorPaths); + } + catch (Exception e) { + throw new MojoExecutionException("Error while processing kapt options", e); + } + + String[] kaptOptions = renderKaptOptions(getKaptOptions(arguments, resolvedArtifacts)); + arguments.pluginOptions = joinArrays(arguments.pluginOptions, kaptOptions); + + String jdkToolsJarPath = getJdkToolsJarPath(); + arguments.pluginClasspaths = joinArrays(arguments.pluginClasspaths, + (jdkToolsJarPath == null) + ? new String[] { resolvedArtifacts.kaptCompilerPluginArtifact } + : new String[] { jdkToolsJarPath, resolvedArtifacts.kaptCompilerPluginArtifact }); + } + + @Nullable + private String getJdkToolsJarPath() { + String javaHomePath = System.getProperty("java.home"); + if (javaHomePath == null || javaHomePath.isEmpty()) { + getLog().warn("Can't determine Java home, 'java.home' property does not exist"); + return null; + } + File javaHome = new File(javaHomePath); + File toolsJar = new File(javaHome, "lib/tools.jar"); + if (toolsJar.exists()) { + return toolsJar.getAbsolutePath(); + } + + // We might be inside jre. + if (javaHome.getName().equals("jre")) { + toolsJar = new File(javaHome.getParent(), "lib/tools.jar"); + if (toolsJar.exists()) { + return toolsJar.getAbsolutePath(); + } + } + + getLog().debug(toolsJar.getAbsolutePath() + " does not exist"); + getLog().warn("'tools.jar' was not found, kapt may work unreliably"); + return null; + } + + @NotNull + private String[] renderKaptOptions(@NotNull List options) { + String[] result = new String[options.size()]; + int i = 0; + for (KaptOption option : options) { + result[i++] = option.toString(); + } + return result; + } + + @NotNull + private String[] joinArrays(@Nullable String[] first, @Nullable String[] second) { + if (first == null) { + first = new String[0]; + } + if (second == null) { + second = new String[0]; + } + + String[] result = new String[first.length + second.length]; + + System.arraycopy(first, 0, result, 0, first.length); + System.arraycopy(second, 0, result, first.length, second.length); + + return result; + } +} \ No newline at end of file diff --git a/libraries/tools/kotlin-maven-plugin/src/main/java/org/jetbrains/kotlin/maven/kapt/KaptOption.java b/libraries/tools/kotlin-maven-plugin/src/main/java/org/jetbrains/kotlin/maven/kapt/KaptOption.java new file mode 100644 index 00000000000..8941e578998 --- /dev/null +++ b/libraries/tools/kotlin-maven-plugin/src/main/java/org/jetbrains/kotlin/maven/kapt/KaptOption.java @@ -0,0 +1,48 @@ +package org.jetbrains.kotlin.maven.kapt; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +class KaptOption { + @NotNull + private final String key; + + @NotNull + private final String value; + + KaptOption(@NotNull String key, boolean value) { + this(key, String.valueOf(value)); + } + + KaptOption(@NotNull String key, @Nullable String[] value) { + this(key, renderStringArray(value)); + } + + KaptOption(@NotNull String key, @Nullable String value) { + this.key = key; + this.value = String.valueOf(value); + } + + @NotNull + private static String renderStringArray(@Nullable String[] arr) { + if (arr == null) { + return ""; + } + + StringBuilder sb = new StringBuilder(); + + for (String s : arr) { + if (sb.length() > 0) { + sb.append(','); + } + sb.append(s); + } + + return sb.toString(); + } + + @Override + public String toString() { + return "plugin:org.jetbrains.kotlin.kapt3:" + key + "=" + value; + } +} diff --git a/libraries/tools/kotlin-maven-plugin/src/main/java/org/jetbrains/kotlin/maven/kapt/KaptTestJvmCompilerMojo.java b/libraries/tools/kotlin-maven-plugin/src/main/java/org/jetbrains/kotlin/maven/kapt/KaptTestJvmCompilerMojo.java new file mode 100644 index 00000000000..13eb61255d6 --- /dev/null +++ b/libraries/tools/kotlin-maven-plugin/src/main/java/org/jetbrains/kotlin/maven/kapt/KaptTestJvmCompilerMojo.java @@ -0,0 +1,90 @@ +package org.jetbrains.kotlin.maven.kapt; + +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.MojoFailureException; +import org.apache.maven.plugins.annotations.LifecyclePhase; +import org.apache.maven.plugins.annotations.Mojo; +import org.apache.maven.plugins.annotations.Parameter; +import org.apache.maven.plugins.annotations.ResolutionScope; +import org.apache.maven.project.MavenProject; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments; + +import java.util.List; + +/** Note! This file was majorly copied from {@link org.jetbrains.kotlin.maven.KotlinTestCompileMojo}. + * Please change the original file if you make changes to {@link KaptTestJvmCompilerMojo}. + * + * @noinspection UnusedDeclaration + */ +@Mojo(name = "test-kapt", defaultPhase = LifecyclePhase.PROCESS_TEST_SOURCES, requiresDependencyResolution = ResolutionScope.TEST) +public class KaptTestJvmCompilerMojo extends KaptJVMCompilerMojo { + /** + * Flag to allow test compilation to be skipped. + */ + @Parameter(property = "maven.test.skip", defaultValue = "false") + private boolean skip; + + // TODO it would be nice to avoid using 2 injected fields for sources + // but I've not figured out how to have a defaulted parameter value + // which is also customisable inside an in a maven pom.xml + // so for now lets just use 2 fields + + /** + * The default source directories containing the sources to be compiled. + */ + @Parameter(defaultValue = "${project.testCompileSourceRoots}", required = true) + private List defaultSourceDirs; + + /** + * The source directories containing the sources to be compiled. + */ + @Parameter + private List sourceDirs; + + @Override + public List getSourceFilePaths() { + if (sourceDirs != null && !sourceDirs.isEmpty()) return sourceDirs; + return defaultSourceDirs; + } + + /** + * The source directories containing the sources to be compiled for tests. + */ + @Parameter(defaultValue = "${project.testCompileSourceRoots}", required = true, readonly = true) + private List defaultSourceDir; + + @Override + public void execute() throws MojoExecutionException, MojoFailureException { + if (skip) { + getLog().info("Test compilation is skipped"); + } else { + super.execute(); + } + } + + @Override + protected void configureSpecificCompilerArguments(@NotNull K2JVMCompilerArguments arguments) throws MojoExecutionException { + module = testModule; + classpath = testClasspath; + arguments.friendPaths = new String[] { output }; + output = testOutput; + super.configureSpecificCompilerArguments(arguments); + } + + @Override + protected List getRelatedSourceRoots(MavenProject project) { + return project.getTestCompileSourceRoots(); + } + + @NotNull + @Override + protected String getSourceSetName() { + return AnnotationProcessingManager.TEST_SOURCE_SET_NAME; + } + + @Override + protected void addKaptSourcesDirectory(@NotNull String path) { + project.addTestCompileSourceRoot(path); + } +} \ No newline at end of file