kpramesh2212 / openapi-merger-plugin

A plugin to merge openapi v3 files
Apache License 2.0
20 stars 8 forks source link

Cannot create regular YAML multiline (without \n) description for "info" field #9

Closed ReginaldoSantos closed 3 years ago

ReginaldoSantos commented 3 years ago

Plugin version: 1.0.3 (also happens with 1.0.4)

./gradlew --version

------------------------------------------------------------
Gradle 6.6.1
------------------------------------------------------------

Build time:   2020-08-25 16:29:12 UTC
Revision:     f2d1fb54a951d8b11d25748e4711bec8d128d7e3

Kotlin:       1.3.72
Groovy:       2.5.12
Ant:          Apache Ant(TM) version 1.10.8 compiled on May 10 2020
JVM:          11.0.11 (Ubuntu 11.0.11+9-Ubuntu-0ubuntu2.20.04)
OS:           Linux 5.8.0-59-generic amd64

build.gradle snippet:

    openApi {
        openApiVersion.set("3.0.1")

        info {
            title.set("Test API".toString())
            description.set('''
              This is the Test API.
              We are trying to add nice and detailed description in YAML info field.
              However, no matter what kind of groovy multiline syntax we use, it is not possible to avoid java line breaks "\n".
              It is desirable that the merge generates pretty clean YAML multiline.
            ''')
            version.set("${project.version}".toString())
            contact {
              name.set("Test API Team")
              email.set("testapiteam@test.cloud")
              url.set("http://testapiteam.cloud")
            }
        }
    }

result snippet:

openapi: 3.0.1
info:
  title: Test API
  description: "\n              This is the Test API.\n              We are trying\
    \ to add nice and detailed description in YAML info field.\n              However,\
    \ no matter what kind of groovy multiline syntax we use, it is not possible to\
    \ avoid java line breaks \"\n\".\n              It is desirable that the merge\
    \ generates pretty clean YAML multiline.\n            "
  contact:
    name: Test API Team
    url: http://testapiteam.cloud
    email: testapiteam@test.cloud
  version: 1.0.0

Let me know if you need any more details to dig on that!

kpramesh2212 commented 3 years ago

@ReginaldoSantos

You're using in kotlin's multiline string literal feature for the description field in the build.gradle.kts file.

If you use the multiline string literal all the escape characters would be preserved thats the reason your description is having the new line character and extra spaces.

pasting the openapi spec in a swagger editor renders the description as expected.

image

image

However if you prefer to not have spaces or new line character then String concatenation would be the best approach.

kpramesh2212 commented 3 years ago

kk Let me check groovy syntax.

kpramesh2212 commented 3 years ago

kk I need to do more investigation here.

ReginaldoSantos commented 3 years ago

Yes @kpramesh2212, I'm using build.gradle (groovy).

Another point is that, even though Swagger Editor renders it well, some generators have problems with that.

For instance, I'm using IBM/openapi-to-graphql and the graphQL playground does not show all the properties when the origin YAML has those "\n" (it works fine so). We could say that is a problem of "openapi-to-graphql", however, once the YAML has its properties changed, I would say it is indeed a "merge issue".

ReginaldoSantos commented 3 years ago

@kpramesh2212 check the attachment in my other issue comment. It was made to reproduce both problems.

kpramesh2212 commented 3 years ago

@ReginaldoSantos

There are 2 problems here in the description field

  1. Comma (,) is not considered as a valid character for generating multi line yaml strings by the underlying swagger lib which in turn uses Jackson yaml parser (I couldnt understand why)

  2. If the string has empty spaces at the end then that is also not considered as a valid character for generating multi line yaml strings

Hence to resolve your problem I had to do the following

Note: I removed all commas from your description and added trim() at the end of description

image

The generated output (groovy dsl)

Note: Generated String is multi line and they are not nicely formatted that's because of groovy

image

The same in Kotlin

image

Note: Generated String is multi line and they are formated nicely (thanks to Kotlin's trimIntend method on the String)

image

ReginaldoSantos commented 3 years ago

@kpramesh2212 wow! You really dig in! Tks.

Indeed very odd behavior with commas (,). I got the same error with colons (:) before a space, but this is documented here.

Last line:

"Plain flow scalars are picky about the : and # characters. They can be in the string, but : cannot appear before a space or newline, and # cannot appear after a space or newline; doing this will cause a syntax error. "

Also, I could fix the indentation with "stripIndent()" from Groovy:

            description.set('''
              This is the Test API.

              We are trying to add nice and detailed description in YAML info field.
              However no matter what kind of groovy multiline syntax we use it is not possible to avoid java line breaks.
              It is desirable that the merge generates pretty clean multiline YAML properties. Example:

                - This is example without colon in the middle;
            '''.stripIndent().trim())

Generated: image

Anyway, this is a workaround, cannot say I'm happy of removing commas from the docs, but I understand problem would lay on "Jackson yaml parser" and not in the plugin.

Thank you very much for your effort to solve this quickly!!!