Skip to content

Commit

Permalink
Added non-JVM codeowners function
Browse files Browse the repository at this point in the history
  • Loading branch information
gmazzo committed Dec 4, 2023
1 parent 5a17de1 commit eae88d3
Show file tree
Hide file tree
Showing 6 changed files with 50 additions and 12 deletions.
12 changes: 12 additions & 0 deletions core/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,23 @@ java.toolchain.languageVersion.set(JavaLanguageVersion.of(8))

kotlin {
jvm()
macosArm64()
iosArm64()
iosSimulatorArm64()
js(IR) { browser(); nodejs() }
applyDefaultHierarchyTemplate()

sourceSets {
val nonJvmMain by creating { dependsOn(commonMain.get()) }
iosMain { dependsOn(nonJvmMain) }
jsMain { dependsOn(nonJvmMain) }
}
}

dependencies {
commonTestImplementation(libs.kotlin.test)
commonTestImplementation(platform(libs.junit.bom))
"nonJvmMainImplementation"(libs.kotlin.reflect)
}

publishing.repositories {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package io.github.gmazzo.codeowners

@Repeatable
@Retention(AnnotationRetention.RUNTIME)
annotation class CodeOwner(
val value: String
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package io.github.gmazzo.codeowners

import kotlin.reflect.KClass

inline fun <reified Type> codeOwnersOf() =
Type::class.codeOwners

expect val KClass<*>.codeOwners: Set<String>

expect val Throwable.codeOwners: Set<String>
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,14 @@ import java.io.Reader
import java.lang.reflect.Proxy
import kotlin.reflect.KClass

inline fun <reified Type> codeOwnersOf() =
Type::class.codeOwners

val KClass<*>.codeOwners
actual val KClass<*>.codeOwners: Set<String>
get() = java.codeOwners

val Class<*>.codeOwners: Set<String>?
val Class<*>.codeOwners: Set<String>
get() = with(topLevelClass()) { classLoader.getCodeOwners(`package`?.name, simpleName) }

val Throwable.codeOwners
get() = stackTrace.asSequence().mapNotNull { it.codeOwners }.firstOrNull()
actual val Throwable.codeOwners
get() = stackTrace.asSequence().mapNotNull { it.codeOwners }.firstOrNull().orEmpty()

private tailrec fun Class<*>.topLevelClass(): Class<*> = when (val enclosing = enclosingClass) {
null -> when {
Expand All @@ -27,18 +24,18 @@ private tailrec fun Class<*>.topLevelClass(): Class<*> = when (val enclosing = e
else -> enclosing.topLevelClass()
}

val StackTraceElement.codeOwners: Set<String>?
val StackTraceElement.codeOwners: Set<String>
get() {
val clazz = runCatching { Class.forName(className) }.getOrNull() ?: return null
val clazz = runCatching { Class.forName(className) }.getOrNull() ?: return emptySet()

return fileName?.substringBeforeLast('.')
?.let { clazz.classLoader.getCodeOwners(clazz.`package`.name, it) }
?: clazz.codeOwners
}

@JvmOverloads
tailrec fun ClassLoader.getCodeOwners(packageName: String?, className: String? = null): Set<String>? {
val packagePath = packageName?.replace('.', '/') ?: return null
tailrec fun ClassLoader.getCodeOwners(packageName: String?, className: String? = null): Set<String> {
val packagePath = packageName?.replace('.', '/') ?: return emptySet()
val path = "$packagePath/${className.orEmpty()}.codeowners"
val owners = getResources(path).asSequence()
.flatMap { it.openStream()?.reader()?.use(Reader::readLines).orEmpty() }
Expand All @@ -47,6 +44,6 @@ tailrec fun ClassLoader.getCodeOwners(packageName: String?, className: String? =
if (owners.isNotEmpty()) return owners
if (className != null) return getCodeOwners(packageName, null)
val index = packagePath.lastIndexOf('/')
if (index < 0) return null
if (index < 0) return emptySet()
return getCodeOwners(packagePath.substring(0, index), null)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package io.github.gmazzo.codeowners

import kotlin.reflect.KClass

actual val KClass<*>.codeOwners: Set<String>
get() = annotations.asSequence()
.filterIsInstance<CodeOwner>()
.map { it.value }

actual val Throwable.codeOwners: Set<String>
get() = this::class.codeOwners
1 change: 1 addition & 0 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ kotlin = "1.9.21"
[libraries]
jgit = "org.eclipse.jgit:org.eclipse.jgit:6.7.0.202309050840-r"
junit-bom = "org.junit:junit-bom:5.8.1"
kotlin-reflect = { module = "org.jetbrains.kotlin:kotlin-reflect", version.ref = "kotlin" }
kotlin-test = { module = "org.jetbrains.kotlin:kotlin-test", version.ref = "kotlin" }

[plugins]
Expand Down

0 comments on commit eae88d3

Please sign in to comment.