Skip to content

Commit acfb250

Browse files
Merge pull request #54 from mduesterhoeft/open-api-3-rename
Rename to restdocs-api-spec
2 parents 782edf2 + 6ae56cc commit acfb250

File tree

78 files changed

+2410
-1049
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

78 files changed

+2410
-1049
lines changed

.travis.yml

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,23 @@ language: java
22
jdk:
33
- oraclejdk8
44
sudo: false
5+
before_cache:
6+
- rm -f $HOME/.gradle/caches/modules-2/modules-2.lock
7+
- rm -fr $HOME/.gradle/caches/*/plugin-resolution/
58
cache:
69
directories:
7-
- "$HOME/.gradle"
10+
- "$HOME/.gradle/caches/"
11+
- "$HOME/.gradle/wrapper/"
812
install: true
913
script: "./gradlew clean build coveralls"
14+
deploy:
15+
provider: script
16+
script: "./gradlew binTrayUpload"
17+
on:
18+
tags: true
1019
env:
1120
global:
1221
- CI_NAME=travis-ci
1322
- secure: nOkY2AcR5Z7hKKzi+zCzmzPk+xiRRrJjGliDJnHnEO7g+iJ8SmT+thHuMFcXqvjxJ006LbR3GPB8M8qgFXFDPEUDRPppShi3waOm1ddlM2iXh9kbCoROoioyRO+F07deH6ExibkLbu/xq3WwAAw7lx/ZP+buc2R2VCbV0nLKP9iE4nHQX8msLgmU1LjWf0Au1Pgl2eWXV0J4/ZJOvcVu9hvBf1Ow4C7BNb0KZmMjeT9uMK0hiGpb9VVbwedOWfsbaFmqmKYqVKS8UtNmG+HBjvZfajrIARKRPc9w9uEvfl4E1H/J7PJLy2kOrCOauj8LMu6DduSrWcg08T5VnH51cavSAsWWG1ImTgEsUBNpllc9r1XLhQCLQ1TWCgGmleqYjZ2ySvg0MQpFjTgXMZC+aDkjZjcEeq3BgrncAR/bcG4ByrZBWyoEXDxBwoMZnkryTxK07UUgXRXdjJUldJ5CQW9oSfd+oEXKJyqQGNt0ob3S0sRS5uhrKniK+6Mwzxf6vXeYvn2fVP5j3hocUz4XzDJQoDDmJi6D4BpwksqJ81CNOHpyeDIOhdXxvA/J8DMCK0Q7tTSbnSOxItaht56CSxqqLSGax3/4Nr+5QX9jpmdJ03HdpP+MOuIl6dZCmE4/w1IFaFEfhpETPlnWZHl1BsOt7omDeW7yCttDq3Y1mXU=
23+
- secure: 4DTaXQyT0oj4GkmDYRT0goQ7B/wGAjLov9xRssyz7aEKZaZZS/y4YSZ7LEI57dZYLkwtekiR1zN6gLnB6XGTMh2MVRGZ1vzcwsR1HebyjFHf5+2YHXRKq/mJk4K4q6t9GtXKZYz3yDnXtn7S2NgkIhye0E1t2874kEPcIEhKClLIGKjCsVenx1ui4WxBMVFPyhAe5KKn73HFTZORzPtTzoYDM9akhZm+Ko0ObreJZdy/P9pHU+RGQjPFWRbjNlrBg1uiBhYOWPGXrOwKMxNnl2fNUilF0QHaDt0oYbeBJvXKgqqC90Qrb067+ynL5S567uesY16A0MtYDIYiDAt0ytSH4B5fjWpFR5WWU+X9uPTAzP4HTwNYfdOBnvtUrRUlYNdxWxwS7ZOzoMFKt7UHs/42VoJBURBBhP7g6qFIJb+OtdDk6iSpqsa/VSMaB59HsKkitB2ZDh7ohmWBu0wZ1iIN6hEYd94/HFWv4C6Fkntbxgv+kVETVNmeA6yLMvLF46Jg8a1s2XptCUFb5kQpgaitbEPnso8lAwXCPRQlj064Ctym8oPCi4hYZcWHm4sF1RYFVweVaa1+5wQI5go6dTgrQajYwRJU0WmtmYfb9pr/l5NeAk2tuYEnX/ILs6TB1by5qJUQzCnaF7YgERrG84t4lqByBGdZaIiFMRIVXCw=
24+
- secure: iEfnO6ZvdyY2Sx0uDafjRgyqPsUueEZtvWumhSRQCBEpQ6MDQiWQTX3SGYtgdX61eShiqwVo3bnp3eeCCojUCtXHFM+sE+bk3NOMuocq4p1Q6uZrt1oe7nK8wYBPdl+5iema1UtSiYiAw6FGlAnDsDjvBkIa7vGpoGyToa68hzLjwNWMi6Jz9JPEoCwIIKSZn8J8gYbeKr1CMLkwpLZYfsh077mXRC22yH0jh7c6kQSfdUuW7a6fELQiQXgccp8qR11oJ5AI17prFa+4q09xCk4pbrhCHMXRrOHDfRLicXWN3qgF8rqETLLRGM1LPpwsgkoFqBEs93RT+3USpWs2H8sC5LgG3m76QP4stRekEmmlJJnIT9ohTt6SAWvrszoYYusTfJbVwQewKXQppshcUIubL7GqaJ0gaTgU7O3tX2o7lTi0dw27FcXV2KpSBSkNok1AZy9iWhGoeSWupi8APe37IwUHjPTiu3on07hbuRXQ/7qvVxujftwiDR3Tbb5AoG3tvtr5+Ru58Ie4PyhxuP1AYbUkgWxVx2MOBHeePHm59wfXIytKoSAGIi0uFwlCqBV926sJCbKwv0c2Kh5SkJvA/1TNTFYITgiiIL9DyxziXUzvsJAkO2ZyA8FLCpMM+WqMnB/M5jxrFzqFFfvhP5dSZSd3OkUO2bhHJuCS2BU=

README.md

Lines changed: 155 additions & 66 deletions
Large diffs are not rendered by default.

build.gradle.kts

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
import com.jfrog.bintray.gradle.BintrayExtension
2+
import com.jfrog.bintray.gradle.BintrayExtension.PackageConfig
3+
import com.jfrog.bintray.gradle.tasks.BintrayUploadTask
14
import org.gradle.internal.impldep.org.eclipse.jgit.lib.ObjectChecker.tag
25
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
36
import org.kt3k.gradle.plugin.CoverallsPluginExtension
@@ -9,12 +12,13 @@ import org.gradle.api.tasks.bundling.Jar
912

1013
plugins {
1114
java
12-
kotlin("jvm") version "1.2.60" apply false
15+
kotlin("jvm") version "1.2.51" apply false
1316
id("pl.allegro.tech.build.axion-release") version "1.9.2"
1417
jacoco
1518
`maven-publish`
1619
id("org.jmailen.kotlinter") version "1.17.0" apply false
1720
id("com.github.kt3k.coveralls") version "2.8.2"
21+
id("com.jfrog.bintray") version "1.8.4" apply false
1822
}
1923

2024
repositories {
@@ -52,6 +56,7 @@ allprojects {
5256
apply(plugin = "jacoco")
5357
apply(plugin = "maven-publish")
5458
apply(plugin = "org.jmailen.kotlinter")
59+
5560
}
5661
}
5762

@@ -76,6 +81,7 @@ subprojects {
7681
}
7782

7883
if (!isSampleProject()) {
84+
7985
tasks.withType<JacocoReport> {
8086
dependsOn("test")
8187
reports {
@@ -86,23 +92,35 @@ subprojects {
8692

8793
val sourcesJar by tasks.creating(Jar::class) {
8894
classifier = "sources"
89-
from(sourceSets["main"].allSource)
95+
from(java.sourceSets["main"].allSource)
9096
}
9197

9298
publishing {
93-
publications {
94-
register("mavenJava", MavenPublication::class) {
99+
(publications) {
100+
"mavenJava"(MavenPublication::class) {
95101
from(components["java"])
96102
artifact(sourcesJar)
97103
}
98104
}
99105
}
106+
apply(plugin = "com.jfrog.bintray")
107+
configure<BintrayExtension> {
108+
user = project.findProperty("bintrayUser") as String? ?: System.getenv("BINTRAY_USER")
109+
key = project.findProperty("bintrayApiKey") as String? ?: System.getenv("BINTRAY_API_KEY")
110+
publish = true
111+
setPublications("mavenJava")
112+
pkg(closureOf<PackageConfig> {
113+
repo = "maven"
114+
name = "restdocs-api-spec"
115+
userOrg = "epages"
116+
})
117+
}
100118
}
101119
}
102120

103121
//coverall multi module plugin configuration starts here
104122
configure<CoverallsPluginExtension> {
105-
sourceDirs = nonSampleProjects.flatMap { it.sourceSets["main"].allSource.srcDirs }.filter { it.exists() }.map { it.path }
123+
sourceDirs = nonSampleProjects.flatMap { it.java.sourceSets["main"].allSource.srcDirs }.filter { it.exists() }.map { it.path }
106124
jacocoReportPath = "$buildDir/reports/jacoco/jacocoRootReport/jacocoRootReport.xml"
107125
}
108126

@@ -122,8 +140,8 @@ tasks {
122140
description = "Generates an aggregate report from all subprojects"
123141
group = "Coverage reports"
124142
dependsOn(jacocoMerge)
125-
sourceDirectories = files(nonSampleProjects.flatMap { it.sourceSets["main"].allSource.srcDirs.filter { it.exists() } } )
126-
classDirectories = files(nonSampleProjects.flatMap { it.sourceSets["main"].output } )
143+
sourceDirectories = files(nonSampleProjects.flatMap { it.java.sourceSets["main"].allSource.srcDirs.filter { it.exists() } } )
144+
classDirectories = files(nonSampleProjects.flatMap { it.java.sourceSets["main"].output } )
127145
executionData(jacocoMerge.destinationFile)
128146
reports {
129147
html.isEnabled = true
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
distributionBase=GRADLE_USER_HOME
22
distributionPath=wrapper/dists
3-
distributionUrl=https\://services.gradle.org/distributions/gradle-4.10-bin.zip
3+
distributionUrl=https\://services.gradle.org/distributions/gradle-4.8-bin.zip
44
zipStoreBase=GRADLE_USER_HOME
55
zipStorePath=wrapper/dists

restdocs-openapi-gradle-plugin/build.gradle.kts renamed to restdocs-api-spec-gradle-plugin/build.gradle.kts

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,10 @@ plugins {
1515
}
1616

1717
gradlePlugin {
18-
plugins {
19-
register("com.epages.restdocs-openapi") {
20-
id = "com.epages.restdocs-openapi"
21-
implementationClass = "com.epages.restdocs.openapi.gradle.RestdocsOpenApiPlugin"
18+
(plugins) {
19+
"com.epages.restdocs-api-spec" {
20+
id = "com.epages.restdocs-api-spec"
21+
implementationClass = "com.epages.restdocs.apispec.gradle.RestdocsApiSpecPlugin"
2222
}
2323
}
2424
}
@@ -32,12 +32,13 @@ dependencies {
3232
compile(kotlin("gradle-plugin"))
3333
compile(kotlin("stdlib-jdk8"))
3434

35-
implementation(project(":restdocs-openapi-model"))
36-
implementation(project(":restdocs-openapi-generator"))
35+
implementation(project(":restdocs-api-spec-openapi-generator"))
36+
implementation(project(":restdocs-api-spec-openapi3-generator"))
3737
implementation("com.fasterxml.jackson.core:jackson-databind:$jacksonVersion")
3838
implementation("com.fasterxml.jackson.module:jackson-module-kotlin:$jacksonVersion")
3939

4040
testImplementation("org.junit.jupiter:junit-jupiter-engine:$junitVersion")
41+
testImplementation("org.junit-pioneer:junit-pioneer:0.2.2")
4142
testImplementation("org.assertj:assertj-core:3.10.0")
4243

4344
testImplementation("com.jayway.jsonpath:json-path:2.4.0")
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package com.epages.restdocs.apispec.gradle
2+
3+
import org.gradle.api.Project
4+
5+
abstract class ApiSpecExtension(protected val project: Project) {
6+
7+
abstract var outputDirectory: String
8+
9+
var snippetsDirectory = "build/generated-snippets"
10+
11+
abstract var outputFileNamePrefix: String
12+
13+
var separatePublicApi: Boolean = false
14+
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
package com.epages.restdocs.apispec.gradle
2+
3+
import com.epages.restdocs.apispec.model.ResourceModel
4+
import com.fasterxml.jackson.databind.DeserializationFeature
5+
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
6+
import com.fasterxml.jackson.module.kotlin.readValue
7+
import org.gradle.api.DefaultTask
8+
import org.gradle.api.tasks.Input
9+
import org.gradle.api.tasks.TaskAction
10+
import java.io.File
11+
12+
abstract class ApiSpecTask : DefaultTask() {
13+
14+
@Input
15+
var separatePublicApi: Boolean = false
16+
17+
@Input
18+
lateinit var outputDirectory: String
19+
20+
@Input
21+
lateinit var snippetsDirectory: String
22+
23+
@Input
24+
lateinit var outputFileNamePrefix: String
25+
26+
private val outputDirectoryFile
27+
get() = project.file(outputDirectory)
28+
29+
private val snippetsDirectoryFile
30+
get() = project.file(snippetsDirectory)
31+
32+
private val objectMapper = jacksonObjectMapper().disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
33+
34+
open fun applyExtension(extension: ApiSpecExtension) {
35+
outputDirectory = extension.outputDirectory
36+
snippetsDirectory = extension.snippetsDirectory
37+
outputFileNamePrefix = extension.outputFileNamePrefix
38+
separatePublicApi = extension.separatePublicApi
39+
}
40+
41+
@TaskAction
42+
fun aggregateResourceModels() {
43+
44+
val resourceModels = snippetsDirectoryFile.walkTopDown()
45+
.filter { it.name == "resource.json" }
46+
.map { objectMapper.readValue<ResourceModel>(it.readText()) }
47+
.toList()
48+
49+
writeSpecificationFile(outputFileNamePrefix, generateSpecification(resourceModels))
50+
51+
if (separatePublicApi) {
52+
val content = generateSpecification(resourceModels.filterNot { it.privateResource })
53+
writeSpecificationFile("$outputFileNamePrefix-public", content)
54+
}
55+
}
56+
57+
private fun writeSpecificationFile(outputFilenamePrefix: String, content: String) {
58+
outputDirectoryFile.mkdir()
59+
File(outputDirectoryFile, "$outputFilenamePrefix.${outputFileExtension()}").writeText(content)
60+
}
61+
62+
protected abstract fun outputFileExtension(): String
63+
64+
protected abstract fun generateSpecification(resourceModels: List<ResourceModel>): String
65+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package com.epages.restdocs.apispec.gradle
2+
3+
import com.epages.restdocs.apispec.model.ResourceModel
4+
import com.epages.restdocs.apispec.openapi3.OpenApi3Generator
5+
import io.swagger.v3.oas.models.servers.Server
6+
import org.gradle.api.tasks.Input
7+
import org.gradle.api.tasks.Optional
8+
9+
open class OpenApi3Task : OpenApiBaseTask() {
10+
11+
@Input
12+
@Optional
13+
var servers: List<Server> = listOf()
14+
15+
fun applyExtension(extension: OpenApi3Extension) {
16+
super.applyExtension(extension)
17+
servers = extension.servers
18+
}
19+
20+
override fun generateSpecification(resourceModels: List<ResourceModel>): String {
21+
return OpenApi3Generator.generateAndSerialize(
22+
resources = resourceModels,
23+
servers = servers,
24+
title = title,
25+
version = apiVersion,
26+
oauth2SecuritySchemeDefinition = oauth2SecuritySchemeDefinition,
27+
format = format
28+
)
29+
}
30+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package com.epages.restdocs.apispec.gradle
2+
3+
import org.gradle.api.tasks.Input
4+
import org.gradle.api.tasks.Optional
5+
6+
abstract class OpenApiBaseTask : ApiSpecTask() {
7+
@Input
8+
@Optional
9+
lateinit var title: String
10+
11+
@Input
12+
@Optional
13+
lateinit var apiVersion: String
14+
15+
@Input
16+
@Optional
17+
lateinit var format: String
18+
19+
@Input @Optional
20+
var oauth2SecuritySchemeDefinition: PluginOauth2Configuration? = null
21+
22+
override fun outputFileExtension() = format
23+
24+
fun applyExtension(extension: OpenApiBaseExtension) {
25+
super.applyExtension(extension)
26+
format = extension.format
27+
oauth2SecuritySchemeDefinition = extension.oauth2SecuritySchemeDefinition
28+
title = extension.title
29+
apiVersion = extension.version
30+
}
31+
}
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
package com.epages.restdocs.apispec.gradle
2+
3+
import com.epages.restdocs.apispec.model.Oauth2Configuration
4+
import com.fasterxml.jackson.databind.ObjectMapper
5+
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory
6+
import com.fasterxml.jackson.module.kotlin.readValue
7+
import groovy.lang.Closure
8+
import io.swagger.v3.oas.models.servers.Server
9+
import org.gradle.api.Project
10+
import java.io.File
11+
12+
abstract class OpenApiBaseExtension(project: Project) : ApiSpecExtension(project) {
13+
override var outputDirectory = "build/openapi"
14+
15+
private val objectMapper = ObjectMapper(YAMLFactory())
16+
17+
var title = "API documentation"
18+
var version = project.version as? String ?: "1.0.0"
19+
20+
var format = "json"
21+
22+
var oauth2SecuritySchemeDefinition: PluginOauth2Configuration? = null
23+
24+
fun setOauth2SecuritySchemeDefinition(closure: Closure<PluginOauth2Configuration>) {
25+
oauth2SecuritySchemeDefinition = project.configure(PluginOauth2Configuration(), closure) as PluginOauth2Configuration
26+
with(oauth2SecuritySchemeDefinition!!) {
27+
if (scopeDescriptionsPropertiesFile != null) {
28+
scopes = scopeDescriptionSource(project.file(scopeDescriptionsPropertiesFile!!))
29+
}
30+
}
31+
}
32+
33+
private fun scopeDescriptionSource(scopeDescriptionsPropertiesFile: File): Map<String, String> {
34+
return scopeDescriptionsPropertiesFile.let { objectMapper.readValue<Map<String, String>>(it) } ?: emptyMap()
35+
}
36+
}
37+
38+
class PluginOauth2Configuration(
39+
var scopeDescriptionsPropertiesFile: String? = null
40+
) : Oauth2Configuration()
41+
42+
open class OpenApiExtension(project: Project) : OpenApiBaseExtension(project) {
43+
44+
override var outputFileNamePrefix = "openapi"
45+
46+
var host: String = "localhost"
47+
var basePath: String? = null
48+
var schemes: Array<String> = arrayOf("http")
49+
50+
companion object {
51+
const val name = "openapi"
52+
}
53+
}
54+
55+
open class OpenApi3Extension(project: Project) : OpenApiBaseExtension(project) {
56+
57+
override var outputFileNamePrefix = "openapi3"
58+
59+
private var _servers: List<Server> = mutableListOf(Server().apply { url = "http://localhost" })
60+
61+
val servers
62+
get() = _servers
63+
64+
fun setServer(serverAction: Closure<Server>) {
65+
_servers = listOf(project.configure(Server(), serverAction) as Server)
66+
}
67+
68+
fun setServer(serverUrl: String) {
69+
_servers = listOf(Server().apply { url = serverUrl })
70+
}
71+
72+
fun setServers(serversActions: List<Closure<Server>>) {
73+
_servers = serversActions.map { project.configure(Server(), it) as Server }
74+
}
75+
76+
companion object {
77+
const val name = "openapi3"
78+
}
79+
}

0 commit comments

Comments
 (0)