From 87265d9ac7e777d0ee78440ed556a2d752ac4a24 Mon Sep 17 00:00:00 2001 From: Jim Schubert Date: Mon, 29 May 2017 20:47:31 -0400 Subject: [PATCH] [kotlin] api/model docs This commit adds Api/Model/Auth documentation to the generated README.md. Because auth support is not yet fully implemented (users can manually set default headers globally), there aren't examples for helper auth methods. Models with inline enums document allowed values rather than pointing to a generated enum class. Two global additionalProperties were added (generateApiDocs, generateModelDocs) to allow templates to conditionally display documentatoin depending on these mutually exclusive settings. All current generators supporting docs will attempt to link to generated models when only api docs are specified. This also moves the $@ bash parameter in bin/kotlin-client-petstore.sh to the end of the args variable. This is because $@ can only be used to pass System properties like -DdebugModels, can can already be passed as: JAVA_OPTS="$JAVA_OPTS -DdebugModels" ./bin/kotlin-client-petstore.sh By moving the $@ to the end of the args, it allows us to pass additional properties and other switches directly to the script. --- bin/kotlin-client-petstore.sh | 2 +- .../io/swagger/codegen/CodegenConstants.java | 6 ++ .../io/swagger/codegen/DefaultGenerator.java | 4 + .../languages/KotlinClientCodegen.java | 21 ++++- .../main/resources/kotlin-client/README.md | 29 ------- .../resources/kotlin-client/README.mustache | 85 +++++++++++++++++++ .../resources/kotlin-client/api_doc.mustache | 65 ++++++++++++++ .../kotlin-client/class_doc.mustache | 15 ++++ .../resources/kotlin-client/enum_doc.mustache | 7 ++ .../kotlin-client/model_doc.mustache | 3 + samples/client/kotlin/README.md | 69 ++++++++++++++- 11 files changed, 270 insertions(+), 36 deletions(-) delete mode 100644 modules/swagger-codegen/src/main/resources/kotlin-client/README.md create mode 100644 modules/swagger-codegen/src/main/resources/kotlin-client/README.mustache create mode 100644 modules/swagger-codegen/src/main/resources/kotlin-client/api_doc.mustache create mode 100644 modules/swagger-codegen/src/main/resources/kotlin-client/class_doc.mustache create mode 100644 modules/swagger-codegen/src/main/resources/kotlin-client/enum_doc.mustache create mode 100644 modules/swagger-codegen/src/main/resources/kotlin-client/model_doc.mustache diff --git a/bin/kotlin-client-petstore.sh b/bin/kotlin-client-petstore.sh index fa017f1e8ef8..4f5a84e472b7 100755 --- a/bin/kotlin-client-petstore.sh +++ b/bin/kotlin-client-petstore.sh @@ -26,6 +26,6 @@ fi # if you've executed sbt assembly previously it will use that instead. export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties" -ags="$@ generate -t modules/swagger-codegen/src/main/resources/kotlin-client -i modules/swagger-codegen/src/test/resources/2_0/petstore.yaml -l kotlin -o samples/client/kotlin" +ags="generate -t modules/swagger-codegen/src/main/resources/kotlin-client -i modules/swagger-codegen/src/test/resources/2_0/petstore.yaml -l kotlin -o samples/client/kotlin $@" java ${JAVA_OPTS} -jar ${executable} ${ags} diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/CodegenConstants.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/CodegenConstants.java index 47a97e4d89d3..d9bf80c1b62a 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/CodegenConstants.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/CodegenConstants.java @@ -173,9 +173,15 @@ public class CodegenConstants { public static final String EXCLUDE_TESTS = "excludeTests"; public static final String EXCLUDE_TESTS_DESC = "Specifies that no tests are to be generated."; + // Not user-configurable. System provided for use in templates. + public static final String GENERATE_API_DOCS = "generateApiDocs"; + public static final String GENERATE_API_TESTS = "generateApiTests"; public static final String GENERATE_API_TESTS_DESC = "Specifies that api tests are to be generated."; + // Not user-configurable. System provided for use in templates. + public static final String GENERATE_MODEL_DOCS = "generateModelDocs"; + public static final String GENERATE_MODEL_TESTS = "generateModelTests"; public static final String GENERATE_MODEL_TESTS_DESC = "Specifies that model tests are to be generated."; diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/DefaultGenerator.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/DefaultGenerator.java index f28e8d20cb3d..5a1ea3e1227e 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/DefaultGenerator.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/DefaultGenerator.java @@ -120,6 +120,10 @@ public class DefaultGenerator extends AbstractGenerator implements Generator { // Additional properties added for tests to exclude references in project related files config.additionalProperties().put(CodegenConstants.GENERATE_API_TESTS, generateApiTests); config.additionalProperties().put(CodegenConstants.GENERATE_MODEL_TESTS, generateModelTests); + + config.additionalProperties().put(CodegenConstants.GENERATE_API_DOCS, generateApiDocumentation); + config.additionalProperties().put(CodegenConstants.GENERATE_MODEL_DOCS, generateModelDocumentation); + if(!generateApiTests && !generateModelTests) { config.additionalProperties().put(CodegenConstants.EXCLUDE_TESTS, true); } diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/KotlinClientCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/KotlinClientCodegen.java index aa1a0039deda..50ed2dc1ee3a 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/KotlinClientCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/KotlinClientCodegen.java @@ -20,6 +20,8 @@ public class KotlinClientCodegen extends DefaultCodegen implements CodegenConfig protected String artifactVersion = "1.0.0"; protected String sourceFolder = "src/main/kotlin"; protected String packageName = "io.swagger.client"; + protected String apiDocPath = "docs/"; + protected String modelDocPath = "docs/"; /** * Constructs an instance of `KotlinClientCodegen`. @@ -30,7 +32,8 @@ public class KotlinClientCodegen extends DefaultCodegen implements CodegenConfig outputFolder = "generated-code" + File.separator + "kotlin-client"; modelTemplateFiles.put("model.mustache", ".kt"); apiTemplateFiles.put("api.mustache", ".kt"); - // TODO: Documentation generation + modelDocTemplateFiles.put("model_doc.mustache", ".md"); + apiDocTemplateFiles.put("api_doc.mustache", ".md"); embeddedTemplateDir = templateDir = "kotlin-client"; apiPackage = packageName + ".apis"; modelPackage = packageName + ".models"; @@ -227,7 +230,10 @@ public class KotlinClientCodegen extends DefaultCodegen implements CodegenConfig additionalProperties.put(CodegenConstants.API_PACKAGE, apiPackage()); additionalProperties.put(CodegenConstants.MODEL_PACKAGE, modelPackage()); - supportingFiles.add(new SupportingFile("README.md", "", "README.md")); + additionalProperties.put("apiDocPath", apiDocPath); + additionalProperties.put("modelDocPath", modelDocPath); + + supportingFiles.add(new SupportingFile("README.mustache", "", "README.md")); supportingFiles.add(new SupportingFile("build.gradle.mustache", "", "build.gradle")); supportingFiles.add(new SupportingFile("settings.gradle.mustache", "", "settings.gradle")); @@ -255,11 +261,22 @@ public class KotlinClientCodegen extends DefaultCodegen implements CodegenConfig return input.replace("\"", ""); } + @Override + public String apiDocFileFolder() { + return (outputFolder + "/" + apiDocPath).replace('/', File.separatorChar); + } + @Override public String apiFileFolder() { return outputFolder + File.separator + sourceFolder + File.separator + apiPackage().replace('.', File.separatorChar); } + @Override + public String modelDocFileFolder() { + return (outputFolder + "/" + modelDocPath).replace('/', File.separatorChar); + } + + @Override public String modelFileFolder() { return outputFolder + File.separator + sourceFolder + File.separator + modelPackage().replace('.', File.separatorChar); diff --git a/modules/swagger-codegen/src/main/resources/kotlin-client/README.md b/modules/swagger-codegen/src/main/resources/kotlin-client/README.md deleted file mode 100644 index 885688a0fd64..000000000000 --- a/modules/swagger-codegen/src/main/resources/kotlin-client/README.md +++ /dev/null @@ -1,29 +0,0 @@ -# Generated Kotlin Client library - -## Requires - -* Kotlin 1.1.2 -* Gradle 3.3 - -## Build - -First, create the gradle wrapper script: - -``` -gradle wrapper -``` - -Then, run: - -``` -./gradlew check assemble -``` - -This runs all tests and packages the library. - -## Notes - -* Supports JSON inputs/outputs, File inputs, and Form inputs. -* Supports collection formats for query parameters: csv, tsv, ssv, pipes. -* Some Kotlin and Java types are fully qualified to avoid conflicts with types defined in Swagger definitions. -* Implementation of ApiClient is intended to reduce method counts, specifically to benefit Android targets. \ No newline at end of file diff --git a/modules/swagger-codegen/src/main/resources/kotlin-client/README.mustache b/modules/swagger-codegen/src/main/resources/kotlin-client/README.mustache new file mode 100644 index 000000000000..7a10bab6c126 --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/kotlin-client/README.mustache @@ -0,0 +1,85 @@ +# {{packageName}} - Kotlin client library for {{appName}} + +## Requires + +* Kotlin 1.1.2 +* Gradle 3.3 + +## Build + +First, create the gradle wrapper script: + +``` +gradle wrapper +``` + +Then, run: + +``` +./gradlew check assemble +``` + +This runs all tests and packages the library. + +## Features/Implementation Notes + +* Supports JSON inputs/outputs, File inputs, and Form inputs. +* Supports collection formats for query parameters: csv, tsv, ssv, pipes. +* Some Kotlin and Java types are fully qualified to avoid conflicts with types defined in Swagger definitions. +* Implementation of ApiClient is intended to reduce method counts, specifically to benefit Android targets. + +{{#generateApiDocs}} + +## Documentation for API Endpoints + +All URIs are relative to *{{{basePath}}}* + +Class | Method | HTTP request | Description +------------ | ------------- | ------------- | ------------- +{{#apiInfo}}{{#apis}}{{#operations}}{{#operation}}*{{classname}}* | [**{{operationId}}**]({{apiDocPath}}{{classname}}.md#{{operationIdLowerCase}}) | **{{httpMethod}}** {{path}} | {{#summary}}{{{summary}}}{{/summary}} +{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}} +{{/generateApiDocs}} + +{{#generateModelDocs}} + +## Documentation for Models + +{{#modelPackage}} +{{#models}}{{#model}} - [{{{modelPackage}}}.{{{classname}}}]({{modelDocPath}}{{{classname}}}.md) +{{/model}}{{/models}} +{{/modelPackage}} +{{^modelPackage}} +No model defined in this package +{{/modelPackage}} +{{/generateModelDocs}} + +{{! TODO: optional documentation for authorization? }} +## Documentation for Authorization + +{{^authMethods}} +All endpoints do not require authorization. +{{/authMethods}} +{{#authMethods}} +{{#last}} +Authentication schemes defined for the API: +{{/last}} +{{/authMethods}} +{{#authMethods}} + +### {{name}} + +{{#isApiKey}}- **Type**: API key +- **API key parameter name**: {{keyParamName}} +- **Location**: {{#isKeyInQuery}}URL query string{{/isKeyInQuery}}{{#isKeyInHeader}}HTTP header{{/isKeyInHeader}} +{{/isApiKey}} +{{#isBasic}}- **Type**: HTTP basic authentication +{{/isBasic}} +{{#isOAuth}}- **Type**: OAuth +- **Flow**: {{flow}} +- **Authorization URL**: {{authorizationUrl}} +- **Scopes**: {{^scopes}}N/A{{/scopes}} +{{#scopes}} - {{scope}}: {{description}} +{{/scopes}} +{{/isOAuth}} + +{{/authMethods}} \ No newline at end of file diff --git a/modules/swagger-codegen/src/main/resources/kotlin-client/api_doc.mustache b/modules/swagger-codegen/src/main/resources/kotlin-client/api_doc.mustache new file mode 100644 index 000000000000..d288470ca886 --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/kotlin-client/api_doc.mustache @@ -0,0 +1,65 @@ +# {{classname}}{{#description}} +{{description}}{{/description}} + +All URIs are relative to *{{basePath}}* + +Method | HTTP request | Description +------------- | ------------- | ------------- +{{#operations}}{{#operation}}[**{{operationId}}**]({{classname}}.md#{{operationId}}) | **{{httpMethod}}** {{path}} | {{#summary}}{{summary}}{{/summary}} +{{/operation}}{{/operations}} + +{{#operations}} +{{#operation}} + +# **{{operationId}}** +> {{#returnType}}{{returnType}} {{/returnType}}{{operationId}}({{#allParams}}{{{paramName}}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) + +{{summary}}{{#notes}} + +{{notes}}{{/notes}} + +### Example +```kotlin +// Import classes: +//import {{{packageName}}}.infrastructure.* +//import {{{modelPackage}}}.* + +{{! TODO: Auth method documentation examples}} +val apiInstance = {{{classname}}}() +{{#allParams}} +val {{{paramName}}} : {{{dataType}}} = {{{example}}} // {{{dataType}}} | {{{description}}} +{{/allParams}} +try { + {{#returnType}}val result : {{{returnType}}} = {{/returnType}}apiInstance.{{{operationId}}}({{#allParams}}{{{paramName}}}{{#hasMore}}, {{/hasMore}}{{/allParams}}){{#returnType}} + println(result){{/returnType}} +} catch (e: ClientException) { + println("4xx response calling {{{classname}}}#{{{operationId}}}") + e.printStackTrace() +} catch (e: ServerException) { + println("5xx response calling {{{classname}}}#{{{operationId}}}") + e.printStackTrace() +} +``` + +### Parameters +{{^allParams}}This endpoint does not need any parameter.{{/allParams}}{{#allParams}}{{#-last}} +Name | Type | Description | Notes +------------- | ------------- | ------------- | -------------{{/-last}}{{/allParams}} +{{#allParams}} **{{paramName}}** | {{#isPrimitiveType}}**{{dataType}}**{{/isPrimitiveType}}{{^isPrimitiveType}}{{#isFile}}**{{dataType}}**{{/isFile}}{{^isFile}}{{#generateModelDocs}}[**{{dataType}}**]({{baseType}}.md){{/generateModelDocs}}{{^generateModelDocs}}**{{dataType}}**{{/generateModelDocs}}{{/isFile}}{{/isPrimitiveType}}| {{description}} |{{^required}} [optional]{{/required}}{{#defaultValue}} [default to {{defaultValue}}]{{/defaultValue}}{{#allowableValues}} [enum: {{#values}}{{{.}}}{{^-last}}, {{/-last}}{{/values}}]{{/allowableValues}} +{{/allParams}} + +### Return type + +{{#returnType}}{{#returnTypeIsPrimitive}}**{{returnType}}**{{/returnTypeIsPrimitive}}{{^returnTypeIsPrimitive}}{{#generateModelDocs}}[**{{returnType}}**]({{returnBaseType}}.md){{/generateModelDocs}}{{^generateModelDocs}}**{{returnType}}**{{/generateModelDocs}}{{/returnTypeIsPrimitive}}{{/returnType}}{{^returnType}}null (empty response body){{/returnType}} + +### Authorization + +{{^authMethods}}No authorization required{{/authMethods}}{{#authMethods}}[{{name}}](../README.md#{{name}}){{^-last}}, {{/-last}}{{/authMethods}} + +### HTTP request headers + + - **Content-Type**: {{#consumes}}{{{mediaType}}}{{#hasMore}}, {{/hasMore}}{{/consumes}}{{^consumes}}Not defined{{/consumes}} + - **Accept**: {{#produces}}{{{mediaType}}}{{#hasMore}}, {{/hasMore}}{{/produces}}{{^produces}}Not defined{{/produces}} + +{{/operation}} +{{/operations}} diff --git a/modules/swagger-codegen/src/main/resources/kotlin-client/class_doc.mustache b/modules/swagger-codegen/src/main/resources/kotlin-client/class_doc.mustache new file mode 100644 index 000000000000..45e19942734d --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/kotlin-client/class_doc.mustache @@ -0,0 +1,15 @@ +# {{classname}} + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +{{#vars}}**{{name}}** | {{#isEnum}}[**inline**](#{{datatypeWithEnum}}){{/isEnum}}{{^isEnum}}{{#isPrimitiveType}}**{{datatype}}**{{/isPrimitiveType}}{{^isPrimitiveType}}[**{{datatype}}**]({{complexType}}.md){{/isPrimitiveType}}{{/isEnum}} | {{description}} | {{^required}} [optional]{{/required}}{{#readOnly}} [readonly]{{/readOnly}} +{{/vars}} +{{#vars}}{{#isEnum}} + +{{!NOTE: see java's resources "pojo_doc.mustache" once enums are fully implemented}} +## Enum: {{baseName}} +Name | Value +---- | -----{{#allowableValues}} +{{name}} | {{#values}}{{.}}{{^-last}}, {{/-last}}{{/values}}{{/allowableValues}} +{{/isEnum}}{{/vars}} diff --git a/modules/swagger-codegen/src/main/resources/kotlin-client/enum_doc.mustache b/modules/swagger-codegen/src/main/resources/kotlin-client/enum_doc.mustache new file mode 100644 index 000000000000..fcb3d7e61aa6 --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/kotlin-client/enum_doc.mustache @@ -0,0 +1,7 @@ +# {{classname}} + +## Enum + +{{#allowableValues}}{{#enumVars}} + * `{{name}}` (value: `{{{value}}}`) +{{/enumVars}}{{/allowableValues}} diff --git a/modules/swagger-codegen/src/main/resources/kotlin-client/model_doc.mustache b/modules/swagger-codegen/src/main/resources/kotlin-client/model_doc.mustache new file mode 100644 index 000000000000..e3b718421188 --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/kotlin-client/model_doc.mustache @@ -0,0 +1,3 @@ +{{#models}}{{#model}} +{{#isEnum}}{{>enum_doc}}{{/isEnum}}{{^isEnum}}{{>class_doc}}{{/isEnum}} +{{/model}}{{/models}} diff --git a/samples/client/kotlin/README.md b/samples/client/kotlin/README.md index 885688a0fd64..410e14e4adb8 100644 --- a/samples/client/kotlin/README.md +++ b/samples/client/kotlin/README.md @@ -1,4 +1,4 @@ -# Generated Kotlin Client library +# io.swagger.client - Kotlin client library for Swagger Petstore ## Requires @@ -14,16 +14,77 @@ gradle wrapper ``` Then, run: - + ``` ./gradlew check assemble ``` This runs all tests and packages the library. -## Notes +## Features/Implementation Notes * Supports JSON inputs/outputs, File inputs, and Form inputs. * Supports collection formats for query parameters: csv, tsv, ssv, pipes. * Some Kotlin and Java types are fully qualified to avoid conflicts with types defined in Swagger definitions. -* Implementation of ApiClient is intended to reduce method counts, specifically to benefit Android targets. \ No newline at end of file +* Implementation of ApiClient is intended to reduce method counts, specifically to benefit Android targets. + + +## Documentation for API Endpoints + +All URIs are relative to *http://petstore.swagger.io/v2* + +Class | Method | HTTP request | Description +------------ | ------------- | ------------- | ------------- +*PetApi* | [**addPet**](docs/PetApi.md#addpet) | **POST** /pet | Add a new pet to the store +*PetApi* | [**deletePet**](docs/PetApi.md#deletepet) | **DELETE** /pet/{petId} | Deletes a pet +*PetApi* | [**findPetsByStatus**](docs/PetApi.md#findpetsbystatus) | **GET** /pet/findByStatus | Finds Pets by status +*PetApi* | [**findPetsByTags**](docs/PetApi.md#findpetsbytags) | **GET** /pet/findByTags | Finds Pets by tags +*PetApi* | [**getPetById**](docs/PetApi.md#getpetbyid) | **GET** /pet/{petId} | Find pet by ID +*PetApi* | [**updatePet**](docs/PetApi.md#updatepet) | **PUT** /pet | Update an existing pet +*PetApi* | [**updatePetWithForm**](docs/PetApi.md#updatepetwithform) | **POST** /pet/{petId} | Updates a pet in the store with form data +*PetApi* | [**uploadFile**](docs/PetApi.md#uploadfile) | **POST** /pet/{petId}/uploadImage | uploads an image +*StoreApi* | [**deleteOrder**](docs/StoreApi.md#deleteorder) | **DELETE** /store/order/{orderId} | Delete purchase order by ID +*StoreApi* | [**getInventory**](docs/StoreApi.md#getinventory) | **GET** /store/inventory | Returns pet inventories by status +*StoreApi* | [**getOrderById**](docs/StoreApi.md#getorderbyid) | **GET** /store/order/{orderId} | Find purchase order by ID +*StoreApi* | [**placeOrder**](docs/StoreApi.md#placeorder) | **POST** /store/order | Place an order for a pet +*UserApi* | [**createUser**](docs/UserApi.md#createuser) | **POST** /user | Create user +*UserApi* | [**createUsersWithArrayInput**](docs/UserApi.md#createuserswitharrayinput) | **POST** /user/createWithArray | Creates list of users with given input array +*UserApi* | [**createUsersWithListInput**](docs/UserApi.md#createuserswithlistinput) | **POST** /user/createWithList | Creates list of users with given input array +*UserApi* | [**deleteUser**](docs/UserApi.md#deleteuser) | **DELETE** /user/{username} | Delete user +*UserApi* | [**getUserByName**](docs/UserApi.md#getuserbyname) | **GET** /user/{username} | Get user by user name +*UserApi* | [**loginUser**](docs/UserApi.md#loginuser) | **GET** /user/login | Logs user into the system +*UserApi* | [**logoutUser**](docs/UserApi.md#logoutuser) | **GET** /user/logout | Logs out current logged in user session +*UserApi* | [**updateUser**](docs/UserApi.md#updateuser) | **PUT** /user/{username} | Updated user + + + +## Documentation for Models + + - [io.swagger.client.models.ApiResponse](docs/ApiResponse.md) + - [io.swagger.client.models.Category](docs/Category.md) + - [io.swagger.client.models.Order](docs/Order.md) + - [io.swagger.client.models.Pet](docs/Pet.md) + - [io.swagger.client.models.Tag](docs/Tag.md) + - [io.swagger.client.models.User](docs/User.md) + + + +## Documentation for Authorization + + +### api_key + +- **Type**: API key +- **API key parameter name**: api_key +- **Location**: HTTP header + + +### petstore_auth + +- **Type**: OAuth +- **Flow**: implicit +- **Authorization URL**: http://petstore.swagger.io/api/oauth/dialog +- **Scopes**: + - write:pets: modify pets in your account + - read:pets: read your pets +