Skip to content
This repository was archived by the owner on Jul 5, 2025. It is now read-only.

Commit a0385c1

Browse files
authored
Merge aa5d9ed into 308fcd6
2 parents 308fcd6 + aa5d9ed commit a0385c1

File tree

86 files changed

+3184
-461
lines changed

Some content is hidden

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

86 files changed

+3184
-461
lines changed

.github/workflows/build-ga.yaml

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,14 @@ jobs:
3737
- name: Lint check
3838
run: ./gradlew ktlintCheck
3939

40-
- name: Build all flavors
40+
- name: Build all targets
4141
run: ./gradlew assemble
4242

43-
- name: Run all tests
44-
run: ./gradlew allTests
43+
- name: Run JVM tests
44+
run: ./gradlew jvmTest
45+
46+
# - name: Run Mac/Native tests
47+
# run: ./gradlew macNativeTest
4548

4649
- name: Prepare for Publishing
4750
run: ./gradlew prepareForPublish

.github/workflows/build-pr.yaml

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,14 @@ jobs:
3737
- name: Lint check
3838
run: ./gradlew ktlintCheck
3939

40-
- name: Build all flavors
40+
- name: Build all targets
4141
run: ./gradlew assemble
4242

43-
- name: Run all tests
44-
run: ./gradlew allTests
43+
- name: Run JVM tests
44+
run: ./gradlew jvmTest
45+
46+
# - name: Run Mac/Native tests
47+
# run: ./gradlew macNativeTest
4548

4649
- name: Prepare for Publishing
4750
run: ./gradlew prepareForPublish

build.gradle.kts

Lines changed: 63 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,10 @@ import org.jetbrains.kotlin.gradle.dsl.JvmTarget
99
import org.jetbrains.kotlin.gradle.dsl.KotlinTargetContainerWithPresetFunctions
1010
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJvmCompilation
1111

12-
// Kudos to @JMFayard for figuring out lots of KMP stuff!
13-
1412
plugins {
1513
application
16-
kotlin("multiplatform") version "1.8.+" // when replacing, search the whole file for "8"
17-
kotlin("plugin.serialization") version "1.8.+"
14+
kotlin("multiplatform") version "1.9.+" // when replacing, search the whole file for "9"
15+
kotlin("plugin.serialization") version "1.9.+"
1816
id("com.apollographql.apollo3") version "4.+"
1917
id("com.github.johnrengelman.shadow") version "8.+"
2018
id("org.jlleitschuh.gradle.ktlint") version "11.+"
@@ -30,12 +28,16 @@ application {
3028
mainClass.set("MainKt")
3129
}
3230

33-
group = Out.group
34-
version = Out.version
31+
val env = Env()
32+
val output = Output(env)
33+
val configurator = Configurator(env, output)
34+
35+
group = output.group
36+
version = output.version
3537

3638
kotlin {
37-
val jvmTarget = Configurator.configureJvmTarget(this)
38-
val nativeTarget = Configurator.configureNativeTarget(this)
39+
val jvmTarget = configurator.configureJvmTarget(this)
40+
val nativeTarget = configurator.configureNativeTarget(this)
3941

4042
sourceSets {
4143

@@ -44,14 +46,14 @@ kotlin {
4446
implementation(kotlin("stdlib-common"))
4547
implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.+")
4648
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.+")
47-
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.+")
49+
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.5.+")
4850
implementation("io.ktor:ktor-client-core:2.3.+")
4951
implementation("io.ktor:ktor-client-auth:2.3.+")
5052
implementation("io.ktor:ktor-client-logging:2.3.+")
5153
implementation("io.ktor:ktor-client-serialization:2.3.+")
5254
implementation("io.ktor:ktor-client-content-negotiation:2.3.+")
5355
implementation("io.ktor:ktor-serialization-kotlinx-json:2.3.+")
54-
implementation("com.squareup.okio:okio:3.+")
56+
implementation("com.squareup.okio:okio:3.4.+")
5557
implementation("net.mamoe.yamlkt:yamlkt:0.+")
5658
implementation("com.apollographql.apollo3:apollo-api:4.+")
5759
implementation("com.apollographql.apollo3:apollo-runtime:4.+")
@@ -62,7 +64,7 @@ kotlin {
6264
dependsOn(commonMain)
6365
dependencies {
6466
implementation(kotlin("test"))
65-
implementation("com.squareup.okio:okio-fakefilesystem:3.+")
67+
implementation("com.squareup.okio:okio-fakefilesystem:3.4.+")
6668
implementation("com.willowtreeapps.assertk:assertk:0.+")
6769
}
6870
}
@@ -122,7 +124,7 @@ kotlin {
122124

123125
// make the JVM 'jar' task work
124126
withType<ShadowJar> {
125-
archiveBaseName.set(Out.artifact)
127+
archiveBaseName.set(output.artifact)
126128
archiveClassifier.set("")
127129
archiveVersion.set("")
128130

@@ -138,8 +140,8 @@ kotlin {
138140
register<Copy>("prepareForPublish") {
139141
group = "distribution"
140142
description = "Prepare the project outputs for publishing"
141-
val distributionsDir = Out.getDistributionsDir()
142-
val artifactName = Out.artifact
143+
val distributionsDir = output.getDistributionsDir()
144+
val artifactName = output.artifact
143145

144146
val dependentTasks = mutableListOf("shadowJar")
145147
if (nativeTarget != null) {
@@ -149,13 +151,13 @@ kotlin {
149151

150152
// take native if available
151153
if (nativeTarget != null) {
152-
from(Out.getBinaryDir(nativeTarget.name)) {
154+
from(output.getBinaryDir(nativeTarget.name)) {
153155
include("$artifactName.kexe")
154156
rename { if (it.endsWith(".kexe")) artifactName else it }
155157
}
156158
}
157159
// take JAR anyway
158-
from(Out.getJarDir()) {
160+
from(output.getJarDir()) {
159161
include("$artifactName.jar")
160162
}
161163

@@ -169,14 +171,14 @@ kotlin {
169171
register<Copy>("install") {
170172
group = "application"
171173
description = "Build the native executable and install it"
172-
val installDir = Out.getInstallDir()
173-
val artifactName = Out.artifact
174+
val installDir = output.getInstallDir()
175+
val artifactName = output.artifact
174176

175177
if (nativeTarget == null) {
176178
// JVM: copy the file to the root directory
177179
dependsOn("shadowJar")
178180

179-
val jarDir = Out.getJarDir()
181+
val jarDir = output.getJarDir()
180182
from(jarDir) {
181183
include("$artifactName.jar")
182184
}
@@ -189,7 +191,7 @@ kotlin {
189191
// Native: copy the file to the programs directory
190192
dependsOn("${nativeTarget.name}Binaries")
191193

192-
val binaryDir = Out.getBinaryDir(nativeTarget.name)
194+
val binaryDir = output.getBinaryDir(nativeTarget.name)
193195
from(binaryDir) {
194196
include("$artifactName.kexe")
195197
rename { artifactName }
@@ -234,21 +236,21 @@ apollo {
234236

235237
sqldelight {
236238
databases {
237-
create(Out.artifact) {
238-
packageName.set(Out.artifact)
239+
create(output.artifact) {
240+
packageName.set(output.artifact)
239241
}
240242
}
241243
}
242244

243245
githubRelease {
244-
val writeToken = OS.env("GITHUB_TOKEN", "<invalid>")
246+
val writeToken = env.sysVar("GITHUB_TOKEN") { "<invalid>" }
245247
if (writeToken == "<invalid>") println("Set \$GITHUB_TOKEN to enable GitHub releases.")
246248

247-
val commitish = OS.env("GITHUB_SHA", default = "master")
248-
val prNumber = OS.env("GITHUB_PR_NUMBER", default = "")
249+
val commitish = env.sysVar("GITHUB_SHA") { "master" }
250+
val prNumber = env.sysVar("GITHUB_PR_NUMBER")
249251
val buildMoment = LocalDateTime.now()
250252
val nowTag = buildMoment.toString("yyyy-MM-dd-HH-mm-ss")
251-
val quality = OS.env("BUILD_QUALITY", default = "Development")
253+
val quality = env.sysVar("BUILD_QUALITY") { "Development" }
252254
var directoryPrefix = ""
253255
var prNumberPrefix = ""
254256
var timestampSuffix = ""
@@ -266,12 +268,12 @@ githubRelease {
266268
timestampSuffix = "/$nowTag"
267269
}
268270
}
269-
val tag = "${directoryPrefix}${prNumberPrefix}v${Out.version}$timestampSuffix"
270-
val name = "[$quality] v${Out.version}"
271+
val tag = "${directoryPrefix}${prNumberPrefix}v${output.version}$timestampSuffix"
272+
val name = "[$quality] v${output.version}"
271273

272274
token(writeToken)
273-
owner(Out.repoOwner)
274-
repo(Out.repoName)
275+
owner(output.repoOwner)
276+
repo(output.repoName)
275277
tagName(tag)
276278
releaseName(name)
277279
targetCommitish(commitish)
@@ -316,10 +318,10 @@ githubRelease {
316318
}
317319
)
318320

319-
val distributionsDir = Out.getDistributionsDir()
320-
val jarFile = file("$distributionsDir/${Out.artifact}.jar")
321+
val distributionsDir = output.getDistributionsDir()
322+
val jarFile = file("$distributionsDir/${output.artifact}.jar")
321323
val configFile = file("src/commonMain/resources/sample.config.yaml")
322-
val unixFile = file("$distributionsDir/${Out.artifact}")
324+
val unixFile = file("$distributionsDir/${output.artifact}")
323325
val toInclude = mutableListOf(jarFile, configFile)
324326
if (unixFile.exists()) toInclude += unixFile
325327
releaseAssets(*toInclude.toTypedArray())
@@ -329,39 +331,44 @@ githubRelease {
329331

330332
// region Utils
331333

332-
object OS {
334+
class Env {
333335
enum class Platform(val targetName: String) { JVM("jvm"), MAC("macNative") }
334336
enum class Arch { X86, ARM }
335337

336338
val currentPlatform = when {
337-
prop("os.name") == "Mac OS X" -> Platform.MAC
339+
sysProp("os.name") == "Mac OS X" -> Platform.MAC
338340
else -> Platform.JVM
339341
}
340342

341343
val currentArch = when {
342-
prop("os.arch") in setOf("arm64", "aarch64") -> Arch.ARM
344+
sysProp("os.arch") in setOf("arm64", "aarch64") -> Arch.ARM
343345
else -> Arch.X86
344346
}
345347

346-
fun prop(name: String, default: String = "") = System.getProperty(name)
348+
inline fun sysProp(name: String, default: () -> String = { "" }) = System.getProperty(name)
347349
.takeIf { !it.isNullOrBlank() }
348-
?: default
350+
?: default()
349351

350-
fun env(name: String, default: String) = System.getenv(name)
352+
inline fun gradleProp(name: String, default: () -> String = { "" }) = providers.gradleProperty(name).orNull
351353
.takeIf { !it.isNullOrBlank() }
352-
?: default
354+
?: default()
355+
356+
inline fun sysVar(name: String, default: () -> String = { "" }) = System.getenv(name)
357+
.takeIf { !it.isNullOrBlank() }
358+
?: default()
359+
353360
}
354361

355-
object Out {
356-
val group = OS.env("PROJECT_GROUP", default = "xyz.marinkovic.milos")
357-
val artifact = OS.env("PROJECT_ARTIFACT", default = "codestats")
358-
val version = OS.env("PROJECT_VERSION", default = "0.3.0")
359-
val repoOwner = OS.env("REPO_OWNER", default = "milosmns")
360-
val repoName = OS.env("REPO_NAME", default = "code-stats")
362+
class Output(private val env: Env) {
363+
val group = env.sysVar("PROJECT_GROUP") { env.gradleProp("config.group") }
364+
val artifact = env.sysVar("PROJECT_ARTIFACT") { env.gradleProp("config.artifact") }
365+
val version = env.sysVar("PROJECT_VERSION") { env.gradleProp("config.version") }
366+
val repoOwner = env.sysVar("REPO_OWNER") { env.gradleProp("config.gitHubRepoOwner") }
367+
val repoName = env.sysVar("REPO_NAME") { env.gradleProp("config.gitHubRepoName") }
361368

362-
fun getInstallDir() = when (OS.currentPlatform) {
363-
OS.Platform.MAC -> "/usr/local/bin"
364-
else -> OS.prop("user.dir")
369+
fun getInstallDir() = when (env.currentPlatform) {
370+
Env.Platform.MAC -> "/usr/local/bin"
371+
else -> env.sysProp("user.dir")
365372
}.replace('/', File.separatorChar)
366373

367374
fun getJarDir() = "build/libs"
@@ -374,10 +381,10 @@ object Out {
374381
.replace('/', File.separatorChar)
375382
}
376383

377-
object Configurator {
384+
class Configurator(private val env: Env, private val output: Output) {
378385

379386
fun configureJvmTarget(container: KotlinTargetContainerWithPresetFunctions) =
380-
container.jvm(OS.Platform.JVM.targetName) {
387+
container.jvm(Env.Platform.JVM.targetName) {
381388
compilations.all {
382389
kotlinOptions.jvmTarget = "17"
383390
compilerOptions.configure {
@@ -388,16 +395,16 @@ object Configurator {
388395
}
389396

390397
fun configureNativeTarget(container: KotlinTargetContainerWithPresetFunctions) =
391-
when (OS.currentPlatform) {
392-
OS.Platform.MAC -> when (OS.currentArch) {
393-
OS.Arch.X86 -> container.macosX64(OS.currentPlatform.targetName)
394-
OS.Arch.ARM -> container.macosArm64(OS.currentPlatform.targetName)
398+
when (env.currentPlatform) {
399+
Env.Platform.MAC -> when (env.currentArch) {
400+
Env.Arch.X86 -> container.macosX64(env.currentPlatform.targetName)
401+
Env.Arch.ARM -> container.macosArm64(env.currentPlatform.targetName)
395402
}
396403

397404
else -> null
398405
}?.also { target ->
399406
target.binaries {
400-
executable(Out.artifact) {
407+
executable(output.artifact) {
401408
entryPoint = "main"
402409
}
403410
all {

gradle.properties

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,13 @@
1+
# Language properties
12
kotlin.code.style=official
23
kotlin.mpp.enableCInteropCommonization=true
34

5+
# Engine properties
46
org.gradle.jvmargs=-Xmx4096m
7+
8+
# Project properties
9+
config.group = xyz.marinkovic.milos
10+
config.artifact = codestats
11+
config.version = 0.4.0
12+
config.gitHubRepoOwner = milosmns
13+
config.gitHubRepoName = code-stats

src/commonMain/kotlin/Main.kt

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import calculator.di.provideCycleTimeCalculator
1+
import calculator.di.provideGenericLongMetricCalculators
22
import components.data.TeamHistoryConfig
33
import history.TeamHistory
44
import history.github.di.provideGitHubHistory
@@ -24,24 +24,23 @@ fun main(): Unit = runBlocking {
2424
try {
2525
// NETWORK EXPERIMENTS
2626
// println("Loading team history...")
27-
// val fetchedUnsorted = mutableListOf<Repository>()
27+
// val fetched = mutableListOf<Repository>()
2828
// teamHistoryConfig.teams.forEach { team ->
2929
// println("Loading for team ${team.title}...")
3030
// team.discussionRepositories.forEach { repoName ->
3131
// println("Loading discussion repository $repoName...")
32-
// fetchedUnsorted += history.fetchRepository(repoName, includeCodeReviews = false, includeDiscussions = true)
32+
// fetched += history.fetchRepository(repoName, includeCodeReviews = false, includeDiscussions = true)
3333
// }
3434
// team.codeRepositories.forEach { repoName ->
3535
// println("Loading code repository $repoName...")
36-
// fetchedUnsorted += history.fetchRepository(repoName, includeCodeReviews = true, includeDiscussions = false)
36+
// fetched += history.fetchRepository(repoName, includeCodeReviews = true, includeDiscussions = false)
3737
// }
3838
// }
3939

4040
// STORAGE EXPERIMENTS
41-
// val storage = provideStoredHistory(teamHistoryConfig)
41+
val storage = provideStoredHistory(teamHistoryConfig)
4242
// storage.purgeAll()
4343
// val storedUnsorted = mutableListOf<Repository>()
44-
// val fetched = fetchedUnsorted.sorted()
4544
// fetched.forEach {
4645
// storage.storeRepositoryDeep(it)
4746
// storedUnsorted += storage.fetchRepository(
@@ -50,9 +49,7 @@ fun main(): Unit = runBlocking {
5049
// includeDiscussions = true,
5150
// )
5251
// }
53-
// val stored = storedUnsorted.sorted()
5452

55-
val storage = provideStoredHistory(teamHistoryConfig)
5653
val stored = storage.fetchAllRepositories().map {
5754
storage.fetchRepository(
5855
it.name,
@@ -68,11 +65,12 @@ fun main(): Unit = runBlocking {
6865
}
6966

7067
// OTHER EXPERIMENTS
71-
val cycleTimeCalculator = provideCycleTimeCalculator()
72-
val cycleTime = cycleTimeCalculator.calculate(stored)
73-
println("\n== Cycle Time ==")
74-
println(cycleTime.simpleFormat)
75-
println("-- CYCLE TIME --\n")
68+
provideGenericLongMetricCalculators().forEach {
69+
val metric = it.calculate(stored)
70+
println("\n== ${metric.name} ==")
71+
println(metric.simpleFormat)
72+
println("-- ${metric.name} --\n")
73+
}
7674
} catch (e: Throwable) {
7775
println("CRITICAL FAILURE! \n\n * ${e.message} * \n\n")
7876
e.printStackTrace()

0 commit comments

Comments
 (0)