Trying to include swagger-codegen with gradle kotlindsl

Viewed 3298

I'm trying to make swagger codegen work in a project built with gradle (kotlin).

My reference is this example here : https://github.com/int128/gradle-swagger-generator-plugin which is made in Gradle groovy version.

Now the build.gradle.kts is the following:

repositories {
    jcenter()
}

plugins {
    java
    id("org.springframework.boot") version "2.1.2.RELEASE"
    id("io.spring.dependency-management") version "1.0.6.RELEASE"
    id("org.hidetake.swagger.generator") version "2.16.0"
}

dependencies {
    implementation("org.springframework.boot:spring-boot-starter-web")
    implementation ("io.swagger:swagger-annotations:1.5.21")
    swaggerCodeGen("io.swagger:swagger-codegen-cli:2.3.1")

    // Use JUnit test framework
    testImplementation ("junit:junit:4.12")
}

swaggerSources {
    petstore {
        inputFile = file('petstore.yaml')
        code {
            language = 'spring'
        }
    }
}

But IntelliJ does not like lines talking about swagger:

IntelliJ error

I am a newbie in gradle so I don't understand what I am supposed to do. Is swaggerCodeGen supposed to be a function? Where does this function supposed to be imported? Where swaggerSources supposed to imported?

2 Answers
import org.hidetake.gradle.swagger.generator.GenerateSwaggerCode

// plugins, repositories are same, but note import above ^^^

dependencies {
    implementation("org.springframework.boot:spring-boot-starter-web")
    implementation ("io.swagger:swagger-annotations:1.5.21")
    "swaggerCodegen"("io.swagger:swagger-codegen-cli:2.3.1") // 1

    // Use JUnit test framework
    testImplementation ("junit:junit:4.12")
}

swaggerSources {
    create("petstore").apply { // 2
        setInputFile(file("petstore.yaml")) // 3
        code(closureOf<GenerateSwaggerCode> { // 4
            language = "spring"
        })
    }
}

1 - dynamically resolved configuration in Kotlin looks like this (dynamically from Groovy, so there is problematically to use it on compile time, extension invoke operator on String is our saviour);

2 - swaggerSources returns you NamedDomainObjectContainer<SwaggerSource>, so to add new container we invoke create with it's name as parameter;

3 - Kotlin does not as flexible as Groovy, so calling setter instead of setting field;

4 - Groovy's closure is far from functional interface, so we specify generic type as in plugin's sources Closure is not parametrised.

You can use this openapi-generator plugin task to generate the swagger code as well. It does the same thing as the swagger codegen plugin. Use it in your build.gradle.kts like:

plugins {
    id("org.openapi.generator") version "5.1.1"
}

openApiGenerate {
    generatorName.set("spring")
    inputSpec.set("$rootDir/src/main/resources/petstore.yaml")
    outputDir.set("$buildDir/generated/")
}

dependencies {
    //Spring boot dependency
    implementation("org.springframework.boot:spring-boot-starter-web")

    // For swagger generated code and annotations
    implementation("io.springfox:springfox-boot-starter:3.0.0") 
    implementation("javax.validation:validation-api:2.0.0.Final")
}

This could be used with a kotlin or java project, then you need to add the generated classes to your sourceSet by doing:

configure<SourceSetContainer> {
    named("main") {
        java.srcDir("$buildDir/generated/src/main/java")
    }
}

The last step is make sure you generate the swagger files before compiling, for Kotlin, add this in your compile task:

tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile> {
    dependsOn("openApiGenerate")
    kotlinOptions.jvmTarget = "11"
}

You can check the generator's properties to adjust the configuration of the generated files.

Related