Giter Site home page Giter Site logo

yelp / swagger-gradle-codegen Goto Github PK

View Code? Open in Web Editor NEW
407.0 18.0 37.0 562 KB

πŸ’« A Gradle Plugin to generate your networking code from Swagger

License: Apache License 2.0

Kotlin 84.42% Shell 0.09% Mustache 15.49%
swagger swagger2 swagger-codegen swagger-api swagger-generator swagger-spec kotlin kotlin-android gradle gradle-plugin

swagger-gradle-codegen's Introduction

Swagger Gradle Codegen

Plugin Portal Pre Merge Checks License Join the chat at https://kotlinlang.slack.com Twitter

A Gradle plugin to generate networking code from a Swagger spec file.

This plugin wraps swagger-codegen, and exposes a configurable generateSwagger gradle task that you can plug inside your gradle build/workflows.

Getting Started

Swagger Gradle Codegen is distributed through Gradle Plugin Portal. To use it you need to add the following dependency to your gradle files. Please note that those code needs to be added the gradle file of the module where you want to generate the code (not the top level build.gradle[.kts] file).

If you're using the Groovy Gradle files:

buildscript {
    repositories {
        maven { url "https://plugins.gradle.org/m2/" }
    }

    dependencies {
        classpath "com.yelp.codegen:plugin:<latest_version>"
    }
}

apply plugin: "com.yelp.codegen.plugin"

generateSwagger {
    platform = "kotlin"
    packageName = "com.yelp.codegen.samples"
    inputFile = file("./sample_specs.json")
    outputDir = file("./src/main/java/")
}

If you're using the Kotlin Gradle files:

plugins {
    id("com.yelp.codegen.plugin") version "<latest_version>"
}

generateSwagger {
    platform.set("kotlin")
    packageName.set("com.yelp.codegen.samples")
    inputFile.set(file("./sample_specs.json"))
    outputDir.set(project.layout.buildDirectory.dir("./src/main/java/"))
}

Please note that the generateSwagger { } block is needed in order to let the plugin work.

Once you setup the plugin correctly, you can call the :generateSwagger gradle task, that will run the code generation with the configuration you provided.

Requirements

In order to run this gradle plugin you need to fulfill the following requirements:

  • Gradle 6.x - This plugin uses Gradle 6 features, and you will need to setup your Gradle wrapper to use 6.8 or more.
  • Java 8+

Supported platforms

The Swagger Gradle Codegen is designed to support multiple platforms. For every platform, we provide templates that are tested and generates opinionated code.

Here the list of the supported platforms:

Platform Description
kotlin Generates Kotlin code and Retrofit interfaces, with RxJava2 for async calls and Moshi for serialization
kotlin-coroutines Generates Kotlin code and Retrofit interfaces, with Kotlin Coroutines for async calls and Moshi for serialization

We're looking forward to more platforms to support in the future. Contributions are more than welcome.

Examples

You can find some examples in this repository to help you set up your generator environment.

  • samples/groovy-android Contains an example of an Android Library configured with a build.gradle file, using the classical Gradle/Groovy as scripting language.

  • samples/kotlin-android Contains an example of an Android Library configured with a build.gradle.kts file, using Kotlin as scripting language.

  • samples/kotlin-coroutines Contains an example of an Android Library configured to output Kotlin Coroutines capable code.

  • samples/junit-tests This sample contains specs used to test edge cases and scenarios that have been reported in the issue tracker or that are worth testing. Tests are executed using moshi-codegen. It does also contains all the generated code inside the /scr/main/java folder. You can use this example to see how the generated code will look like (like here).

How the generated code will look like

Here you can find some examples of how the generated code will look like in your project.

Configuration

To configure the generator, please use the generateSwagger { } block. Here an example of this block with all the properties.

generateSwagger {
    platform.set("kotlin")
    packageName.set("com.yelp.codegen.integrations")
    specName.set("integration")
    specVersion.set("1.0.0")
    inputFile.set(file("../sample_specs.json"))
    outputDir.set(project.layout.buildDirectory.dir("./src/main/java/"))
    features {
        headersToRemove.add("Accept-Language")
    }
}

And here a table with all the properties and their default values:

Property Description Default
inputFile Defines the path to the Swagger spec file REQUIRED
platform Defines the platform/templates that will be used. See Supported platforms for a list of them. "kotlin"
packageName Defines the fully qualified package name that will be used as root when generating the code. "com.codegen.default"
specName Defines the name of the service that is going to be built. "defaultname"
specVersion Defines the version of the spec that is going to be used. If not provided, the version will be read from the specfile. If version is missing will default to "0.0.0"
outputDir Defines the output root folder for the generated files. $buildDir/gen
extraFiles Defines a folder with extra files that will be copied over after the generation (e.g. util classes or overrides). not set by default

Please note that all those properties can be configured with command line flags that mirrors 1:1 the property name. E.g.:

./gradlew generateSwagger --inputFile=./sample/specs.json

Extra Features

You can use the features { } block to specify customization or enabled/disable specific features for your generator.

Here a list of all the supported features:

Feature Description Command line
headersToRemove List of headers that needs to be ignored for every endpoints. The headers in this list will be dropped and not generated as parameters for the endpoints. -ignoreheaders=

Building

To contribute or to start developing the Swagger Codegen Plugin, you need to set up your environment.

Make sure you have:

  • Python (needed for pre-commit hook)
  • Java/Kotlin (needed for compiling the plugin code)

We also recommend you set up:

  • aactivator To correctly manage your venv connected to this project
  • IntelliJ IDEA Either the Community or the Ultimate edition are great to contribute to the plugin.

Before starting developing, please run:

./gradlew installHooks

This will take care of installing the pre-commit hooks to keep a consistent style in the codebase.

While developing, you can build, run pre-commits, checks & tests on the plugin using:

./gradlew preMerge

Make sure your tests are all green βœ… locally before submitting PRs.

NOTE: If you don't have the Android SDK you can skip the Android related tasks by setting SKIP_ANDROID enviromental variable (tests will be run on the CI anyway).

Contributing/Support

Support for this project is offered in the #swagger-gradle-codegen channel on the Kotlinlang slack (request an invite here).

We're looking for contributors! Feel free to open issues/pull requests to help me improve this project.

If you found a new issue related to incompatible Swagger specs, please attach also the spec file to help investigate the issue.

License πŸ“„

This project is licensed under the Apache 2.0 License - see the License file for details

swagger-gradle-codegen's People

Contributors

agologan avatar cortinico avatar doug-precocity avatar filipemp avatar guilhe avatar macisamuele avatar markov avatar martinbonnin avatar matthewtpage avatar redwarp avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

swagger-gradle-codegen's Issues

Build failed on Version 1.1.0

Once I update the version to 1.1.0 it gave build failure but the plugin is working with version 1.0.0

> Task :generateSwagger FAILED
####################
Yelp Swagger Codegen
####################
Platform         kotlin
Package          com.yelp.codegen.integrations
specName         integration
specVers         1.0.0
input            /Users/chatura/swagger-gen/swagger-gradle-codegen-master/samples/sample_specs.json
output           /Users/chatura/swagger-gen/swagger-gradle-codegen-master/samples/groovy-android/src/main/java
groupId          com.yelp.codegen.integrations
artifactId       com.yelp.codegen.integrations
features         Accept-Language

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':generateSwagger'.
> com/yelp/codegen/utils/InlineModelResolver has been compiled by a more recent version of the Java Runtime (class file version 55.0), this version of the Java Runtime only recognizes class file versions up to 52.0

These are my configurations

------------------------------------------------------------
Gradle 5.5
------------------------------------------------------------

Build time:   2019-06-28 17:36:05 UTC
Revision:     83820928f3ada1a3a1dbd9a6c0d47eb3f199378f

Kotlin:       1.3.31
Groovy:       2.5.4
Ant:          Apache Ant(TM) version 1.9.14 compiled on March 12 2019
JVM:          1.8.0_212 (AdoptOpenJDK 25.212-b04)
OS:           Mac OS X 10.13.6 x86_64

securityDefinitions are not added to the headers

Thank you for the great plugin.

It seems security definitions are not added to the headers and generated code has empty headers which giving runtime errors. Please see below swagger example.

"/login": {
            "post": {

                "security": [
                    {
                        "apiKey": []
                    }
                ] 
            }
        }
"securityDefinitions": {
        "apiKey": {
            "type": "apiKey",
            "name": "x-api-key",
            "in": "header"
        },
        "accessToken": {
            "type": "apiKey",
            "name": "x-access-token",
            "in": "header",
            "description": "Unique user authentication token"
        }
    }

Runtime Error on ZonedDateTime

I'm getting runtime error while converting bellow date-time , how can I fix this ?

 "expirationTime": {
          "type": "string",
          "format": "date-time",
          "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`"
        }
Caused by: java.lang.IllegalArgumentException: Cannot serialize abstract class org.threeten.bp.ZoneId
    for class org.threeten.bp.ZoneId zone
    for class org.threeten.bp.ZonedDateTime expirationTime

Question: what if we have multiple input files?

I'm in a situation where we rely on at least three swagger files for 3rd party APIs that we consume.

What is the recommendation for setting up a gradle file to generate code for three or several dozen swagger files?

Thanks!

How to remove usingPUT?

1, How to remove ALL usingPUT/usingPOST/UsingGET1/using* at the end of the suspend fun?

2, How to remove header:

"X-Operation-ID: blabla"?

3, How to generate responses under models/responses and requests under models/requests?

BTW, Thanks for the library!

Arrays handling seems bugged

I found a bug when generating api for a service responsing with an array of objects. Generated code doesn't point to proper class definition (TestObject in the example below replaced with Any?) despite it was properly generated.

Input:

{
  "swagger": "2.0",
  "info": {
    "version": "1.0",
    "title": "test-swagger",
    "description": "https://test-swagger.com/"
  },
  "schemes": [
    "https",
    "http"
  ],
  "produces": [
    "application/json"
  ],
  "consumes": [
    "application/json"
  ],
  "paths": {
    "/api/test/swagger": {
      "get": {
        "tags": [
          "test-swagger"
        ],
        "summary": "Test swagger.",
        "parameters": [
          {
            "name": "id",
            "in": "query",
            "required": true,
            "description": "Uniqe id.",
            "type": "string"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "schema": {
              "properties": {
                "cities": {
                  "type": "array",
                  "items": {
                    "$ref": "#/definitions/TestObject"
                  }
                }
              }
            }
          }
        }
      }
    }
  },
  "definitions": {
    "TestObject": {
      "properties": {
        "name": {
          "type": "string"
        }
      }
    }
  }
}

Output:

package com.test.package.apis

import com.test.package.models.Any?
import retrofit2.http.GET
import retrofit2.http.Headers

@JvmSuppressWildcards
interface TestSwaggerApi {
    /**
     * Test swagger.
     * The endpoint is owned by defaultname service owner
     * @param id Uniqe id. (required)
     */
    @Headers(
        "Content-Type: application/json"
    )
    @GET("/api/test/swagger")
    suspend fun apiTestSwaggerGet(
        @retrofit2.http.Query("id") id: String
    ): Map<String, Any?>
}
package com.test.package.models

import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass

/**
 * @property name
 */
@JsonClass(generateAdapter = true)
data class TestObject(
    @Json(name = "name") @field:Json(name = "name") var name: String? = null
)

Endpoint URL is invalid

In Retrofit, baseUrl must end in "/" hence endpoint must start without "/"
Ex:

Plugin generated endpoint starts with "/"

@GET("/devices")
 fun devicesGet(
   @retrofit2.http.Query("all") all: Boolean?,
   @retrofit2.http.Query("userId") userId: Int?,
   @retrofit2.http.Query("id") id: Int?,
   @retrofit2.http.Query("uniqueId") uniqueId: String?
 ): Single<List<Device>>

which should remove "/" from the API interface like

  @GET("devices")
  fun devicesGet(
    @retrofit2.http.Query("all") all: Boolean?,
    @retrofit2.http.Query("userId") userId: Int?,
    @retrofit2.http.Query("id") id: Int?,
    @retrofit2.http.Query("uniqueId") uniqueId: String?
  ): Single<List<Device>>

New enum from API support

Hi!

First off thank you for taking the time maintaining this library and for sharing it.

I was wondering how I can handle the case when the backend adds a new enum case to the api. In our current implementation using Moshi we fallback to null when mapping those. Using the generated code from this library our deserialization fails if we send a new enum case in the JSON response. How are you currently solving this case? Is this something that is supported?

Thanks!

Jon

Usage and dependency documentation

Thanks for the great project! I just wanted to suggest adding some details to the documentation regarding usage as well as dependencies.

It's true that all of these things are available in the code via tests but it's not super intuitive where to find them. As I write this I know that I found the usage; it's fairly easy but since I didn't commit it to memory I'll have to dig through the tests again.

The same is true for the dependencies for Retrofit and Moshi and whatever else I might need. I'll have to dig around in the code to find out what version is supported.

To solve this, it would be great to have something in the README that has the 3-4 lines of code needed to use the generated output as well as the list of dependencies that need to be added to the build.

Thanks!

Setup CodeCov

We currently don't track code coverage.

Given that I added a lot of JUnit tests here #48 and #42 would probably be valuable to have Codecov reporting the coverage change on every Pull Request.

Read Swagger.json from URL

Can Specification be read from a URL ?

Also Do you have any sample code of using these with Rx and Retrofit?

Generate files under `build/generated/`

The plugin could generate the files under a separate build/generated directory so as not to pollute the src/main/java sourceSet. Also, it would be nice to add generateSwagger as a prerequisite of compileKotlin

Handle null values in Kotlin TypesAdapter

Example: Null values for BigDecimal in request body will throw "Nesting Problem" error. Description of root cause is similar to the issue described here: square/moshi#806

The TypesAdapter will need explicit handling for null values to prevent this.

Add support for moshi-kotlin-codegen

We're currently generating code that relies on moshi-kotlin:

private val moshi = Moshi.Builder()
.add(XNullableAdapterFactory())
.add(KotlinJsonAdapterFactory())
.add(TypesAdapterFactory())
.build()

This has the side effect of pulling in the kotlin-reflect dependency that is a pretty big jar.

We should consider moving over to moshi-kotlin-codegen.

Ideally we just need to generate the @JsonClass annotation for our data classes and make sure we provide proper proguard rules for it.

Sample doesn't works

I use the sample project android kotlin, but i have an error when i run generateSwagger

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':app:generateSwagger'.
> com/yelp/codegen/utils/InlineModelResolver

and with a swagger v3, i have a diffrent result

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':app:generateSwagger'.
> missing swagger input or config!

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

Plugin is failing with endpoints and inlined parameters + additionalProperties

Just got a bug report on Slack for swagger-gradle-codegen (credits to @vanniktech). After some small investigation with @macisamuele looks like the issue is with paths that have parameters with inlined additional properties.

Here a minimal spec that is breaking the plugin:

{
  "swagger": "2.0",
  "info": {
    "version": "1.0",
    "title": ""
  },
  "definitions": {
    "model": {
      "type": "object",
      "additionalProperties": {
        "type": "string"
      }
    }
  },
  "paths": {
    "/works": {
      "post": {
        "parameters": [
          {
            "in": "body",
            "name": "body",
            "schema": {
              "$ref" : "#/definitions/model"
            }
          }
        ],
        "responses": {
          "default": {
            "description": "something"
          }
        }
      }
    },
    "/broken": {
      "post": {
        "parameters": [
          {
            "in": "body",
            "name": "body",
            "schema": {
              "type": "object",
              "additionalProperties": {
                "type": "string"
              }
            }
          }
        ],
        "responses": {
          "default": {
            "description": "something"
          }
        }
      }
    }
  }
}

The current workaround is to replace this:

         {
            "in": "body",
            "name": "body",
            "schema": {
              "type": "object",
              "additionalProperties": {
                "type": "string"
              }
            }
          }

with:

          {
            "in": "body",
            "name": "body",
            "schema": {
              "$ref" : "#/definitions/model"
            }
          }

And have the additionalProperties not defined inline.

Here the failure message:

Execution failed for task ':generateSwagger'.
> Could not process operation:
    Tag: Tag {
  	name: default
  	description: null
  	externalDocs: null
  	extensions:{}}
    Operation: null
    Resource: post /broken
    Definitions: {model=io.swagger.models.ModelImpl@a2a8ef}
    Exception: null cannot be cast to non-null type io.swagger.models.ModelImpl

Kotlin support of "." (dot) on variable name causing an issue with query parameters' kotlin variable names with dots is shown as syntax error.

  fun apiSectionsArticlesGetSubresource(
    @retrofit2.http.Path("id") id: String,
    @retrofit2.http.Query("dateCreated[before]") dateCreatedBefore: String?,
   ...
   ...
    @retrofit2.http.Query("datePublished[after]") datePublishedAfter: String?,
    @retrofit2.http.Query("datePublished[strictly_after]") datePublishedStrictlyAfter: String?,
    @retrofit2.http.Query("author") author: String?,
    @retrofit2.http.Query("author[]") author2: List<String>?,
This above was fixed in #31 
    @retrofit2.http.Query("articlesection.name") articlesection.name: String?, //Shown as syntax error articlesection.name

    @retrofit2.http.Query("articlesection") articlesection: String?,
    @retrofit2.http.Query("articlesection[]") articlesection2: List<String>?, #fix 31
    @retrofit2.http.Query("author.name") authorname: String?,// Manual Fix , remove dot . 
    @retrofit2.http.Query("page") page: Int?,
    @retrofit2.http.Query("itemsPerPage") itemsPerPage: Int?
  ): Single<List<ArticleMinusarticleRead>>```

Swagger

{
        "tags": [
          "Article"
        ],
        "summary": "Retrieves the collection of Article resources.",
        "operationId": "getArticleCollection",
        "produces": [
          "application/ld+json",
          "application/json",
          "text/html",
          "application/hal+json",
          "multipart/form-data",
          "application/vnd.api+json"
        ],
        "parameters": [
          {
            "name": "dateCreated[before]",
            "in": "query",
            "required": false,
            "type": "string"
          },
          {
            "name": "dateCreated[strictly_before]",
            "in": "query",
            "required": false,
            "type": "string"
          },
          {
            "name": "dateCreated[after]",
            "in": "query",
            "required": false,
            "type": "string"
          },
          {
            "name": "dateCreated[strictly_after]",
            "in": "query",
            "required": false,
            "type": "string"
          },
          {
            "name": "dateModified[before]",
            "in": "query",
            "required": false,
            "type": "string"
          },
          {
            "name": "dateModified[strictly_before]",
            "in": "query",
            "required": false,
            "type": "string"
          },
          {
            "name": "dateModified[after]",
            "in": "query",
            "required": false,
            "type": "string"
          },
          {
            "name": "dateModified[strictly_after]",
            "in": "query",
            "required": false,
            "type": "string"
          },
          {
            "name": "datePublished[before]",
            "in": "query",
            "required": false,
            "type": "string"
          },
          {
            "name": "datePublished[strictly_before]",
            "in": "query",
            "required": false,
            "type": "string"
          },
          {
            "name": "datePublished[after]",
            "in": "query",
            "required": false,
            "type": "string"
          },
          {
            "name": "datePublished[strictly_after]",
            "in": "query",
            "required": false,
            "type": "string"
          },
          {
            "name": "author",
            "in": "query",
            "required": false,
            "type": "string"
          },
          {
            "name": "author[]",
            "in": "query",
            "required": false,
            "type": "array",
            "items": {
              "type": "string"
            },
            "collectionFormat": "multi"
          },
          {
            "name": "articlesection.name",
            "in": "query",
            "required": false,
            "type": "string"
          },
          {
            "name": "articlesection",
            "in": "query",
            "required": false,
            "type": "string"
          },
          {
            "name": "articlesection[]",
            "in": "query",
            "required": false,
            "type": "array",
            "items": {
              "type": "string"
            },
            "collectionFormat": "multi"
          },
          {
            "name": "author.name",
            "in": "query",
            "required": false,
            "type": "string"
          },
          {
            "name": "page",
            "in": "query",
            "description": "The collection page number",
            "required": false,
            "type": "integer"
          },
          {
            "name": "itemsPerPage",
            "in": "query",
            "description": "The number of items per page",
            "required": false,
            "type": "integer"
          }
        ],
        "responses": {
          "200": {
            "description": "Article collection response",
            "schema": {
              "type": "array",
              "items": {
                "$ref": "#/definitions/Article-article.read"
              }
            }
          }
        }
      }

Add code examples for the generated code

The project received a lot of feedbacks related to "how the generated code will look like". @jbrick Suggested we should add a section with Example of Generated code. Also this should highlight that we generate both Retrofit Apis and Kotlin Data classes (as is not really visible from the README).

Endpoint URL is invalid

@cortinico This is with regards to #46 ,

My API base URL is something like this https://example.com/api/v5/ and Retrofit required "/" at the end of the base URL.

Since the plugin add "/" to API @GET("/something") so it goes to
@GET("/something"): https://example.com/something

BUT actually, it should go to https://example.com/api/v5/something which means the API interface should remove "/" @GET("something") . I removed "/" manually and the generated SDK working fine.

How can I resolve this rather modify the generated APIs manually?

NB:

Add trailing slash to base URL, remove leading slash from relative URL.

square/retrofit#907 (comment)

Query collectionFormat not working despite existing support

While there is support added via annotations and CollectionFormatConverterFactory.kt this does not work and will instead pass the parameters as multiple values.
E.g. snippet definition snippet:

      # expected: color=red,black,white
      # actual: color=red&color=black&color=white
      parameters:
        - in: query
          name: color
          type: array
          collectionFormat: csv
          items:
            type: string

This happens because Retrofit applies the converter on a per value basis so the type check in CollectionFormatConverter will always go through the string branch returning an unmodified value which than gets appended to the query as an extra parameter.

Looking at the retrofit code (RequestFactory.java#L442) if we get an Iterable, than each value in that list will get converted and added to the query. So while our CSV stringConverter is selected, it will never get applied as we want it to be.

While I have a few ideas on how to approach this, they all involve making ParameterHandler.java in Retrofit, aware of apply'ing the conversion as a single value if a converter exists while keeping the current multi-value behavior for the BuiltInConverter string converter.

This does imply a significant change in Retrofit but maybe I'm missing something and there's already a better way to do this.
Any ideas? @JakeWharton maybe you could share your perspective.

Support polymorphism

Swagger specifications allow models to be polymorphic via a discriminator field (doc).

This allows a model, let's say Animal to be a sort of parent in the hierarchy of other types like Dog, Cat, etc.

The polymorphic approach is generally interesting when an endpoint is returning a base object (ie. Animal) that can be specified more detailed by related type or when your endpoint returns a list of mixed objects.

Retrofit example

class Animal(open var type: String)
data class Dog(override var type: String, var name: String): Animal(type=type)
data class Cat(override var type: String, var size: Int): Animal(type=type)

@JvmSuppressWildcards
interface SwaggerApi {
    @GET("/animals")
    fun getAnimals(): Single<List<Animal>>
}

The endpoint GET /animals might be returning a JSON similar to

[
    {"type": "dog", "name": "name"},
    {"type": "cat", "size": 1},
    {"type": "whale", "weight": 42}
]

and ideally we should be able to decode it as

listOf(
    Dog(type="dog", name="name"),
    Cat(type"cat", size=1),
    Animal(type="whale")
)

Without real support for polymorphism (as for version 1.3.0) the response would be decoded as

listOf(
    Animal(type="dog"),
    Animal(type="cat"),
    Animal(type="whale")
)

which leads to some information loss (the dog name was sent to the client and the client should have known about it)

Disclaimer: The above presented example is mostly to help understand the feature that polymorphism brings to codegen.
An other possibility might be to define inheritance via sealed classes

sealed class Animal(open var type: String) {
    data class DefaultAnimal(override var type: String): Animal(type=type)  // How to pick a name that has not been used yet?
    data class Dog(override var type: String, var name: String): Animal(type=type)
    data class Cat(override var type: String, var size: Int): Animal(type=type)
}

Does someone have other ideas?

Update the Gradle Plugin API to use Lazy Configuration

We should consider updating our Gradle plugin API to use the Gradle Lazy Configuration approach (Provider and Property to allow lazy configuration of the task).
https://docs.gradle.org/current/userguide/lazy_configuration.html

More context on this in the thread on #16

Currently the inputFile property is the only required property to properly configure swagger-gradle-codenge. If the inputFile property is not provided, the gradle build is broken.
Ideally we would love to break just the execution of the generateSwagger task and provide an informative message to the user.

Setup AppVeyor

We should setup AppVeyor (https://www.appveyor.com/) to run the test suite on Windows as well. One of our test was failing (see #55) on Windows and I would love to catch those scenarios in the future.

Verify correctness of endpoints with file parameters

While working on #90 I was having troubles on writing a simple test that sends a file to the mock server.
This was mostly caused by the fact that the mock server is receiving the toString representation of the RequestBody and not its real content.

At this point I'm not 100% sure that the current plugin is able to generate proper retrofit APIs that allow file uploads.

The scope of this issue is to track the effort needed, if any, to ensure file upload capabilities.

Nullability change in moshi JsonAdapter

I'm getting errors on the generated classes for

  • LocalDateAdapter
  • ZonedDateTimeAdapter
  • BigDecimalJsonAdapter

The method

override fun toJson(writer: JsonWriter?, value: ZonedDateTime?) {

seems to have changed to

override fun toJson(writer: JsonWriter, value: ZonedDateTime?) {

but I'm using the same moshi versions as the samples (1.8.0)

Screen Shot 2019-12-13 at 20 09 35

Applying plugin attempts to read configuration before it is initialized

Using the standard example from the README:

apply plugin: "com.yelp.codegen.plugin"

generateSwagger {
    platform = "kotlin"
    packageName = "com.yelp.codegen.samples"
    inputFile = file("./sample_specs.json")
    outputDir = file("./src/main/java/")
}

The plugin fails to apply:

* What went wrong:
An exception occurred applying plugin request [id: 'com.yelp.codegen.plugin', version: '1.0.0']
> Failed to apply plugin [id 'com.yelp.codegen.plugin']
   > Could not create task ':lib-models:generateSwagger'.
      > lateinit property inputFile has not been initialized
Stack trace

org.gradle.api.plugins.InvalidPluginException: An exception occurred applying plugin request [id: 'com.yelp.codegen.plugin', version: '1.0.0']
        at org.gradle.plugin.use.internal.DefaultPluginRequestApplicator.exceptionOccurred(DefaultPluginRequestApplicator.java:247)
        at org.gradle.plugin.use.internal.DefaultPluginRequestApplicator.applyPlugin(DefaultPluginRequestApplicator.java:229)
        at org.gradle.plugin.use.internal.DefaultPluginRequestApplicator.applyPlugins(DefaultPluginRequestApplicator.java:148)
        at org.gradle.configuration.DefaultScriptPluginFactory$ScriptPluginImpl.apply(DefaultScriptPluginFactory.java:186)
        at org.gradle.configuration.BuildOperationScriptPlugin$1$1.run(BuildOperationScriptPlugin.java:69)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:301)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:293)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:175)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:91)
        at org.gradle.internal.operations.DelegatingBuildOperationExecutor.run(DelegatingBuildOperationExecutor.java:31)
        at org.gradle.configuration.BuildOperationScriptPlugin$1.execute(BuildOperationScriptPlugin.java:66)
        at org.gradle.configuration.BuildOperationScriptPlugin$1.execute(BuildOperationScriptPlugin.java:63)
        at org.gradle.configuration.internal.DefaultUserCodeApplicationContext.apply(DefaultUserCodeApplicationContext.java:48)
        at org.gradle.configuration.BuildOperationScriptPlugin.apply(BuildOperationScriptPlugin.java:63)
        at org.gradle.configuration.project.BuildScriptProcessor$1.run(BuildScriptProcessor.java:44)
        at org.gradle.internal.Factories$1.create(Factories.java:25)
        at org.gradle.api.internal.project.DefaultProjectStateRegistry$ProjectStateImpl.withMutableState(DefaultProjectStateRegistry.java:200)
        at org.gradle.api.internal.project.DefaultProjectStateRegistry$ProjectStateImpl.withMutableState(DefaultProjectStateRegistry.java:186)
        at org.gradle.configuration.project.BuildScriptProcessor.execute(BuildScriptProcessor.java:41)
        at org.gradle.configuration.project.BuildScriptProcessor.execute(BuildScriptProcessor.java:26)
        at org.gradle.configuration.project.ConfigureActionsProjectEvaluator.evaluate(ConfigureActionsProjectEvaluator.java:34)
        at org.gradle.configuration.project.LifecycleProjectEvaluator$EvaluateProject$1.run(LifecycleProjectEvaluator.java:106)
        at org.gradle.internal.Factories$1.create(Factories.java:25)
        at org.gradle.internal.work.DefaultWorkerLeaseService.withLocks(DefaultWorkerLeaseService.java:183)
        at org.gradle.internal.work.StopShieldingWorkerLeaseService.withLocks(StopShieldingWorkerLeaseService.java:40)
        at org.gradle.api.internal.project.DefaultProjectStateRegistry$ProjectStateImpl.withProjectLock(DefaultProjectStateRegistry.java:226)
        at org.gradle.api.internal.project.DefaultProjectStateRegistry$ProjectStateImpl.access$700(DefaultProjectStateRegistry.java:143)
        at org.gradle.api.internal.project.DefaultProjectStateRegistry$ProjectStateImpl$1.create(DefaultProjectStateRegistry.java:215)
        at org.gradle.internal.work.DefaultWorkerLeaseService.withoutLocks(DefaultWorkerLeaseService.java:254)
        at org.gradle.internal.work.StopShieldingWorkerLeaseService.withoutLocks(StopShieldingWorkerLeaseService.java:50)
        at org.gradle.api.internal.project.DefaultProjectStateRegistry$ProjectStateImpl.withMutableState(DefaultProjectStateRegistry.java:211)
        at org.gradle.api.internal.project.DefaultProjectStateRegistry$ProjectStateImpl.withMutableState(DefaultProjectStateRegistry.java:186)
        at org.gradle.configuration.project.LifecycleProjectEvaluator$EvaluateProject.run(LifecycleProjectEvaluator.java:95)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:301)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:293)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:175)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:91)
        at org.gradle.internal.operations.DelegatingBuildOperationExecutor.run(DelegatingBuildOperationExecutor.java:31)
        at org.gradle.configuration.project.LifecycleProjectEvaluator.evaluate(LifecycleProjectEvaluator.java:67)
        at org.gradle.api.internal.project.DefaultProject.evaluate(DefaultProject.java:693)
        at org.gradle.api.internal.project.DefaultProject.evaluate(DefaultProject.java:141)
        at org.gradle.api.internal.project.DefaultProjectAccessListener.evaluateProjectAndDiscoverTasks(DefaultProjectAccessListener.java:32)
        at org.gradle.api.internal.project.DefaultProjectAccessListener.beforeResolvingProjectDependency(DefaultProjectAccessListener.java:28)
        at org.gradle.api.internal.artifacts.dependencies.DefaultProjectDependency.beforeResolved(DefaultProjectDependency.java:101)
        at org.gradle.api.internal.artifacts.ivyservice.moduleconverter.dependencies.ProjectIvyDependencyDescriptorFactory.createDependencyDescriptor(ProjectIvyDependencyDescriptorFactory.java:41)
        at org.gradle.api.internal.artifacts.ivyservice.moduleconverter.dependencies.DefaultDependencyDescriptorFactory.createDependencyDescriptor(DefaultDependencyDescriptorFactory.java:46)
        at org.gradle.api.internal.artifacts.ivyservice.moduleconverter.dependencies.DefaultLocalConfigurationMetadataBuilder.addDependencies(DefaultLocalConfigurationMetadataBuilder.java:58)
        at org.gradle.api.internal.artifacts.ivyservice.moduleconverter.dependencies.DefaultLocalConfigurationMetadataBuilder.addDependenciesAndExcludes(DefaultLocalConfigurationMetadataBuilder.java:48)
        at org.gradle.internal.component.local.model.DefaultLocalComponentMetadata$DefaultLocalConfigurationMetadata.realizeDependencies(DefaultLocalComponentMetadata.java:499)
        at org.gradle.internal.component.local.model.DefaultLocalComponentMetadata$DefaultLocalConfigurationMetadata.addDefinedExcludes(DefaultLocalComponentMetadata.java:456)
        at org.gradle.internal.component.local.model.DefaultLocalComponentMetadata$DefaultLocalConfigurationMetadata.getExcludes(DefaultLocalComponentMetadata.java:447)
        at org.gradle.api.internal.artifacts.ivyservice.resolveengine.graph.builder.NodeState.getModuleResolutionFilter(NodeState.java:384)
        at org.gradle.api.internal.artifacts.ivyservice.resolveengine.graph.builder.NodeState.visitOutgoingDependencies(NodeState.java:192)
        at org.gradle.api.internal.artifacts.ivyservice.resolveengine.graph.builder.DependencyGraphBuilder.traverseGraph(DependencyGraphBuilder.java:169)
        at org.gradle.api.internal.artifacts.ivyservice.resolveengine.graph.builder.DependencyGraphBuilder.resolve(DependencyGraphBuilder.java:131)
        at org.gradle.api.internal.artifacts.ivyservice.resolveengine.DefaultArtifactDependencyResolver.resolve(DefaultArtifactDependencyResolver.java:121)
        at org.gradle.api.internal.artifacts.ivyservice.DefaultConfigurationResolver.resolveGraph(DefaultConfigurationResolver.java:171)
        at org.gradle.api.internal.artifacts.ivyservice.ShortCircuitEmptyConfigurationResolver.resolveGraph(ShortCircuitEmptyConfigurationResolver.java:86)
        at org.gradle.api.internal.artifacts.ivyservice.ErrorHandlingConfigurationResolver.resolveGraph(ErrorHandlingConfigurationResolver.java:73)
        at org.gradle.api.internal.artifacts.configurations.DefaultConfiguration$7.run(DefaultConfiguration.java:580)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:301)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:293)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:175)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:91)
        at org.gradle.internal.operations.DelegatingBuildOperationExecutor.run(DelegatingBuildOperationExecutor.java:31)
        at org.gradle.api.internal.artifacts.configurations.DefaultConfiguration.resolveGraphIfRequired(DefaultConfiguration.java:571)
        at org.gradle.api.internal.artifacts.configurations.DefaultConfiguration.access$600(DefaultConfiguration.java:135)
        at org.gradle.api.internal.artifacts.configurations.DefaultConfiguration$6.run(DefaultConfiguration.java:551)
        at org.gradle.api.internal.project.DefaultProjectStateRegistry$SafeExclusiveLockImpl.withLock(DefaultProjectStateRegistry.java:244)
        at org.gradle.api.internal.artifacts.configurations.DefaultConfiguration.resolveExclusively(DefaultConfiguration.java:547)
        at org.gradle.api.internal.artifacts.configurations.DefaultConfiguration.resolveToStateOrLater(DefaultConfiguration.java:542)
        at org.gradle.api.internal.artifacts.configurations.DefaultConfiguration.access$2200(DefaultConfiguration.java:135)
        at org.gradle.api.internal.artifacts.configurations.DefaultConfiguration$ConfigurationFileCollection.getSelectedArtifacts(DefaultConfiguration.java:1158)
        at org.gradle.api.internal.artifacts.configurations.DefaultConfiguration$ConfigurationFileCollection.getFiles(DefaultConfiguration.java:1147)
        at org.gradle.api.internal.file.AbstractFileCollection.iterator(AbstractFileCollection.java:72)
        at com.google.common.collect.ImmutableCollection$Builder.addAll(ImmutableCollection.java:384)
        at com.google.common.collect.ImmutableCollection$ArrayBasedBuilder.addAll(ImmutableCollection.java:476)
        at com.google.common.collect.ImmutableSet$Builder.addAll(ImmutableSet.java:518)
        at org.gradle.api.internal.file.CompositeFileCollection.getFiles(CompositeFileCollection.java:80)
        at org.gradle.api.internal.file.CompositeFileCollection.getFiles(CompositeFileCollection.java:54)
        at org.jetbrains.kotlin.gradle.plugin.Android25ProjectHandler.getResDirectories(Android25ProjectHandler.kt:109)
        at org.jetbrains.kotlin.gradle.plugin.Android25ProjectHandler.getResDirectories(Android25ProjectHandler.kt:20)
        at org.jetbrains.kotlin.gradle.internal.AndroidSubplugin$applyExperimental$4.invoke(AndroidSubplugin.kt:207)
        at org.jetbrains.kotlin.gradle.internal.AndroidSubplugin$applyExperimental$4.invoke(AndroidSubplugin.kt:78)
        at org.jetbrains.kotlin.gradle.plugin.Android25ProjectHandler$sam$org_gradle_api_Action$0.execute(Android25ProjectHandler.kt)
        at org.gradle.api.internal.DefaultDomainObjectCollection.all(DefaultDomainObjectCollection.java:158)
        at org.jetbrains.kotlin.gradle.plugin.Android25ProjectHandler.forEachVariant(Android25ProjectHandler.kt:28)
        at org.jetbrains.kotlin.gradle.internal.AndroidSubplugin.applyExperimental(AndroidSubplugin.kt:205)
        at org.jetbrains.kotlin.gradle.internal.AndroidSubplugin.apply(AndroidSubplugin.kt:110)
        at org.jetbrains.kotlin.gradle.internal.AndroidSubplugin.apply(AndroidSubplugin.kt:78)
        at org.jetbrains.kotlin.gradle.plugin.SubpluginEnvironment.addSubpluginOptions(SubpluginEnvironment.kt:85)
        at org.jetbrains.kotlin.gradle.plugin.SubpluginEnvironment.addSubpluginOptions(SubpluginEnvironment.kt:50)
        at org.jetbrains.kotlin.gradle.plugin.AbstractAndroidProjectHandler.applySubplugins(KotlinPlugin.kt:753)
        at org.jetbrains.kotlin.gradle.plugin.AbstractAndroidProjectHandler.access$applySubplugins(KotlinPlugin.kt:616)
        at org.jetbrains.kotlin.gradle.plugin.AbstractAndroidProjectHandler$handleProject$2$3.invoke(KotlinPlugin.kt:692)
        at org.jetbrains.kotlin.gradle.plugin.AbstractAndroidProjectHandler$handleProject$2$3.invoke(KotlinPlugin.kt:616)
        at org.jetbrains.kotlin.gradle.plugin.Android25ProjectHandler$sam$org_gradle_api_Action$0.execute(Android25ProjectHandler.kt)
        at org.gradle.api.internal.DefaultDomainObjectCollection.all(DefaultDomainObjectCollection.java:158)
        at org.jetbrains.kotlin.gradle.plugin.Android25ProjectHandler.forEachVariant(Android25ProjectHandler.kt:28)
        at org.jetbrains.kotlin.gradle.plugin.AbstractAndroidProjectHandler$handleProject$2.execute(KotlinPlugin.kt:690)
        at org.jetbrains.kotlin.gradle.plugin.AbstractAndroidProjectHandler$handleProject$2.execute(KotlinPlugin.kt:616)
        at org.gradle.configuration.internal.DefaultListenerBuildOperationDecorator$BuildOperationEmittingAction$1$1.run(DefaultListenerBuildOperationDecorator.java:150)
        at org.gradle.configuration.internal.DefaultUserCodeApplicationContext.reapply(DefaultUserCodeApplicationContext.java:58)
        at org.gradle.configuration.internal.DefaultListenerBuildOperationDecorator$BuildOperationEmittingAction$1.run(DefaultListenerBuildOperationDecorator.java:147)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:301)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:293)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:175)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:91)
        at org.gradle.configuration.internal.DefaultListenerBuildOperationDecorator$BuildOperationEmittingAction.execute(DefaultListenerBuildOperationDecorator.java:144)
        at org.gradle.internal.event.BroadcastDispatch$ActionInvocationHandler.dispatch(BroadcastDispatch.java:91)
        at org.gradle.internal.event.BroadcastDispatch$ActionInvocationHandler.dispatch(BroadcastDispatch.java:80)
        at org.gradle.internal.event.AbstractBroadcastDispatch.dispatch(AbstractBroadcastDispatch.java:42)
        at org.gradle.internal.event.BroadcastDispatch$SingletonDispatch.dispatch(BroadcastDispatch.java:230)
        at org.gradle.internal.event.BroadcastDispatch$SingletonDispatch.dispatch(BroadcastDispatch.java:149)
        at org.gradle.internal.event.AbstractBroadcastDispatch.dispatch(AbstractBroadcastDispatch.java:58)
        at org.gradle.internal.event.BroadcastDispatch$CompositeDispatch.dispatch(BroadcastDispatch.java:324)
        at org.gradle.internal.event.BroadcastDispatch$CompositeDispatch.dispatch(BroadcastDispatch.java:234)
        at org.gradle.internal.event.ListenerBroadcast.dispatch(ListenerBroadcast.java:140)
        at org.gradle.internal.event.ListenerBroadcast.dispatch(ListenerBroadcast.java:37)
        at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:93)
        at com.sun.proxy.$Proxy25.afterEvaluate(Unknown Source)
        at org.gradle.configuration.project.LifecycleProjectEvaluator$NotifyAfterEvaluate$1.execute(LifecycleProjectEvaluator.java:190)
        at org.gradle.configuration.project.LifecycleProjectEvaluator$NotifyAfterEvaluate$1.execute(LifecycleProjectEvaluator.java:187)
        at org.gradle.api.internal.project.DefaultProject.stepEvaluationListener(DefaultProject.java:1419)
        at org.gradle.configuration.project.LifecycleProjectEvaluator$NotifyAfterEvaluate.run(LifecycleProjectEvaluator.java:196)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:301)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:293)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:175)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:91)
        at org.gradle.internal.operations.DelegatingBuildOperationExecutor.run(DelegatingBuildOperationExecutor.java:31)
        at org.gradle.configuration.project.LifecycleProjectEvaluator$EvaluateProject$1.run(LifecycleProjectEvaluator.java:111)
        at org.gradle.internal.Factories$1.create(Factories.java:25)
        at org.gradle.internal.work.DefaultWorkerLeaseService.withLocks(DefaultWorkerLeaseService.java:183)
        at org.gradle.internal.work.StopShieldingWorkerLeaseService.withLocks(StopShieldingWorkerLeaseService.java:40)
        at org.gradle.api.internal.project.DefaultProjectStateRegistry$ProjectStateImpl.withProjectLock(DefaultProjectStateRegistry.java:226)
        at org.gradle.api.internal.project.DefaultProjectStateRegistry$ProjectStateImpl.access$700(DefaultProjectStateRegistry.java:143)
        at org.gradle.api.internal.project.DefaultProjectStateRegistry$ProjectStateImpl$1.create(DefaultProjectStateRegistry.java:215)
        at org.gradle.internal.work.DefaultWorkerLeaseService.withoutLocks(DefaultWorkerLeaseService.java:254)
        at org.gradle.internal.work.StopShieldingWorkerLeaseService.withoutLocks(StopShieldingWorkerLeaseService.java:50)
        at org.gradle.api.internal.project.DefaultProjectStateRegistry$ProjectStateImpl.withMutableState(DefaultProjectStateRegistry.java:211)
        at org.gradle.api.internal.project.DefaultProjectStateRegistry$ProjectStateImpl.withMutableState(DefaultProjectStateRegistry.java:186)
        at org.gradle.configuration.project.LifecycleProjectEvaluator$EvaluateProject.run(LifecycleProjectEvaluator.java:95)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:301)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:293)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:175)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:91)
        at org.gradle.internal.operations.DelegatingBuildOperationExecutor.run(DelegatingBuildOperationExecutor.java:31)
        at org.gradle.configuration.project.LifecycleProjectEvaluator.evaluate(LifecycleProjectEvaluator.java:67)
        at org.gradle.api.internal.project.DefaultProject.evaluate(DefaultProject.java:693)
        at org.gradle.api.internal.project.DefaultProject.evaluate(DefaultProject.java:141)
        at org.gradle.api.internal.project.DefaultProjectAccessListener.evaluateProjectAndDiscoverTasks(DefaultProjectAccessListener.java:32)
        at org.gradle.api.internal.project.DefaultProjectAccessListener.beforeResolvingProjectDependency(DefaultProjectAccessListener.java:28)
        at org.gradle.api.internal.artifacts.dependencies.DefaultProjectDependency.beforeResolved(DefaultProjectDependency.java:101)
        at org.gradle.api.internal.artifacts.ivyservice.moduleconverter.dependencies.ProjectIvyDependencyDescriptorFactory.createDependencyDescriptor(ProjectIvyDependencyDescriptorFactory.java:41)
        at org.gradle.api.internal.artifacts.ivyservice.moduleconverter.dependencies.DefaultDependencyDescriptorFactory.createDependencyDescriptor(DefaultDependencyDescriptorFactory.java:46)
        at org.gradle.api.internal.artifacts.ivyservice.moduleconverter.dependencies.DefaultLocalConfigurationMetadataBuilder.addDependencies(DefaultLocalConfigurationMetadataBuilder.java:58)
        at org.gradle.api.internal.artifacts.ivyservice.moduleconverter.dependencies.DefaultLocalConfigurationMetadataBuilder.addDependenciesAndExcludes(DefaultLocalConfigurationMetadataBuilder.java:48)
        at org.gradle.internal.component.local.model.DefaultLocalComponentMetadata$DefaultLocalConfigurationMetadata.realizeDependencies(DefaultLocalComponentMetadata.java:499)
        at org.gradle.internal.component.local.model.DefaultLocalComponentMetadata$DefaultLocalConfigurationMetadata.addDefinedExcludes(DefaultLocalComponentMetadata.java:456)
        at org.gradle.internal.component.local.model.DefaultLocalComponentMetadata$DefaultLocalConfigurationMetadata.getExcludes(DefaultLocalComponentMetadata.java:447)
        at org.gradle.api.internal.artifacts.ivyservice.resolveengine.graph.builder.NodeState.getModuleResolutionFilter(NodeState.java:384)
        at org.gradle.api.internal.artifacts.ivyservice.resolveengine.graph.builder.NodeState.visitOutgoingDependencies(NodeState.java:192)
        at org.gradle.api.internal.artifacts.ivyservice.resolveengine.graph.builder.DependencyGraphBuilder.traverseGraph(DependencyGraphBuilder.java:169)
        at org.gradle.api.internal.artifacts.ivyservice.resolveengine.graph.builder.DependencyGraphBuilder.resolve(DependencyGraphBuilder.java:131)
        at org.gradle.api.internal.artifacts.ivyservice.resolveengine.DefaultArtifactDependencyResolver.resolve(DefaultArtifactDependencyResolver.java:121)
        at org.gradle.api.internal.artifacts.ivyservice.DefaultConfigurationResolver.resolveGraph(DefaultConfigurationResolver.java:171)
        at org.gradle.api.internal.artifacts.ivyservice.ShortCircuitEmptyConfigurationResolver.resolveGraph(ShortCircuitEmptyConfigurationResolver.java:86)
        at org.gradle.api.internal.artifacts.ivyservice.ErrorHandlingConfigurationResolver.resolveGraph(ErrorHandlingConfigurationResolver.java:73)
        at org.gradle.api.internal.artifacts.configurations.DefaultConfiguration$7.run(DefaultConfiguration.java:580)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:301)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:293)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:175)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:91)
        at org.gradle.internal.operations.DelegatingBuildOperationExecutor.run(DelegatingBuildOperationExecutor.java:31)
        at org.gradle.api.internal.artifacts.configurations.DefaultConfiguration.resolveGraphIfRequired(DefaultConfiguration.java:571)
        at org.gradle.api.internal.artifacts.configurations.DefaultConfiguration.access$600(DefaultConfiguration.java:135)
        at org.gradle.api.internal.artifacts.configurations.DefaultConfiguration$6.run(DefaultConfiguration.java:551)
        at org.gradle.api.internal.project.DefaultProjectStateRegistry$SafeExclusiveLockImpl.withLock(DefaultProjectStateRegistry.java:244)
        at org.gradle.api.internal.artifacts.configurations.DefaultConfiguration.resolveExclusively(DefaultConfiguration.java:547)
        at org.gradle.api.internal.artifacts.configurations.DefaultConfiguration.resolveToStateOrLater(DefaultConfiguration.java:542)
        at org.gradle.api.internal.artifacts.configurations.DefaultConfiguration.access$2200(DefaultConfiguration.java:135)
        at org.gradle.api.internal.artifacts.configurations.DefaultConfiguration$ConfigurationFileCollection.getSelectedArtifacts(DefaultConfiguration.java:1158)
        at org.gradle.api.internal.artifacts.configurations.DefaultConfiguration$ConfigurationFileCollection.getFiles(DefaultConfiguration.java:1147)
        at org.gradle.api.internal.file.AbstractFileCollection.iterator(AbstractFileCollection.java:72)
        at com.google.common.collect.ImmutableCollection$Builder.addAll(ImmutableCollection.java:384)
        at com.google.common.collect.ImmutableCollection$ArrayBasedBuilder.addAll(ImmutableCollection.java:476)
        at com.google.common.collect.ImmutableSet$Builder.addAll(ImmutableSet.java:518)
        at org.gradle.api.internal.file.CompositeFileCollection.getFiles(CompositeFileCollection.java:80)
        at org.gradle.api.internal.file.CompositeFileCollection.getFiles(CompositeFileCollection.java:54)
        at org.jetbrains.kotlin.gradle.plugin.Android25ProjectHandler.getResDirectories(Android25ProjectHandler.kt:109)
        at org.jetbrains.kotlin.gradle.plugin.Android25ProjectHandler.getResDirectories(Android25ProjectHandler.kt:20)
        at org.jetbrains.kotlin.gradle.internal.AndroidSubplugin$applyExperimental$4.invoke(AndroidSubplugin.kt:207)
        at org.jetbrains.kotlin.gradle.internal.AndroidSubplugin$applyExperimental$4.invoke(AndroidSubplugin.kt:78)
        at org.jetbrains.kotlin.gradle.plugin.Android25ProjectHandler$sam$org_gradle_api_Action$0.execute(Android25ProjectHandler.kt)
        at org.gradle.api.internal.DefaultDomainObjectCollection.all(DefaultDomainObjectCollection.java:158)
        at org.jetbrains.kotlin.gradle.plugin.Android25ProjectHandler.forEachVariant(Android25ProjectHandler.kt:28)
        at org.jetbrains.kotlin.gradle.internal.AndroidSubplugin.applyExperimental(AndroidSubplugin.kt:205)
        at org.jetbrains.kotlin.gradle.internal.AndroidSubplugin.apply(AndroidSubplugin.kt:110)
        at org.jetbrains.kotlin.gradle.internal.AndroidSubplugin.apply(AndroidSubplugin.kt:78)
        at org.jetbrains.kotlin.gradle.plugin.SubpluginEnvironment.addSubpluginOptions(SubpluginEnvironment.kt:85)
        at org.jetbrains.kotlin.gradle.plugin.SubpluginEnvironment.addSubpluginOptions(SubpluginEnvironment.kt:50)
        at org.jetbrains.kotlin.gradle.plugin.AbstractAndroidProjectHandler.applySubplugins(KotlinPlugin.kt:753)
        at org.jetbrains.kotlin.gradle.plugin.AbstractAndroidProjectHandler.access$applySubplugins(KotlinPlugin.kt:616)
        at org.jetbrains.kotlin.gradle.plugin.AbstractAndroidProjectHandler$handleProject$2$3.invoke(KotlinPlugin.kt:692)
        at org.jetbrains.kotlin.gradle.plugin.AbstractAndroidProjectHandler$handleProject$2$3.invoke(KotlinPlugin.kt:616)
        at org.jetbrains.kotlin.gradle.plugin.Android25ProjectHandler$sam$org_gradle_api_Action$0.execute(Android25ProjectHandler.kt)
        at org.gradle.api.internal.DefaultDomainObjectCollection.all(DefaultDomainObjectCollection.java:158)
        at org.jetbrains.kotlin.gradle.plugin.Android25ProjectHandler.forEachVariant(Android25ProjectHandler.kt:28)
        at org.jetbrains.kotlin.gradle.plugin.AbstractAndroidProjectHandler$handleProject$2.execute(KotlinPlugin.kt:690)
        at org.jetbrains.kotlin.gradle.plugin.AbstractAndroidProjectHandler$handleProject$2.execute(KotlinPlugin.kt:616)
        at org.gradle.configuration.internal.DefaultListenerBuildOperationDecorator$BuildOperationEmittingAction$1$1.run(DefaultListenerBuildOperationDecorator.java:150)
        at org.gradle.configuration.internal.DefaultUserCodeApplicationContext.reapply(DefaultUserCodeApplicationContext.java:58)
        at org.gradle.configuration.internal.DefaultListenerBuildOperationDecorator$BuildOperationEmittingAction$1.run(DefaultListenerBuildOperationDecorator.java:147)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:301)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:293)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:175)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:91)
        at org.gradle.configuration.internal.DefaultListenerBuildOperationDecorator$BuildOperationEmittingAction.execute(DefaultListenerBuildOperationDecorator.java:144)
        at org.gradle.internal.event.BroadcastDispatch$ActionInvocationHandler.dispatch(BroadcastDispatch.java:91)
        at org.gradle.internal.event.BroadcastDispatch$ActionInvocationHandler.dispatch(BroadcastDispatch.java:80)
        at org.gradle.internal.event.AbstractBroadcastDispatch.dispatch(AbstractBroadcastDispatch.java:42)
        at org.gradle.internal.event.BroadcastDispatch$SingletonDispatch.dispatch(BroadcastDispatch.java:230)
        at org.gradle.internal.event.BroadcastDispatch$SingletonDispatch.dispatch(BroadcastDispatch.java:149)
        at org.gradle.internal.event.AbstractBroadcastDispatch.dispatch(AbstractBroadcastDispatch.java:58)
        at org.gradle.internal.event.BroadcastDispatch$CompositeDispatch.dispatch(BroadcastDispatch.java:324)
        at org.gradle.internal.event.BroadcastDispatch$CompositeDispatch.dispatch(BroadcastDispatch.java:234)
        at org.gradle.internal.event.ListenerBroadcast.dispatch(ListenerBroadcast.java:140)
        at org.gradle.internal.event.ListenerBroadcast.dispatch(ListenerBroadcast.java:37)
        at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:93)
        at com.sun.proxy.$Proxy25.afterEvaluate(Unknown Source)
        at org.gradle.configuration.project.LifecycleProjectEvaluator$NotifyAfterEvaluate$1.execute(LifecycleProjectEvaluator.java:190)
        at org.gradle.configuration.project.LifecycleProjectEvaluator$NotifyAfterEvaluate$1.execute(LifecycleProjectEvaluator.java:187)
        at org.gradle.api.internal.project.DefaultProject.stepEvaluationListener(DefaultProject.java:1419)
        at org.gradle.configuration.project.LifecycleProjectEvaluator$NotifyAfterEvaluate.run(LifecycleProjectEvaluator.java:196)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:301)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:293)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:175)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:91)
        at org.gradle.internal.operations.DelegatingBuildOperationExecutor.run(DelegatingBuildOperationExecutor.java:31)
        at org.gradle.configuration.project.LifecycleProjectEvaluator$EvaluateProject$1.run(LifecycleProjectEvaluator.java:111)
        at org.gradle.internal.Factories$1.create(Factories.java:25)
        at org.gradle.internal.work.DefaultWorkerLeaseService.withLocks(DefaultWorkerLeaseService.java:183)
        at org.gradle.internal.work.StopShieldingWorkerLeaseService.withLocks(StopShieldingWorkerLeaseService.java:40)
        at org.gradle.api.internal.project.DefaultProjectStateRegistry$ProjectStateImpl.withProjectLock(DefaultProjectStateRegistry.java:226)
        at org.gradle.api.internal.project.DefaultProjectStateRegistry$ProjectStateImpl.access$700(DefaultProjectStateRegistry.java:143)
        at org.gradle.api.internal.project.DefaultProjectStateRegistry$ProjectStateImpl$1.create(DefaultProjectStateRegistry.java:215)
        at org.gradle.internal.work.DefaultWorkerLeaseService.withoutLocks(DefaultWorkerLeaseService.java:254)
        at org.gradle.internal.work.StopShieldingWorkerLeaseService.withoutLocks(StopShieldingWorkerLeaseService.java:50)
        at org.gradle.api.internal.project.DefaultProjectStateRegistry$ProjectStateImpl.withMutableState(DefaultProjectStateRegistry.java:211)
        at org.gradle.api.internal.project.DefaultProjectStateRegistry$ProjectStateImpl.withMutableState(DefaultProjectStateRegistry.java:186)
        at org.gradle.configuration.project.LifecycleProjectEvaluator$EvaluateProject.run(LifecycleProjectEvaluator.java:95)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:301)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:293)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:175)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:91)
        at org.gradle.internal.operations.DelegatingBuildOperationExecutor.run(DelegatingBuildOperationExecutor.java:31)
        at org.gradle.configuration.project.LifecycleProjectEvaluator.evaluate(LifecycleProjectEvaluator.java:67)
        at org.gradle.api.internal.project.DefaultProject.evaluate(DefaultProject.java:693)
        at org.gradle.api.internal.project.DefaultProject.evaluate(DefaultProject.java:141)
        at org.gradle.api.internal.project.DefaultProjectAccessListener.evaluateProjectAndDiscoverTasks(DefaultProjectAccessListener.java:32)
        at org.gradle.api.internal.project.DefaultProjectAccessListener.beforeResolvingProjectDependency(DefaultProjectAccessListener.java:28)
        at org.gradle.api.internal.artifacts.dependencies.DefaultProjectDependency.beforeResolved(DefaultProjectDependency.java:101)
        at org.gradle.api.internal.artifacts.ivyservice.moduleconverter.dependencies.ProjectIvyDependencyDescriptorFactory.createDependencyDescriptor(ProjectIvyDependencyDescriptorFactory.java:41)
        at org.gradle.api.internal.artifacts.ivyservice.moduleconverter.dependencies.DefaultDependencyDescriptorFactory.createDependencyDescriptor(DefaultDependencyDescriptorFactory.java:46)
        at org.gradle.api.internal.artifacts.ivyservice.moduleconverter.dependencies.DefaultLocalConfigurationMetadataBuilder.addDependencies(DefaultLocalConfigurationMetadataBuilder.java:58)
        at org.gradle.api.internal.artifacts.ivyservice.moduleconverter.dependencies.DefaultLocalConfigurationMetadataBuilder.addDependenciesAndExcludes(DefaultLocalConfigurationMetadataBuilder.java:48)
        at org.gradle.internal.component.local.model.DefaultLocalComponentMetadata$DefaultLocalConfigurationMetadata.realizeDependencies(DefaultLocalComponentMetadata.java:499)
        at org.gradle.internal.component.local.model.DefaultLocalComponentMetadata$DefaultLocalConfigurationMetadata.addDefinedExcludes(DefaultLocalComponentMetadata.java:456)
        at org.gradle.internal.component.local.model.DefaultLocalComponentMetadata$DefaultLocalConfigurationMetadata.getExcludes(DefaultLocalComponentMetadata.java:447)
        at org.gradle.api.internal.artifacts.ivyservice.resolveengine.graph.builder.NodeState.getModuleResolutionFilter(NodeState.java:384)
        at org.gradle.api.internal.artifacts.ivyservice.resolveengine.graph.builder.NodeState.visitOutgoingDependencies(NodeState.java:192)
        at org.gradle.api.internal.artifacts.ivyservice.resolveengine.graph.builder.DependencyGraphBuilder.traverseGraph(DependencyGraphBuilder.java:169)
        at org.gradle.api.internal.artifacts.ivyservice.resolveengine.graph.builder.DependencyGraphBuilder.resolve(DependencyGraphBuilder.java:131)
        at org.gradle.api.internal.artifacts.ivyservice.resolveengine.DefaultArtifactDependencyResolver.resolve(DefaultArtifactDependencyResolver.java:121)
        at org.gradle.api.internal.artifacts.ivyservice.DefaultConfigurationResolver.resolveGraph(DefaultConfigurationResolver.java:171)
        at org.gradle.api.internal.artifacts.ivyservice.ShortCircuitEmptyConfigurationResolver.resolveGraph(ShortCircuitEmptyConfigurationResolver.java:86)
        at org.gradle.api.internal.artifacts.ivyservice.ErrorHandlingConfigurationResolver.resolveGraph(ErrorHandlingConfigurationResolver.java:73)
        at org.gradle.api.internal.artifacts.configurations.DefaultConfiguration$7.run(DefaultConfiguration.java:580)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:301)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:293)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:175)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:91)
        at org.gradle.internal.operations.DelegatingBuildOperationExecutor.run(DelegatingBuildOperationExecutor.java:31)
        at org.gradle.api.internal.artifacts.configurations.DefaultConfiguration.resolveGraphIfRequired(DefaultConfiguration.java:571)
        at org.gradle.api.internal.artifacts.configurations.DefaultConfiguration.access$600(DefaultConfiguration.java:135)
        at org.gradle.api.internal.artifacts.configurations.DefaultConfiguration$6.run(DefaultConfiguration.java:551)
        at org.gradle.api.internal.project.DefaultProjectStateRegistry$SafeExclusiveLockImpl.withLock(DefaultProjectStateRegistry.java:244)
        at org.gradle.api.internal.artifacts.configurations.DefaultConfiguration.resolveExclusively(DefaultConfiguration.java:547)
        at org.gradle.api.internal.artifacts.configurations.DefaultConfiguration.resolveToStateOrLater(DefaultConfiguration.java:542)
        at org.gradle.api.internal.artifacts.configurations.DefaultConfiguration.access$2200(DefaultConfiguration.java:135)
        at org.gradle.api.internal.artifacts.configurations.DefaultConfiguration$ConfigurationFileCollection.getSelectedArtifacts(DefaultConfiguration.java:1158)
        at org.gradle.api.internal.artifacts.configurations.DefaultConfiguration$ConfigurationFileCollection.getFiles(DefaultConfiguration.java:1147)
        at org.gradle.api.internal.file.AbstractFileCollection.iterator(AbstractFileCollection.java:72)
        at com.google.common.collect.ImmutableCollection$Builder.addAll(ImmutableCollection.java:384)
        at com.google.common.collect.ImmutableCollection$ArrayBasedBuilder.addAll(ImmutableCollection.java:476)
        at com.google.common.collect.ImmutableSet$Builder.addAll(ImmutableSet.java:518)
        at org.gradle.api.internal.file.CompositeFileCollection.getFiles(CompositeFileCollection.java:80)
        at org.gradle.api.internal.file.CompositeFileCollection.getFiles(CompositeFileCollection.java:54)
        at org.jetbrains.kotlin.gradle.plugin.Android25ProjectHandler.getResDirectories(Android25ProjectHandler.kt:109)
        at org.jetbrains.kotlin.gradle.plugin.Android25ProjectHandler.getResDirectories(Android25ProjectHandler.kt:20)
        at org.jetbrains.kotlin.gradle.internal.AndroidSubplugin$applyExperimental$4.invoke(AndroidSubplugin.kt:207)
        at org.jetbrains.kotlin.gradle.internal.AndroidSubplugin$applyExperimental$4.invoke(AndroidSubplugin.kt:78)
        at org.jetbrains.kotlin.gradle.plugin.Android25ProjectHandler$sam$org_gradle_api_Action$0.execute(Android25ProjectHandler.kt)
        at org.gradle.api.internal.DefaultDomainObjectCollection.all(DefaultDomainObjectCollection.java:158)
        at org.jetbrains.kotlin.gradle.plugin.Android25ProjectHandler.forEachVariant(Android25ProjectHandler.kt:26)
        at org.jetbrains.kotlin.gradle.internal.AndroidSubplugin.applyExperimental(AndroidSubplugin.kt:205)
        at org.jetbrains.kotlin.gradle.internal.AndroidSubplugin.apply(AndroidSubplugin.kt:110)
        at org.jetbrains.kotlin.gradle.internal.AndroidSubplugin.apply(AndroidSubplugin.kt:78)
        at org.jetbrains.kotlin.gradle.plugin.SubpluginEnvironment.addSubpluginOptions(SubpluginEnvironment.kt:85)
        at org.jetbrains.kotlin.gradle.plugin.SubpluginEnvironment.addSubpluginOptions(SubpluginEnvironment.kt:50)
        at org.jetbrains.kotlin.gradle.plugin.AbstractAndroidProjectHandler.applySubplugins(KotlinPlugin.kt:753)
        at org.jetbrains.kotlin.gradle.plugin.AbstractAndroidProjectHandler.access$applySubplugins(KotlinPlugin.kt:616)
        at org.jetbrains.kotlin.gradle.plugin.AbstractAndroidProjectHandler$handleProject$2$3.invoke(KotlinPlugin.kt:692)
        at org.jetbrains.kotlin.gradle.plugin.AbstractAndroidProjectHandler$handleProject$2$3.invoke(KotlinPlugin.kt:616)
        at org.jetbrains.kotlin.gradle.plugin.Android25ProjectHandler$sam$org_gradle_api_Action$0.execute(Android25ProjectHandler.kt)
        at org.gradle.api.internal.DefaultDomainObjectCollection.all(DefaultDomainObjectCollection.java:158)
        at org.jetbrains.kotlin.gradle.plugin.Android25ProjectHandler.forEachVariant(Android25ProjectHandler.kt:26)
        at org.jetbrains.kotlin.gradle.plugin.AbstractAndroidProjectHandler$handleProject$2.execute(KotlinPlugin.kt:690)
        at org.jetbrains.kotlin.gradle.plugin.AbstractAndroidProjectHandler$handleProject$2.execute(KotlinPlugin.kt:616)
        at org.gradle.configuration.internal.DefaultListenerBuildOperationDecorator$BuildOperationEmittingAction$1$1.run(DefaultListenerBuildOperationDecorator.java:150)
        at org.gradle.configuration.internal.DefaultUserCodeApplicationContext.reapply(DefaultUserCodeApplicationContext.java:58)
        at org.gradle.configuration.internal.DefaultListenerBuildOperationDecorator$BuildOperationEmittingAction$1.run(DefaultListenerBuildOperationDecorator.java:147)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:301)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:293)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:175)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:91)
        at org.gradle.configuration.internal.DefaultListenerBuildOperationDecorator$BuildOperationEmittingAction.execute(DefaultListenerBuildOperationDecorator.java:144)
        at org.gradle.internal.event.BroadcastDispatch$ActionInvocationHandler.dispatch(BroadcastDispatch.java:91)
        at org.gradle.internal.event.BroadcastDispatch$ActionInvocationHandler.dispatch(BroadcastDispatch.java:80)
        at org.gradle.internal.event.AbstractBroadcastDispatch.dispatch(AbstractBroadcastDispatch.java:42)
        at org.gradle.internal.event.BroadcastDispatch$SingletonDispatch.dispatch(BroadcastDispatch.java:230)
        at org.gradle.internal.event.BroadcastDispatch$SingletonDispatch.dispatch(BroadcastDispatch.java:149)
        at org.gradle.internal.event.AbstractBroadcastDispatch.dispatch(AbstractBroadcastDispatch.java:58)
        at org.gradle.internal.event.BroadcastDispatch$CompositeDispatch.dispatch(BroadcastDispatch.java:324)
        at org.gradle.internal.event.BroadcastDispatch$CompositeDispatch.dispatch(BroadcastDispatch.java:234)
        at org.gradle.internal.event.ListenerBroadcast.dispatch(ListenerBroadcast.java:140)
        at org.gradle.internal.event.ListenerBroadcast.dispatch(ListenerBroadcast.java:37)
        at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:93)
        at com.sun.proxy.$Proxy25.afterEvaluate(Unknown Source)
        at org.gradle.configuration.project.LifecycleProjectEvaluator$NotifyAfterEvaluate$1.execute(LifecycleProjectEvaluator.java:190)
        at org.gradle.configuration.project.LifecycleProjectEvaluator$NotifyAfterEvaluate$1.execute(LifecycleProjectEvaluator.java:187)
        at org.gradle.api.internal.project.DefaultProject.stepEvaluationListener(DefaultProject.java:1419)
        at org.gradle.configuration.project.LifecycleProjectEvaluator$NotifyAfterEvaluate.run(LifecycleProjectEvaluator.java:196)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:301)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:293)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:175)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:91)
        at org.gradle.internal.operations.DelegatingBuildOperationExecutor.run(DelegatingBuildOperationExecutor.java:31)
        at org.gradle.configuration.project.LifecycleProjectEvaluator$EvaluateProject$1.run(LifecycleProjectEvaluator.java:111)
        at org.gradle.internal.Factories$1.create(Factories.java:25)
        at org.gradle.internal.work.DefaultWorkerLeaseService.withLocks(DefaultWorkerLeaseService.java:183)
        at org.gradle.internal.work.StopShieldingWorkerLeaseService.withLocks(StopShieldingWorkerLeaseService.java:40)
        at org.gradle.api.internal.project.DefaultProjectStateRegistry$ProjectStateImpl.withProjectLock(DefaultProjectStateRegistry.java:226)
        at org.gradle.api.internal.project.DefaultProjectStateRegistry$ProjectStateImpl.withMutableState(DefaultProjectStateRegistry.java:220)
        at org.gradle.api.internal.project.DefaultProjectStateRegistry$ProjectStateImpl.withMutableState(DefaultProjectStateRegistry.java:186)
        at org.gradle.configuration.project.LifecycleProjectEvaluator$EvaluateProject.run(LifecycleProjectEvaluator.java:95)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:301)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:293)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:175)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:91)
        at org.gradle.internal.operations.DelegatingBuildOperationExecutor.run(DelegatingBuildOperationExecutor.java:31)
        at org.gradle.configuration.project.LifecycleProjectEvaluator.evaluate(LifecycleProjectEvaluator.java:67)
        at org.gradle.api.internal.project.DefaultProject.evaluate(DefaultProject.java:693)
        at org.gradle.api.internal.project.DefaultProject.evaluate(DefaultProject.java:141)
        at org.gradle.execution.TaskPathProjectEvaluator.configure(TaskPathProjectEvaluator.java:35)
        at org.gradle.execution.TaskPathProjectEvaluator.configureHierarchy(TaskPathProjectEvaluator.java:62)
        at org.gradle.configuration.DefaultBuildConfigurer.configure(DefaultBuildConfigurer.java:41)
        at org.gradle.initialization.DefaultGradleLauncher$ConfigureBuild.run(DefaultGradleLauncher.java:302)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:301)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:293)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:175)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:91)
        at org.gradle.internal.operations.DelegatingBuildOperationExecutor.run(DelegatingBuildOperationExecutor.java:31)
        at org.gradle.initialization.DefaultGradleLauncher.configureBuild(DefaultGradleLauncher.java:210)
        at org.gradle.initialization.DefaultGradleLauncher.doBuildStages(DefaultGradleLauncher.java:151)
        at org.gradle.initialization.DefaultGradleLauncher.executeTasks(DefaultGradleLauncher.java:134)
        at org.gradle.internal.invocation.GradleBuildController$1.execute(GradleBuildController.java:58)
        at org.gradle.internal.invocation.GradleBuildController$1.execute(GradleBuildController.java:55)
        at org.gradle.internal.invocation.GradleBuildController$3.create(GradleBuildController.java:82)
        at org.gradle.internal.invocation.GradleBuildController$3.create(GradleBuildController.java:75)
        at org.gradle.internal.work.DefaultWorkerLeaseService.withLocks(DefaultWorkerLeaseService.java:183)
        at org.gradle.internal.work.StopShieldingWorkerLeaseService.withLocks(StopShieldingWorkerLeaseService.java:40)
        at org.gradle.internal.invocation.GradleBuildController.doBuild(GradleBuildController.java:75)
        at org.gradle.internal.invocation.GradleBuildController.run(GradleBuildController.java:55)
        at org.gradle.tooling.internal.provider.ExecuteBuildActionRunner.run(ExecuteBuildActionRunner.java:31)
        at org.gradle.launcher.exec.ChainingBuildActionRunner.run(ChainingBuildActionRunner.java:35)
        at org.gradle.launcher.exec.BuildOutcomeReportingBuildActionRunner.run(BuildOutcomeReportingBuildActionRunner.java:58)
        at org.gradle.tooling.internal.provider.ValidatingBuildActionRunner.run(ValidatingBuildActionRunner.java:32)
        at org.gradle.launcher.exec.BuildCompletionNotifyingBuildActionRunner.run(BuildCompletionNotifyingBuildActionRunner.java:39)
        at org.gradle.launcher.exec.RunAsBuildOperationBuildActionRunner$3.call(RunAsBuildOperationBuildActionRunner.java:49)
        at org.gradle.launcher.exec.RunAsBuildOperationBuildActionRunner$3.call(RunAsBuildOperationBuildActionRunner.java:44)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor$CallableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:315)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor$CallableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:305)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:175)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:101)
        at org.gradle.internal.operations.DelegatingBuildOperationExecutor.call(DelegatingBuildOperationExecutor.java:36)
        at org.gradle.launcher.exec.RunAsBuildOperationBuildActionRunner.run(RunAsBuildOperationBuildActionRunner.java:44)
        at org.gradle.launcher.exec.InProcessBuildActionExecuter$1.transform(InProcessBuildActionExecuter.java:49)
        at org.gradle.launcher.exec.InProcessBuildActionExecuter$1.transform(InProcessBuildActionExecuter.java:46)
        at org.gradle.composite.internal.DefaultRootBuildState.run(DefaultRootBuildState.java:78)
        at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:46)
        at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:31)
        at org.gradle.launcher.exec.BuildTreeScopeBuildActionExecuter.execute(BuildTreeScopeBuildActionExecuter.java:42)
        at org.gradle.launcher.exec.BuildTreeScopeBuildActionExecuter.execute(BuildTreeScopeBuildActionExecuter.java:28)
        at org.gradle.tooling.internal.provider.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:78)
        at org.gradle.tooling.internal.provider.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:52)
        at org.gradle.tooling.internal.provider.SubscribableBuildActionExecuter.execute(SubscribableBuildActionExecuter.java:59)
        at org.gradle.tooling.internal.provider.SubscribableBuildActionExecuter.execute(SubscribableBuildActionExecuter.java:36)
        at org.gradle.tooling.internal.provider.SessionScopeBuildActionExecuter.execute(SessionScopeBuildActionExecuter.java:68)
        at org.gradle.tooling.internal.provider.SessionScopeBuildActionExecuter.execute(SessionScopeBuildActionExecuter.java:38)
        at org.gradle.tooling.internal.provider.GradleThreadBuildActionExecuter.execute(GradleThreadBuildActionExecuter.java:37)
        at org.gradle.tooling.internal.provider.GradleThreadBuildActionExecuter.execute(GradleThreadBuildActionExecuter.java:26)
        at org.gradle.tooling.internal.provider.ParallelismConfigurationBuildActionExecuter.execute(ParallelismConfigurationBuildActionExecuter.java:43)
        at org.gradle.tooling.internal.provider.ParallelismConfigurationBuildActionExecuter.execute(ParallelismConfigurationBuildActionExecuter.java:29)
        at org.gradle.tooling.internal.provider.StartParamsValidatingActionExecuter.execute(StartParamsValidatingActionExecuter.java:60)
        at org.gradle.tooling.internal.provider.StartParamsValidatingActionExecuter.execute(StartParamsValidatingActionExecuter.java:32)
        at org.gradle.tooling.internal.provider.SessionFailureReportingActionExecuter.execute(SessionFailureReportingActionExecuter.java:55)
        at org.gradle.tooling.internal.provider.SessionFailureReportingActionExecuter.execute(SessionFailureReportingActionExecuter.java:41)
        at org.gradle.tooling.internal.provider.SetupLoggingActionExecuter.execute(SetupLoggingActionExecuter.java:48)
        at org.gradle.tooling.internal.provider.SetupLoggingActionExecuter.execute(SetupLoggingActionExecuter.java:32)
        at org.gradle.launcher.daemon.server.exec.ExecuteBuild.doBuild(ExecuteBuild.java:67)
        at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)
        at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
        at org.gradle.launcher.daemon.server.exec.WatchForDisconnection.execute(WatchForDisconnection.java:37)
        at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
        at org.gradle.launcher.daemon.server.exec.ResetDeprecationLogger.execute(ResetDeprecationLogger.java:26)
        at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
        at org.gradle.launcher.daemon.server.exec.RequestStopIfSingleUsedDaemon.execute(RequestStopIfSingleUsedDaemon.java:34)
        at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
        at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.call(ForwardClientInput.java:74)
        at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.call(ForwardClientInput.java:72)
        at org.gradle.util.Swapper.swap(Swapper.java:38)
        at org.gradle.launcher.daemon.server.exec.ForwardClientInput.execute(ForwardClientInput.java:72)
        at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
        at org.gradle.launcher.daemon.server.exec.LogAndCheckHealth.execute(LogAndCheckHealth.java:55)
        at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
        at org.gradle.launcher.daemon.server.exec.LogToClient.doBuild(LogToClient.java:62)
        at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)
        at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
        at org.gradle.launcher.daemon.server.exec.EstablishBuildEnvironment.doBuild(EstablishBuildEnvironment.java:81)
        at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)
        at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
        at org.gradle.launcher.daemon.server.exec.StartBuildOrRespondWithBusy$1.run(StartBuildOrRespondWithBusy.java:50)
        at org.gradle.launcher.daemon.server.DaemonStateCoordinator$1.run(DaemonStateCoordinator.java:295)
        at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:63)
        at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:46)
        at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:55)
Caused by: org.gradle.api.internal.plugins.PluginApplicationException: Failed to apply plugin [id 'com.yelp.codegen.plugin']
        at org.gradle.api.internal.plugins.DefaultPluginManager.doApply(DefaultPluginManager.java:163)
        at org.gradle.api.internal.plugins.DefaultPluginManager.apply(DefaultPluginManager.java:133)
        at org.gradle.plugin.use.internal.DefaultPluginRequestApplicator$3.run(DefaultPluginRequestApplicator.java:151)
        at org.gradle.plugin.use.internal.DefaultPluginRequestApplicator.applyPlugin(DefaultPluginRequestApplicator.java:225)
        ... 445 more
Caused by: org.gradle.api.internal.tasks.DefaultTaskContainer$TaskCreationException: Could not create task ':lib-models:generateSwagger'.
        at org.gradle.api.internal.tasks.DefaultTaskContainer.taskCreationException(DefaultTaskContainer.java:703)
        at org.gradle.api.internal.tasks.DefaultTaskContainer.access$600(DefaultTaskContainer.java:78)
        at org.gradle.api.internal.tasks.DefaultTaskContainer$TaskCreatingProvider.domainObjectCreationException(DefaultTaskContainer.java:695)
        at org.gradle.api.internal.DefaultNamedDomainObjectCollection$AbstractDomainObjectCreatingProvider.tryCreate(DefaultNamedDomainObjectCollection.java:931)
        at org.gradle.api.internal.tasks.DefaultTaskContainer$TaskCreatingProvider.access$1301(DefaultTaskContainer.java:641)
        at org.gradle.api.internal.tasks.DefaultTaskContainer$TaskCreatingProvider$1.run(DefaultTaskContainer.java:668)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:301)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:293)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:175)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:91)
        at org.gradle.internal.operations.DelegatingBuildOperationExecutor.run(DelegatingBuildOperationExecutor.java:31)
        at org.gradle.api.internal.tasks.DefaultTaskContainer$TaskCreatingProvider.tryCreate(DefaultTaskContainer.java:664)
        at org.gradle.api.internal.DefaultNamedDomainObjectCollection$AbstractDomainObjectCreatingProvider.getOrNull(DefaultNamedDomainObjectCollection.java:912)
        at org.gradle.api.internal.provider.AbstractReadOnlyProvider.get(AbstractReadOnlyProvider.java:27)
        at org.gradle.api.internal.DefaultNamedDomainObjectCollection$AbstractDomainObjectCreatingProvider.get(DefaultNamedDomainObjectCollection.java:898)
        at org.gradle.api.internal.DefaultDomainObjectCollection.addLater(DefaultDomainObjectCollection.java:271)
        at org.gradle.api.internal.DefaultNamedDomainObjectCollection.addLater(DefaultNamedDomainObjectCollection.java:145)
        at org.gradle.api.internal.tasks.DefaultTaskContainer.addLaterInternal(DefaultTaskContainer.java:751)
        at org.gradle.api.internal.tasks.DefaultTaskContainer.access$900(DefaultTaskContainer.java:78)
        at org.gradle.api.internal.tasks.DefaultTaskContainer$3.call(DefaultTaskContainer.java:414)
        at org.gradle.api.internal.tasks.DefaultTaskContainer$3.call(DefaultTaskContainer.java:401)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor$CallableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:315)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor$CallableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:305)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:175)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:101)
        at org.gradle.internal.operations.DelegatingBuildOperationExecutor.call(DelegatingBuildOperationExecutor.java:36)
        at org.gradle.api.internal.tasks.DefaultTaskContainer.registerTask(DefaultTaskContainer.java:401)
        at org.gradle.api.internal.tasks.DefaultTaskContainer.register(DefaultTaskContainer.java:373)
        at org.gradle.kotlin.dsl.TaskContainerScope.register(TaskContainerExtensions.kt)
        at com.yelp.codegen.Plugin_gradle.<init>(plugin.gradle.kts:23)
        at com.yelp.codegen.PluginPlugin.apply(PluginPlugin.kt:14)
        at com.yelp.codegen.PluginPlugin.apply(PluginPlugin.kt:8)
        at org.gradle.api.internal.plugins.ImperativeOnlyPluginTarget.applyImperative(ImperativeOnlyPluginTarget.java:42)
        at org.gradle.api.internal.plugins.RuleBasedPluginTarget.applyImperative(RuleBasedPluginTarget.java:50)
        at org.gradle.api.internal.plugins.DefaultPluginManager.addPlugin(DefaultPluginManager.java:177)
        at org.gradle.api.internal.plugins.DefaultPluginManager.access$300(DefaultPluginManager.java:51)
        at org.gradle.api.internal.plugins.DefaultPluginManager$AddPluginBuildOperation.run(DefaultPluginManager.java:267)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:301)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:293)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:175)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:91)
        at org.gradle.internal.operations.DelegatingBuildOperationExecutor.run(DelegatingBuildOperationExecutor.java:31)
        at org.gradle.api.internal.plugins.DefaultPluginManager$2.execute(DefaultPluginManager.java:155)
        at org.gradle.api.internal.plugins.DefaultPluginManager$2.execute(DefaultPluginManager.java:152)
        at org.gradle.configuration.internal.DefaultUserCodeApplicationContext.apply(DefaultUserCodeApplicationContext.java:48)
        at org.gradle.api.internal.plugins.DefaultPluginManager.doApply(DefaultPluginManager.java:152)
        ... 448 more
Caused by: kotlin.UninitializedPropertyAccessException: lateinit property inputFile has not been initialized
        at com.yelp.codegen.plugin.GenerateTaskConfiguration.getInputFile(GenerateTaskConfiguration.kt:12)
        at com.yelp.codegen.Plugin_gradle$$special$$inlined$invoke$lambda$1.invoke(plugin.gradle.kts:14)
        at com.yelp.codegen.Plugin_gradle$$special$$inlined$invoke$lambda$1.invoke(plugin.gradle.kts:4)
        at com.yelp.codegen.Plugin_gradle$inlined$sam$i$org_gradle_api_Action$0.execute(TaskContainerExtensions.kt)
        at org.gradle.api.internal.DefaultMutationGuard$2.execute(DefaultMutationGuard.java:41)
        at org.gradle.api.internal.DefaultMutationGuard$2.execute(DefaultMutationGuard.java:41)
        at org.gradle.api.internal.DefaultCollectionCallbackActionDecorator$BuildOperationEmittingAction$1$1.run(DefaultCollectionCallbackActionDecorator.java:100)
        at org.gradle.configuration.internal.DefaultUserCodeApplicationContext.reapply(DefaultUserCodeApplicationContext.java:58)
        at org.gradle.api.internal.DefaultCollectionCallbackActionDecorator$BuildOperationEmittingAction$1.run(DefaultCollectionCallbackActionDecorator.java:97)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:301)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:293)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:175)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:91)
        at org.gradle.api.internal.DefaultCollectionCallbackActionDecorator$BuildOperationEmittingAction.execute(DefaultCollectionCallbackActionDecorator.java:94)
        at org.gradle.internal.ImmutableActionSet$SetWithFewActions.execute(ImmutableActionSet.java:285)
        at org.gradle.api.internal.DefaultDomainObjectCollection.doAdd(DefaultDomainObjectCollection.java:247)
        at org.gradle.api.internal.DefaultNamedDomainObjectCollection.doAdd(DefaultNamedDomainObjectCollection.java:112)
        at org.gradle.api.internal.DefaultDomainObjectCollection.add(DefaultDomainObjectCollection.java:241)
        at org.gradle.api.internal.DefaultNamedDomainObjectCollection$AbstractDomainObjectCreatingProvider.tryCreate(DefaultNamedDomainObjectCollection.java:927)
        ... 490 more

Organize samples as submodules of a single `:sample` gradle module

The more we keep on adding samples to this project (we now have 3 but they might grow), the more gradle modules this project will have. Gradle allows to create submodules so ideally we should have a structure like this:

β”œβ”€β”€ build.gradle.kts
β”œβ”€β”€ plugin
β”‚   └── build.gradle.kts
β”œβ”€β”€ samples
β”‚   └── sample-groovy-android
|          └── build.gradle.kts
|          └── README.md
β”‚   └── sample-kotlin-android
|          └── build.gradle.kts
|          └── README.md
β”‚   └── ...
|          └── build.gradle.kts
|          └── README.md
└── settings.gradle.kts

Every module will have its own markdown file with samples and short guides on how to use it. The idea is to achieve something like this: https://github.com/gradle/kotlin-dsl/tree/master/samples

Project Setup is currently broken on master

Checking out the project and opening it locally results in Gradle not properly discovering the sample projects (thanks @doug-precocity for reporting).

The issue is caused by our settings.gradle.kts file here:

return this
.pluginManagement
.repositories
.filterIsInstance<MavenArtifactRepository>()
.any {
try {
URL("${it.url}$path").openStream().use { stream ->
return@any stream.read() >= 0
}
} catch (ignored: java.io.IOException) {
return@any false
}
}

During every Gradle sync, we check if an instance of the swagger-gradle-codegen plugin is available either locally or on a remote maven repo. If the plugin is not found, the sample projects are excluded from the build (as they can't run without the gradle plugin).

Currently, the URL provided by Gradle Portal is broken (is missing a trailing slash) and this is preventing the build from finding the plugin. A workaroud is currently to install the plugin on Maven Local (./gradlew plugin:publishToMavenLocal) but we should definitely fix the script.

Remove support for moshi-reflective approach

PR #82 has added support for code-generated Moshi Adapters.
As result of the discussion on the PR we need clear up the current mixed support of reflective and moshi-codegen approach.

We need to do it in order to:

  • reduce complexity
  • reduce dependencies (as mentioned in #62 moshi-kotlin depends on kotlin-reflect which is pretty big)
  • provide better performances with the least surprises for user

In order to achieve such objective we need to:

  • Remove kotlin-android-with-moshi-kotlin-codegen and update kotlin-android to use only moshi-kotlin-codegen
  • Update groovy-android
  • Improve documentation to highlight a possible approach to still use reflective approach (a way to rebuild GeneratedCodeConverters.moshi)

Disclaimer: The list is not supposed to be complete, so if I'm missing something please update the checklist ;)

Kotlin support of Square Bracket on variable name causing an issue with query parameters' kotlin variable names with square brackets as syntax error

@JvmSuppressWildcards
interface JobPostingApi {
  

  /** 
   * Retrieves the collection of JobPosting resources.
   * The endpoint is owned by defaultname service owner
   * @param datePosted[before]  (optional)
   * @param datePosted[strictlyBefore]  (optional)
   * @param datePosted[after]  (optional)
   * @param datePosted[strictlyAfter]  (optional)
   * @param page The collection page number (optional)
   * @param itemsPerPage The number of items per page (optional)
   */
  @Headers(
    "X-Operation-ID: getJobPostingCollection"
  )
  @GET("/api/job_postings")
  fun getJobPostingCollection(
    @retrofit2.http.Query("datePosted[before]") datePosted[before]: String?, <===ERROR
    @retrofit2.http.Query("datePosted[strictly_before]") datePosted[strictlyBefore]: String?, <===ERROR
    @retrofit2.http.Query("datePosted[after]") datePosted[after]: String?,<===ERROR
    @retrofit2.http.Query("datePosted[strictly_after]") datePosted[strictlyAfter]: String?,<===ERROR
    @retrofit2.http.Query("page") page: Int?,<===CORRECT
    @retrofit2.http.Query("itemsPerPage") itemsPerPage: Int?
  ): Single<List<JobPosting>>

A type annotation is required on the value parameter.

Another Example

/** 
   * Retrieves the collection of City resources.
   * The endpoint is owned by defaultname service owner
   * @param id  (optional)
   * @param id[]  (optional)
   * @param name  (optional)
   * @param name[]  (optional)
   * @param page The collection page number (optional)
   * @param itemsPerPage The number of items per page (optional)
   */
  @Headers(
    "X-Operation-ID: getCityCollection"
  )
  @GET("/api/cities")
  fun getCityCollection(
    @retrofit2.http.Query("id") id: Int?,
    @retrofit2.http.Query("id[]") id[]: List<Int>?,
    @retrofit2.http.Query("name") name: String?,
    @retrofit2.http.Query("name[]") name[]: List<String>?,
    @retrofit2.http.Query("page") page: Int?,
    @retrofit2.http.Query("itemsPerPage") itemsPerPage: Int?
  ): Single<List<City>>

Empty Headers added to the API when there no operationId in Swagger

Empty header added to the API ( @headers() ) when there no operationId. This is giving runtime error
java.lang.IllegalArgumentException: @Headers annotation is empty.

Remove the empty header or add auto-generated operationId like "X-Operation-ID: deviceGet"

Empty operationId found for path: get /devices. Renamed to auto-generated operationId: devicesGet

Ex:

Bellow endpoint doesn't include opertationID which add empty @Headers() while generating the code.

       "/devices": {
            "get": {
                "summary": "Fetch a list of Devices",
                "description": "Without any params, returns a list of the user's devices",
                "tags": [
                    "Device"
                ],
                "parameters": [
                    {
                        "$ref": "#/parameters/all"
                    },
                    {
                        "$ref": "#/parameters/userId"
                    },
                    {
                        "name": "id",
                        "in": "query",
                        "description": "To fetch one or more devices. Multiple params can be passed like `id=31&id=42`",
                        "required": false,
                        "type": "integer",
                        "collectionFormat": "multi"
                    },
                    {
                        "name": "uniqueId",
                        "in": "query",
                        "description": "To fetch one or more devices. Multiple params can be passed like `uniqueId=333331&uniqieId=44442`",
                        "required": false,
                        "type": "string",
                        "collectionFormat": "multi"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "schema": {
                            "type": "array",
                            "items": {
                                "$ref": "#/definitions/Device"
                            }
                        }
                    },
                    "400": {
                        "description": "No permission"
                    }
                }
            }

Screen Shot 2019-07-11 at 11 37 01 am

Support for set model directories

generateSwagger {
    platform.set("kotlin")
    packageName.set("com.yelp.codegen.samples")
    inputFile.set(file("./sample_specs.json"))
    outputDir.set(project.layout.buildDirectory.dir("./src/main/java/"))
}

we need something like:

generateSwagger {
    platform.set("kotlin")
    packageName.set("com.yelp.codegen.samples")
    inputFile.set(file("./sample_specs.json"))
    outputDir.set(project.layout.buildDirectory.dir("./src/main/java/"))
    
    requestModelsDirectory.set("models/requests")  -> default is models
    responseModelsDirectory.set("models/responses") -> default is models
}

Can you help me in that?

Enums in query and MULTI

Hi,

The code generated ended up with an import import …yelpcodegen.tools.MULTI that does not exist.

I checked the swagger and the only places I found "multi" was on a query parameter that is an enum and contains "collectionFormat": "multi", (I didn't check what this meant). Looking at the generated code, the request contains a List in the place of the enum.

So, two questions. Is the import a bug? And could the request be generated with the enum class instead of a List?

Here's the generated code vs the swagger.

Screen Shot 2019-12-13 at 20 27 53

Features headers to remove not working

Using the new 1.4.0 version and the previous one 1.3.0, headers to remove function isn't working.

This is the output of my successful generateSwagger task:

> Task :app:generateSwagger
Successfully read version from Swagger Spec file: 1.1.0
####################
Yelp Swagger Codegen
####################
Platform 	 kotlin-coroutines
Package 	 com.my.super.project
specName 	 [ DEFAULT ] defaultname
specVers 	 1.1.0
input 		 /home/projects/app/swagger.json
output 		 /home/projects/app/src/main/java
groupId 	 com.my.super.project
artifactId 	 com.my.super.project
features 	 X-HTTP-Method-Override, X-Operation-ID, Content-Type

BUILD SUCCESSFUL in 1s
1 actionable task: 1 executed
10:09:41 PM: Task execution finished 'generateSwagger'.

And this is my gradle configuration:

generateSwagger {
    platform = "kotlin-coroutines"
    packageName = "com.my.super.project"
    outputDir = file("./src/main/java/")
    features {
        headersToRemove = ["X-HTTP-Method-Override", "X-Operation-ID", "Content-Type"]
    }
    inputFile = file("../swagger/destination/PointsOfInterest_v1_Swagger_specification.json")
}

And this is the output of my Api:

@Headers(
        "X-Operation-ID: getPointOfInterest",
      "Content-Type: application/json"
    )
    @GET("api/{poisId}")
    suspend fun getPointOfInterest(
        @retrofit2.http.Path("poisId") poisId: String
    ): Map<String, Any?>

By the awesome project and thx for the help !

Unable to load class 'org.gradle.kotlin.dsl.precompile.v1.PrecompiledProjectScript'.

Hi.
made a new project, gradle version 3.5.3 (<<< EDIT: actually it is 5.4.1)
added in the the module gradle file:

buildscript {
    repositories {
        maven { url "https://plugins.gradle.org/m2/" }
    }
    dependencies {
        classpath "com.yelp.codegen:plugin:1.3.0"
    }
}
apply plugin: "com.yelp.codegen.plugin"
generateSwagger {
    platform = "kotlin"
    packageName = "com.yelp.codegen.samples"
    inputFile = file("./sample_specs.json")
    outputDir = file("./src/main/java/")
}

but I get this error:
Unable to load class 'org.gradle.kotlin.dsl.precompile.v1.PrecompiledProjectScript'.

can somebdoy help me ? thx!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.