Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
50f4844
Update all dependencies
renovate[bot] Nov 21, 2024
590eb8e
Start
JavierSegoviaCordoba Nov 15, 2024
644432b
Step 1
JavierSegoviaCordoba Nov 15, 2024
b02ea7c
Create Qonto plugin
JavierSegoviaCordoba Nov 13, 2024
fad4726
Create the Gradle task
JavierSegoviaCordoba Nov 13, 2024
f48ff81
Step 2
JavierSegoviaCordoba Nov 15, 2024
02b71a0
Register the Gradle task
JavierSegoviaCordoba Nov 13, 2024
497ee8b
Apply the Gradle Base plugin
JavierSegoviaCordoba Nov 13, 2024
1c456f2
Add Gradle task depends on assemble task
JavierSegoviaCordoba Nov 13, 2024
d9f40a8
Step 3
JavierSegoviaCordoba Nov 15, 2024
4b86796
Change Gradle task to be cacheable
JavierSegoviaCordoba Nov 13, 2024
1c0ffb0
Add inputs to the Gradle task
JavierSegoviaCordoba Nov 13, 2024
9cf3d28
Add inputs configuration
JavierSegoviaCordoba Nov 13, 2024
81cfea2
Add outputs to the Gradle task
JavierSegoviaCordoba Nov 13, 2024
0e5ff12
Step 4
JavierSegoviaCordoba Nov 15, 2024
5c34c4c
Add file generation to the Gradle task
JavierSegoviaCordoba Nov 13, 2024
bb5f089
Add generated dir to the main Kotlin source set (wrong way)
JavierSegoviaCordoba Nov 13, 2024
3315a95
Add the Gradle task outputs to the Kotlin main source set
JavierSegoviaCordoba Nov 13, 2024
88b5c6c
Step 5
JavierSegoviaCordoba Nov 15, 2024
f414231
Create QontoExtension
JavierSegoviaCordoba Nov 13, 2024
2829f4e
Change Gradle task implementation to use Qonto extension data
JavierSegoviaCordoba Nov 13, 2024
d1191a5
Step 6
JavierSegoviaCordoba Nov 15, 2024
14da968
Add option to projectDescription input
JavierSegoviaCordoba Nov 15, 2024
36ba98f
Step 7
JavierSegoviaCordoba Jan 7, 2025
e3132c7
Add version validation report with `Problems` API
JavierSegoviaCordoba Jan 7, 2025
4d96f48
Finish
JavierSegoviaCordoba Jan 7, 2025
323c588
Update dependency gradle to v8.13
renovate[bot] Feb 25, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
976 changes: 976 additions & 0 deletions README.md

Large diffs are not rendered by default.

6 changes: 6 additions & 0 deletions application/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
plugins {
application
alias(libs.plugins.kotlin.jvm)
alias(libs.plugins.qonto)
}

application {
Expand All @@ -9,3 +10,8 @@ application {

group = "com.qonto"
version = "1.0.0"

qonto {
projectDescription = "The Qonto Gradle Workshop!"
// projectDescription.set("Qonto Workshop!") same as above due to the new Kotlin Compiler plugin
}
10 changes: 9 additions & 1 deletion application/src/main/kotlin/com/qonto/application/main.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
package com.qonto.application

fun main() {
println("Hello, world!")
println(
"""
Project data:
Group: ${com.qonto.Project.group}
Name: ${com.qonto.Project.name}
Version: ${com.qonto.Project.version}
Additional lines: ${com.qonto.Project.description}
""".trimIndent()
)
}
9 changes: 9 additions & 0 deletions build-logic/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,15 @@ plugins {
`kotlin-dsl`
}

gradlePlugin {
plugins {
register("QontoPlugin") {
id = "qonto"
implementationClass = "com.qonto.QontoPlugin"
}
}
}

dependencies {
implementation(libs.plugins.kotlin.jvm.artifact)
}
Expand Down
24 changes: 24 additions & 0 deletions build-logic/src/main/kotlin/com/qonto/QontoExtension.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.qonto

import javax.inject.Inject
import org.gradle.api.Project
import org.gradle.api.model.ObjectFactory
import org.gradle.api.provider.Property
import org.gradle.kotlin.dsl.create
import org.gradle.kotlin.dsl.property

open class QontoExtension
@Inject constructor(
objects: ObjectFactory,
) {

val projectDescription: Property<String> =
objects.property<String>().convention("Gradle workshop")

companion object {

const val NAME = "qonto"

fun register(project: Project): QontoExtension = project.extensions.create(NAME)
}
}
143 changes: 143 additions & 0 deletions build-logic/src/main/kotlin/com/qonto/QontoGenerateProjectDataTask.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
@file:Suppress("UnstableApiUsage")

package com.qonto

import javax.inject.Inject
import org.gradle.api.DefaultTask
import org.gradle.api.Project
import org.gradle.api.file.DirectoryProperty
import org.gradle.api.file.ProjectLayout
import org.gradle.api.file.RegularFileProperty
import org.gradle.api.logging.Logger
import org.gradle.api.model.ObjectFactory
import org.gradle.api.plugins.BasePlugin
import org.gradle.api.problems.Problems
import org.gradle.api.problems.Severity
import org.gradle.api.provider.Property
import org.gradle.api.tasks.CacheableTask
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.Internal
import org.gradle.api.tasks.OutputDirectory
import org.gradle.api.tasks.TaskAction
import org.gradle.api.tasks.TaskProvider
import org.gradle.api.tasks.options.Option
import org.gradle.kotlin.dsl.configure
import org.gradle.kotlin.dsl.property
import org.gradle.kotlin.dsl.register
import org.jetbrains.kotlin.gradle.dsl.KotlinProjectExtension
import org.slf4j.LoggerFactory

@CacheableTask
abstract class QontoGenerateProjectDataTask
@Inject constructor(
private val logger: Logger,
objects: ObjectFactory,
layout: ProjectLayout,
) : DefaultTask() {

// Inject via constructor fails in Gradle 8.12, move to constructor when it is fixed
@get:Inject
abstract val problems: Problems

@Input
val projectGroup: Property<String> = objects.property()

@Input
val projectName: Property<String> = objects.property()

@Input
val projectVersion: Property<String> = objects.property()

@Input
@Option(option = "projectDescription", description = "The project description")
val projectDescription: Property<String> = objects.property<String>()

@OutputDirectory
val outputDir: DirectoryProperty =
objects
.directoryProperty()
.convention(layout.buildDirectory.dir("generated/kotlin/com/qonto"))

@Internal
val outputFile: RegularFileProperty =
objects
.fileProperty()
.convention { outputDir.file("Project.kt").get().asFile }

init {
group = "qonto"
description = "Generates the project data"
}

@TaskAction
fun run() {
if (!projectVersion.get().matches(VersionRegex)) {
problems.reporter.throwing {
id("invalid-version", "The project version is invalid")
contextualLabel("The project version '${projectVersion.get()}' is invalid")
severity(Severity.ERROR)
withException(IllegalStateException("The project version is invalid"))
solution("Provide a valid version (example: 'project.version = 1.0.0')")
}
}

logger.quiet("Generating project data...")
logger.quiet("Project group: ${projectGroup.get()}")
logger.quiet("Project name: ${projectName.get()}")
logger.quiet("Project version: ${projectVersion.get()}")
logger.quiet("Project description: ${projectDescription.get()}")

outputDir.get().asFile.mkdirs()
outputFile.get().asFile.apply {
createNewFile()
writeText(
"""
package com.qonto

data object Project {
const val group: String = "${projectGroup.get()}"
const val name: String = "${projectName.get()}"
const val version: String = "${projectVersion.get()}"
const val description: String = "${projectDescription.get()}"
}
""".trimIndent(),
)
}
}

companion object {

const val NAME: String = "generateProjectData"

private val VersionRegex = Regex(
"""^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?${'$'}""",
)

fun register(project: Project, qontoExtension: QontoExtension) {
val generateProjectData: TaskProvider<QontoGenerateProjectDataTask> =
project.tasks.register<QontoGenerateProjectDataTask>(
name = NAME,
LoggerFactory.getLogger("qonto"),
)

generateProjectData.configure {
projectGroup.set(project.provider { "${project.group}" })
projectName.set(project.provider { project.name })
projectVersion.set(project.provider { "${project.version}" })
projectDescription.set(qontoExtension.projectDescription)
}

project.tasks.named(BasePlugin.ASSEMBLE_TASK_NAME).configure {
dependsOn(generateProjectData)
}

project.pluginManager.withPlugin("org.jetbrains.kotlin.jvm") {
project.configure<KotlinProjectExtension> {
sourceSets.named("main") {
kotlin.srcDirs(generateProjectData)
}
}
}
}
}
}
17 changes: 17 additions & 0 deletions build-logic/src/main/kotlin/com/qonto/QontoPlugin.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.qonto

import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.plugins.BasePlugin
import org.gradle.kotlin.dsl.apply

class QontoPlugin : Plugin<Project> {

override fun apply(target: Project) {
val qontoExtension: QontoExtension = QontoExtension.register(target)
target.pluginManager.apply(BasePlugin::class)
target.logger.quiet("Hello from QontoPlugin!")

QontoGenerateProjectDataTask.register(target, qontoExtension)
}
}
3 changes: 2 additions & 1 deletion gradle/libs.versions.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
[versions]
kotlin = "2.0.21"
kotlin = "2.1.10"

[plugins]
kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" }
qonto = { id = "qonto" }
Binary file modified gradle/wrapper/gradle-wrapper.jar
Binary file not shown.
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.11-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
Expand Down
5 changes: 2 additions & 3 deletions gradlew
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,7 @@ done
# shellcheck disable=SC2034
APP_BASE_NAME=${0##*/}
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s
' "$PWD" ) || exit
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit

# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum
Expand Down Expand Up @@ -206,7 +205,7 @@ fi
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'

# Collect all arguments for the java command:
# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
# and any embedded shellness will be escaped.
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
# treated as '${Hostname}' itself on the command line.
Expand Down
Loading