diff --git a/README.md b/README.md index dee42c9..e6ba230 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,13 @@
-
-
-
+
+
+
-
-
-
-
+
+
+
+
@@ -39,6 +39,7 @@ The plugin automatically:
- Adds MapStruct dependencies (`mapstruct` and `mapstruct-processor`)
- Detects optional dependencies (Lombok, Spring, Camel, Quarkus, Protobuf) in your project
- Adds required binding libraries when needed (e.g., `lombok-mapstruct-binding` for Lombok)
+- Detects Kotlin and automatically applies `kapt` plugin with proper configuration
- Configures compiler arguments based on your `mapstruct {}` block settings
- Runs after project evaluation to ensure all dependencies are resolved
diff --git a/build.gradle b/build.gradle
index f372f29..08d5fc5 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,8 +1,8 @@
plugins {
+ id 'com.vanniktech.maven.publish' version '0.37.0'
id 'com.gradle.plugin-publish' version '2.1.1'
id 'io.freefair.lombok' version '9.5.0'
id 'org.sonarqube' version '7.3.1.8318'
- id 'com.vanniktech.maven.publish' version '0.37.0'
id 'java-gradle-plugin'
id 'jacoco'
}
@@ -40,6 +40,8 @@ dependencies {
testImplementation 'org.springframework.boot:org.springframework.boot.gradle.plugin:4.1.0'
// id 'com.google.protobuf' version '0.10.0'
testImplementation 'com.google.protobuf:com.google.protobuf.gradle.plugin:0.10.0'
+ // id 'org.jetbrains.kotlin.jvm' version '2.0.21'
+ testImplementation 'org.jetbrains.kotlin:kotlin-gradle-plugin:2.0.21'
testImplementation 'org.assertj:assertj-core:3.27.7'
testImplementation 'org.junit.jupiter:junit-jupiter:6.1.2'
diff --git a/src/main/java/io/github/akazver/gradle/plugins/mapstruct/MapstructPlugin.java b/src/main/java/io/github/akazver/gradle/plugins/mapstruct/MapstructPlugin.java
index ba13c77..83a0f2a 100644
--- a/src/main/java/io/github/akazver/gradle/plugins/mapstruct/MapstructPlugin.java
+++ b/src/main/java/io/github/akazver/gradle/plugins/mapstruct/MapstructPlugin.java
@@ -21,8 +21,7 @@ public void apply(@NotNull Project project) {
project.getExtensions().create("mapstruct", MapstructExtension.class);
project.afterEvaluate(it -> {
- dependencyManager.addRequiredDependencies();
- dependencyManager.addOptionalDependencies();
+ dependencyManager.addDependencies();
compilerArgsManager.addCompilerArgs();
});
}
diff --git a/src/main/java/io/github/akazver/gradle/plugins/mapstruct/manager/DependencyManager.java b/src/main/java/io/github/akazver/gradle/plugins/mapstruct/manager/DependencyManager.java
index d3439a1..f6d77b3 100644
--- a/src/main/java/io/github/akazver/gradle/plugins/mapstruct/manager/DependencyManager.java
+++ b/src/main/java/io/github/akazver/gradle/plugins/mapstruct/manager/DependencyManager.java
@@ -8,6 +8,7 @@
import org.gradle.api.logging.Logger;
import org.gradle.api.logging.Logging;
import org.gradle.api.plugins.ExtensionContainer;
+import org.gradle.api.plugins.PluginManager;
import static io.github.akazver.gradle.plugins.mapstruct.dependency.AdditionalDependency.*;
import static io.github.akazver.gradle.plugins.mapstruct.dependency.MarkerDependency.*;
@@ -27,19 +28,34 @@ public class DependencyManager {
private final ConfigurationContainer configurations;
private final ExtensionContainer extensions;
private final DependencyHandler dependencies;
+ private final PluginManager pluginManager;
public DependencyManager(Project project) {
this.configurations = project.getConfigurations();
this.extensions = project.getExtensions();
this.dependencies = project.getDependencies();
+ this.pluginManager = project.getPluginManager();
}
- public void addRequiredDependencies() {
+ public void addDependencies() {
+ boolean hasKotlin = hasExtension("kotlin");
+ String processorConfig = hasKotlin ? "kapt" : "annotationProcessor";
+
+ if (hasKotlin) {
+ pluginManager.apply("org.jetbrains.kotlin.kapt");
+ }
+
+ addRequiredDependencies(processorConfig);
+ addOptionalDependencies(processorConfig);
+ }
+
+ private void addRequiredDependencies(String processorConfig) {
LOGGER.lifecycle(ADDING_MESSAGE, "MapStruct");
- addDependencies(MAPSTRUCT, MAPSTRUCT_PROCESSOR);
+ addDependency(MAPSTRUCT);
+ addDependency(MAPSTRUCT_PROCESSOR, processorConfig);
}
- public void addOptionalDependencies() {
+ private void addOptionalDependencies(String processorConfig) {
boolean hasLombok = hasExtension("lombok") || hasDependency(LOMBOK);
boolean hasBinding = hasDependency(LOMBOK_MAPSTRUCT_BINDING);
boolean hasSpringBoot = hasExtension("springBoot") || hasDependency(SPRING_BOOT);
@@ -50,12 +66,14 @@ public void addOptionalDependencies() {
if (hasLombok && !hasBinding) {
LOGGER.lifecycle(ADDING_MESSAGE, "Lombok");
- addDependency(LOMBOK_MAPSTRUCT_BINDING);
+ addDependency(LOMBOK_MAPSTRUCT_BINDING, processorConfig);
}
if (hasSpringBoot || hasSpring) {
LOGGER.lifecycle(ADDING_MESSAGE, "Spring");
- addDependencies(MAPSTRUCT_SPRING_EXTENSIONS, MAPSTRUCT_SPRING_ANNOTATIONS, MAPSTRUCT_SPRING_TEST_EXTENSIONS);
+ addDependency(MAPSTRUCT_SPRING_EXTENSIONS, processorConfig);
+ addDependency(MAPSTRUCT_SPRING_ANNOTATIONS);
+ addDependency(MAPSTRUCT_SPRING_TEST_EXTENSIONS);
}
if (hasCamel) {
@@ -97,15 +115,13 @@ private boolean hasExtension(String extensionName) {
return extensions.findByName(extensionName) != null;
}
- private void addDependency(PluginDependency pluginDependency) {
+ private void addDependency(PluginDependency pluginDependency, String configuration) {
LOGGER.lifecycle(DEPENDENCY_PREFIX, pluginDependency.getId());
- dependencies.add(pluginDependency.getConfiguration(), pluginDependency.getId());
+ dependencies.add(configuration, pluginDependency.getId());
}
- private void addDependencies(PluginDependency... pluginDependencies) {
- for (PluginDependency pluginDependency : pluginDependencies) {
- addDependency(pluginDependency);
- }
+ private void addDependency(PluginDependency pluginDependency) {
+ addDependency(pluginDependency, pluginDependency.getConfiguration());
}
}
diff --git a/src/test/java/io/github/akazver/gradle/plugins/mapstruct/DependencyTest.java b/src/test/java/io/github/akazver/gradle/plugins/mapstruct/DependencyTest.java
index 9250742..bdac36d 100644
--- a/src/test/java/io/github/akazver/gradle/plugins/mapstruct/DependencyTest.java
+++ b/src/test/java/io/github/akazver/gradle/plugins/mapstruct/DependencyTest.java
@@ -7,6 +7,7 @@
import org.gradle.api.Project;
import org.gradle.api.artifacts.Dependency;
import org.gradle.api.artifacts.DependencySet;
+import org.jetbrains.kotlin.gradle.plugin.KotlinPluginWrapper;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.boot.gradle.plugin.SpringBootPlugin;
@@ -303,6 +304,63 @@ void addOptionalDependenciesWithProtobufPlugin() {
optionalDependenciesWithoutSpringTest(project, expectedAnnotationProcessor, expectedImplementation);
}
+ @Test
+ @DisplayName("Add dependencies with Kotlin plugin")
+ void addDependenciesWithKotlinPlugin() {
+ Project project = fetchBaseProject();
+ project.getPluginManager().apply(KotlinPluginWrapper.class);
+ evaluate(project);
+
+ assertThat(project.getPlugins().findPlugin("org.jetbrains.kotlin.jvm")).isNotNull();
+ assertThat(project.getPlugins().findPlugin("org.jetbrains.kotlin.kapt")).isNotNull();
+
+ assertThat(fetchDependencyIds(project, "kapt"))
+ .hasSize(1)
+ .first()
+ .isEqualTo(MAPSTRUCT_PROCESSOR.getId());
+
+ assertThat(fetchDependencyIds(project, "implementation"))
+ .hasSize(1)
+ .first()
+ .isEqualTo(MAPSTRUCT.getId());
+
+ assertThat(fetchDependencyIds(project, "annotationProcessor"))
+ .isEmpty();
+ }
+
+ @Test
+ @DisplayName("Add dependencies with Kotlin plugin and Spring")
+ void addDependenciesWithKotlinPluginAndSpring() {
+ Project project = fetchBaseProject();
+ project.getPluginManager().apply(KotlinPluginWrapper.class);
+ project.getDependencies().add(SPRING_CORE.getConfiguration(), SPRING_CORE.getId());
+ evaluate(project);
+
+ assertThat(project.getPlugins().findPlugin("org.jetbrains.kotlin.jvm")).isNotNull();
+ assertThat(project.getPlugins().findPlugin("org.jetbrains.kotlin.kapt")).isNotNull();
+
+ String[] expectedKapt = {
+ MAPSTRUCT_PROCESSOR.getId(),
+ MAPSTRUCT_SPRING_EXTENSIONS.getId()
+ };
+
+ String[] expectedImplementation = {
+ SPRING_CORE.getId(), MAPSTRUCT.getId(),
+ MAPSTRUCT_SPRING_ANNOTATIONS.getId()
+ };
+
+ assertThat(fetchDependencyIds(project, "kapt"))
+ .hasSize(expectedKapt.length)
+ .containsExactlyInAnyOrder(expectedKapt);
+
+ assertThat(fetchDependencyIds(project, "implementation"))
+ .hasSize(expectedImplementation.length)
+ .containsExactlyInAnyOrder(expectedImplementation);
+
+ assertThat(fetchDependencyIds(project, "annotationProcessor"))
+ .isEmpty();
+ }
+
private void optionalDependenciesTest(Project project, String[] expectedAnnotationProcessor, String[] expectedImplementation) {
String[] expectedTestImplementation =
Stream.concat(Arrays.stream(expectedImplementation), Stream.of(MAPSTRUCT_SPRING_TEST_EXTENSIONS.getId()))