Skip to content

Commit a245d90

Browse files
authored
Refactoring of gradle scripts to add 'jvm' target to cli (#417)
### What's done: - adding new jvm target to improve Idea coding experience
1 parent 6385eda commit a245d90

16 files changed

Lines changed: 161 additions & 83 deletions

File tree

build.gradle.kts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
1-
21
import com.saveourtool.save.buildutils.configureDiktat
32
import com.saveourtool.save.buildutils.configurePublishing
43
import com.saveourtool.save.buildutils.configureVersioning
54
import com.saveourtool.save.buildutils.createDetektTask
65
import com.saveourtool.save.buildutils.installGitHooks
76

7+
// version generation
88
configureVersioning()
9-
9+
// checks and validations
1010
configureDiktat()
1111
createDetektTask()
1212
installGitHooks()
13-
13+
// publishing to maven central
1414
configurePublishing()

buildSrc/src/main/kotlin/com/saveourtool/save/buildutils/JacocoConfiguration.kt

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,13 @@
22
* Configure JaCoCo for code coverage calculation
33
*/
44

5+
@file:Suppress("FILE_WILDCARD_IMPORTS")
6+
57
package com.saveourtool.save.buildutils
68

79
import org.gradle.api.Project
810
import org.gradle.api.tasks.testing.Test
9-
import org.gradle.kotlin.dsl.apply
10-
import org.gradle.kotlin.dsl.configure
11-
import org.gradle.kotlin.dsl.get
12-
import org.gradle.kotlin.dsl.getByType
13-
import org.gradle.kotlin.dsl.getValue
14-
import org.gradle.kotlin.dsl.named
15-
import org.gradle.kotlin.dsl.provideDelegate
16-
import org.gradle.kotlin.dsl.register
11+
import org.gradle.kotlin.dsl.*
1712
import org.gradle.testing.jacoco.plugins.JacocoPlugin
1813
import org.gradle.testing.jacoco.plugins.JacocoPluginExtension
1914
import org.gradle.testing.jacoco.plugins.JacocoTaskExtension
@@ -37,7 +32,8 @@ fun Project.configureJacoco() {
3732
isEnabled = true
3833
}
3934
}
40-
val jacocoTestReportTask by tasks.register<JacocoReport>("jacocoTestReport") {
35+
36+
val configure: JacocoReport.() -> Unit = {
4137
executionData(jvmTestTask.extensions.getByType(JacocoTaskExtension::class.java).destinationFile)
4238
// todo: include platform-specific source sets
4339
additionalSourceDirs(kotlin.sourceSets["commonMain"].kotlin.sourceDirectories)
@@ -49,6 +45,18 @@ fun Project.configureJacoco() {
4945
html.required.set(true)
5046
}
5147
}
48+
49+
// `application` plugin creates jacocoTestReport task in plugin section (this is definitely incorrect behavior)
50+
// AFTER that in "com.saveourtool.save.buildutils.kotlin-library" we try to register this task once again and fail
51+
// so the order of plugins in `apply` is critically important
52+
val jacocoTestReportTask = if (project.name == "save-cli") {
53+
val jacocoTestReportTask by tasks.named("jacocoTestReport", configure)
54+
jacocoTestReportTask
55+
} else {
56+
val jacocoTestReportTask by tasks.register("jacocoTestReport", configure)
57+
jacocoTestReportTask
58+
}
59+
5260
jvmTestTask.finalizedBy(jacocoTestReportTask)
5361
jacocoTestReportTask.dependsOn(jvmTestTask)
5462
}

gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,4 @@ kotlin.mpp.stability.nowarn=true
1313
kotlin.native.cacheKind.linuxX64=none
1414
kotlin.mpp.hierarchicalStructureSupport=true
1515
# making custom cinterop libraries available in shared source sets
16-
kotlin.mpp.enableCInteropCommonization=true
16+
kotlin.mpp.enableCInteropCommonization=true

save-cli/build.gradle.kts

Lines changed: 62 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,33 @@
1-
import com.saveourtool.save.buildutils.configureDetekt
2-
import com.saveourtool.save.buildutils.configureDiktat
3-
import com.saveourtool.save.buildutils.configurePublishing
4-
51
import org.gradle.nativeplatform.platform.internal.DefaultNativePlatform.getCurrentOperatingSystem
6-
import org.jetbrains.kotlin.gradle.targets.jvm.tasks.KotlinJvmTest
2+
import org.gradle.nativeplatform.platform.internal.DefaultOperatingSystem
3+
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
74

85
plugins {
9-
kotlin("multiplatform")
6+
application
7+
id("com.saveourtool.save.buildutils.kotlin-library")
108
}
119

1210
kotlin {
13-
jvm()
1411
val os = getCurrentOperatingSystem()
15-
val saveTarget = listOf(when {
16-
os.isWindows -> mingwX64()
17-
os.isLinux -> linuxX64()
18-
os.isMacOsX -> macosX64()
19-
else -> throw GradleException("Unknown operating system $os")
20-
})
2112

22-
configure(saveTarget) {
23-
binaries {
24-
val name = "save-${project.version}-${this@configure.name}"
25-
executable {
26-
this.baseName = name
27-
entryPoint = "com.saveourtool.save.cli.main"
28-
}
29-
}
30-
}
13+
jvm()
14+
15+
registerNativeBinaries(os, this)
3116

3217
sourceSets {
33-
all {
34-
languageSettings.optIn("kotlin.RequiresOptIn")
18+
val commonMain by getting {
19+
dependencies {
20+
api(libs.okio)
21+
}
3522
}
36-
val jvmMain by getting
3723

38-
val commonMain by getting
39-
val nativeMain by creating {
40-
dependsOn(commonMain)
24+
val commonNonJsMain by getting {
4125
dependencies {
4226
implementation(projects.saveCore)
27+
implementation(projects.saveCommon)
4328
implementation(libs.kotlinx.serialization.properties)
4429
}
4530
}
46-
saveTarget.forEach {
47-
getByName("${it.name}Main").dependsOn(nativeMain)
48-
}
49-
50-
val commonTest by getting
5131

5232
val jvmTest by getting {
5333
dependencies {
@@ -61,6 +41,46 @@ kotlin {
6141
}
6242
}
6343

44+
linkProperExecutable(os)
45+
46+
tasks.withType<Test>().configureEach {
47+
dependsOn(":save-core:downloadTestResources")
48+
}
49+
}
50+
51+
application {
52+
mainClass.set("com.saveourtool.save.cli.SaveCliRunnerKt")
53+
}
54+
55+
/**
56+
* @param os
57+
* @param kotlin
58+
* @throws GradleException
59+
*/
60+
fun registerNativeBinaries(os: DefaultOperatingSystem, kotlin: KotlinMultiplatformExtension) {
61+
val saveTarget = when {
62+
os.isWindows -> kotlin.mingwX64()
63+
os.isLinux -> kotlin.linuxX64()
64+
os.isMacOsX -> kotlin.macosX64()
65+
else -> throw GradleException("Unknown operating system $os")
66+
}
67+
68+
configure(listOf(saveTarget)) {
69+
binaries {
70+
val name = "save-${project.version}-${this@configure.name}"
71+
executable {
72+
this.baseName = name
73+
entryPoint = "com.saveourtool.save.cli.main"
74+
}
75+
}
76+
}
77+
}
78+
79+
/**
80+
* @param os
81+
* @throws GradleException
82+
*/
83+
fun linkProperExecutable(os: DefaultOperatingSystem) {
6484
val linkReleaseExecutableTaskProvider = when {
6585
os.isLinux -> tasks.getByName("linkReleaseExecutableLinuxX64")
6686
os.isWindows -> tasks.getByName("linkReleaseExecutableMingwX64")
@@ -71,6 +91,13 @@ kotlin {
7191
dependsOn(linkReleaseExecutableTaskProvider)
7292
}
7393

94+
// disable building of some binaries to speed up build
95+
// possible values: `all` - build all binaries, `debug` - build only debug binaries
96+
val enabledExecutables = if (hasProperty("enabledExecutables")) property("enabledExecutables") as String else null
97+
if (enabledExecutables != null && enabledExecutables != "all") {
98+
linkReleaseExecutableTaskProvider.enabled = false
99+
}
100+
74101
// Integration test should be able to have access to binary during the execution. Also we use here the debug version,
75102
// in aim to have ability to run it in CI, which operates only with debug versions
76103
tasks.getByName("jvmTest").dependsOn(tasks.getByName(
@@ -81,23 +108,8 @@ kotlin {
81108
else -> throw GradleException("Unknown operating system $os")
82109
}
83110
))
84-
85-
tasks.withType<Test>().configureEach {
86-
dependsOn(":save-core:downloadTestResources")
87-
}
88-
89-
// disable building of some binaries to speed up build
90-
// possible values: `all` - build all binaries, `debug` - build only debug binaries
91-
val enabledExecutables = if (hasProperty("enabledExecutables")) property("enabledExecutables") as String else null
92-
if (enabledExecutables != null && enabledExecutables != "all" || enabledExecutables == "debug") {
93-
linkReleaseExecutableTaskProvider.enabled = false
94-
}
95111
}
96112

97-
configurePublishing()
98-
configureDiktat()
99-
configureDetekt()
100-
101-
tasks.withType<KotlinJvmTest> {
102-
useJUnitPlatform()
113+
application {
114+
mainClass.set("com.saveourtool.save.cli.SaveCliRunnerKt")
103115
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/**
2+
* This file is a workaround to several issues that we don't have time to investigate:
3+
* 1) shitty IDEA bugs that prevent resolving of FileSystem.SYSTEM
4+
* 2) gradle kotlin plugin bugs that block the resolving of FileSystem.SYSTEM in native projects
5+
*/
6+
7+
package com.saveourtool.save.cli
8+
9+
import okio.FileSystem
10+
11+
// see the description of this file
12+
expect val fs: FileSystem

save-cli/src/nativeMain/kotlin/com/saveourtool/save/cli/ExitCodes.kt renamed to save-cli/src/commonNonJsMain/kotlin/com/saveourtool/save/cli/ExitCodes.kt

File renamed without changes.

save-cli/src/nativeMain/kotlin/com/saveourtool/save/cli/SaveCliRunner.kt renamed to save-cli/src/commonNonJsMain/kotlin/com/saveourtool/save/cli/SaveCliRunner.kt

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,12 @@
44

55
package com.saveourtool.save.cli
66

7+
import com.saveourtool.save.cli.config.of
78
import com.saveourtool.save.core.Save
89
import com.saveourtool.save.core.config.SaveProperties
9-
import com.saveourtool.save.core.config.of
10-
import okio.FileSystem
1110

1211
fun main(args: Array<String>) {
1312
val config = SaveProperties.of(args)
14-
Save(config, FileSystem.SYSTEM)
13+
Save(config, fs)
1514
.performAnalysis()
1615
}

save-cli/src/nativeMain/kotlin/com/saveourtool/save/core/config/SavePropertiesExt.kt renamed to save-cli/src/commonNonJsMain/kotlin/com/saveourtool/save/cli/config/SavePropertiesExt.kt

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,17 @@
22
* Utilities to work with SAVE config in CLI mode
33
*/
44

5-
package com.saveourtool.save.core.config
5+
package com.saveourtool.save.cli.config
66

77
import com.saveourtool.save.cli.ExitCodes
8+
import com.saveourtool.save.cli.fs
89
import com.saveourtool.save.cli.logging.logErrorAndExit
10+
import com.saveourtool.save.core.config.SaveProperties
11+
import com.saveourtool.save.core.config.resolveSaveTomlConfig
912
import com.saveourtool.save.core.logging.logDebug
1013
import com.saveourtool.save.core.logging.logType
1114

1215
import okio.FileNotFoundException
13-
import okio.FileSystem
1416
import okio.IOException
1517
import okio.Path.Companion.toPath
1618

@@ -20,7 +22,7 @@ import okio.Path.Companion.toPath
2022
*/
2123
fun SaveProperties.Companion.of(args: Array<String>): SaveProperties {
2224
val configFromCli = try {
23-
parseArgs(FileSystem.SYSTEM, args)
25+
parseArgs(fs, args)
2426
} catch (e: IOException) {
2527
return logErrorAndExit(
2628
ExitCodes.INVALID_CONFIGURATION,
@@ -42,7 +44,7 @@ fun SaveProperties.Companion.of(args: Array<String>): SaveProperties {
4244
private fun SaveProperties.validate(): SaveProperties {
4345
val fullConfigPath = testRootDir.toPath().resolveSaveTomlConfig()
4446
try {
45-
FileSystem.SYSTEM.metadata(fullConfigPath)
47+
fs.metadata(fullConfigPath)
4648
} catch (e: FileNotFoundException) {
4749
return logErrorAndExit(
4850
ExitCodes.INVALID_CONFIGURATION, "Not able to find configuration file '$fullConfigPath'." +
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
/**
2+
* Logging utilities specific for native code.
3+
*/
4+
5+
package com.saveourtool.save.cli.logging
6+
7+
import com.saveourtool.save.cli.ExitCodes
8+
9+
/**
10+
* Log [message] with level ERROR and exit process with code [exitCode]
11+
*
12+
* @param exitCode exit code
13+
* @param message message to log
14+
* @return nothing, program terminates in this method
15+
*/
16+
@Deprecated("never use this method in save-core as it can lead to a break of save-cloud application")
17+
expect fun logErrorAndExit(exitCode: ExitCodes, message: String): Nothing
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
/**
2+
* This file is a workaround to several issues that we don't have time to investigate:
3+
* 1) shitty IDEA bugs that prevent resolving of FileSystem.SYSTEM
4+
* 2) gradle kotlin plugin bugs that block the resolving of FileSystem.SYSTEM in native projects
5+
*/
6+
7+
package com.saveourtool.save.cli
8+
9+
import okio.FileSystem
10+
11+
actual val fs: FileSystem = FileSystem.SYSTEM

0 commit comments

Comments
 (0)