Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
5 of 6 tasks
mooreds opened this issue Jan 18, 2022 · 4 comments · Fixed by #17537
Closed
5 of 6 tasks

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

mooreds opened this issue Jan 18, 2022 · 4 comments · Fixed by #17537

Comments

@mooreds
Copy link

mooreds commented Jan 18, 2022

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.

@mooreds mooreds changed the title [BUG] [Ruby] enum with value 'end' causes codegen to fail [BUG] [Ruby] enum with value 'end' causes runtime syntax error Jan 18, 2022
@mooreds
Copy link
Author

mooreds commented Jan 19, 2022

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

@mooreds
Copy link
Author

mooreds commented Jan 5, 2024

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

@wing328
Copy link
Member

wing328 commented Jan 5, 2024

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.

@mooreds
Copy link
Author

mooreds commented Jan 5, 2024

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants