kinda sorta processor (#3)
This commit is contained in:
@ -0,0 +1,12 @@
|
|||||||
|
package org.leafygreens.kompendium
|
||||||
|
|
||||||
|
import org.leafygreens.kompendium.models.OpenApiSpec
|
||||||
|
import org.leafygreens.kompendium.models.OpenApiSpecInfo
|
||||||
|
|
||||||
|
class Kompendium {
|
||||||
|
val spec = OpenApiSpec(
|
||||||
|
info = OpenApiSpecInfo(),
|
||||||
|
servers = mutableListOf(),
|
||||||
|
paths = mutableMapOf()
|
||||||
|
)
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
package org.leafygreens.kompendium.annotations
|
||||||
|
|
||||||
|
@Retention(AnnotationRetention.SOURCE)
|
||||||
|
@Target(AnnotationTarget.FUNCTION, AnnotationTarget.CLASS)
|
||||||
|
annotation class KompendiumContact(
|
||||||
|
val name: String,
|
||||||
|
val url: String = "",
|
||||||
|
val email: String = ""
|
||||||
|
)
|
@ -0,0 +1,10 @@
|
|||||||
|
package org.leafygreens.kompendium.annotations
|
||||||
|
|
||||||
|
@Retention(AnnotationRetention.SOURCE)
|
||||||
|
@Target(AnnotationTarget.FUNCTION, AnnotationTarget.CLASS)
|
||||||
|
annotation class KompendiumInfo(
|
||||||
|
val title: String,
|
||||||
|
val version: String,
|
||||||
|
val description: String = "",
|
||||||
|
val termsOfService: String = ""
|
||||||
|
)
|
@ -0,0 +1,8 @@
|
|||||||
|
package org.leafygreens.kompendium.annotations
|
||||||
|
|
||||||
|
@Retention(AnnotationRetention.SOURCE)
|
||||||
|
@Target(AnnotationTarget.FUNCTION, AnnotationTarget.CLASS)
|
||||||
|
annotation class KompendiumLicense(
|
||||||
|
val name: String,
|
||||||
|
val url: String = ""
|
||||||
|
)
|
@ -0,0 +1,5 @@
|
|||||||
|
package org.leafygreens.kompendium.annotations
|
||||||
|
|
||||||
|
@Retention(AnnotationRetention.SOURCE)
|
||||||
|
@Target(AnnotationTarget.FUNCTION)
|
||||||
|
annotation class KompendiumModule
|
@ -0,0 +1,7 @@
|
|||||||
|
package org.leafygreens.kompendium.annotations
|
||||||
|
|
||||||
|
@Retention(AnnotationRetention.SOURCE)
|
||||||
|
@Target(AnnotationTarget.FUNCTION, AnnotationTarget.CLASS)
|
||||||
|
annotation class KompendiumServers(
|
||||||
|
val urls: Array<String>
|
||||||
|
)
|
@ -4,8 +4,8 @@ data class OpenApiSpec(
|
|||||||
val openapi: String = "3.0.3",
|
val openapi: String = "3.0.3",
|
||||||
val info: OpenApiSpecInfo? = null,
|
val info: OpenApiSpecInfo? = null,
|
||||||
// TODO Needs to default to server object with url of `/`
|
// TODO Needs to default to server object with url of `/`
|
||||||
val servers: List<OpenApiSpecServer>? = null,
|
val servers: MutableList<OpenApiSpecServer>? = null,
|
||||||
val paths: Map<String, OpenApiSpecPathItem>? = null,
|
val paths: MutableMap<String, OpenApiSpecPathItem>? = null,
|
||||||
val components: OpenApiSpecComponents? = null,
|
val components: OpenApiSpecComponents? = null,
|
||||||
// todo needs to reference objects in the components -> security scheme 🤔
|
// todo needs to reference objects in the components -> security scheme 🤔
|
||||||
val security: List<Map<String, List<String>>>? = null,
|
val security: List<Map<String, List<String>>>? = null,
|
@ -0,0 +1,12 @@
|
|||||||
|
package org.leafygreens.kompendium.models
|
||||||
|
|
||||||
|
import java.net.URI
|
||||||
|
|
||||||
|
data class OpenApiSpecInfo(
|
||||||
|
var title: String? = null,
|
||||||
|
var version: String? = null,
|
||||||
|
var description: String? = null,
|
||||||
|
var termsOfService: URI? = null,
|
||||||
|
var contact: OpenApiSpecInfoContact? = null,
|
||||||
|
var license: OpenApiSpecInfoLicense? = null
|
||||||
|
)
|
@ -3,7 +3,7 @@ package org.leafygreens.kompendium.models
|
|||||||
import java.net.URI
|
import java.net.URI
|
||||||
|
|
||||||
data class OpenApiSpecInfoContact(
|
data class OpenApiSpecInfoContact(
|
||||||
val name: String,
|
var name: String,
|
||||||
val url: URI? = null,
|
var url: URI? = null,
|
||||||
val email: String? = null // TODO Enforce email?
|
var email: String? = null // TODO Enforce email?
|
||||||
)
|
)
|
@ -3,6 +3,6 @@ package org.leafygreens.kompendium.models
|
|||||||
import java.net.URI
|
import java.net.URI
|
||||||
|
|
||||||
data class OpenApiSpecInfoLicense(
|
data class OpenApiSpecInfoLicense(
|
||||||
val name: String,
|
var name: String,
|
||||||
val url: URI?
|
var url: URI? = null
|
||||||
)
|
)
|
@ -1,7 +1,6 @@
|
|||||||
package org.leafygreens.kompendium.models
|
package org.leafygreens.kompendium.models
|
||||||
|
|
||||||
data class OpenApiSpecPathItem(
|
data class OpenApiSpecPathItem(
|
||||||
// val `$ref`: String?, // TODO need example of this... or just make whole thing referencable?
|
|
||||||
val summary: String? = null,
|
val summary: String? = null,
|
||||||
val description: String? = null,
|
val description: String? = null,
|
||||||
val get: OpenApiSpecPathItemOperation? = null,
|
val get: OpenApiSpecPathItemOperation? = null,
|
@ -53,7 +53,7 @@ object TestData {
|
|||||||
description = "Find out more about Swagger",
|
description = "Find out more about Swagger",
|
||||||
url = URI("http://swagger.io")
|
url = URI("http://swagger.io")
|
||||||
),
|
),
|
||||||
servers = listOf(
|
servers = mutableListOf(
|
||||||
OpenApiSpecServer(
|
OpenApiSpecServer(
|
||||||
url = URI("https://petstore.swagger.io/v2")
|
url = URI("https://petstore.swagger.io/v2")
|
||||||
),
|
),
|
||||||
@ -83,7 +83,7 @@ object TestData {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
paths = mapOf(
|
paths = mutableMapOf(
|
||||||
"/pet" to OpenApiSpecPathItem(
|
"/pet" to OpenApiSpecPathItem(
|
||||||
put = OpenApiSpecPathItemOperation(
|
put = OpenApiSpecPathItemOperation(
|
||||||
tags = setOf("pet"),
|
tags = setOf("pet"),
|
@ -1,4 +1,5 @@
|
|||||||
plugins {
|
plugins {
|
||||||
|
kotlin("kapt")
|
||||||
application
|
application
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6,7 +7,8 @@ dependencies {
|
|||||||
implementation(platform("org.jetbrains.kotlin:kotlin-bom"))
|
implementation(platform("org.jetbrains.kotlin:kotlin-bom"))
|
||||||
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
|
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
|
||||||
|
|
||||||
implementation(projects.kompendium)
|
implementation(projects.kompendiumCore)
|
||||||
|
kapt(projects.kompendiumProcessor)
|
||||||
|
|
||||||
implementation(libs.bundles.ktor)
|
implementation(libs.bundles.ktor)
|
||||||
implementation(libs.bundles.logging)
|
implementation(libs.bundles.logging)
|
@ -0,0 +1,49 @@
|
|||||||
|
package org.leafygreens.kompendium.playground
|
||||||
|
|
||||||
|
import io.ktor.application.Application
|
||||||
|
import io.ktor.application.call
|
||||||
|
import io.ktor.response.respondText
|
||||||
|
import io.ktor.routing.get
|
||||||
|
import io.ktor.routing.route
|
||||||
|
import io.ktor.routing.routing
|
||||||
|
import io.ktor.server.engine.embeddedServer
|
||||||
|
import io.ktor.server.netty.Netty
|
||||||
|
import org.leafygreens.kompendium.annotations.KompendiumContact
|
||||||
|
import org.leafygreens.kompendium.annotations.KompendiumInfo
|
||||||
|
import org.leafygreens.kompendium.annotations.KompendiumLicense
|
||||||
|
import org.leafygreens.kompendium.annotations.KompendiumModule
|
||||||
|
import org.leafygreens.kompendium.annotations.KompendiumServers
|
||||||
|
|
||||||
|
@KompendiumInfo(
|
||||||
|
title = "Test API",
|
||||||
|
version = "0.0.1",
|
||||||
|
description = "An API for testing"
|
||||||
|
)
|
||||||
|
@KompendiumContact(
|
||||||
|
name = "Homer Simpson",
|
||||||
|
url = "https://en.wikipedia.org/wiki/The_Simpsons",
|
||||||
|
email = "chunkylover53@aol.com"
|
||||||
|
)
|
||||||
|
@KompendiumLicense(
|
||||||
|
name = "DOH",
|
||||||
|
url = "https://opensource.org/licenses/DOH"
|
||||||
|
)
|
||||||
|
@KompendiumServers(urls = [ "https://thesimpsonsquoteapi.glitch.me/quotes" ])
|
||||||
|
fun main() {
|
||||||
|
embeddedServer(
|
||||||
|
Netty,
|
||||||
|
port = 8080,
|
||||||
|
module = Application::mainModule
|
||||||
|
).start(wait = true)
|
||||||
|
}
|
||||||
|
|
||||||
|
@KompendiumModule
|
||||||
|
fun Application.mainModule() {
|
||||||
|
routing {
|
||||||
|
route("/") {
|
||||||
|
get {
|
||||||
|
call.respondText("hi")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
33
kompendium-processor/build.gradle.kts
Normal file
33
kompendium-processor/build.gradle.kts
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
plugins {
|
||||||
|
kotlin("kapt")
|
||||||
|
`java-library`
|
||||||
|
`maven-publish`
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
implementation(platform("org.jetbrains.kotlin:kotlin-bom"))
|
||||||
|
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
|
||||||
|
implementation(projects.kompendiumCore)
|
||||||
|
implementation("com.google.auto.service:auto-service:1.0")
|
||||||
|
kapt("com.google.auto.service:auto-service:1.0")
|
||||||
|
testImplementation("org.jetbrains.kotlin:kotlin-test")
|
||||||
|
testImplementation("org.jetbrains.kotlin:kotlin-test-junit")
|
||||||
|
}
|
||||||
|
//
|
||||||
|
//publishing {
|
||||||
|
// repositories {
|
||||||
|
// maven {
|
||||||
|
// name = "GithubPackages"
|
||||||
|
// url = uri("https://maven.pkg.github.com/lg-backbone/kompendium")
|
||||||
|
// credentials {
|
||||||
|
// username = System.getenv("GITHUB_ACTOR")
|
||||||
|
// password = System.getenv("GITHUB_TOKEN")
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// publications {
|
||||||
|
// create<MavenPublication>("kompendium") {
|
||||||
|
// from(components["kotlin"])
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//}
|
@ -0,0 +1,112 @@
|
|||||||
|
package org.leafygreens.kompendium.processor
|
||||||
|
|
||||||
|
import com.google.auto.service.AutoService
|
||||||
|
import java.net.URI
|
||||||
|
import javax.annotation.processing.AbstractProcessor
|
||||||
|
import javax.annotation.processing.Processor
|
||||||
|
import javax.annotation.processing.RoundEnvironment
|
||||||
|
import javax.annotation.processing.SupportedSourceVersion
|
||||||
|
import javax.lang.model.SourceVersion
|
||||||
|
import javax.lang.model.element.TypeElement
|
||||||
|
import org.leafygreens.kompendium.Kompendium
|
||||||
|
import org.leafygreens.kompendium.annotations.KompendiumContact
|
||||||
|
import org.leafygreens.kompendium.annotations.KompendiumInfo
|
||||||
|
import org.leafygreens.kompendium.annotations.KompendiumLicense
|
||||||
|
import org.leafygreens.kompendium.annotations.KompendiumModule
|
||||||
|
import org.leafygreens.kompendium.annotations.KompendiumServers
|
||||||
|
import org.leafygreens.kompendium.models.OpenApiSpecInfoContact
|
||||||
|
import org.leafygreens.kompendium.models.OpenApiSpecInfoLicense
|
||||||
|
import org.leafygreens.kompendium.models.OpenApiSpecServer
|
||||||
|
|
||||||
|
@AutoService(Processor::class)
|
||||||
|
@SupportedSourceVersion(SourceVersion.RELEASE_8)
|
||||||
|
class KompendiumProcessor : AbstractProcessor() {
|
||||||
|
|
||||||
|
private val kompendium = Kompendium()
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val KAPT_KOTLIN_GENERATED_OPTION_NAME = "kapt.kotlin.generated"
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getSupportedAnnotationTypes(): MutableSet<String> {
|
||||||
|
return mutableSetOf(
|
||||||
|
KompendiumInfo::class.java.canonicalName,
|
||||||
|
KompendiumContact::class.java.canonicalName,
|
||||||
|
KompendiumLicense::class.java.canonicalName,
|
||||||
|
KompendiumServers::class.java.canonicalName,
|
||||||
|
KompendiumModule::class.java.canonicalName
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO Throw error if more than 1 info, contact, etc.?
|
||||||
|
override fun process(annotations: MutableSet<out TypeElement>?, roundEnv: RoundEnvironment?): Boolean {
|
||||||
|
roundEnv?.getElementsAnnotatedWith(KompendiumInfo::class.java)?.forEach {
|
||||||
|
val info = it.getAnnotation(KompendiumInfo::class.java)
|
||||||
|
processKompendiumInfo(info)
|
||||||
|
}
|
||||||
|
roundEnv?.getElementsAnnotatedWith(KompendiumContact::class.java)?.forEach {
|
||||||
|
val contact = it.getAnnotation(KompendiumContact::class.java)
|
||||||
|
processKompendiumContact(contact)
|
||||||
|
}
|
||||||
|
roundEnv?.getElementsAnnotatedWith(KompendiumLicense::class.java)?.forEach {
|
||||||
|
val license = it.getAnnotation(KompendiumLicense::class.java)
|
||||||
|
processKompendiumLicense(license)
|
||||||
|
}
|
||||||
|
roundEnv?.getElementsAnnotatedWith(KompendiumServers::class.java)?.forEach {
|
||||||
|
val servers = it.getAnnotation(KompendiumServers::class.java)
|
||||||
|
processKompendiumServers(servers)
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun processKompendiumInfo(info: KompendiumInfo) {
|
||||||
|
kompendium.spec.info?.apply {
|
||||||
|
this.title = info.title
|
||||||
|
this.version = info.version
|
||||||
|
info.description.blankToNull()?.let { desc ->
|
||||||
|
this.description = desc
|
||||||
|
}
|
||||||
|
info.termsOfService.blankToNull()?.let { tos ->
|
||||||
|
this.termsOfService = URI(tos)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun processKompendiumContact(contact: KompendiumContact) {
|
||||||
|
kompendium.spec.info?.apply {
|
||||||
|
this.contact = OpenApiSpecInfoContact(
|
||||||
|
name = contact.name
|
||||||
|
).apply {
|
||||||
|
contact.url.blankToNull()?.let { url ->
|
||||||
|
this.url = URI(url)
|
||||||
|
}
|
||||||
|
contact.email.blankToNull()?.let { email ->
|
||||||
|
this.email = email
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun processKompendiumLicense(license: KompendiumLicense) {
|
||||||
|
kompendium.spec.info?.apply {
|
||||||
|
this.license = OpenApiSpecInfoLicense(
|
||||||
|
name = license.name
|
||||||
|
).apply {
|
||||||
|
license.url.blankToNull()?.let { url ->
|
||||||
|
this.url = URI(url)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun processKompendiumServers(servers: KompendiumServers) {
|
||||||
|
servers.urls.forEach { url ->
|
||||||
|
kompendium.spec.servers?.add(OpenApiSpecServer(URI(url)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun String.blankToNull(): String? = ifBlank {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,7 +0,0 @@
|
|||||||
package org.leafygreens.kompendium
|
|
||||||
|
|
||||||
import org.leafygreens.kompendium.models.OpenApiSpec
|
|
||||||
|
|
||||||
class Kompendium {
|
|
||||||
val spec = OpenApiSpec()
|
|
||||||
}
|
|
@ -1,12 +0,0 @@
|
|||||||
package org.leafygreens.kompendium.models
|
|
||||||
|
|
||||||
import java.net.URI
|
|
||||||
|
|
||||||
data class OpenApiSpecInfo(
|
|
||||||
val title: String,
|
|
||||||
val version: String,
|
|
||||||
val description: String?,
|
|
||||||
val termsOfService: URI? = null,
|
|
||||||
val contact: OpenApiSpecInfoContact? = null,
|
|
||||||
val license: OpenApiSpecInfoLicense? = null
|
|
||||||
)
|
|
@ -1,28 +0,0 @@
|
|||||||
package org.leafygreens.kompendium.playground
|
|
||||||
|
|
||||||
import io.ktor.application.Application
|
|
||||||
import io.ktor.application.call
|
|
||||||
import io.ktor.response.respondText
|
|
||||||
import io.ktor.routing.get
|
|
||||||
import io.ktor.routing.route
|
|
||||||
import io.ktor.routing.routing
|
|
||||||
import io.ktor.server.engine.embeddedServer
|
|
||||||
import io.ktor.server.netty.Netty
|
|
||||||
|
|
||||||
fun main() {
|
|
||||||
embeddedServer(
|
|
||||||
Netty,
|
|
||||||
port = 8080,
|
|
||||||
module = Application::mainModule
|
|
||||||
).start(wait = true)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun Application.mainModule() {
|
|
||||||
routing {
|
|
||||||
route("/") {
|
|
||||||
get {
|
|
||||||
call.respondText("hi")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,6 +1,7 @@
|
|||||||
rootProject.name = "root"
|
rootProject.name = "kompendium"
|
||||||
include("kompendium")
|
include("kompendium-core")
|
||||||
include("playground")
|
include("kompendium-processor")
|
||||||
|
include("kompendium-playground")
|
||||||
|
|
||||||
// Feature Previews
|
// Feature Previews
|
||||||
enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS")
|
enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS")
|
||||||
|
Reference in New Issue
Block a user