kinda sorta processor (#3)

This commit is contained in:
Ryan Brink
2021-04-12 12:21:28 -04:00
committed by GitHub
parent e6c671f810
commit 492933d728
37 changed files with 273 additions and 61 deletions

View File

@ -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()
)
}

View File

@ -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 = ""
)

View File

@ -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 = ""
)

View File

@ -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 = ""
)

View File

@ -0,0 +1,5 @@
package org.leafygreens.kompendium.annotations
@Retention(AnnotationRetention.SOURCE)
@Target(AnnotationTarget.FUNCTION)
annotation class KompendiumModule

View File

@ -0,0 +1,7 @@
package org.leafygreens.kompendium.annotations
@Retention(AnnotationRetention.SOURCE)
@Target(AnnotationTarget.FUNCTION, AnnotationTarget.CLASS)
annotation class KompendiumServers(
val urls: Array<String>
)

View File

@ -4,8 +4,8 @@ data class OpenApiSpec(
val openapi: String = "3.0.3",
val info: OpenApiSpecInfo? = null,
// TODO Needs to default to server object with url of `/`
val servers: List<OpenApiSpecServer>? = null,
val paths: Map<String, OpenApiSpecPathItem>? = null,
val servers: MutableList<OpenApiSpecServer>? = null,
val paths: MutableMap<String, OpenApiSpecPathItem>? = null,
val components: OpenApiSpecComponents? = null,
// todo needs to reference objects in the components -> security scheme 🤔
val security: List<Map<String, List<String>>>? = null,

View File

@ -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
)

View File

@ -3,7 +3,7 @@ package org.leafygreens.kompendium.models
import java.net.URI
data class OpenApiSpecInfoContact(
val name: String,
val url: URI? = null,
val email: String? = null // TODO Enforce email?
var name: String,
var url: URI? = null,
var email: String? = null // TODO Enforce email?
)

View File

@ -3,6 +3,6 @@ package org.leafygreens.kompendium.models
import java.net.URI
data class OpenApiSpecInfoLicense(
val name: String,
val url: URI?
var name: String,
var url: URI? = null
)

View File

@ -1,7 +1,6 @@
package org.leafygreens.kompendium.models
data class OpenApiSpecPathItem(
// val `$ref`: String?, // TODO need example of this... or just make whole thing referencable?
val summary: String? = null,
val description: String? = null,
val get: OpenApiSpecPathItemOperation? = null,

View File

@ -53,7 +53,7 @@ object TestData {
description = "Find out more about Swagger",
url = URI("http://swagger.io")
),
servers = listOf(
servers = mutableListOf(
OpenApiSpecServer(
url = URI("https://petstore.swagger.io/v2")
),
@ -83,7 +83,7 @@ object TestData {
)
)
),
paths = mapOf(
paths = mutableMapOf(
"/pet" to OpenApiSpecPathItem(
put = OpenApiSpecPathItemOperation(
tags = setOf("pet"),

View File

@ -1,4 +1,5 @@
plugins {
kotlin("kapt")
application
}
@ -6,7 +7,8 @@ dependencies {
implementation(platform("org.jetbrains.kotlin:kotlin-bom"))
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
implementation(projects.kompendium)
implementation(projects.kompendiumCore)
kapt(projects.kompendiumProcessor)
implementation(libs.bundles.ktor)
implementation(libs.bundles.logging)

View File

@ -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")
}
}
}
}

View 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"])
// }
// }
//}

View File

@ -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
}
}

View File

@ -1,7 +0,0 @@
package org.leafygreens.kompendium
import org.leafygreens.kompendium.models.OpenApiSpec
class Kompendium {
val spec = OpenApiSpec()
}

View File

@ -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
)

View File

@ -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")
}
}
}
}

View File

@ -1,6 +1,7 @@
rootProject.name = "root"
include("kompendium")
include("playground")
rootProject.name = "kompendium"
include("kompendium-core")
include("kompendium-processor")
include("kompendium-playground")
// Feature Previews
enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS")