build: Simplify build infrastructure for command line tools (#613)

Provide a build convention plugin for command line tools, and use
`libs.versions.toml` for command line tool dependencies. Adjust the
individual tool `build.gradle.kts` files accordingly.

Remove unnecessary `gradle.properties` and `settings.gradle` files for
projects that are included as subprojects, not included builds.

Add a trivial test for each command line tool so there are tests to run
and provide some confidence that automated library upgrades don't break
command line tool compilation.
This commit is contained in:
Nik Clayton 2024-04-15 15:06:55 +02:00 committed by GitHub
parent 4d7f8d4682
commit 5f198b0d90
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
13 changed files with 120 additions and 116 deletions

View File

@ -63,5 +63,9 @@ gradlePlugin {
id = "pachli.android.lint"
implementationClass = "AndroidLintConventionPlugin"
}
register("tool") {
id = "pachli.tool"
implementationClass = "ToolConventionPlugin"
}
}
}

View File

@ -0,0 +1,38 @@
/*
* Copyright 2024 Pachli Association
*
* This file is a part of Pachli.
*
* This program is free software; you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation; either version 3 of the
* License, or (at your option) any later version.
*
* Pachli is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*
* You should have received a copy of the GNU General Public License along with Pachli; if not,
* see <http://www.gnu.org/licenses>.
*/
import app.pachli.libs
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.kotlin.dsl.dependencies
class ToolConventionPlugin : Plugin<Project> {
override fun apply(target: Project) {
with(target) {
dependencies {
add("implementation", libs.findLibrary("kotlin-logging-jvm").get())
add("implementation", libs.findLibrary("logback").get())
add("implementation", libs.findLibrary("clikt").get())
add("testImplementation", libs.findLibrary("truth").get())
add("testImplementation", libs.findLibrary("junit-jupiter").get())
add("testImplementation", libs.findLibrary("junit-jupiter-params").get())
add("testRuntimeOnly", "org.junit.platform:junit-platform-launcher")
}
}
}
}

View File

@ -73,6 +73,14 @@ turbine = "1.1.0"
unified-push = "2.1.1"
xmlwriter = "1.0.4"
# Tool dependencies
betterparse = "0.4.4"
clikt = "4.3.0"
icu4j = "74.2"
junit-jupiter = "5.10.2"
kotlin-logging-jvm = "6.0.4"
logback = "1.5.3"
[plugins]
aboutlibraries = { id = "com.mikepenz.aboutlibraries.plugin", version.ref = "aboutlibraries" }
android-application = { id = "com.android.application", version.ref = "agp" }
@ -94,6 +102,7 @@ pachli-android-application-flavors = { id = "pachli.android.application.flavors"
pachli-android-hilt = { id = "pachli.android.hilt", version = "unspecified" }
pachli-android-library = { id = "pachli.android.library", version = "unspecified" }
pachli-android-room = { id = "pachli.android.room", version = "unspecified" }
pachli-tool = { id = "pachli.tool", version = "unspecified" }
[libraries]
aboutlibraries-core = { module = "com.mikepenz:aboutlibraries-core", version.ref = "aboutlibraries" }
@ -162,6 +171,8 @@ hilt-android = { module = "com.google.dagger:hilt-android", version.ref = "hilt"
hilt-compiler = { module = "com.google.dagger:hilt-compiler", version.ref = "hilt" }
hilt-android-testing = { module = "com.google.dagger:hilt-android-testing", version.ref = "hilt" }
junit = { module = "junit:junit", version.ref = "junit" }
junit-jupiter = { module = "org.junit.jupiter:junit-jupiter", version.ref = "junit-jupiter" }
junit-jupiter-params = { module = "org.junit.jupiter:junit-jupiter-params", version.ref = "junit-jupiter" }
kotlin-result = { module = "com.michael-bull.kotlin-result:kotlin-result", version.ref = "kotlin-result" }
kotlin-result-coroutines = { module = "com.michael-bull.kotlin-result:kotlin-result-coroutines", version.ref = "kotlin-result" }
kotlinx-coroutines-android = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-android", version.ref = "coroutines" }
@ -200,6 +211,13 @@ turbine = { module = "app.cash.turbine:turbine", version.ref = "turbine" }
unified-push = { module = "com.github.UnifiedPush:android-connector", version.ref = "unified-push" }
xmlwriter = { module = "org.pageseeder.xmlwriter:pso-xmlwriter", version.ref = "xmlwriter" }
# Tool libraries
betterparse = { module = "com.github.h0tk3y.betterParse:better-parse", version.ref = "betterparse" }
clikt = { module = "com.github.ajalt.clikt:clikt", version.ref = "clikt" }
icu4j = { module = "com.ibm.icu:icu4j", version.ref = "icu4j"}
kotlin-logging-jvm = { module = "io.github.oshai:kotlin-logging-jvm", version.ref = "kotlin-logging-jvm" }
logback = { module = "ch.qos.logback:logback-classic", version.ref = "logback" }
# build-logic dependencies
android-gradlePlugin = { module = "com.android.tools.build:gradle", version.ref = "agp" }
kotlin-gradlePlugin = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin", version.ref = "kotlin" }

View File

@ -65,6 +65,7 @@ include(":core:ui")
include(":feature:about")
include(":feature:lists")
include(":feature:login")
include(":tools")
include(":tools:mklanguages")
include(":tools:mkserverversions")
include(":tools:mvstring")

View File

@ -17,17 +17,21 @@
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
alias(libs.plugins.kotlin.jvm)
}
subprojects {
apply(plugin = "kotlin")
apply(plugin = "application")
dependencies {
add("implementation", "com.github.ajalt.clikt:clikt:4.3.0")
}
tasks.withType<KotlinCompile>().configureEach {
kotlinOptions {
freeCompilerArgs = freeCompilerArgs + "-opt-in=kotlin.RequiresOptIn"
}
}
tasks.withType<Test>().configureEach {
useJUnitPlatform()
}
}

View File

@ -15,26 +15,15 @@
* see <http://www.gnu.org/licenses>.
*/
plugins {
alias(libs.plugins.pachli.tool)
}
application {
mainClass = "app.pachli.mklanguages.MainKt"
}
dependencies {
// ICU
implementation("com.ibm.icu:icu4j:74.2")
// Parsing
implementation("com.github.h0tk3y.betterParse:better-parse:0.4.4")
// Logging
implementation("io.github.oshai:kotlin-logging-jvm:6.0.4")
implementation("ch.qos.logback:logback-classic:1.5.3")
// Testing
testImplementation(kotlin("test"))
testImplementation("org.junit.jupiter:junit-jupiter-params:5.10.2") // for parameterized tests
}
tasks.test {
useJUnitPlatform()
implementation(libs.betterparse)
implementation(libs.icu4j)
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2023 Pachli Association
* Copyright 2024 Pachli Association
*
* This file is a part of Pachli.
*
@ -15,16 +15,17 @@
* see <http://www.gnu.org/licenses>.
*/
dependencyResolutionManagement {
repositories {
google()
mavenCentral()
}
versionCatalogs {
create("libs") {
from(files("../gradle/libs.versions.toml"))
}
}
}
package app.pachli.mklanguages
rootProject.name = "checks"
import com.github.ajalt.clikt.testing.test
import com.google.common.truth.Truth.assertThat
import org.junit.jupiter.api.Test
class AppTest {
@Test
fun testHelp() {
val app = App()
val result = app.test("--help")
assertThat(result.statusCode).isEqualTo(0)
}
}

View File

@ -18,8 +18,8 @@
package app.pachli.mklanguages
import com.github.h0tk3y.betterParse.grammar.parseToEnd
import com.google.common.truth.Truth.assertThat
import java.util.stream.Stream
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Nested
import org.junit.jupiter.api.parallel.Execution
import org.junit.jupiter.api.parallel.ExecutionMode
@ -49,7 +49,7 @@ internal class ValuesParserTest {
@ParameterizedTest
@MethodSource("getParams")
fun `returns the expected locale`(params: Params) {
assertEquals(params.expected, parser.parseToEnd(params.filename).locale)
assertThat(parser.parseToEnd(params.filename).locale).isEqualTo(params.expected)
}
}
}

View File

@ -18,6 +18,7 @@
plugins {
alias(libs.plugins.google.ksp)
alias(libs.plugins.apollographql)
alias(libs.plugins.pachli.tool)
}
application {
@ -25,24 +26,10 @@ application {
}
dependencies {
// GraphQL client
implementation(libs.apollo.runtime)
// Logging
implementation("io.github.oshai:kotlin-logging-jvm:6.0.4")
implementation("ch.qos.logback:logback-classic:1.5.3")
// Moshi
implementation(libs.moshi)
ksp(libs.moshi.codegen)
// Testing
testImplementation(kotlin("test"))
testImplementation("org.junit.jupiter:junit-jupiter-params:5.10.2") // for parameterized tests
}
tasks.test {
useJUnitPlatform()
}
apollo {

View File

@ -1,5 +1,5 @@
/*
* Copyright 2023 Pachli Association
* Copyright 2024 Pachli Association
*
* This file is a part of Pachli.
*
@ -15,16 +15,17 @@
* see <http://www.gnu.org/licenses>.
*/
dependencyResolutionManagement {
repositories {
google()
mavenCentral()
}
versionCatalogs {
create("libs") {
from(files("../../gradle/libs.versions.toml"))
}
}
}
package app.pachli.mkserverversions
rootProject.name = "mklanguages"
import com.github.ajalt.clikt.testing.test
import com.google.common.truth.Truth
import org.junit.jupiter.api.Test
class AppTest {
@Test
fun testHelp() {
val app = App()
val result = app.test("--help")
Truth.assertThat(result.statusCode).isEqualTo(0)
}
}

View File

@ -15,20 +15,10 @@
* see <http://www.gnu.org/licenses>.
*/
plugins {
alias(libs.plugins.pachli.tool)
}
application {
mainClass = "app.pachli.mvstring.MainKt"
}
dependencies {
// Logging
implementation("io.github.oshai:kotlin-logging-jvm:6.0.4")
implementation("ch.qos.logback:logback-classic:1.5.3")
// Testing
testImplementation(kotlin("test"))
testImplementation("org.junit.jupiter:junit-jupiter-params:5.10.2") // for parameterized tests
}
tasks.test {
useJUnitPlatform()
}

View File

@ -1,30 +0,0 @@
/*
* Copyright 2023 Pachli Association
*
* This file is a part of Pachli.
*
* This program is free software; you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation; either version 3 of the
* License, or (at your option) any later version.
*
* Pachli is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*
* You should have received a copy of the GNU General Public License along with Pachli; if not,
* see <http://www.gnu.org/licenses>.
*/
dependencyResolutionManagement {
repositories {
google()
mavenCentral()
}
versionCatalogs {
create("libs") {
from(files("../../gradle/libs.versions.toml"))
}
}
}
rootProject.name = "mvstring"

View File

@ -15,16 +15,17 @@
* see <http://www.gnu.org/licenses>.
*/
dependencyResolutionManagement {
repositories {
google()
mavenCentral()
}
versionCatalogs {
create("libs") {
from(files("../../gradle/libs.versions.toml"))
}
}
}
package app.pachli.mvstring
rootProject.name = "mkserverversions"
import com.github.ajalt.clikt.testing.test
import com.google.common.truth.Truth
import org.junit.jupiter.api.Test
class AppTest {
@Test
fun testHelp() {
val app = App()
val result = app.test("--help")
Truth.assertThat(result.statusCode).isEqualTo(0)
}
}