Skip to content

Commit 287c3d5

Browse files
committed
upgrade gradle, kotlin, publish plugin
Signed-off-by: Alex Pichler <alex.pichler@cloudflight.io>
1 parent f799490 commit 287c3d5

File tree

33 files changed

+407
-59
lines changed

33 files changed

+407
-59
lines changed

build.gradle.kts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
plugins {
22
id("java-gradle-plugin")
33
id("maven-publish")
4-
id("com.gradle.plugin-publish") version "1.1.0"
4+
id("groovy")
5+
id("com.gradle.plugin-publish") version "2.0.0"
56
}
67

78
description = "An opinionated approach to configure a gradle project automatically by convention. It supports to automatically configure various plugins to reduce boilerplate code in gradle projects."
@@ -51,8 +52,14 @@ dependencies {
5152
testImplementation(libs.bundles.testImplementationDependencies)
5253

5354
testRuntimeOnly(libs.junit.engine)
55+
testRuntimeOnly(libs.junit.platform.launcher)
5456

5557
constraints {
58+
// TODO: remove when upgrading io.cloudflight.autoconfigure-settings in settings.gradle.kts
59+
// io.cloudflight.autoconfigure-settings 1.2.0 pulls in kotlin gradle plugin 2.1.20
60+
// this breaks the build as it depends on features only available up to gradle 8.13
61+
implementation(libs.kotlin.gradleplugin)
62+
5663
api(libs.jackson)
5764
api(libs.swagger.jersey2.jaxrs)
5865
api(libs.reflections)
@@ -61,8 +68,8 @@ dependencies {
6168
}
6269

6370
tasks.compileTestKotlin.configure {
64-
kotlinOptions {
65-
freeCompilerArgs += "-opt-in=kotlin.io.path.ExperimentalPathApi"
71+
compilerOptions {
72+
optIn.add("kotlin.io.path.ExperimentalPathApi")
6673
}
6774
}
6875

gradle/libs.versions.toml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
[versions]
22
java = "21"
3-
kotlin = "2.1.20"
3+
kotlin = "2.3.0"
44
kotlinx-serialization = "1.8.1"
55
maven-artifact = "3.9.9"
66
jupiter = "5.11.4"
7+
junit-platform = "1.11.4"
78
assertj = "3.27.3"
89
jackson = "2.14.2"
910

@@ -31,7 +32,7 @@ reckon-plugin = { module = "org.ajoberstar.reckon:org.ajoberstar.reckon.gradle.p
3132

3233
# IMPORTANT: do not update, see https://github.com/gigaSproule/swagger-gradle-plugin/issues/186
3334
swagger-gradle-plugin = { module = "com.benjaminsproule:swagger-gradle-plugin", version = "1.0.8" }
34-
swagger-codegen-plugin = { module = "gradle.plugin.org.hidetake:gradle-swagger-generator-plugin", version = "2.19.1" }
35+
swagger-codegen-plugin = { module = "gradle.plugin.org.hidetake:gradle-swagger-generator-plugin", version = "2.19.2" }
3536

3637
# this could be removed as soon as https://github.com/gigaSproule/swagger-gradle-plugin/issues/186 is fixed
3738
# because the latest version from the swagger-gradle-plugin already has the 1.6 version of the swagger library on the classpath.
@@ -47,6 +48,7 @@ reflections = { module = "org.reflections:reflections", version = { strictly = "
4748
junit-api = { module = "org.junit.jupiter:junit-jupiter-api", version.ref = "jupiter" }
4849
junit-params = { module = "org.junit.jupiter:junit-jupiter-params", version.ref = "jupiter" }
4950
junit-engine = { module = "org.junit.jupiter:junit-jupiter-engine", version.ref = "jupiter" }
51+
junit-platform-launcher = { module = "org.junit.platform:junit-platform-launcher", version.ref = "junit-platform" }
5052

5153
assertj-core = { module = "org.assertj:assertj-core", version.ref = "assertj" }
5254

gradle/wrapper/gradle-wrapper.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
distributionBase=GRADLE_USER_HOME
22
distributionPath=wrapper/dists
3-
distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip
3+
distributionUrl=https\://services.gradle.org/distributions/gradle-9.3.0-bin.zip
44
networkTimeout=10000
55
validateDistributionUrl=true
66
zipStoreBase=GRADLE_USER_HOME

settings.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
plugins {
2-
id("io.cloudflight.autoconfigure-settings") version "1.1.2"
2+
id("io.cloudflight.autoconfigure-settings") version "1.2.0"
33
}
44

55
rootProject.name = "autoconfigure"
Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
package com.benjaminsproule.swagger.gradleplugin.reader.resolver
2+
3+
import com.benjaminsproule.swagger.gradleplugin.classpath.ClassFinder
4+
import com.benjaminsproule.swagger.gradleplugin.exceptions.GenerateException
5+
import com.fasterxml.jackson.databind.JavaType
6+
import com.fasterxml.jackson.databind.ObjectMapper
7+
import io.swagger.annotations.ApiModelProperty
8+
import io.swagger.converter.ModelConverter
9+
import io.swagger.converter.ModelConverterContext
10+
import io.swagger.jackson.ModelResolver
11+
import io.swagger.models.Model
12+
import io.swagger.models.properties.Property
13+
import org.apache.commons.lang3.reflect.FieldUtils
14+
import org.slf4j.Logger
15+
import org.slf4j.LoggerFactory
16+
import org.springframework.core.annotation.AnnotationUtils
17+
18+
import java.lang.annotation.Annotation
19+
import java.lang.reflect.Field
20+
import java.lang.reflect.Method
21+
import java.lang.reflect.Type
22+
23+
/**
24+
* Monkey-patched ModelModifier to use JavaType in resolve() call instead of Type.
25+
* In groovy 3, type is automatically converted, but in groovy 4 (from gradle 9.0+) it is not.
26+
* TODO: Remove this when https://github.com/gigaSproule/swagger-gradle-plugin/issues/186 is fixed.
27+
*/
28+
class ModelModifier extends ModelResolver {
29+
private Map<String, JavaType> modelSubtitutes = [:]
30+
List<String> apiModelPropertyAccessExclusions = []
31+
private ClassFinder classFinder
32+
33+
private static Logger LOG = LoggerFactory.getLogger(ModelModifier)
34+
35+
ModelModifier(ObjectMapper mapper, ClassFinder classFinder) {
36+
super(mapper)
37+
this.classFinder = classFinder
38+
}
39+
40+
void addModelSubstitute(String fromClass, String toClass) throws GenerateException {
41+
try {
42+
JavaType toType = _mapper.constructType(classFinder.loadClass(toClass))
43+
modelSubtitutes.put(fromClass, toType)
44+
} catch (ClassNotFoundException ignored) {
45+
LOG.warn("Problem with loading class: ${toClass}. Mapping from: ${fromClass} to: ${toClass} will be ignored.")
46+
}
47+
}
48+
49+
@Override
50+
Property resolveProperty(Type type, ModelConverterContext context, Annotation[] annotations, Iterator<ModelConverter> chain) {
51+
// for method parameter types we get here Type but we need JavaType
52+
JavaType javaType = toJavaType(type)
53+
String typeName = javaType.getRawClass().getCanonicalName()
54+
55+
if (modelSubtitutes.containsKey(typeName)) {
56+
return super.resolveProperty(modelSubtitutes.get(typeName), context, annotations, chain)
57+
} else if (chain.hasNext()) {
58+
return chain.next().resolveProperty(type, context, annotations, chain)
59+
} else {
60+
return super.resolveProperty(type, context, annotations, chain)
61+
}
62+
63+
}
64+
65+
@Override
66+
Model resolve(Type type, ModelConverterContext context, Iterator<ModelConverter> chain) {
67+
// for method parameter types we get here Type but we need JavaType
68+
JavaType javaType = toJavaType(type)
69+
String typeName = javaType.getRawClass().getCanonicalName()
70+
def model
71+
if (modelSubtitutes.containsKey(typeName)) {
72+
model = super.resolve(modelSubtitutes.get(typeName), context, chain)
73+
} else {
74+
// --- FIX START ---
75+
// WAS: model = super.resolve(type, context, chain)
76+
// CHANGE: Pass 'javaType' to explicitly target resolve(JavaType, ...)
77+
model = super.resolve(javaType, context, chain)
78+
// --- FIX END ---
79+
}
80+
81+
// If there are no @ApiModelPropety exclusions configured, return the untouched model
82+
if (apiModelPropertyAccessExclusions == null || apiModelPropertyAccessExclusions.isEmpty()) {
83+
return model
84+
}
85+
86+
Class<?> cls = javaType.getRawClass()
87+
88+
for (Method method : cls.getDeclaredMethods()) {
89+
ApiModelProperty apiModelPropertyAnnotation = AnnotationUtils.findAnnotation(method, ApiModelProperty)
90+
91+
processProperty(apiModelPropertyAnnotation, model)
92+
}
93+
94+
for (Field field : FieldUtils.getAllFields(cls)) {
95+
ApiModelProperty apiModelPropertyAnnotation = AnnotationUtils.getAnnotation(field, ApiModelProperty)
96+
97+
processProperty(apiModelPropertyAnnotation, model)
98+
}
99+
100+
return model
101+
}
102+
103+
/**
104+
* Remove property from {@link Model} for provided {@link ApiModelProperty}.
105+
* @param apiModelPropertyAnnotation annotation
106+
* @param model model with properties
107+
*/
108+
private void processProperty(ApiModelProperty apiModelPropertyAnnotation, Model model) {
109+
if (apiModelPropertyAnnotation == null) {
110+
return
111+
}
112+
113+
String apiModelPropertyAccess = apiModelPropertyAnnotation.access()
114+
String apiModelPropertyName = apiModelPropertyAnnotation.name()
115+
116+
// If the @ApiModelProperty is not populated with both #name and #access, skip it
117+
if (apiModelPropertyAccess.isEmpty() || apiModelPropertyName.isEmpty()) {
118+
return
119+
}
120+
121+
// Check to see if the value of @ApiModelProperty#access is one to exclude.
122+
// If so, remove it from the previously-calculated model.
123+
if (apiModelPropertyAccessExclusions.contains(apiModelPropertyAccess)) {
124+
model.getProperties().remove(apiModelPropertyName)
125+
}
126+
}
127+
128+
/**
129+
* Converts {@link Type} to {@link JavaType}.
130+
* @param type object to convert
131+
* @return object converted to {@link JavaType}
132+
*/
133+
private JavaType toJavaType(Type type) {
134+
JavaType typeToFind
135+
if (type instanceof JavaType) {
136+
typeToFind = (JavaType) type
137+
} else {
138+
typeToFind = _mapper.constructType(type)
139+
}
140+
return typeToFind
141+
}
142+
}

0 commit comments

Comments
 (0)