swagger-api / swagger-codegen

swagger-codegen contains a template-driven engine to generate documentation, API clients and server stubs in different languages by parsing your OpenAPI / Swagger definition.
http://swagger.io
Apache License 2.0
16.73k stars 6.02k forks source link

[Spring] Improve CI and maven integration: regenerate all files depending on swagger specs at every build #5542

Open nicusX opened 7 years ago

nicusX commented 7 years ago
Description

As a best practice for code generation with a CI pipeline driven by maven, it should be able to regenerate every file that depends on Swagger spec file.

Speaking about Spring Boot, these files are:

Using Maven, these files should be regenerated at every build, into ./target/generated-sources (usually ignored in VCS).

Any other file might be optionally generated, on demand (as opposed as automatically at every build), only on the developer's machine and into ./src.

Currently, this only partially works using the swagger-codegen-maven-plugin and spring language.

Specifyng interfaceOnly=true, the following files are generated:

By default, swagger-codegen-maven-plugin correctly generates into ./target/generated-sources

I see two distinct problems here:

  1. pom.xml, README.md, .swagger-codegen-ignore should not be generated when interfaceOnly=true (and it also doen't make sense generating them into ./target/generated-sources)
  2. It should be possible to regnerate also SwaggerDocumentationConfig.java

The .swagger-codegen-ignore file is not useful, as you only may ignore files, not selectively activate their generation.

Swagger-codegen version

Verified using Swagger Codegen Maven plugin 2.2.2 (release) and CLI 2.2.2

Swagger declaration file content or url

It does not depend on Swagger specs. I used this for testing: https://github.com/OAI/OpenAPI-Specification/blob/master/examples/v2.0/json/petstore-minimal.json

Command line used for generation

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.example</groupId>
    <artifactId>example</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>
    <name>sample</name>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.3.RELEASE</version>
        <relativePath/>
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <application.package>com.example</application.package>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jersey</artifactId>
        </dependency>
        <dependency>
            <groupId>io.swagger</groupId>
            <artifactId>swagger-annotations</artifactId>
            <version>1.5.13</version>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>2.6.1</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>io.swagger</groupId>
                <artifactId>swagger-codegen-maven-plugin</artifactId>
                <version>2.2.2</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>generate</goal>
                        </goals>
                        <configuration>
                            <inputSpec>src/main/resources/swagger.json</inputSpec>
                            <language>spring</language>
                            <configOptions>
                                <interfaceOnly>true</interfaceOnly>
                                <dateLibrary>java8</dateLibrary>
                                <java8>true</java8>
                            </configOptions>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

The effect is reproducible with the following CLI, but as the build is controlled by Maven, only the Maven plugin should be used.

swagger-codegen -l spring -i src/main/resources/swagger.json -o src/ -c config.json

using the following config.json:

{
  "dateLibrary" : "java8",
  "java8" : true,
  "interfaceOnly" : true  
}
Steps to reproduce
  1. Create a maven project using the pom.xml file above
  2. Copy a specs file into ./src/main/resources/ project subdirectory
  3. run mvn clean generate-sources
Related issues

None AFAIK

Suggest a Fix

The current SpringCodegen.java implementation might be easily modified not to generate pom.xml, README.md, .swagger-codegen-ignore when interfaceOnly=true

Selectively regenerating SwaggerDocumentationConfig.java might need a separage, language specific option.

swatisacheti commented 6 years ago

Has this issue been fixed? We're also using the interfaceOnly option but it still generates the pom.xml, README.md and .swagger-codegen-ignore. We don't want these files to be generated for our project. Is there a way we can tell swagger codegen not to generate these files? Currently using swagger-codegen 2.2.3 version

cbornet commented 6 years ago

You can use <generateSupportingFiles>false</generateSupportingFiles> to prevent those files from being generated.

swatisacheti commented 6 years ago

Where do you specify false? We're using gradle to generate our code:

task generateApi { inputs.file("$projectDir/$swaggerSourceFile") outputs.dir("$projectDir/$generatedSources") doLast { def config = new CodegenConfigurator() config.setInputSpec("file:///$projectDir/$swaggerSourceFile") config.setOutputDir("$projectDir") config.setLang('spring') config.setAdditionalProperties([ 'interfaceOnly' : 'true', 'dateLibrary' : 'java8', 'apiPackage' : 'net.flitech.land.hotel.api', 'modelPackage' : 'net.flitech.land.hotel.api.model', 'hideGenerationTimestamp' : 'true',
'sourceFolder' : generatedSources ]) new DefaultGenerator().opts(config.toClientOptInput()).generate() } }

cbornet commented 6 years ago

For gradle, I would recommend using the gradle plugin. See an example conf : https://github.com/jhipster/generator-jhipster/blob/master/generators/server/templates/gradle/_swagger.gradle

inidona commented 6 years ago

we are changing from codegen 2.2.3 to codegen 2.3.1 and now no more pom.xml were generated. We generationg with 'interfaceOnly' : 'true', and after maven build we deploying the builded jar file separatly to our maven registry. this process ist now broken. i think it is necessary to control the generation of pom.xml with an separate parameter, should i implement this and make an pull request ?

thanks andreas