├── .github
├── labeler.yml
└── workflows
│ ├── community.yml
│ └── sbt.yml
├── .gitignore
├── .java-version
├── LICENSE
├── README.md
├── build.sbt
├── project
├── build.properties
└── plugin.sbt
├── publish.sbt
└── src
├── main
└── scala
│ └── org
│ └── openapitools
│ └── generator
│ └── sbt
│ └── plugin
│ ├── OpenApiGeneratorKeys.scala
│ ├── OpenApiGeneratorPlugin.scala
│ └── tasks
│ ├── OpenApiGenerateTask.scala
│ └── OpenApiGeneratorsTask.scala
└── sbt-test
└── sbt-openapi-generator
└── simple
├── build.sbt
├── config.yaml
├── openapi.yaml
├── project
├── build.properties
└── plugin.sbt
├── src
└── main
│ └── scala
│ └── Main.scala
├── test
└── version.sbt
/.github/labeler.yml:
--------------------------------------------------------------------------------
1 | # labeler "full" schema
2 | # see https://github.com/marketplace/actions/auto-labeler
3 | # enable labeler on issues, prs, or both.
4 | enable:
5 | issues: true
6 | prs: true
7 |
8 | # comments object allows you to specify a different message for issues and prs
9 | comments:
10 | issues: |
11 | Thanks for opening this issue!
12 | We've automatically applied any labels matching text in your issue.
13 | prs: |
14 | Thanks for the contribution!
15 | We've automatically applied labels that seem to represent your pull request.
16 |
17 | # Labels is an object where:
18 | # - keys are labels
19 | # - values are objects of { include: [ pattern ], exclude: [ pattern ] }
20 | # - pattern must be a valid regex, and is applied globally to
21 | # title + description of issues and/or prs (see enabled config above)
22 | # - 'include' patterns will associate a label if any of these patterns match
23 | # - 'exclude' patterns will ignore this label if any of these patterns match
24 | labels:
25 | 'bug':
26 | include:
27 | - '\s*?\[bug(s)?\]\b'
28 | - '\s*?\[fix\]\b'
29 | exclude: []
30 | 'help wanted':
31 | include:
32 | - '\bhelp wanted\b'
33 | exclude:
34 | - '\bquestion\b'
35 | - '\bhelp( me)?\b'
36 | 'question':
37 | include:
38 | - '\bhelp( me)?\b'
39 | - '\b\[question\]\b'
40 | 'enhancement':
41 | include:
42 | - '\bfeat\b'
43 | - '\bfeature\b'
44 | exclude: []
--------------------------------------------------------------------------------
/.github/workflows/community.yml:
--------------------------------------------------------------------------------
1 | name: Community
2 | on:
3 | issues:
4 | types: [opened, edited, milestoned]
5 | pull_request_target:
6 | types: [opened]
7 |
8 | jobs:
9 |
10 | labeler:
11 | runs-on: ubuntu-latest
12 |
13 | steps:
14 | - name: Check Labels
15 | id: labeler
16 | uses: jimschubert/labeler-action@v1
17 | with:
18 | GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
19 |
--------------------------------------------------------------------------------
/.github/workflows/sbt.yml:
--------------------------------------------------------------------------------
1 | name: Scala CI
2 |
3 | # Support "official releases" on master, and release fixes on release/ prefixed branches
4 | on:
5 | push:
6 | branches:
7 | - 'master'
8 | - 'releases/**'
9 | - '!releases/**-alpha'
10 | paths-ignore:
11 | - 'docs/**'
12 | - 'README.md'
13 | pull_request:
14 | branches:
15 | - 'master'
16 | # trigger on new branch/tag creation
17 | create: []
18 |
19 | jobs:
20 | build:
21 | runs-on: ubuntu-latest
22 | steps:
23 | - uses: actions/checkout@v2
24 | with:
25 | fetch-depth: 0
26 | - name: Set up JDK
27 | uses: actions/setup-java@v2
28 | with:
29 | java-version: 11
30 | distribution: temurin
31 | - name: Setup sbt launcher
32 | uses: sbt/setup-sbt@v1
33 | - name: Cache SBT ivy cache
34 | uses: actions/cache@v4
35 | with:
36 | path: ~/.ivy2/cache
37 | key: ${{ runner.os }}-sbt-ivy-cache-${{ hashFiles('**/*.sbt') }}
38 | - name: Cache SBT
39 | uses: actions/cache@v4
40 | with:
41 | path: ~/.sbt
42 | key: ${{ runner.os }}-sbt-${{ hashFiles('**/*.sbt') }}
43 | - name: Run tests
44 | run: sbt ^test ^scripted
45 | #- name: Publish
46 | # if: github.ref == 'refs/heads/master' || startsWith(github.ref, 'refs/tags/v')
47 | # env:
48 | # BINTRAY_USER: ${{ secrets.BINTRAY_USER }}
49 | # BINTRAY_PASS: ${{ secrets.BINTRAY_PASS }}
50 | # run: sbt ^publish
51 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .bsp
2 |
3 | # Created by https://www.gitignore.io/api/osx,sbt,linux,scala,intellij
4 | # Edit at https://www.gitignore.io/?templates=osx,sbt,linux,scala,intellij
5 |
6 | ### Intellij ###
7 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm
8 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
9 |
10 | # User-specific stuff
11 | .idea/**/workspace.xml
12 | .idea/**/tasks.xml
13 | .idea/**/usage.statistics.xml
14 | .idea/**/dictionaries
15 | .idea/**/shelf
16 |
17 | # Generated files
18 | .idea/**/contentModel.xml
19 |
20 | # Sensitive or high-churn files
21 | .idea/**/dataSources/
22 | .idea/**/dataSources.ids
23 | .idea/**/dataSources.local.xml
24 | .idea/**/sqlDataSources.xml
25 | .idea/**/dynamic.xml
26 | .idea/**/uiDesigner.xml
27 | .idea/**/dbnavigator.xml
28 |
29 | # Gradle
30 | .idea/**/gradle.xml
31 | .idea/**/libraries
32 |
33 | # Gradle and Maven with auto-import
34 | # When using Gradle or Maven with auto-import, you should exclude module files,
35 | # since they will be recreated, and may cause churn. Uncomment if using
36 | # auto-import.
37 | # .idea/modules.xml
38 | # .idea/*.iml
39 | # .idea/modules
40 | *.iml
41 | *.ipr
42 |
43 | # CMake
44 | cmake-build-*/
45 |
46 | # Mongo Explorer plugin
47 | .idea/**/mongoSettings.xml
48 |
49 | # File-based project format
50 | *.iws
51 |
52 | # IntelliJ
53 | out/
54 |
55 | # mpeltonen/sbt-idea plugin
56 | .idea_modules/
57 |
58 | # JIRA plugin
59 | atlassian-ide-plugin.xml
60 |
61 | # Cursive Clojure plugin
62 | .idea/replstate.xml
63 |
64 | # Crashlytics plugin (for Android Studio and IntelliJ)
65 | com_crashlytics_export_strings.xml
66 | crashlytics.properties
67 | crashlytics-build.properties
68 | fabric.properties
69 |
70 | # Editor-based Rest Client
71 | .idea/httpRequests
72 |
73 | # Android studio 3.1+ serialized cache file
74 | .idea/caches/build_file_checksums.ser
75 |
76 | ### Intellij Patch ###
77 | # Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721
78 |
79 | # *.iml
80 | # modules.xml
81 | # .idea/misc.xml
82 | # *.ipr
83 |
84 | # Sonarlint plugin
85 | .idea/**/sonarlint/
86 |
87 | # SonarQube Plugin
88 | .idea/**/sonarIssues.xml
89 |
90 | # Markdown Navigator plugin
91 | .idea/**/markdown-navigator.xml
92 | .idea/**/markdown-navigator/
93 |
94 | ### Linux ###
95 | *~
96 |
97 | # temporary files which can be created if a process still has a handle open of a deleted file
98 | .fuse_hidden*
99 |
100 | # KDE directory preferences
101 | .directory
102 |
103 | # Linux trash folder which might appear on any partition or disk
104 | .Trash-*
105 |
106 | # .nfs files are created when an open file is removed but is still being accessed
107 | .nfs*
108 |
109 | ### OSX ###
110 | # General
111 | .DS_Store
112 | .AppleDouble
113 | .LSOverride
114 |
115 | # Icon must end with two \r
116 | Icon
117 |
118 | # Thumbnails
119 | ._*
120 |
121 | # Files that might appear in the root of a volume
122 | .DocumentRevisions-V100
123 | .fseventsd
124 | .Spotlight-V100
125 | .TemporaryItems
126 | .Trashes
127 | .VolumeIcon.icns
128 | .com.apple.timemachine.donotpresent
129 |
130 | # Directories potentially created on remote AFP share
131 | .AppleDB
132 | .AppleDesktop
133 | Network Trash Folder
134 | Temporary Items
135 | .apdisk
136 |
137 | ### SBT ###
138 | # Simple Build Tool
139 | # http://www.scala-sbt.org/release/docs/Getting-Started/Directories.html#configuring-version-control
140 |
141 | dist/*
142 | target/
143 | lib_managed/
144 | src_managed/
145 | project/boot/
146 | project/plugins/project/
147 | .history
148 | .cache
149 | .lib/
150 |
151 | ### Scala ###
152 | *.class
153 | *.log
154 | *.metals
155 |
156 | # End of https://www.gitignore.io/api/osx,sbt,linux,scala,intellij
157 |
158 | .vscode
159 | metals.sbt
160 | .bloop
--------------------------------------------------------------------------------
/.java-version:
--------------------------------------------------------------------------------
1 | 11
2 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2020 OpenAPI-Generator Contributors (https://openapi-generator.tech)
2 |
3 | Licensed under the Apache License, Version 2.0 (the "License");
4 | you may not use this file except in compliance with the License.
5 | You may obtain a copy of the License at
6 |
7 | http://www.apache.org/licenses/LICENSE-2.0
8 |
9 | Unless required by applicable law or agreed to in writing, software
10 | distributed under the License is distributed on an "AS IS" BASIS,
11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | See the License for the specific language governing permissions and
13 | limitations under the License.
14 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # sbt-openapi-generator
2 |
3 | 
4 |
5 | A Sbt plugin to support the OpenAPI generator project.
6 |
7 | # Usage
8 |
9 | Add to your `project/plugins.sbt`:
10 |
11 | ```sbt
12 | addSbtPlugin("org.openapitools" % "sbt-openapi-generator" % "7.13.0")
13 | ```
14 |
15 | # Configuration
16 |
17 | Configuration based on project module is recommended way to separate specifications by modules.
18 |
19 | You must define one of the settings `openApiInputSpec` or `openApiConfigFile` to able run plugin to generate.
20 |
21 | Settings will be picked up from `openApiConfigFile` first if defined and then will be overwritten with module specified
22 | settings if provided
23 |
24 | With the next example module `generated` will be defined as:
25 |
26 | ```sbt
27 | lazy val generated = project.in(file("generated"))
28 | .settings(
29 | openApiInputSpec := "openapi.yaml",
30 | openApiConfigFile := "config.yaml"
31 | )
32 | ```
33 |
34 | There is a helpers to have boolean settings more readable. Instead of `Some(true)` it possible to do next:
35 | ```sbt
36 | openApiValidateSpec := SettingDisabled,
37 | openApiGenerateModelTests := SettingEnabled,
38 | ```
39 | # Execution
40 |
41 | To print all available languages use
42 | ```shell script
43 | sbt openApiGenerators
44 | ```
45 |
46 | To run template generation process
47 | ```shell script
48 | sbt openApiGenerate
49 | ```
50 | or per defined module
51 | ```shell script
52 | sbt generated/openApiGenerate
53 | ```
54 |
55 | # Settings
56 |
57 |
58 | | Setting | Type | Description |
59 | |----------|--------|--------------------------|
60 | | openApiGeneratorName *| `String` | The name of the generator which will handle codegen. (see \"openApiGenerators\" task)
Required. Can be provided as `generatorName` option of `openApiConfigFile` json config |
61 | | openApiInputSpec *| `String` | The Open API 2.0/3.x specification location (file or url)
Required. Can be provided as `inputSpec` option of `openApiConfigFile` json config |
62 | | openApiOutputDir| `String` | The output target directory into which code will be generated |
63 | | openApiConfigFile **| `String` | Path to json configuration file
This setting is required with `generatorName` and `inputSpec` settings provided if sbt settings `openApiGeneratorName` and `openApiInputSpec` are absent |
64 | | openApiAdditionalProperties | `Map[String, String]` | Sets additional properties that can be referenced by the mustache templates in the format of name=value,name=value. You can also have multiple occurrences of this option |
65 | | openApiGlobalProperties | `Map[String, String]` |Sets specified system properties |
66 | | openApiVerbose | `Option[Boolean]` | The verbosity of generation |
67 | | openApiValidateSpec | `Option[Boolean]` | Whether or not an input specification should be validated upon generation |
68 | | openApiTemplateDir | `String` | The template directory holding a custom template |
69 | | openApiAuth | `String` | Adds authorization headers when fetching the OpenAPI definitions remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values |
70 | | openApiSkipOverwrite | `Option[Boolean]` | Specifies if the existing files should be overwritten during the generation |
71 | | openApiPackageName | `String` | Package for generated classes (where supported) |
72 | | openApiApiPackage | `String` | Package for generated api classes |
73 | | openApiModelPackage | `String` | Package for generated models |
74 | | openApiModelNamePrefix | `String` | Prefix that will be prepended to all model names |
75 | | openApiModelNameSuffix | `String` | Suffix that will be appended to all model names |
76 | | openApiInstantiationTypes | `Map[String, String]` | Sets instantiation type mappings |
77 | | openApiTypeMappings | `Map[String, String]` | Sets mappings between OpenAPI spec types and generated code types |
78 | | openApiServerVariables | `Map[String, String]` | Sets server variable for server URL template substitution, in the format of name=value,name=value. You can also have multiple occurrences of this option |
79 | | openApiLanguageSpecificPrimitives | `List[String]` | Specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double |
80 | | openApiImportMappings | `Map[String, String]` | Specifies mappings between a given class and the import that should be used for that class |
81 | | openApiInvokerPackage | `String` | Root package for generated code |
82 | | openApiGroupId | `String` | groupId in generated pom.xml/build.sbt |
83 | | openApiId | `String` | artifactId in generated pom.xml/build.sbt. This also becomes part of the generated library's filename |
84 | | openApiLibrary | `String` | library template (sub-template) |
85 | | openApiGitHost | `String` |Git host, e.g. gitlab.com |
86 | | openApiGitUserId | `String` | Git user ID, e.g. openapitools |
87 | | openApiGitRepoId | `String` | Git repo ID, e.g. openapi-generator |
88 | | openApiReleaseNote | `String` | Release note, default to 'Minor update' |
89 | | openApiHttpUserAgent | `String` | HTTP user agent, e.g. codegen_csharp_api_client, default to 'OpenAPI-Generator/{packageVersion}}/{language}' |
90 | | openApiReservedWordsMappings | `Map[String, String]` | ]("Specifies how a reserved name should be escaped to |
91 | | openApiIgnoreFileOverride | `String` | Specifies an override location for the .openapi-generator-ignore file. Most useful on initial generation. |
92 | | openApiRemoveOperationIdPrefix | `Option[Boolean]` | Remove prefix of operationId, e.g. config_getId => getId |
93 | | openApiApiFilesConstrainedTo | `List[String]` | Defines which API-related files should be generated. This allows you to create a subset of generated files (or none at all) |
94 | | openApiModelFilesConstrainedTo | `List[String]` | Defines which model-related files should be generated. This allows you to create a subset of generated files (or none at all) |
95 | | openApiSupportingFilesConstrainedTo | `List[String]` | Defines which supporting files should be generated. This allows you to create a subset of generated files (or none at all |
96 | | openApiGenerateModelTests | `Option[Boolean]` | Specifies that model tests are to be generated |
97 | | openApiGenerateModelDocumentation | `Option[Boolean]` | Defines whether or not model-related _documentation_ files should be generated |
98 | | openApiGenerateApiTests | `Option[Boolean]` | Specifies that api tests are to be generated |
99 | | openApiGenerateApiDocumentation | `Option[Boolean]` | Defines whether or not api-related _documentation_ files should be generated |
100 | | openApiWithXml | `Option[Boolean]` | A special-case setting which configures some generators with XML support. In some cases, this forces json OR xml, so the default here is false |
101 | | openApiLogToStderr | `Option[Boolean]` | To write all log messages (not just errors) to STDOUT |
102 | | openApiEnablePostProcessFile | `Option[Boolean]` | Enable post-processing file using environment variables | \
103 | | openApiSkipValidateSpec | `Option[Boolean]` | To skip spec validation. When true, we will skip the default behavior of validating a spec before generation |
104 | | openApiGenerateAliasAsModel | `Option[Boolean]` | Generate model implementation for aliases to map and array schemas |
105 | | openApiGenerateMetadata | `Option[Boolean]` | Generate metadata files used by OpenAPI Generator. This includes `.openapi-generator-ignore` and any files within `.openapi-generator`. |
106 |
107 | # Examples
108 |
109 | Please see [an sbt-test configuration](src/sbt-test) for examples of using the plugin.
110 | Do not run those examples directly, please copy them to separate place first.
111 |
112 | # Contribution and Tests
113 |
114 | Write plugin integration tests under [src/sbt-test](src/sbt-test)
115 |
116 | Execute next command to run tests:
117 |
118 | ```shell script
119 | sbt scripted
120 | ```
121 |
122 | More information about how to write and execute tests [is here](https://www.scala-sbt.org/1.x/docs/Testing-sbt-plugins.html)
123 |
--------------------------------------------------------------------------------
/build.sbt:
--------------------------------------------------------------------------------
1 | ThisBuild / name := "sbt-openapi-generator"
2 | ThisBuild / description :=
3 | """
4 | This plugin supports common functionality found in Open API Generator CLI as a sbt plugin.
5 |
6 | This gives you the ability to generate client SDKs, documentation, new generators, and to validate Open API 2.0 and 3.x
7 | specifications as part of your build. Other tasks are available as command line tasks.
8 | """
9 |
10 | lazy val `sbt-openapi-generator` = (project in file("."))
11 | .settings(
12 | scalaVersion := "2.12.15",
13 | crossScalaVersions := Seq(scalaVersion.value, "2.11.12"),
14 | crossSbtVersions := List("0.13.17", "1.3.10"),
15 | sbtPlugin := true,
16 |
17 | publishMavenStyle := true,
18 |
19 | scriptedLaunchOpts := {
20 | scriptedLaunchOpts.value ++ Seq("-Xmx1024M", "-server", "-Dplugin.version=" + version.value)
21 | },
22 |
23 | scriptedBufferLog := false,
24 |
25 | resolvers ++= Seq(
26 | Resolver.sbtPluginRepo("snapshots"),
27 | Resolver.sonatypeRepo("snapshots")
28 | ),
29 |
30 | version := "7.13.0",
31 |
32 | homepage := Some(url("https://openapi-generator.tech")),
33 |
34 | organization := "org.openapitools",
35 | organizationName := "OpenAPI-Generator Contributors",
36 | organizationHomepage := Some(url("https://github.com/OpenAPITools")),
37 |
38 | licenses += ("The Apache Software License, Version 2.0", url("https://www.apache.org/licenses/LICENSE-2.0.txt")),
39 |
40 | developers += Developer(
41 | id = "openapitools",
42 | name = "OpenAPI-Generator Contributors",
43 | email = "team@openapitools.org",
44 | url = url("https://github.com/OpenAPITools")
45 | ),
46 |
47 | scmInfo := Some(
48 | ScmInfo(
49 | browseUrl = url("https://github.com/OpenAPITools/openapi-generator"),
50 | connection = "scm:git:git://github.com/OpenAPITools/openapi-generator.git",
51 | devConnection = "scm:git:ssh://git@github.com:OpenAPITools/openapi-generator.git")
52 | ),
53 |
54 | libraryDependencies += "org.openapitools" % "openapi-generator" % "7.13.0"
55 | ).enablePlugins(SbtPlugin)
56 |
--------------------------------------------------------------------------------
/project/build.properties:
--------------------------------------------------------------------------------
1 | sbt.version=1.6.2
2 |
--------------------------------------------------------------------------------
/project/plugin.sbt:
--------------------------------------------------------------------------------
1 | // Manages publishing.
2 | //addSbtPlugin("org.foundweekends" % "sbt-bintray" % "0.5.6")
3 | addSbtPlugin("org.xerial.sbt" % "sbt-sonatype" % "3.10.0")
4 |
5 | // Versions the build.
6 | //addSbtPlugin("com.dwijnand" % "sbt-dynver" % "5.0.1")
7 |
--------------------------------------------------------------------------------
/publish.sbt:
--------------------------------------------------------------------------------
1 | ThisBuild / organization := "org.openapitools.sbt-openapi-generator"
2 | ThisBuild / organizationName := "OpenAPITools"
3 | ThisBuild / organizationHomepage := Some(url("http://openapitools.org"))
4 |
5 | ThisBuild / scmInfo := Some(
6 | ScmInfo(
7 | url("https://github.com/openapitools/sbt-openapi-generator"),
8 | "scm:git@github.com:openapitools/sbt-openapi-generator.git"
9 | )
10 | )
11 | ThisBuild / developers := List(
12 | Developer(
13 | id = "openapitools",
14 | name = "OpenAPI Tools",
15 | email = "team@openapitools.org",
16 | url = url("http://openapitools.org")
17 | )
18 | )
19 |
20 | ThisBuild / description := "openapi-generator sbt plugin."
21 | ThisBuild / licenses := List(
22 | "Apache 2" -> new URL("http://www.apache.org/licenses/LICENSE-2.0.txt")
23 | )
24 | ThisBuild / homepage := Some(url("https://github.com/openapitools/sbt-openapi-generator"))
25 |
26 | // Remove all additional repository other than Maven Central from POM
27 | ThisBuild / pomIncludeRepository := { _ => false }
28 | ThisBuild / publishTo := {
29 | // For accounts created after Feb 2021:
30 | // val nexus = "https://s01.oss.sonatype.org/"
31 | val nexus = "https://oss.sonatype.org/"
32 | //if (isSnapshot.value) Some("snapshots" at nexus + "content/repositories/snapshots")
33 | //else Some("releases" at nexus + "service/local/staging/deploy/maven2")
34 | Some("releases" at nexus + "service/local/staging/deploy/maven2")
35 | }
36 | ThisBuild / publishMavenStyle := true
37 |
--------------------------------------------------------------------------------
/src/main/scala/org/openapitools/generator/sbt/plugin/OpenApiGeneratorKeys.scala:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2020 OpenAPI-Generator Contributors (https://openapi-generator.tech)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | *
7 | * You may obtain a copy of the License at
8 | *
9 | * https://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | package org.openapitools.generator.sbt.plugin
19 |
20 | import org.openapitools.codegen.CodegenConstants
21 | import sbt.{File, settingKey, taskKey}
22 |
23 | trait OpenApiGeneratorKeys {
24 | final val openApiGenerate = taskKey[Seq[File]]("Generate code via Open API Tools Generator for Open API 2.0 or 3.x specification documents.")
25 | final val openApiGenerators = taskKey[Unit]("Print list of available generators")
26 |
27 | final val openApiInputSpec = settingKey[String]("The Open API 2.0/3.x specification location.")
28 | final val openApiOutputDir = settingKey[String]("The output target directory into which code will be generated.")
29 | final val openApiConfigFile = settingKey[String]("Path to json configuration file.\n" +
30 | "File content should be in a json format { \"optionKey\":\"optionValue\", \"optionKey1\":\"optionValue1\"...}\n" +
31 | "Supported options can be different for each language. Run config-help -g {generator name} command for language specific config options.")
32 | final val openApiAdditionalProperties = settingKey[Map[String, String]]("Sets additional properties that can be referenced by the mustache templates in the format of name=value,name=value.\n" +
33 | "You can also have multiple occurrences of this option.")
34 | @deprecated("use openApiGlobalProperties instead") final val openApiSystemProperties = settingKey[Map[String, String]]("Sets specified system properties.")
35 | final val openApiGlobalProperties = settingKey[Map[String, String]]("Sets specified system properties.")
36 |
37 | final val openApiVerbose = settingKey[Option[Boolean]]("The verbosity of generation")
38 | final val openApiValidateSpec = settingKey[Option[Boolean]]("Whether or not an input specification should be validated upon generation.")
39 | final val openApiGeneratorName = settingKey[String]("The name of the generator which will handle codegen. (see \"openApiGenerators\" task)")
40 | final val openApiTemplateDir = settingKey[String]("The template directory holding a custom template.")
41 | final val openApiAuth = settingKey[String]("Adds authorization headers when fetching the OpenAPI definitions remotely.\n" +
42 | "Pass in a URL-encoded string of name:header with a comma separating multiple values")
43 | final val openApiSkipOverwrite = settingKey[Option[Boolean]]("Specifies if the existing files should be overwritten during the generation.")
44 | final val openApiPackageName = settingKey[String](CodegenConstants.PACKAGE_NAME_DESC)
45 | final val openApiApiPackage = settingKey[String](CodegenConstants.API_PACKAGE_DESC)
46 | final val openApiModelPackage = settingKey[String](CodegenConstants.MODEL_PACKAGE_DESC)
47 | final val openApiModelNamePrefix = settingKey[String](CodegenConstants.MODEL_NAME_PREFIX_DESC)
48 | final val openApiModelNameSuffix = settingKey[String](CodegenConstants.MODEL_NAME_SUFFIX_DESC)
49 | final val openApiInstantiationTypes = settingKey[Map[String, String]]("Sets instantiation type mappings.")
50 | final val openApiTypeMappings = settingKey[Map[String, String]]("Sets mappings between OpenAPI spec types and generated code types.")
51 | final val openApiServerVariables = settingKey[Map[String, String]]("Sets server variable for server URL template substitution, in the format of name=value,name=value.\n"
52 | + "You can also have multiple occurrences of this option.")
53 |
54 | final val openApiLanguageSpecificPrimitives = settingKey[List[String]]("Specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double.")
55 | final val openApiImportMappings = settingKey[Map[String, String]]("Specifies mappings between a given class and the import that should be used for that class.")
56 | final val openApiInvokerPackage = settingKey[String](CodegenConstants.INVOKER_PACKAGE_DESC)
57 | //TODO: change to sbt organization
58 | final val openApiGroupId = settingKey[String](CodegenConstants.GROUP_ID_DESC)
59 | //TODO: change to sbt name
60 | final val openApiId = settingKey[String](CodegenConstants.ARTIFACT_ID_DESC)
61 |
62 | final val openApiLibrary = settingKey[String](CodegenConstants.LIBRARY_DESC)
63 | final val openApiGitHost = settingKey[String](CodegenConstants.GIT_HOST_DESC)
64 | final val openApiGitUserId = settingKey[String](CodegenConstants.GIT_USER_ID_DESC)
65 | final val openApiGitRepoId = settingKey[String](CodegenConstants.GIT_REPO_ID_DESC)
66 | final val openApiReleaseNote = settingKey[String](CodegenConstants.RELEASE_NOTE_DESC)
67 | final val openApiHttpUserAgent = settingKey[String](CodegenConstants.HTTP_USER_AGENT_DESC)
68 | final val openApiReservedWordsMappings = settingKey[Map[String, String]]("Specifies how a reserved name should be escaped to.")
69 | final val openApiIgnoreFileOverride = settingKey[String](CodegenConstants.IGNORE_FILE_OVERRIDE_DESC)
70 | final val openApiRemoveOperationIdPrefix = settingKey[Option[Boolean]]("Remove prefix of operationId, e.g. config_getId => getId")
71 |
72 | /**
73 | * Defines which API-related files should be generated. This allows you to create a subset of generated files (or none at all).
74 | *
75 | * This option enables/disables generation of ALL api-related files.
76 | *
77 | * NOTE: Configuring any one of [apiFilesConstrainedTo], [modelFilesConstrainedTo], or [supportingFilesConstrainedTo] results
78 | * in others being disabled. That is, OpenAPI Generator considers any one of these to define a subset of generation.
79 | * For more control over generation of individual files, configure an ignore file and refer to it via [ignoreFileOverride].
80 | */
81 | final val openApiApiFilesConstrainedTo = settingKey[List[String]]("Defines which API-related files should be generated. This allows you to create a subset of generated files (or none at all).")
82 |
83 | /**
84 | * Defines which model-related files should be generated. This allows you to create a subset of generated files (or none at all).
85 | *
86 | * NOTE: Configuring any one of [apiFilesConstrainedTo], [modelFilesConstrainedTo], or [supportingFilesConstrainedTo] results
87 | * in others being disabled. That is, OpenAPI Generator considers any one of these to define a subset of generation.
88 | * For more control over generation of individual files, configure an ignore file and refer to it via [ignoreFileOverride].
89 | */
90 | final val openApiModelFilesConstrainedTo = settingKey[List[String]]("Defines which model-related files should be generated. This allows you to create a subset of generated files (or none at all).")
91 |
92 | /**
93 | * Defines which supporting files should be generated. This allows you to create a subset of generated files (or none at all).
94 | *
95 | * Supporting files are those related to projects/frameworks which may be modified
96 | * by consumers.
97 | *
98 | * NOTE: Configuring any one of [apiFilesConstrainedTo], [modelFilesConstrainedTo], or [supportingFilesConstrainedTo] results
99 | * in others being disabled. That is, OpenAPI Generator considers any one of these to define a subset of generation.
100 | * For more control over generation of individual files, configure an ignore file and refer to it via [ignoreFileOverride].
101 | */
102 | final val openApiSupportingFilesConstrainedTo = settingKey[List[String]]("Defines which supporting files should be generated. This allows you to create a subset of generated files (or none at all).")
103 |
104 | /**
105 | * Defines whether or not model-related _test_ files should be generated.
106 | *
107 | * This option enables/disables generation of ALL model-related _test_ files.
108 | *
109 | * For more control over generation of individual files, configure an ignore file and
110 | * refer to it via [ignoreFileOverride].
111 | */
112 | final val openApiGenerateModelTests = settingKey[Option[Boolean]](CodegenConstants.GENERATE_MODEL_TESTS_DESC)
113 |
114 | /**
115 | * Defines whether or not model-related _documentation_ files should be generated.
116 | *
117 | * This option enables/disables generation of ALL model-related _documentation_ files.
118 | *
119 | * For more control over generation of individual files, configure an ignore file and
120 | * refer to it via [ignoreFileOverride].
121 | */
122 | final val openApiGenerateModelDocumentation = settingKey[Option[Boolean]]("Defines whether or not model-related _documentation_ files should be generated.")
123 |
124 | /**
125 | * Defines whether or not api-related _test_ files should be generated.
126 | *
127 | * This option enables/disables generation of ALL api-related _test_ files.
128 | *
129 | * For more control over generation of individual files, configure an ignore file and
130 | * refer to it via [ignoreFileOverride].
131 | */
132 | final val openApiGenerateApiTests = settingKey[Option[Boolean]](CodegenConstants.GENERATE_API_TESTS_DESC)
133 |
134 | /**
135 | * Defines whether or not api-related _documentation_ files should be generated.
136 | *
137 | * This option enables/disables generation of ALL api-related _documentation_ files.
138 | *
139 | * For more control over generation of individual files, configure an ignore file and
140 | * refer to it via [ignoreFileOverride].
141 | */
142 | final val openApiGenerateApiDocumentation = settingKey[Option[Boolean]]("Defines whether or not api-related _documentation_ files should be generated.")
143 | final val openApiWithXml = settingKey[Option[Boolean]]("A special-case setting which configures some generators with XML support. In some cases, this forces json OR xml, so the default here is false.")
144 |
145 | final val openApiLogToStderr = settingKey[Option[Boolean]]("To write all log messages (not just errors) to STDOUT")
146 |
147 | /**
148 | * To enable the file post-processing hook. This enables executing an external post-processor (usually a linter program).
149 | * This only enables the post-processor. To define the post-processing command, define an environment variable such as
150 | * LANG_POST_PROCESS_FILE (e.g. GO_POST_PROCESS_FILE, SCALA_POST_PROCESS_FILE). Please open an issue if your target
151 | * generator does not support this functionality.
152 | */
153 | final val openApiEnablePostProcessFile = settingKey[Option[Boolean]](CodegenConstants.ENABLE_POST_PROCESS_FILE_DESC)
154 |
155 | final val openApiSkipValidateSpec = settingKey[Option[Boolean]]("To skip spec validation. When true, we will skip the default behavior of validating a spec before generation.")
156 |
157 | /**
158 | * To generate alias (array, list, map) as model. When false, top-level objects defined as array, list, or map will result in those
159 | * definitions generated as top-level Array-of-items, List-of-items, Map-of-items definitions.
160 | * When true, A model representation either containing or extending the array,list,map (depending on specific generator implementation) will be generated.
161 | */
162 | final val openApiGenerateAliasAsModel = settingKey[Option[Boolean]](CodegenConstants.GENERATE_ALIAS_AS_MODEL_DESC)
163 |
164 | /**
165 | * Indicate whether or not to generate OpenAPI Generator metadata files.
166 | * These files include .openapi-generator/VERSION, .openapi-generator-ignore, and any other metadata files
167 | * used by OpenAPI Generator.
168 | */
169 | final val openApiGenerateMetadata = settingKey[Option[Boolean]]("Generate metadata files used by OpenAPI Generator. This includes .openapi-generator-ignore and any files within .openapi-generator.")
170 |
171 | }
172 |
--------------------------------------------------------------------------------
/src/main/scala/org/openapitools/generator/sbt/plugin/OpenApiGeneratorPlugin.scala:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2020 OpenAPI-Generator Contributors (https://openapi-generator.tech)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | *
7 | * You may obtain a copy of the License at
8 | *
9 | * https://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | package org.openapitools.generator.sbt.plugin
19 |
20 | import org.openapitools.generator.sbt.plugin.tasks.{OpenApiGenerateTask, OpenApiGeneratorsTask}
21 | import sbt.Keys.aggregate
22 | import sbt.plugins.JvmPlugin
23 | import sbt.{Def, File, config, taskKey}
24 |
25 | object OpenApiGeneratorPlugin extends sbt.AutoPlugin
26 | with OpenApiGeneratorsTask
27 | with OpenApiGenerateTask {
28 | self =>
29 |
30 | override def requires: JvmPlugin.type = sbt.plugins.JvmPlugin
31 |
32 | override def trigger: sbt.PluginTrigger = allRequirements
33 |
34 | object autoImport extends OpenApiGeneratorKeys {
35 |
36 | def SettingEnabled: Option[Boolean] = Some(true)
37 |
38 | def SettingDisabled: Option[Boolean] = Some(false)
39 |
40 |
41 | }
42 |
43 | val out = taskKey[Seq[File]]("Out")
44 |
45 | val OpenApiCodegen = config("openApiCodegen")
46 |
47 | override def globalSettings: Seq[Def.Setting[_]] = Seq(
48 | aggregate in openApiGenerators := false
49 | )
50 |
51 | private lazy val baseSettings: Seq[sbt.Setting[_]] = Seq[sbt.Setting[_]](
52 | openApiInputSpec := "",
53 | openApiOutputDir := "",
54 | openApiConfigFile := "",
55 | openApiAdditionalProperties := Map.empty[String, String],
56 | openApiSystemProperties := Map.empty[String, String],
57 | openApiGlobalProperties := Map.empty[String, String],
58 | openApiVerbose := None,
59 | openApiValidateSpec := None,
60 | openApiGeneratorName := "",
61 | openApiTemplateDir := "",
62 | openApiAuth := "",
63 | openApiSkipOverwrite := None,
64 | openApiPackageName := "",
65 | openApiApiPackage := "",
66 | openApiModelPackage := "",
67 | openApiModelNamePrefix := "",
68 | openApiModelNameSuffix := "",
69 | openApiInstantiationTypes := Map.empty[String, String],
70 | openApiTypeMappings := Map.empty[String, String],
71 | openApiServerVariables := Map.empty[String, String],
72 | openApiLanguageSpecificPrimitives := List[String](),
73 | openApiImportMappings := Map.empty[String, String],
74 | openApiInvokerPackage := "",
75 | openApiGroupId := "",
76 | openApiId := "",
77 | openApiLibrary := "",
78 | openApiGitHost := "",
79 | openApiGitUserId := "",
80 | openApiGitRepoId := "",
81 | openApiReleaseNote := "",
82 | openApiHttpUserAgent := "",
83 | openApiReservedWordsMappings := Map.empty[String, String],
84 | openApiIgnoreFileOverride := "",
85 | openApiRemoveOperationIdPrefix := None,
86 | openApiApiFilesConstrainedTo := List[String](),
87 | openApiModelFilesConstrainedTo := List[String](),
88 | openApiSupportingFilesConstrainedTo := List[String](),
89 | openApiGenerateModelTests := None,
90 | openApiGenerateModelDocumentation := None,
91 | openApiGenerateApiTests := None,
92 | openApiGenerateApiDocumentation := None,
93 | openApiWithXml := None,
94 | openApiLogToStderr := None,
95 | openApiEnablePostProcessFile := None,
96 | openApiSkipValidateSpec := None,
97 | openApiGenerateAliasAsModel := None,
98 | openApiGenerateMetadata := None
99 | )
100 |
101 | override lazy val projectSettings: Seq[Def.Setting[_]] = Seq[sbt.Setting[_]](
102 | openApiGenerators := openApiGeneratorsTask.value,
103 | openApiGenerate := openApiGenerateTask.value
104 | ) ++ baseSettings
105 |
106 | }
107 |
--------------------------------------------------------------------------------
/src/main/scala/org/openapitools/generator/sbt/plugin/tasks/OpenApiGenerateTask.scala:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2020 OpenAPI-Generator Contributors (https://openapi-generator.tech)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | *
7 | * You may obtain a copy of the License at
8 | *
9 | * https://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 | package org.openapitools.generator.sbt.plugin.tasks
18 |
19 | import org.openapitools.codegen.config.{CodegenConfigurator, GlobalSettings}
20 | import org.openapitools.codegen.{CodegenConstants, DefaultGenerator}
21 | import org.openapitools.generator.sbt.plugin.OpenApiGeneratorKeys
22 | import sbt.Keys._
23 | import sbt.{Def, _}
24 |
25 | import scala.collection.JavaConverters._
26 | import scala.util.{Failure, Success, Try}
27 |
28 | trait OpenApiGenerateTask extends OpenApiGeneratorKeys {
29 |
30 | protected[this] def openApiGenerateTask: Def.Initialize[Task[Seq[File]]] = Def.task {
31 |
32 | val logger = sbt.Keys.streams.value.log
33 |
34 | if (openApiConfigFile.value.isEmpty && openApiGeneratorName.value.isEmpty) {
35 | Seq()
36 | } else {
37 | val configurator: CodegenConfigurator = if (openApiConfigFile.value.nonEmpty) {
38 | val config = openApiConfigFile.value
39 | logger.info(s"read configuration from $config")
40 | CodegenConfigurator.fromFile(config)
41 | } else new CodegenConfigurator()
42 |
43 | if (openApiSupportingFilesConstrainedTo.value.nonEmpty) {
44 | GlobalSettings.setProperty(CodegenConstants.SUPPORTING_FILES, openApiSupportingFilesConstrainedTo.value.mkString(","))
45 | } else {
46 | GlobalSettings.clearProperty(CodegenConstants.SUPPORTING_FILES)
47 | }
48 |
49 | if (openApiModelFilesConstrainedTo.value.nonEmpty) {
50 | GlobalSettings.setProperty(CodegenConstants.MODELS, openApiModelFilesConstrainedTo.value.mkString(","))
51 | } else {
52 | GlobalSettings.clearProperty(CodegenConstants.MODELS)
53 | }
54 |
55 | if (openApiApiFilesConstrainedTo.value.nonEmpty) {
56 | GlobalSettings.setProperty(CodegenConstants.APIS, openApiApiFilesConstrainedTo.value.mkString(","))
57 | } else {
58 | GlobalSettings.clearProperty(CodegenConstants.APIS)
59 | }
60 |
61 | openApiGenerateApiDocumentation.value.foreach { value =>
62 | GlobalSettings.setProperty(CodegenConstants.API_DOCS, value.toString)
63 | }
64 |
65 | openApiGenerateModelDocumentation.value.foreach { value =>
66 | GlobalSettings.setProperty(CodegenConstants.MODEL_DOCS, value.toString)
67 | }
68 |
69 | openApiGenerateModelTests.value.foreach { value =>
70 | GlobalSettings.setProperty(CodegenConstants.MODEL_TESTS, value.toString)
71 | }
72 |
73 | openApiGenerateApiTests.value.foreach { value =>
74 | GlobalSettings.setProperty(CodegenConstants.API_TESTS, value.toString)
75 | }
76 |
77 | openApiWithXml.value.foreach { value =>
78 | GlobalSettings.setProperty(CodegenConstants.WITH_XML, value.toString)
79 | }
80 |
81 | // now override with any specified parameters
82 | openApiVerbose.value.foreach { value =>
83 | configurator.setVerbose(value)
84 | }
85 | openApiValidateSpec.value.foreach { value =>
86 | configurator.setValidateSpec(value)
87 | }
88 |
89 | openApiSkipOverwrite.value.foreach { value =>
90 | configurator.setSkipOverwrite(value)
91 | }
92 |
93 | if (openApiInputSpec.value.nonEmpty) {
94 | configurator.setInputSpec(openApiInputSpec.value)
95 | }
96 |
97 |
98 | if (openApiGeneratorName.value.nonEmpty) {
99 | configurator.setGeneratorName(openApiGeneratorName.value)
100 | }
101 |
102 | if (openApiOutputDir.value.nonEmpty) {
103 | configurator.setOutputDir(openApiOutputDir.value)
104 | }
105 |
106 | if (openApiAuth.value.nonEmpty) {
107 | configurator.setAuth(openApiAuth.value)
108 | }
109 |
110 | if (openApiTemplateDir.value.nonEmpty) {
111 | configurator.setTemplateDir(openApiTemplateDir.value)
112 | }
113 |
114 | if (openApiPackageName.value.nonEmpty) {
115 | configurator.setPackageName(openApiPackageName.value)
116 | }
117 |
118 | if (openApiApiPackage.value.nonEmpty) {
119 | configurator.setApiPackage(openApiApiPackage.value)
120 | }
121 |
122 | if (openApiModelPackage.value.nonEmpty) {
123 | configurator.setModelPackage(openApiModelPackage.value)
124 | }
125 |
126 | if (openApiModelNamePrefix.value.nonEmpty) {
127 | configurator.setModelNamePrefix(openApiModelNamePrefix.value)
128 | }
129 |
130 | if (openApiModelNameSuffix.value.nonEmpty) {
131 | configurator.setModelNameSuffix(openApiModelNameSuffix.value)
132 | }
133 |
134 | if (openApiInvokerPackage.value.nonEmpty) {
135 | configurator.setInvokerPackage(openApiInvokerPackage.value)
136 | }
137 |
138 | if (openApiGroupId.value.nonEmpty) {
139 | configurator.setGroupId(openApiGroupId.value)
140 | }
141 |
142 | if (openApiId.value.nonEmpty) {
143 | configurator.setArtifactId(openApiId.value)
144 | }
145 |
146 | if ((version in openApiGenerate).value.nonEmpty) {
147 | configurator.setArtifactVersion(version.value)
148 | }
149 |
150 | if (openApiLibrary.value.nonEmpty) {
151 | configurator.setLibrary(openApiLibrary.value)
152 | }
153 |
154 | if (openApiGitHost.value.nonEmpty) {
155 | configurator.setGitHost(openApiGitHost.value)
156 | }
157 |
158 | if (openApiGitUserId.value.nonEmpty) {
159 | configurator.setGitUserId(openApiGitUserId.value)
160 | }
161 |
162 |
163 | if (openApiGitRepoId.value.nonEmpty) {
164 | configurator.setGitRepoId(openApiGitRepoId.value)
165 | }
166 |
167 | if (openApiReleaseNote.value.nonEmpty) {
168 | configurator.setReleaseNote(openApiReleaseNote.value)
169 | }
170 |
171 | if (openApiHttpUserAgent.value.nonEmpty) {
172 | configurator.setHttpUserAgent(openApiHttpUserAgent.value)
173 | }
174 |
175 | if (openApiIgnoreFileOverride.value.nonEmpty) {
176 | configurator.setIgnoreFileOverride(openApiIgnoreFileOverride.value)
177 | }
178 |
179 | openApiRemoveOperationIdPrefix.value.foreach { value =>
180 | configurator.setRemoveOperationIdPrefix(value)
181 | }
182 |
183 | openApiLogToStderr.value.foreach { value =>
184 | configurator.setLogToStderr(value)
185 | }
186 |
187 | openApiEnablePostProcessFile.value.foreach { value =>
188 | configurator.setEnablePostProcessFile(value)
189 | }
190 |
191 | openApiSkipValidateSpec.value.foreach { value =>
192 | configurator.setValidateSpec(!value)
193 | }
194 |
195 | openApiGenerateAliasAsModel.value.foreach { value =>
196 | configurator.setGenerateAliasAsModel(value)
197 | }
198 |
199 | if (openApiGlobalProperties.value.nonEmpty || openApiSystemProperties.value.nonEmpty) {
200 | (openApiSystemProperties.value ++ openApiGlobalProperties.value).foreach { entry =>
201 | configurator.addGlobalProperty(entry._1, entry._2)
202 | }
203 | }
204 |
205 | if (openApiInstantiationTypes.value.nonEmpty) {
206 | openApiInstantiationTypes.value.foreach { entry =>
207 | configurator.addInstantiationType(entry._1, entry._2)
208 | }
209 | }
210 |
211 | if (openApiImportMappings.value.nonEmpty) {
212 | openApiImportMappings.value.foreach { entry =>
213 | configurator.addImportMapping(entry._1, entry._2)
214 | }
215 | }
216 |
217 | if (openApiTypeMappings.value.nonEmpty) {
218 | openApiTypeMappings.value.foreach { entry =>
219 | configurator.addTypeMapping(entry._1, entry._2)
220 | }
221 | }
222 |
223 | if (openApiAdditionalProperties.value.nonEmpty) {
224 | openApiAdditionalProperties.value.foreach { entry =>
225 | configurator.addAdditionalProperty(entry._1, entry._2)
226 | }
227 | }
228 |
229 | if (openApiServerVariables.value.nonEmpty) {
230 | openApiServerVariables.value.foreach { entry =>
231 | configurator.addServerVariable(entry._1, entry._2)
232 | }
233 | }
234 |
235 | if (openApiLanguageSpecificPrimitives.value.nonEmpty) {
236 | openApiLanguageSpecificPrimitives.value.foreach { it =>
237 | configurator.addLanguageSpecificPrimitive(it)
238 | }
239 | }
240 |
241 | if (openApiReservedWordsMappings.value.nonEmpty) {
242 | openApiReservedWordsMappings.value.foreach { entry =>
243 | configurator.addAdditionalReservedWordMapping(entry._1, entry._2)
244 | }
245 | }
246 |
247 | Try(configurator.toClientOptInput) match {
248 | case Success(clientOptInput) =>
249 | Try {
250 | val gen = new DefaultGenerator()
251 |
252 | gen.opts(clientOptInput)
253 |
254 | openApiGenerateMetadata.value.foreach { value =>
255 | gen.setGenerateMetadata(value)
256 | }
257 |
258 | val res = gen.generate().asScala
259 |
260 | logger.info(s"Successfully generated code to ${clientOptInput.getConfig.getOutputDir}")
261 | res
262 | } match {
263 | case Success(value) => value
264 | case Failure(ex) =>
265 | throw new Exception("Code generation failed.", ex)
266 | }
267 | case Failure(ex) =>
268 | logger.error(ex.getMessage)
269 | Seq.empty
270 | }
271 | }
272 | }
273 | }
274 |
--------------------------------------------------------------------------------
/src/main/scala/org/openapitools/generator/sbt/plugin/tasks/OpenApiGeneratorsTask.scala:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2020 OpenAPI-Generator Contributors (https://openapi-generator.tech)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | *
7 | * You may obtain a copy of the License at
8 | *
9 | * https://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | package org.openapitools.generator.sbt.plugin.tasks
19 |
20 | import org.openapitools.codegen.meta.Stability
21 | import org.openapitools.codegen.{CodegenConfigLoader, CodegenType}
22 | import sbt.{Def, Task}
23 |
24 | import scala.collection.JavaConverters._
25 |
26 | trait OpenApiGeneratorsTask {
27 |
28 | protected[this] def openApiGeneratorsTask: Def.Initialize[Task[Unit]] = Def.task {
29 | val generators = CodegenConfigLoader.getAll.asScala
30 | val types = CodegenType.values()
31 |
32 | val stabilities = Stability.values().filterNot {
33 | _ == Stability.DEPRECATED
34 | }
35 |
36 | val out = new StringBuilder
37 |
38 | out ++= "The following generators are available:" + System.lineSeparator()
39 | for (t <- types) {
40 | val filteredGenerators = generators.filter(_.getTag == t).sortBy(_.getName)
41 | if (filteredGenerators.nonEmpty) {
42 | out ++= s" $t generators:" + System.lineSeparator()
43 | filteredGenerators.foreach {
44 | generator =>
45 | val meta = generator.getGeneratorMetadata
46 | val stability = meta.getStability
47 | val include = stabilities.contains(stability)
48 | if (include) {
49 | out ++= s" - ${generator.getName}"
50 | if (stability != Stability.STABLE) {
51 | out ++= s" (${stability.value()})"
52 | }
53 | out ++= System.lineSeparator()
54 | }
55 | }
56 | }
57 | }
58 | out ++= System.lineSeparator()
59 | out ++= System.lineSeparator()
60 |
61 | println(out)
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/src/sbt-test/sbt-openapi-generator/simple/build.sbt:
--------------------------------------------------------------------------------
1 | scalaVersion := "2.12.10"
2 |
3 | externalResolvers += Resolver.sonatypeRepo("snapshots")
4 |
5 | lazy val generated = project.in(file("generated"))
6 | .enablePlugins(OpenApiGeneratorPlugin)
7 | .settings(
8 | openApiInputSpec := "openapi.yaml",
9 | openApiConfigFile := "config.yaml",
10 | openApiValidateSpec := SettingDisabled,
11 | openApiGenerateModelTests := SettingEnabled
12 | )
13 |
14 | lazy val root = (project in file("."))
15 | .settings(
16 | name := "openapi-generator-example"
17 | )
18 | .dependsOn(generated)
19 | .aggregate(generated)
20 |
--------------------------------------------------------------------------------
/src/sbt-test/sbt-openapi-generator/simple/config.yaml:
--------------------------------------------------------------------------------
1 | apiPackage: "org.openapitools.client.custom.api"
2 | generatorName: "scala-akka"
3 | outputDir : "generated"
4 | additionalProperties:
5 | dateLibrary: "joda"
6 |
--------------------------------------------------------------------------------
/src/sbt-test/sbt-openapi-generator/simple/openapi.yaml:
--------------------------------------------------------------------------------
1 | openapi: 3.0.1
2 | info:
3 | title: Swagger Petstore
4 | description: 'This is a sample server Petstore server. You can find out more about Swagger
5 | at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For
6 | this sample, you can use the api key `special-key` to test the authorization filters.'
7 | termsOfService: http://swagger.io/terms/
8 | contact:
9 | email: apiteam@swagger.io
10 | license:
11 | name: Apache 2.0
12 | url: http://www.apache.org/licenses/LICENSE-2.0.html
13 | version: 1.0.0
14 | externalDocs:
15 | description: Find out more about Swagger
16 | url: http://swagger.io
17 | servers:
18 | - url: https://petstore.swagger.io/v2
19 | - url: http://petstore.swagger.io/v2
20 | tags:
21 | - name: pet
22 | description: Everything about your Pets
23 | externalDocs:
24 | description: Find out more
25 | url: http://swagger.io
26 | - name: store
27 | description: Access to Petstore orders
28 | - name: user
29 | description: Operations about user
30 | externalDocs:
31 | description: Find out more about our store
32 | url: http://swagger.io
33 | paths:
34 | /pet:
35 | put:
36 | tags:
37 | - pet
38 | summary: Update an existing pet
39 | operationId: updatePet
40 | requestBody:
41 | description: Pet object that needs to be added to the store
42 | content:
43 | application/json:
44 | schema:
45 | $ref: '#/components/schemas/Pet'
46 | application/xml:
47 | schema:
48 | $ref: '#/components/schemas/Pet'
49 | required: true
50 | responses:
51 | 400:
52 | description: Invalid ID supplied
53 | content: {}
54 | 404:
55 | description: Pet not found
56 | content: {}
57 | 405:
58 | description: Validation exception
59 | content: {}
60 | security:
61 | - petstore_auth:
62 | - write:pets
63 | - read:pets
64 | post:
65 | tags:
66 | - pet
67 | summary: Add a new pet to the store
68 | operationId: addPet
69 | requestBody:
70 | description: Pet object that needs to be added to the store
71 | content:
72 | application/json:
73 | schema:
74 | $ref: '#/components/schemas/Pet'
75 | application/xml:
76 | schema:
77 | $ref: '#/components/schemas/Pet'
78 | required: true
79 | responses:
80 | 405:
81 | description: Invalid input
82 | content: {}
83 | security:
84 | - petstore_auth:
85 | - write:pets
86 | - read:pets
87 | /pet/findByStatus:
88 | get:
89 | tags:
90 | - pet
91 | summary: Finds Pets by status
92 | description: Multiple status values can be provided with comma separated strings
93 | operationId: findPetsByStatus
94 | parameters:
95 | - name: status
96 | in: query
97 | description: Status values that need to be considered for filter
98 | required: true
99 | style: form
100 | explode: true
101 | schema:
102 | type: array
103 | items:
104 | type: string
105 | default: available
106 | enum:
107 | - available
108 | - pending
109 | - sold
110 | responses:
111 | 200:
112 | description: successful operation
113 | content:
114 | application/xml:
115 | schema:
116 | type: array
117 | items:
118 | $ref: '#/components/schemas/Pet'
119 | application/json:
120 | schema:
121 | type: array
122 | items:
123 | $ref: '#/components/schemas/Pet'
124 | 400:
125 | description: Invalid status value
126 | content: {}
127 | security:
128 | - petstore_auth:
129 | - write:pets
130 | - read:pets
131 | /pet/findByTags:
132 | get:
133 | tags:
134 | - pet
135 | summary: Finds Pets by tags
136 | description: Muliple tags can be provided with comma separated strings. Use tag1,
137 | tag2, tag3 for testing.
138 | operationId: findPetsByTags
139 | parameters:
140 | - name: tags
141 | in: query
142 | description: Tags to filter by
143 | required: true
144 | style: form
145 | explode: true
146 | schema:
147 | type: array
148 | items:
149 | type: string
150 | responses:
151 | 200:
152 | description: successful operation
153 | content:
154 | application/xml:
155 | schema:
156 | type: array
157 | items:
158 | $ref: '#/components/schemas/Pet'
159 | application/json:
160 | schema:
161 | type: array
162 | items:
163 | $ref: '#/components/schemas/Pet'
164 | 400:
165 | description: Invalid tag value
166 | content: {}
167 | deprecated: true
168 | security:
169 | - petstore_auth:
170 | - write:pets
171 | - read:pets
172 | /pet/{petId}:
173 | get:
174 | tags:
175 | - pet
176 | summary: Find pet by ID
177 | description: Returns a single pet
178 | operationId: getPetById
179 | parameters:
180 | - name: petId
181 | in: path
182 | description: ID of pet to return
183 | required: true
184 | schema:
185 | type: integer
186 | format: int64
187 | responses:
188 | 200:
189 | description: successful operation
190 | content:
191 | application/xml:
192 | schema:
193 | $ref: '#/components/schemas/Pet'
194 | application/json:
195 | schema:
196 | $ref: '#/components/schemas/Pet'
197 | 400:
198 | description: Invalid ID supplied
199 | content: {}
200 | 404:
201 | description: Pet not found
202 | content: {}
203 | security:
204 | - api_key: []
205 | post:
206 | tags:
207 | - pet
208 | summary: Updates a pet in the store with form data
209 | operationId: updatePetWithForm
210 | parameters:
211 | - name: petId
212 | in: path
213 | description: ID of pet that needs to be updated
214 | required: true
215 | schema:
216 | type: integer
217 | format: int64
218 | requestBody:
219 | content:
220 | application/x-www-form-urlencoded:
221 | schema:
222 | properties:
223 | name:
224 | type: string
225 | description: Updated name of the pet
226 | status:
227 | type: string
228 | description: Updated status of the pet
229 | responses:
230 | 405:
231 | description: Invalid input
232 | content: {}
233 | security:
234 | - petstore_auth:
235 | - write:pets
236 | - read:pets
237 | delete:
238 | tags:
239 | - pet
240 | summary: Deletes a pet
241 | operationId: deletePet
242 | parameters:
243 | - name: api_key
244 | in: header
245 | schema:
246 | type: string
247 | - name: petId
248 | in: path
249 | description: Pet id to delete
250 | required: true
251 | schema:
252 | type: integer
253 | format: int64
254 | responses:
255 | 400:
256 | description: Invalid ID supplied
257 | content: {}
258 | 404:
259 | description: Pet not found
260 | content: {}
261 | security:
262 | - petstore_auth:
263 | - write:pets
264 | - read:pets
265 | /pet/{petId}/uploadImage:
266 | post:
267 | tags:
268 | - pet
269 | summary: uploads an image
270 | operationId: uploadFile
271 | parameters:
272 | - name: petId
273 | in: path
274 | description: ID of pet to update
275 | required: true
276 | schema:
277 | type: integer
278 | format: int64
279 | requestBody:
280 | content:
281 | multipart/form-data:
282 | schema:
283 | properties:
284 | additionalMetadata:
285 | type: string
286 | description: Additional data to pass to server
287 | file:
288 | type: string
289 | description: file to upload
290 | format: binary
291 | responses:
292 | 200:
293 | description: successful operation
294 | content:
295 | application/json:
296 | schema:
297 | $ref: '#/components/schemas/ApiResponse'
298 | security:
299 | - petstore_auth:
300 | - write:pets
301 | - read:pets
302 | /store/inventory:
303 | get:
304 | tags:
305 | - store
306 | summary: Returns pet inventories by status
307 | description: Returns a map of status codes to quantities
308 | operationId: getInventory
309 | responses:
310 | 200:
311 | description: successful operation
312 | content:
313 | application/json:
314 | schema:
315 | type: object
316 | additionalProperties:
317 | type: integer
318 | format: int32
319 | security:
320 | - api_key: []
321 | /store/order:
322 | post:
323 | tags:
324 | - store
325 | summary: Place an order for a pet
326 | operationId: placeOrder
327 | requestBody:
328 | description: order placed for purchasing the pet
329 | content:
330 | '*/*':
331 | schema:
332 | $ref: '#/components/schemas/Order'
333 | required: true
334 | responses:
335 | 200:
336 | description: successful operation
337 | content:
338 | application/xml:
339 | schema:
340 | $ref: '#/components/schemas/Order'
341 | application/json:
342 | schema:
343 | $ref: '#/components/schemas/Order'
344 | 400:
345 | description: Invalid Order
346 | content: {}
347 | /store/order/{orderId}:
348 | get:
349 | tags:
350 | - store
351 | summary: Find purchase order by ID
352 | description: For valid response try integer IDs with value >= 1 and <= 10. Other
353 | values will generated exceptions
354 | operationId: getOrderById
355 | parameters:
356 | - name: orderId
357 | in: path
358 | description: ID of pet that needs to be fetched
359 | required: true
360 | schema:
361 | maximum: 10.0
362 | minimum: 1.0
363 | type: integer
364 | format: int64
365 | responses:
366 | 200:
367 | description: successful operation
368 | content:
369 | application/xml:
370 | schema:
371 | $ref: '#/components/schemas/Order'
372 | application/json:
373 | schema:
374 | $ref: '#/components/schemas/Order'
375 | 400:
376 | description: Invalid ID supplied
377 | content: {}
378 | 404:
379 | description: Order not found
380 | content: {}
381 | delete:
382 | tags:
383 | - store
384 | summary: Delete purchase order by ID
385 | description: For valid response try integer IDs with positive integer value. Negative
386 | or non-integer values will generate API errors
387 | operationId: deleteOrder
388 | parameters:
389 | - name: orderId
390 | in: path
391 | description: ID of the order that needs to be deleted
392 | required: true
393 | schema:
394 | minimum: 1.0
395 | type: integer
396 | format: int64
397 | responses:
398 | 400:
399 | description: Invalid ID supplied
400 | content: {}
401 | 404:
402 | description: Order not found
403 | content: {}
404 | /user:
405 | post:
406 | tags:
407 | - user
408 | summary: Create user
409 | description: This can only be done by the logged in user.
410 | operationId: createUser
411 | requestBody:
412 | description: Created user object
413 | content:
414 | '*/*':
415 | schema:
416 | $ref: '#/components/schemas/User'
417 | required: true
418 | responses:
419 | default:
420 | description: successful operation
421 | content: {}
422 | /user/createWithArray:
423 | post:
424 | tags:
425 | - user
426 | summary: Creates list of users with given input array
427 | operationId: createUsersWithArrayInput
428 | requestBody:
429 | description: List of user object
430 | content:
431 | '*/*':
432 | schema:
433 | type: array
434 | items:
435 | $ref: '#/components/schemas/User'
436 | required: true
437 | responses:
438 | default:
439 | description: successful operation
440 | content: {}
441 | /user/createWithList:
442 | post:
443 | tags:
444 | - user
445 | summary: Creates list of users with given input array
446 | operationId: createUsersWithListInput
447 | requestBody:
448 | description: List of user object
449 | content:
450 | '*/*':
451 | schema:
452 | type: array
453 | items:
454 | $ref: '#/components/schemas/User'
455 | required: true
456 | responses:
457 | default:
458 | description: successful operation
459 | content: {}
460 | /user/login:
461 | get:
462 | tags:
463 | - user
464 | summary: Logs user into the system
465 | operationId: loginUser
466 | parameters:
467 | - name: username
468 | in: query
469 | description: The user name for login
470 | required: true
471 | schema:
472 | type: string
473 | - name: password
474 | in: query
475 | description: The password for login in clear text
476 | required: true
477 | schema:
478 | type: string
479 | responses:
480 | 200:
481 | description: successful operation
482 | headers:
483 | X-Rate-Limit:
484 | description: calls per hour allowed by the user
485 | schema:
486 | type: integer
487 | format: int32
488 | X-Expires-After:
489 | description: date in UTC when token expires
490 | schema:
491 | type: string
492 | format: date-time
493 | content:
494 | application/xml:
495 | schema:
496 | type: string
497 | application/json:
498 | schema:
499 | type: string
500 | 400:
501 | description: Invalid username/password supplied
502 | content: {}
503 | /user/logout:
504 | get:
505 | tags:
506 | - user
507 | summary: Logs out current logged in user session
508 | operationId: logoutUser
509 | responses:
510 | default:
511 | description: successful operation
512 | content: {}
513 | /user/{username}:
514 | get:
515 | tags:
516 | - user
517 | summary: Get user by user name
518 | operationId: getUserByName
519 | parameters:
520 | - name: username
521 | in: path
522 | description: 'The name that needs to be fetched. Use user1 for testing. '
523 | required: true
524 | schema:
525 | type: string
526 | responses:
527 | 200:
528 | description: successful operation
529 | content:
530 | application/xml:
531 | schema:
532 | $ref: '#/components/schemas/User'
533 | application/json:
534 | schema:
535 | $ref: '#/components/schemas/User'
536 | 400:
537 | description: Invalid username supplied
538 | content: {}
539 | 404:
540 | description: User not found
541 | content: {}
542 | put:
543 | tags:
544 | - user
545 | summary: Updated user
546 | description: This can only be done by the logged in user.
547 | operationId: updateUser
548 | parameters:
549 | - name: username
550 | in: path
551 | description: name that need to be updated
552 | required: true
553 | schema:
554 | type: string
555 | requestBody:
556 | description: Updated user object
557 | content:
558 | '*/*':
559 | schema:
560 | $ref: '#/components/schemas/User'
561 | required: true
562 | responses:
563 | 400:
564 | description: Invalid user supplied
565 | content: {}
566 | 404:
567 | description: User not found
568 | content: {}
569 | delete:
570 | tags:
571 | - user
572 | summary: Delete user
573 | description: This can only be done by the logged in user.
574 | operationId: deleteUser
575 | parameters:
576 | - name: username
577 | in: path
578 | description: The name that needs to be deleted
579 | required: true
580 | schema:
581 | type: string
582 | responses:
583 | 400:
584 | description: Invalid username supplied
585 | content: {}
586 | 404:
587 | description: User not found
588 | content: {}
589 | components:
590 | schemas:
591 | Order:
592 | type: object
593 | properties:
594 | id:
595 | type: integer
596 | format: int64
597 | petId:
598 | type: integer
599 | format: int64
600 | quantity:
601 | type: integer
602 | format: int32
603 | shipDate:
604 | type: string
605 | format: date-time
606 | status:
607 | type: string
608 | description: Order Status
609 | enum:
610 | - placed
611 | - approved
612 | - delivered
613 | complete:
614 | type: boolean
615 | default: false
616 | xml:
617 | name: Order
618 | Category:
619 | type: object
620 | properties:
621 | id:
622 | type: integer
623 | format: int64
624 | name:
625 | type: string
626 | xml:
627 | name: Category
628 | User:
629 | type: object
630 | properties:
631 | id:
632 | type: integer
633 | format: int64
634 | username:
635 | type: string
636 | firstName:
637 | type: string
638 | lastName:
639 | type: string
640 | email:
641 | type: string
642 | password:
643 | type: string
644 | phone:
645 | type: string
646 | userStatus:
647 | type: integer
648 | description: User Status
649 | format: int32
650 | xml:
651 | name: User
652 | Tag:
653 | type: object
654 | properties:
655 | id:
656 | type: integer
657 | format: int64
658 | name:
659 | type: string
660 | xml:
661 | name: Tag
662 | Pet:
663 | required:
664 | - name
665 | - photoUrls
666 | type: object
667 | properties:
668 | id:
669 | type: integer
670 | format: int64
671 | category:
672 | $ref: '#/components/schemas/Category'
673 | name:
674 | type: string
675 | example: doggie
676 | photoUrls:
677 | type: array
678 | xml:
679 | name: photoUrl
680 | wrapped: true
681 | items:
682 | type: string
683 | tags:
684 | type: array
685 | xml:
686 | name: tag
687 | wrapped: true
688 | items:
689 | $ref: '#/components/schemas/Tag'
690 | status:
691 | type: string
692 | description: pet status in the store
693 | enum:
694 | - available
695 | - pending
696 | - sold
697 | xml:
698 | name: Pet
699 | ApiResponse:
700 | type: object
701 | properties:
702 | code:
703 | type: integer
704 | format: int32
705 | type:
706 | type: string
707 | message:
708 | type: string
709 | securitySchemes:
710 | petstore_auth:
711 | type: oauth2
712 | flows:
713 | implicit:
714 | authorizationUrl: http://petstore.swagger.io/oauth/dialog
715 | scopes:
716 | write:pets: modify pets in your account
717 | read:pets: read your pets
718 | api_key:
719 | type: apiKey
720 | name: api_key
721 | in: header
722 |
--------------------------------------------------------------------------------
/src/sbt-test/sbt-openapi-generator/simple/project/build.properties:
--------------------------------------------------------------------------------
1 | sbt.version=1.10.11
2 |
--------------------------------------------------------------------------------
/src/sbt-test/sbt-openapi-generator/simple/project/plugin.sbt:
--------------------------------------------------------------------------------
1 | resolvers ++= Seq(
2 | Resolver.sonatypeRepo("snapshots")
3 | )
4 | sys.props.get("plugin.version") match {
5 | case Some(x) => addSbtPlugin("org.openapitools" % "sbt-openapi-generator" % x)
6 | case _ =>
7 | throw new Exception("The system property 'plugin.version' is not defined.")
8 | }
--------------------------------------------------------------------------------
/src/sbt-test/sbt-openapi-generator/simple/src/main/scala/Main.scala:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 OpenAPI-Generator Contributors (https://openapi-generator.tech)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package simple.src.main.scala
18 |
19 | object Main extends App {
20 | println("hello world")
21 | }
22 |
--------------------------------------------------------------------------------
/src/sbt-test/sbt-openapi-generator/simple/test:
--------------------------------------------------------------------------------
1 | > openApiGenerators
2 | > openApiGenerate
3 | > reload
4 | $ exists generated/build.sbt
5 | $ exists generated/.openapi-generator-ignore
6 | $ exists generated/.openapi-generator/VERSION
7 | $ exists generated/src/main/scala/org/openapitools/client/core/ApiInvoker.scala
8 | $ exists generated/src/main/scala/org/openapitools/client/model/ApiResponse.scala
9 | $ exists generated/src/main/scala/org/openapitools/client/model/Category.scala
10 | $ exists generated/src/main/scala/org/openapitools/client/custom/api/PetApi.scala
11 |
--------------------------------------------------------------------------------
/src/sbt-test/sbt-openapi-generator/simple/version.sbt:
--------------------------------------------------------------------------------
1 | version := "1.0.0"
2 |
--------------------------------------------------------------------------------