OpenAPITools / openapi-generator

OpenAPI Generator allows generation of API client libraries (SDK generation), server stubs, documentation and configuration automatically given an OpenAPI Spec (v2, v3)
https://openapi-generator.tech
Apache License 2.0
21.36k stars 6.46k forks source link

[BUG][Go] generator skipping post processing for supporting files #10718

Closed mxyng closed 4 months ago

mxyng commented 2 years ago

Bug Report Checklist

Description

Generated Golang support files, configuration.go, client.go, response.go, are not run through the post processor.

openapi-generator version
$ openapi-generator-cli version
5.2.1
OpenAPI declaration file content or url
Dereferenced OpenAPI specification from APITools.dev ```json { "swagger": "2.0", "info": { "version": "1.0.0", "title": "Swagger Petstore", "description": "A sample API that uses a petstore as an example to demonstrate features in the swagger-2.0 specification\n" }, "consumes": [ "application/json" ], "produces": [ "application/json" ], "paths": { "/pets": { "get": { "description": "Returns all pets from the petstore", "responses": { "200": { "description": "pet response", "schema": { "type": "array", "items": { "title": "Pet", "type": "object", "required": [ "name" ], "properties": { "name": { "type": "string", "minLength": 1, "maxLength": 25 }, "type": { "type": "string", "enum": [ "cat", "dog", "fish", "bird" ] }, "birthdate": { "type": "string", "format": "date" }, "owner": { "title": "Pet Owner", "type": "object", "required": [ "name" ], "properties": { "name": { "type": "object", "required": [ "first", "last" ], "properties": { "first": { "type": "string", "minLength": 1, "maxLength": 25 }, "last": { "type": "string", "minLength": 1, "maxLength": 25 } } }, "address": { "title": "Address", "type": "object", "properties": { "street1": { "type": "string" }, "street2": { "type": "string" }, "city": { "type": "string" }, "state": { "type": "string" }, "postalCode": { "type": "string" } } } } } } } } }, "default": { "description": "unexpected error", "schema": { "title": "Error Model", "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "integer", "format": "int32" }, "message": { "type": "string" }, "helpURL": { "type": "string", "format": "url" } } } } } }, "post": { "description": "Creates a new pet in the store", "parameters": [ { "name": "pet", "in": "body", "description": "Pet to add to the store", "required": true, "schema": { "title": "Pet", "type": "object", "required": [ "name" ], "properties": { "name": { "type": "string", "minLength": 1, "maxLength": 25 }, "type": { "type": "string", "enum": [ "cat", "dog", "fish", "bird" ] }, "birthdate": { "type": "string", "format": "date" }, "owner": { "title": "Pet Owner", "type": "object", "required": [ "name" ], "properties": { "name": { "type": "object", "required": [ "first", "last" ], "properties": { "first": { "type": "string", "minLength": 1, "maxLength": 25 }, "last": { "type": "string", "minLength": 1, "maxLength": 25 } } }, "address": { "title": "Address", "type": "object", "properties": { "street1": { "type": "string" }, "street2": { "type": "string" }, "city": { "type": "string" }, "state": { "type": "string" }, "postalCode": { "type": "string" } } } } } } } } ], "responses": { "200": { "description": "pet response", "schema": { "title": "Pet", "type": "object", "required": [ "name" ], "properties": { "name": { "type": "string", "minLength": 1, "maxLength": 25 }, "type": { "type": "string", "enum": [ "cat", "dog", "fish", "bird" ] }, "birthdate": { "type": "string", "format": "date" }, "owner": { "title": "Pet Owner", "type": "object", "required": [ "name" ], "properties": { "name": { "type": "object", "required": [ "first", "last" ], "properties": { "first": { "type": "string", "minLength": 1, "maxLength": 25 }, "last": { "type": "string", "minLength": 1, "maxLength": 25 } } }, "address": { "title": "Address", "type": "object", "properties": { "street1": { "type": "string" }, "street2": { "type": "string" }, "city": { "type": "string" }, "state": { "type": "string" }, "postalCode": { "type": "string" } } } } } } } }, "default": { "description": "unexpected error", "schema": { "title": "Error Model", "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "integer", "format": "int32" }, "message": { "type": "string" }, "helpURL": { "type": "string", "format": "url" } } } } } } }, "/pets/{name}": { "get": { "description": "Returns a single pet by name", "parameters": [ { "name": "name", "in": "path", "description": "Name of the pet to fetch", "required": true, "type": "string" } ], "responses": { "200": { "description": "pet response", "schema": { "title": "Pet", "type": "object", "required": [ "name" ], "properties": { "name": { "type": "string", "minLength": 1, "maxLength": 25 }, "type": { "type": "string", "enum": [ "cat", "dog", "fish", "bird" ] }, "birthdate": { "type": "string", "format": "date" }, "owner": { "title": "Pet Owner", "type": "object", "required": [ "name" ], "properties": { "name": { "type": "object", "required": [ "first", "last" ], "properties": { "first": { "type": "string", "minLength": 1, "maxLength": 25 }, "last": { "type": "string", "minLength": 1, "maxLength": 25 } } }, "address": { "title": "Address", "type": "object", "properties": { "street1": { "type": "string" }, "street2": { "type": "string" }, "city": { "type": "string" }, "state": { "type": "string" }, "postalCode": { "type": "string" } } } } } } } }, "default": { "description": "unexpected error", "schema": { "title": "Error Model", "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "integer", "format": "int32" }, "message": { "type": "string" }, "helpURL": { "type": "string", "format": "url" } } } } } } } }, "definitions": { "pet": { "title": "Pet", "type": "object", "required": [ "name" ], "properties": { "name": { "type": "string", "minLength": 1, "maxLength": 25 }, "type": { "type": "string", "enum": [ "cat", "dog", "fish", "bird" ] }, "birthdate": { "type": "string", "format": "date" }, "owner": { "title": "Pet Owner", "type": "object", "required": [ "name" ], "properties": { "name": { "type": "object", "required": [ "first", "last" ], "properties": { "first": { "type": "string", "minLength": 1, "maxLength": 25 }, "last": { "type": "string", "minLength": 1, "maxLength": 25 } } }, "address": { "title": "Address", "type": "object", "properties": { "street1": { "type": "string" }, "street2": { "type": "string" }, "city": { "type": "string" }, "state": { "type": "string" }, "postalCode": { "type": "string" } } } } } } }, "pet-owner": { "title": "Pet Owner", "type": "object", "required": [ "name" ], "properties": { "name": { "type": "object", "required": [ "first", "last" ], "properties": { "first": { "type": "string", "minLength": 1, "maxLength": 25 }, "last": { "type": "string", "minLength": 1, "maxLength": 25 } } }, "address": { "title": "Address", "type": "object", "properties": { "street1": { "type": "string" }, "street2": { "type": "string" }, "city": { "type": "string" }, "state": { "type": "string" }, "postalCode": { "type": "string" } } } } }, "errorModel": { "title": "Error Model", "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "integer", "format": "int32" }, "message": { "type": "string" }, "helpURL": { "type": "string", "format": "url" } } } } } ```
Generation Details

openapitools.json

{
  "$schema": "node_modules/@openapitools/openapi-generator-cli/config.schema.json",
  "spaces": 2,
  "generator-cli": {
    "version": "5.2.1",
    "generators": {
      "go-client": {
        "generatorName": "go",
        "output": "#{cwd}/internal/api",
        "glob": "openapi.yaml",
        "enablePostProcessFile": true,
        "additionalProperties": {
          "packageName": "api",
          "isGoSubmodule": true
        }
      }
    }
  }
}

Makefile

export GO_POST_PROCESS_FILE=bash go-post-process.sh

.PHONY: openapi
openapi:
    npx @openapitools/openapi-generator-cli generate --generator-key go-client

go-post-process.sh

#!/bin/sh

gofmt -w -s $1
Generator output ``` $ make openapi npx @openapitools/openapi-generator-cli generate --generator-key go-client [[go-client] openapi.json] [main] INFO o.o.codegen.DefaultGenerator - Generating with dryRun=false [[go-client] openapi.json] [main] INFO o.o.c.ignore.CodegenIgnoreProcessor - Output directory (/mnt/internal/api) does not exist, or is inaccessible. No file (.openapi-generator-ignore) will be evaluated. [[go-client] openapi.json] [main] INFO o.o.codegen.DefaultGenerator - OpenAPI Generator: go (client) [[go-client] openapi.json] [main] INFO o.o.codegen.DefaultGenerator - Generator 'go' is considered stable. [[go-client] openapi.json] [main] INFO o.o.codegen.utils.URLPathUtils - 'host' (OAS 2.0) or 'servers' (OAS 3.0) not defined in the spec. Default to [http://localhost] for server URL [http://localhost/] [[go-client] openapi.json] [main] INFO o.o.codegen.utils.URLPathUtils - 'host' (OAS 2.0) or 'servers' (OAS 3.0) not defined in the spec. Default to [http://localhost] for server URL [http://localhost/] [[go-client] openapi.json] [main] INFO o.o.codegen.TemplateManager - writing file /mnt/internal/api/model_address.go [[go-client] openapi.json] [main] INFO o.o.c.languages.AbstractGoCodegen - Successfully executed: bash go-post-process.sh /mnt/internal/api/model_address.go [[go-client] openapi.json] [main] INFO o.o.codegen.TemplateManager - writing file /mnt/internal/api/docs/Address.md [[go-client] openapi.json] [main] INFO o.o.codegen.TemplateManager - writing file /mnt/internal/api/model_error_model.go [[go-client] openapi.json] [main] INFO o.o.c.languages.AbstractGoCodegen - Successfully executed: bash go-post-process.sh /mnt/internal/api/model_error_model.go [[go-client] openapi.json] [main] INFO o.o.codegen.TemplateManager - writing file /mnt/internal/api/docs/ErrorModel.md [[go-client] openapi.json] [main] INFO o.o.codegen.TemplateManager - writing file /mnt/internal/api/model_pet.go [[go-client] openapi.json] [main] INFO o.o.c.languages.AbstractGoCodegen - Successfully executed: bash go-post-process.sh /mnt/internal/api/model_pet.go [[go-client] openapi.json] [main] INFO o.o.codegen.TemplateManager - writing file /mnt/internal/api/docs/Pet.md [[go-client] openapi.json] [main] INFO o.o.codegen.TemplateManager - writing file /mnt/internal/api/model_pet_1.go [[go-client] openapi.json] [main] INFO o.o.c.languages.AbstractGoCodegen - Successfully executed: bash go-post-process.sh /mnt/internal/api/model_pet_1.go [[go-client] openapi.json] [main] INFO o.o.codegen.TemplateManager - writing file /mnt/internal/api/docs/Pet1.md [[go-client] openapi.json] [main] INFO o.o.codegen.TemplateManager - writing file /mnt/internal/api/model_pet_owner.go [[go-client] openapi.json] [main] INFO o.o.c.languages.AbstractGoCodegen - Successfully executed: bash go-post-process.sh /mnt/internal/api/model_pet_owner.go [[go-client] openapi.json] [main] INFO o.o.codegen.TemplateManager - writing file /mnt/internal/api/docs/PetOwner.md [[go-client] openapi.json] [main] INFO o.o.codegen.TemplateManager - writing file /mnt/internal/api/model_pet_owner_name.go [[go-client] openapi.json] [main] INFO o.o.c.languages.AbstractGoCodegen - Successfully executed: bash go-post-process.sh /mnt/internal/api/model_pet_owner_name.go [[go-client] openapi.json] [main] INFO o.o.codegen.TemplateManager - writing file /mnt/internal/api/docs/PetOwnerName.md [[go-client] openapi.json] [main] WARN o.o.codegen.DefaultCodegen - Empty operationId found for path: get /pets. Renamed to auto-generated operationId: petsGet [[go-client] openapi.json] [main] WARN o.o.codegen.DefaultCodegen - Empty operationId found for path: post /pets. Renamed to auto-generated operationId: petsPost [[go-client] openapi.json] [main] WARN o.o.codegen.DefaultCodegen - Empty operationId found for path: get /pets/{name}. Renamed to auto-generated operationId: petsNameGet [[go-client] openapi.json] [main] INFO o.o.codegen.utils.URLPathUtils - 'host' (OAS 2.0) or 'servers' (OAS 3.0) not defined in the spec. Default to [http://localhost] for server URL [http://localhost/] [[go-client] openapi.json] [main] INFO o.o.codegen.TemplateManager - writing file /mnt/internal/api/api_default.go [[go-client] openapi.json] [main] INFO o.o.c.languages.AbstractGoCodegen - Successfully executed: bash go-post-process.sh /mnt/internal/api/api_default.go [[go-client] openapi.json] [main] INFO o.o.codegen.TemplateManager - writing file /mnt/internal/api/docs/DefaultApi.md [[go-client] openapi.json] [main] INFO o.o.codegen.utils.URLPathUtils - 'host' (OAS 2.0) or 'servers' (OAS 3.0) not defined in the spec. Default to [http://localhost] for server URL [http://localhost/] [[go-client] openapi.json] [main] INFO o.o.codegen.TemplateManager - writing file /mnt/internal/api/api/openapi.yaml [[go-client] openapi.json] [main] INFO o.o.codegen.TemplateManager - writing file /mnt/internal/api/README.md [[go-client] openapi.json] [main] INFO o.o.codegen.TemplateManager - writing file /mnt/internal/api/git_push.sh [[go-client] openapi.json] [main] INFO o.o.codegen.TemplateManager - writing file /mnt/internal/api/.gitignore [[go-client] openapi.json] [main] INFO o.o.codegen.TemplateManager - writing file /mnt/internal/api/configuration.go [[go-client] openapi.json] [main] INFO o.o.codegen.TemplateManager - writing file /mnt/internal/api/client.go [[go-client] openapi.json] [main] INFO o.o.codegen.TemplateManager - writing file /mnt/internal/api/response.go [[go-client] openapi.json] [main] INFO o.o.codegen.TemplateManager - writing file /mnt/internal/api/go.mod [[go-client] openapi.json] [main] INFO o.o.codegen.TemplateManager - writing file /mnt/internal/api/go.sum [[go-client] openapi.json] [main] INFO o.o.codegen.TemplateManager - writing file /mnt/internal/api/.travis.yml [[go-client] openapi.json] [main] INFO o.o.codegen.TemplateManager - writing file /mnt/internal/api/utils.go [[go-client] openapi.json] [main] INFO o.o.codegen.TemplateManager - writing file /mnt/internal/api/.openapi-generator-ignore [[go-client] openapi.json] [main] INFO o.o.codegen.TemplateManager - writing file /mnt/internal/api/.openapi-generator/VERSION [[go-client] openapi.json] [main] INFO o.o.codegen.TemplateManager - writing file /mnt/internal/api/.openapi-generator/FILES [[go-client] openapi.json] ################################################################################ [[go-client] openapi.json] # Thanks for using OpenAPI Generator. # [[go-client] openapi.json] # Please consider donation to help us maintain this project ? # [[go-client] openapi.json] # https://opencollective.com/openapi_generator/donate # [[go-client] openapi.json] ################################################################################ [[go-client] openapi.json] java -jar "/root/.npm/_npx/6e21a6866cba782f/node_modules/@openapitools/openapi-generator-cli/versions/5.2.1.jar" generate --input-spec="/mnt/openapi.json" --generator-name="go" --output="/mnt/internal/api" --enable-post-process-file --additional-properties="packageName=api,isGoSubmodule=true" exited with code 0 [go-client] openapi.json ```

Excerpts

Regular generated files are being post processed.

[[go-client] openapi.json] [main] INFO  o.o.codegen.TemplateManager - writing file /mnt/internal/api/model_address.go
[[go-client] openapi.json] [main] INFO  o.o.c.languages.AbstractGoCodegen - Successfully executed: bash go-post-process.sh /mnt/internal/api/model_address.go
[[go-client] openapi.json] [main] INFO  o.o.codegen.TemplateManager - writing file /mnt/internal/api/docs/Address.md
[[go-client] openapi.json] [main] INFO  o.o.codegen.TemplateManager - writing file /mnt/internal/api/model_error_model.go
[[go-client] openapi.json] [main] INFO  o.o.c.languages.AbstractGoCodegen - Successfully executed: bash go-post-process.sh /mnt/internal/api/model_error_model.go
[[go-client] openapi.json] [main] INFO  o.o.codegen.TemplateManager - writing file /mnt/internal/api/docs/ErrorModel.md
[[go-client] openapi.json] [main] INFO  o.o.codegen.TemplateManager - writing file /mnt/internal/api/model_pet.go
[[go-client] openapi.json] [main] INFO  o.o.c.languages.AbstractGoCodegen - Successfully executed: bash go-post-process.sh /mnt/internal/api/model_pet.go
[[go-client] openapi.json] [main] INFO  o.o.codegen.TemplateManager - writing file /mnt/internal/api/docs/Pet.md
[[go-client] openapi.json] [main] INFO  o.o.codegen.TemplateManager - writing file /mnt/internal/api/model_pet_1.go
[[go-client] openapi.json] [main] INFO  o.o.c.languages.AbstractGoCodegen - Successfully executed: bash go-post-process.sh /mnt/internal/api/model_pet_1.go
[[go-client] openapi.json] [main] INFO  o.o.codegen.TemplateManager - writing file /mnt/internal/api/docs/Pet1.md
[[go-client] openapi.json] [main] INFO  o.o.codegen.TemplateManager - writing file /mnt/internal/api/model_pet_owner.go
[[go-client] openapi.json] [main] INFO  o.o.c.languages.AbstractGoCodegen - Successfully executed: bash go-post-process.sh /mnt/internal/api/model_pet_owner.go
[[go-client] openapi.json] [main] INFO  o.o.codegen.TemplateManager - writing file /mnt/internal/api/docs/PetOwner.md
[[go-client] openapi.json] [main] INFO  o.o.codegen.TemplateManager - writing file /mnt/internal/api/model_pet_owner_name.go
[[go-client] openapi.json] [main] INFO  o.o.c.languages.AbstractGoCodegen - Successfully executed: bash go-post-process.sh /mnt/internal/api/model_pet_owner_name.go

However, supporting files are not.

[[go-client] openapi.json] [main] INFO  o.o.codegen.TemplateManager - writing file /mnt/internal/api/configuration.go
[[go-client] openapi.json] [main] INFO  o.o.codegen.TemplateManager - writing file /mnt/internal/api/client.go
[[go-client] openapi.json] [main] INFO  o.o.codegen.TemplateManager - writing file /mnt/internal/api/response.go
Steps to reproduce
  1. Copy openapi.json, openapitools.json, Makefile, and go-post-process.sh into a directory
  2. Run make openapi
  3. Results should be identical to the logs above.
Related issues/PRs
Suggest a fix

Golang sets supporting-mustache as a support file type for post processing here but DefaultGenerator calls the post processor with type supporting-file here which isn't listed as a valid type according to the docstring for postProcessFile.

The proposal is to change the call to postProcessFile() and pass in supporting-mustache instead of supporting-file.

This likely affects other generated clients as well if implementors reference the docstring of postProcessFile as opposed to the code, as is the case of CLibcurlClientCodegen.java

ashb commented 1 year ago

Still an issue on 6.6.0