Skip to content

Commit 9cfbb8f

Browse files
author
Соболев Василий
committed
Add Quarkus and Protobuf support, improve documentation
- Add automatic detection and dependency management for Quarkus and Protobuf - Switch from configuration-based to extension-based plugin detection - Add real plugin dependencies for testing (Spring Boot, Quarkus, Protobuf) - Enhance README with Requirements, How it works, Troubleshooting sections - Add Contributing guide and improve dependency table - Enable Gradle configuration cache and increase JVM memory - Modernize code with Java 17+ features
1 parent 90c75d5 commit 9cfbb8f

9 files changed

Lines changed: 172 additions & 53 deletions

File tree

README.md

Lines changed: 56 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
<p align="center">
22
<a href="https://github.com/AkaZver/mapstruct-plugin/actions"><img src="https://github.com/AkaZver/mapstruct-plugin/workflows/Build/badge.svg" alt="Actions Status"></a>
3+
<a href="#"><img src="https://img.shields.io/gradle-plugin-portal/v/com.github.akazver.mapstruct?label=Plugin Version&logo=github" alt="Plugin Version"></a>
34
<a href="https://sonarcloud.io"><img src="https://sonarcloud.io/api/project_badges/measure?project=AkaZver_mapstruct-plugin&metric=alert_status" alt="Quality Gate Status"></a>
45
<a href="https://sonarcloud.io"><img src="https://sonarcloud.io/api/project_badges/measure?project=AkaZver_mapstruct-plugin&metric=coverage" alt="Coverage"></a>
56
<br/>
@@ -18,33 +19,49 @@
1819

1920
Gradle plugin for easy [MapStruct](https://mapstruct.org/) setup
2021

21-
Usage:
22+
## Requirements
23+
24+
- **Gradle:** 9.0 or higher
25+
- **Java:** 17 or higher
26+
27+
## Usage
28+
2229
```groovy
2330
plugins {
24-
id 'com.github.akazver.mapstruct' version '2.0.0'
31+
id 'com.github.akazver.mapstruct' version 'X.Y.Z'
2532
}
2633
```
2734

28-
## Dependencies
29-
**MapStruct** (required)
30-
- [mapstruct](https://mvnrepository.com/artifact/org.mapstruct/mapstruct) (implementation)
31-
- [mapstruct-processor](https://mvnrepository.com/artifact/org.mapstruct/mapstruct-processor) (annotationProcessor)
35+
## How it works
3236

33-
**Lombok** (optional)
34-
- [lombok-mapstruct-binding](https://mvnrepository.com/artifact/org.projectlombok/lombok-mapstruct-binding) (annotationProcessor)
37+
The plugin automatically:
3538

36-
**Spring** (optional)
37-
- [mapstruct-spring-annotations](https://mvnrepository.com/artifact/org.mapstruct.extensions.spring/mapstruct-spring-annotations) (implementation)
38-
- [mapstruct-spring-extensions](https://mvnrepository.com/artifact/org.mapstruct.extensions.spring/mapstruct-spring-extensions) (annotationProcessor)
39-
- [mapstruct-spring-test-extensions](https://mvnrepository.com/artifact/org.mapstruct.extensions.spring/mapstruct-spring-test-extensions) (testImplementation)
39+
- Adds MapStruct dependencies (`mapstruct` and `mapstruct-processor`)
40+
- Detects optional dependencies (Lombok, Spring, Camel, Quarkus, Protobuf) in your project
41+
- Adds required binding libraries when needed (e.g., `lombok-mapstruct-binding` for Lombok)
42+
- Configures compiler arguments based on your `mapstruct {}` block settings
43+
- Runs after project evaluation to ensure all dependencies are resolved
4044

41-
**Camel** (optional)
42-
- [camel-mapstruct](https://mvnrepository.com/artifact/org.apache.camel/camel-mapstruct) (implementation)
43-
- [camel-mapstruct-starter](https://mvnrepository.com/artifact/org.apache.camel.springboot/camel-mapstruct-starter) (implementation)
44-
- [camel-quarkus-mapstruct](https://mvnrepository.com/artifact/org.apache.camel.quarkus/camel-quarkus-mapstruct) (implementation)
45+
## Dependencies
46+
47+
| Category | GitHub | Maven | Configuration |
48+
|----------------------------|---------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------|
49+
| **MapStruct** *(required)* | [mapstruct/mapstruct](https://github.com/mapstruct/mapstruct) | [org.mapstruct/mapstruct](https://mvnrepository.com/artifact/org.mapstruct/mapstruct) | `implementation` |
50+
| | | [org.mapstruct/mapstruct-processor](https://mvnrepository.com/artifact/org.mapstruct/mapstruct-processor) | `annotationProcessor` |
51+
| **Lombok** | [projectlombok/lombok](https://github.com/projectlombok/lombok) | [org.projectlombok/lombok-mapstruct-binding](https://mvnrepository.com/artifact/org.projectlombok/lombok-mapstruct-binding) | `annotationProcessor` |
52+
| **Spring** | [mapstruct/mapstruct-spring-extensions](https://github.com/mapstruct/mapstruct-spring-extensions) | [org.mapstruct.extensions.spring/mapstruct-spring-annotations](https://mvnrepository.com/artifact/org.mapstruct.extensions.spring/mapstruct-spring-annotations) | `implementation` |
53+
| | | [org.mapstruct.extensions.spring/mapstruct-spring-extensions](https://mvnrepository.com/artifact/org.mapstruct.extensions.spring/mapstruct-spring-extensions) | `annotationProcessor` |
54+
| | | [org.mapstruct.extensions.spring/mapstruct-spring-test-extensions](https://mvnrepository.com/artifact/org.mapstruct.extensions.spring/mapstruct-spring-test-extensions) | `testImplementation` |
55+
| **Camel** | [apache/camel](https://github.com/apache/camel) | [org.apache.camel/camel-mapstruct](https://mvnrepository.com/artifact/org.apache.camel/camel-mapstruct) | `implementation` |
56+
| | [apache/camel-spring-boot](https://github.com/apache/camel-spring-boot) | [org.apache.camel.springboot/camel-mapstruct-starter](https://mvnrepository.com/artifact/org.apache.camel.springboot/camel-mapstruct-starter) | `implementation` |
57+
| | [apache/camel-quarkus](https://github.com/apache/camel-quarkus) | [org.apache.camel.quarkus/camel-quarkus-mapstruct](https://mvnrepository.com/artifact/org.apache.camel.quarkus/camel-quarkus-mapstruct) | `implementation` |
58+
| **Quarkus** | [quarkiverse/quarkus-mapstruct](https://github.com/quarkiverse/quarkus-mapstruct) | [io.quarkiverse.mapstruct/quarkus-mapstruct](https://mvnrepository.com/artifact/io.quarkiverse.mapstruct/quarkus-mapstruct) | `implementation` |
59+
| **Protobuf** | [entur/mapstruct-spi-protobuf](https://github.com/entur/mapstruct-spi-protobuf) | [no.entur.mapstruct.spi/protobuf-spi-impl](https://mvnrepository.com/artifact/no.entur.mapstruct.spi/protobuf-spi-impl) | `implementation` |
4560

4661
## Config
62+
4763
Plugin adds configuration block which looks like this:
64+
4865
```groovy
4966
mapstruct {
5067
suppressGeneratorTimestamp = true
@@ -60,8 +77,30 @@ mapstruct {
6077
}
6178
```
6279

63-
All parameters used according to official
80+
All parameters used according to official
6481
[documentation](https://mapstruct.org/documentation/stable/reference/html/#configuration-options)
6582

83+
## Troubleshooting
84+
85+
### MapStruct not generating mappers
86+
87+
Make sure you have the Java plugin applied and that annotation processing is enabled in your IDE.
88+
89+
### Lombok + MapStruct conflicts
90+
91+
The plugin automatically adds `lombok-mapstruct-binding` when Lombok is detected. If you still have issues, ensure
92+
Lombok plugin is applied before MapStruct plugin.
93+
94+
## Contributing
95+
96+
Contributions are welcome! Please feel free to submit a Pull Request.
97+
98+
1. Fork the repository
99+
2. Create your feature branch (`git checkout -b feature/amazing-feature`)
100+
3. Commit your changes (`git commit -m 'Add amazing feature'`)
101+
4. Push to the branch (`git push origin feature/amazing-feature`)
102+
5. Open a Pull Request
103+
66104
## License
105+
67106
[![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2FAkaZver%2Fmapstruct-plugin.svg?type=large)](https://app.fossa.com/projects/git%2Bgithub.com%2FAkaZver%2Fmapstruct-plugin?ref=badge_large)

build.gradle

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,19 @@ gradlePlugin {
2828
repositories {
2929
mavenLocal()
3030
mavenCentral()
31+
gradlePluginPortal()
3132
}
3233

3334
dependencies {
35+
// id 'io.freefair.lombok' version '9.5.0'
3436
testImplementation 'io.freefair.gradle:lombok-plugin:9.5.0'
37+
// id 'io.quarkus' version '3.38.0'
38+
testImplementation 'io.quarkus:io.quarkus.gradle.plugin:3.38.0'
39+
// id 'org.springframework.boot' version '4.1.0'
40+
testImplementation 'org.springframework.boot:org.springframework.boot.gradle.plugin:4.1.0'
41+
// id 'com.google.protobuf' version '0.10.0'
42+
testImplementation 'com.google.protobuf:com.google.protobuf.gradle.plugin:0.10.0'
43+
3544
testImplementation 'org.assertj:assertj-core:3.27.7'
3645
testImplementation 'org.junit.jupiter:junit-jupiter:6.1.2'
3746
testImplementation 'org.junit.platform:junit-platform-launcher:6.1.2'
@@ -42,6 +51,12 @@ dependencies {
4251
test {
4352
useJUnitPlatform()
4453
finalizedBy jacocoTestReport
54+
maxParallelForks = 1
55+
}
56+
57+
configurations.testImplementation {
58+
exclude group: 'org.slf4j'
59+
exclude group: 'org.jboss.slf4j'
4560
}
4661

4762
java {

gradle.properties

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1-
org.gradle.jvmargs=-Dfile.encoding=UTF-8 -Dconsole.encoding=UTF-8
1+
org.gradle.jvmargs=-Dfile.encoding=UTF-8 -Dconsole.encoding=UTF-8 -Xmx4g
2+
org.gradle.configuration-cache=true

src/main/java/com/github/akazver/gradle/plugins/mapstruct/dependency/AdditionalDependency.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,14 @@ public class AdditionalDependency extends PluginDependency {
5151
public static final AdditionalDependency CAMEL_QUARKUS_MAPSTRUCT =
5252
new AdditionalDependency("implementation", "org.apache.camel.quarkus:camel-quarkus-mapstruct:3.36.0");
5353

54+
// https://mvnrepository.com/artifact/io.quarkiverse.mapstruct/quarkus-mapstruct
55+
public static final AdditionalDependency QUARKUS_MAPSTRUCT =
56+
new AdditionalDependency("implementation", "io.quarkiverse.mapstruct:quarkus-mapstruct:1.1.0");
57+
58+
// https://mvnrepository.com/artifact/no.entur.mapstruct.spi/protobuf-spi-impl
59+
public static final AdditionalDependency PROTOBUF_SPI_IMPL =
60+
new AdditionalDependency("implementation", "no.entur.mapstruct.spi:protobuf-spi-impl:1.62.0");
61+
5462
public AdditionalDependency(String configuration, String id) {
5563
super(configuration, id);
5664
}

src/main/java/com/github/akazver/gradle/plugins/mapstruct/dependency/MarkerDependency.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@ public class MarkerDependency extends PluginDependency {
3535
public static final MarkerDependency QUARKUS_CORE =
3636
new MarkerDependency("implementation", "io.quarkus:quarkus-core:3.38.0");
3737

38+
// https://mvnrepository.com/artifact/com.google.protobuf/protobuf-java
39+
public static final MarkerDependency PROTOBUF_JAVA =
40+
new MarkerDependency("implementation", "com.google.protobuf:protobuf-java:4.35.1");
41+
3842
public MarkerDependency(String configuration, String id) {
3943
super(configuration, id);
4044
}

src/main/java/com/github/akazver/gradle/plugins/mapstruct/dependency/PluginDependency.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,7 @@ public PluginDependency(String configuration, String id) {
2828
String[] split = id.split(":");
2929

3030
if (split.length != 3) {
31-
String message = String.format("Dependency id '%s' is invalid", id);
32-
throw new MapstructPluginException(message);
31+
throw new MapstructPluginException("Dependency id '%s' is invalid".formatted(id));
3332
}
3433

3534
this.group = split[0];

src/main/java/com/github/akazver/gradle/plugins/mapstruct/manager/CompilerArgsManager.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,9 @@ private String fetchCompilerArg(MapstructExtension extension, String name) {
5353
PropertyDescriptor descriptor = new PropertyDescriptor(name, MapstructExtension.class);
5454
Object value = descriptor.getReadMethod().invoke(extension);
5555

56-
return String.format(COMPILER_ARG_PATTERN, name, value);
56+
return COMPILER_ARG_PATTERN.formatted(name, value);
5757
} catch (IllegalAccessException | InvocationTargetException | IntrospectionException exception) {
58-
String message = String.format("Can't fetch compiler argument for '%s'", name);
59-
throw new MapstructPluginException(message, exception);
58+
throw new MapstructPluginException("Can't fetch compiler argument for '%s'".formatted(name), exception);
6059
}
6160
}
6261

src/main/java/com/github/akazver/gradle/plugins/mapstruct/manager/DependencyManager.java

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,6 @@ public class DependencyManager {
2424
private static final String ADDING_MESSAGE = "Adding {} dependencies";
2525
private static final String DEPENDENCY_PREFIX = "- {}";
2626

27-
private static final String LOMBOK_CONFIG_NAME = "lombok";
28-
private static final String SPRING_BOOT_CONFIG_NAME = "bootArchives";
29-
private static final String QUARKUS_EXT_NAME = "quarkus";
30-
3127
private final ConfigurationContainer configurations;
3228
private final ExtensionContainer extensions;
3329
private final DependencyHandler dependencies;
@@ -44,12 +40,13 @@ public void addRequiredDependencies() {
4440
}
4541

4642
public void addOptionalDependencies() {
47-
boolean hasLombok = hasConfiguration(LOMBOK_CONFIG_NAME) || hasDependency(LOMBOK);
43+
boolean hasLombok = hasExtension("lombok") || hasDependency(LOMBOK);
4844
boolean hasBinding = hasDependency(LOMBOK_MAPSTRUCT_BINDING);
49-
boolean hasSpringBoot = hasConfiguration(SPRING_BOOT_CONFIG_NAME) || hasDependency(SPRING_BOOT);
45+
boolean hasSpringBoot = hasExtension("springBoot") || hasDependency(SPRING_BOOT);
5046
boolean hasSpring = hasDependency(SPRING_CORE);
5147
boolean hasCamel = hasDependency(CAMEL_CORE);
52-
boolean hasQuarkus = hasExtension(QUARKUS_EXT_NAME) || hasDependency(QUARKUS_CORE);
48+
boolean hasQuarkus = hasExtension("quarkus") || hasDependency(QUARKUS_CORE);
49+
boolean hasProtobuf = hasExtension("protobuf") || hasDependency(PROTOBUF_JAVA);
5350

5451
if (hasLombok && !hasBinding) {
5552
LOGGER.lifecycle(ADDING_MESSAGE, "Lombok");
@@ -72,6 +69,16 @@ public void addOptionalDependencies() {
7269
addDependency(CAMEL_MAPSTRUCT);
7370
}
7471
}
72+
73+
if (hasQuarkus) {
74+
LOGGER.lifecycle(ADDING_MESSAGE, "Quarkus");
75+
addDependency(QUARKUS_MAPSTRUCT);
76+
}
77+
78+
if (hasProtobuf) {
79+
LOGGER.lifecycle(ADDING_MESSAGE, "Protobuf");
80+
addDependency(PROTOBUF_SPI_IMPL);
81+
}
7582
}
7683

7784
private boolean isNeededDependency(Dependency dependency, PluginDependency pluginDependency) {
@@ -86,11 +93,6 @@ private boolean hasDependency(PluginDependency pluginDependency) {
8693
.anyMatch(dependency -> isNeededDependency(dependency, pluginDependency));
8794
}
8895

89-
private boolean hasConfiguration(String configurationName) {
90-
return configurations.findByName(configurationName) != null;
91-
}
92-
93-
@SuppressWarnings("SameParameterValue")
9496
private boolean hasExtension(String extensionName) {
9597
return extensions.findByName(extensionName) != null;
9698
}

0 commit comments

Comments
 (0)