OpenAPITools/openapi-generator

[BUG] [Ruby] enum with value 'end' causes runtime syntax error

mooreds opened this issue · 4 comments

Bug Report Checklist

  • Have you provided a full/minimal spec to reproduce the issue?
  • Have you validated the input using an OpenAPI validator (example)?
  • Have you tested with the latest master to confirm the issue still exists?
  • Have you searched for related issues/PRs?
  • What's the actual output vs expected output?
  • [Optional] Sponsorship to speed up the bug fix or feature request (example)
Description

I have an openapi template with an enum with a value of end. While code generation succeeds, the generated code is not compatible with ruby (tested under 2.7.0, 3.0.2 gave me a different error).

openapi-generator version
$ npx @openapitools/openapi-generator-cli version
5.3.1

Not a regression as far as I know. I didn't see any closed bugs describing the issue.

OpenAPI declaration file content or url
openapi: "3.0.3"
info:
  version: 1.0.0
  license:
    name: Apache2
  title: "Test API"

paths:
  "/api/test/useractionphase":
    post:
      requestBody:
        content:
          application/json:
            schema:
              "$ref": "#/components/schemas/UserActionPhase"
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/SendResponse"
        default:
          description: Error
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/Errors"
components:
  schemas:
    Errors:
      type: string
      enum:
      - success
    SendResponse:
      type: string
      enum:
      - error
    UserActionPhase:
      description: The phases of a time-based user action.
      type: string
      enum:
      - start
      - modify
      - cancel
      - end
  securitySchemes:
    apikey:
      type: apiKey
      name: Authorization
      in: header

Here's the script code (it is pulled from the readme):

require 'openapi_client'

api_instance = OpenapiClient::DefaultApi.new
opts = {
  body: 'body_example' # String |
}

begin
  result = api_instance.api_test_useractionphase_post(opts)
  p result
rescue OpenapiClient::ApiError => e
  puts "Exception when calling DefaultApi->api_test_useractionphase_post: #{e}"
end
Generation Details
  • npx @openapitools/openapi-generator-cli generate -i openapi.yaml -g ruby -o ruby
Steps to reproduce
  • run the script: ruby -Iruby/lib script.rb

You get the error message:

Traceback (most recent call last):
	5: from script.rb:1:in `<main>'
	4: from /Users/dan/.rvm/rubies/ruby-2.7.0/lib/ruby/2.7.0/rubygems/core_ext/kernel_require.rb:72:in `require'
	3: from /Users/dan/.rvm/rubies/ruby-2.7.0/lib/ruby/2.7.0/rubygems/core_ext/kernel_require.rb:72:in `require'
	2: from /path/to/ruby/lib/openapi_client.rb:22:in `<top (required)>'
	1: from /Users/dan/.rvm/rubies/ruby-2.7.0/lib/ruby/2.7.0/rubygems/core_ext/kernel_require.rb:72:in `require'
/Users/dan/.rvm/rubies/ruby-2.7.0/lib/ruby/2.7.0/rubygems/core_ext/kernel_require.rb:72:in `require': /path/to/ruby/lib/openapi_client/models/user_action_phase.rb:21: syntax error, unexpected '=', expecting '{' (SyntaxError)
    END = "end".freeze

Looking at user_action_phase.rb:

# ...
    START = "start".freeze
    MODIFY = "modify".freeze
    CANCEL = "cancel".freeze
    END = "end".freeze
# ...

If you change END = "end".freeze to END1 = "end".freeze then ruby can execute.

I tried looking at the templates to modify how the enum was generated but couldn't figure out how to change it with just a template. I also looked at changing the value in the openapi yaml file, but enums don't support any metadata (the value that is passed to the endpoint needs to be end, unfortunately).

Related issues/PRs

I didn't see any related issues.

https://stackoverflow.com/questions/66465888/how-to-define-enum-mapping-in-openapi has some suggestions, but it doesn't look like x-enum-varnames is supported: https://github.com/OpenAPITools/openapi-generator/blob/master/docs/generators/ruby.md

Suggest a fix

Maybe I could use RUBY_POST_PROCESS_FILE to postprocess the file? I'm not familiar with the ruby codegen process, but https://github.com/OpenAPITools/openapi-generator/blob/master/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractRubyCodegen.java looks like it has end as a reserved word. Maybe there's an enum processing in https://github.com/OpenAPITools/openapi-generator/blob/master/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java#L670 that needs to be modified? Or allowableValues needs to handle uppercase? I'm speculating here.

Workaround:

Put the following in a shell script:

/usr/bin/sed -i "" 's/END = "end".freeze/END_ENUM = "end".freeze/' $1

Then add that as a postprocess step:

export RUBY_POST_PROCESS_FILE=/path/to/shellscript.sh

Then postprocess your ruby client libraries:

npx @openapitools/openapi-generator-cli generate  --enable-post-process-file  -i openapi.yaml  -g ruby -o ruby

With 7.2 you need to use the following postprocess.sh file

/usr/bin/sed -i "" 's/END = "end".freeze/END_ENUM = "end".freeze/' $1
/usr/bin/sed -i "" 's/END]/END_ENUM]/' $1

thanks for sharing the workaround.

I've filed #17537 to add enum name mapping feature to the Ruby generators so one can map end to something else in a single command.

Thanks @wing328 I look forward to testing this when 7.3.0 is released. Cheers!