Versionsinfo in META-INF/MANIFEST.MF eintragen

This commit is contained in:
Hartmut Bauer committed 2025-03-12 00:22:03 +01:00
1 parent f5b99c3038
commit 0ec2193cc7
6 files changed
+116 -121

No files matched your search

+17 -12
View File
@@ -1,27 +1,32 @@
import java.time.Instant
/*
* This file was generated by the Gradle 'init' task.
*
* This is a general purpose Gradle build.
* To learn more about Gradle by exploring our Samples at https://docs.gradle.org/8.6/samples
*/
plugins {
`kotlin-dsl`
`maven-publish`
}
repositories {
mavenCentral()
maven("https://nexus.keinekekse.net/repository/maven-public/")
}
group = "net.keinekekse"
version = libs.versions.versionplugin.get()
version = masterLibs.versions.versionPluginVersion.get()
description = "Adds version information to the project."
project.ext.set("displayname", "Version-Plugin")
project.ext.set("copyright", "(c) 2024 Hartmut Bauer")
project.ext.set("buildTimestamp", Instant.now().toString())
extra["displayname"] = "Version-Plugin"
extra["copyright"] = "Copyright (c) 2024-2025 Hartmut Bauer"
extra["buildTimestamp"] = Instant.now().toString()
publishing {
repositories {
maven {
credentials {
username = "admin"
password = "admin123"
}
url = uri("https://nexus.keinekekse.net/repository/maven-releases/")
}
}
}
gradlePlugin {
plugins {
create("version-plugin") {
@@ -33,6 +38,6 @@ gradlePlugin {
java {
toolchain {
languageVersion.set(JavaLanguageVersion.of(17))
languageVersion.set(JavaLanguageVersion.of(masterLibs.versions.javaVersion.get()))
}
}
+1
View File
@@ -0,0 +1 @@
kotlin.code.style=official
+1 -1
View File
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
+6 -9
View File
@@ -1,16 +1,13 @@
/*
* This file was generated by the Gradle 'init' task.
*
* The settings file is used to specify which projects to include in your build.
* For more detailed information on multi-project builds, please refer to https://docs.gradle.org/8.6/userguide/multi_project_builds.html in the Gradle documentation.
*/
rootProject.name = "version-plugin"
dependencyResolutionManagement {
repositories {
maven("https://nexus.keinekekse.net/repository/maven-public/")
}
versionCatalogs {
create("libs") {
from(files("../../gradle-deps/libs.versions.toml"))
create("masterLibs") {
from("net.keinekekse:version-catalog:56")
}
}
}
@@ -3,127 +3,129 @@ package net.keinekekse.version
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.file.RegularFile
import org.gradle.api.java.archives.Manifest
import org.gradle.api.tasks.bundling.Jar
import org.gradle.api.tasks.bundling.War
import org.gradle.kotlin.dsl.extra
import org.gradle.kotlin.dsl.getValue
import org.gradle.kotlin.dsl.named
import java.io.FileInputStream
import java.io.FileOutputStream
import java.io.OutputStreamWriter
import java.time.Instant
import java.util.*
class VersionPlugin : Plugin<Project> {
private lateinit var versionFileName: String
private val buildNumProp = "buildNumber"
private val addTaskName = "addVersion"
private var isWar = false
companion object {
private const val BUILDNUMBER_FILE = "buildnumber.properties"
private const val BUILD_NUMBER_KEY = "build.number"
private const val GENERATED_COMMENT = "auto generated"
}
override fun apply(project: Project) {
// println("Version Plugin")
val extension = project.extensions.create("version", VersionPluginExtension::class.java)
versionFileName = extension.propertiesFilename.orNull ?: "${project.name}.properties"
validateNoSubprojects(project)
val warSource =
project.layout.projectDirectory.file("src/main/webapp/WEB-INF/classes/${versionFileName}")
val jarSource =
project.layout.projectDirectory.file("src/main/properties/${versionFileName}")
val targetDir = project.layout.buildDirectory.dir("resources/main")
val countFile = project.layout.projectDirectory.file("buildnumber.properties")
if (warSource.asFile.parentFile.parentFile.exists()) {
isWar = true
}
if (isWar) {
if (!warSource.asFile.parentFile.exists())
warSource.asFile.parentFile.mkdir()
checkVersionFile(warSource)
} else {
checkVersionFile(jarSource)
}
project.afterEvaluate {
val projectInfo = ProjectInfo(
version = project.version.toString(),
displayName = getOptionalExtra(project, "displayname"),
copyright = getOptionalExtra(project, "copyright"),
name = project.name,
description = project.description ?: ""
)
if (isWar) {
isWar = isWarProject(project)
if (isWar) {
addManifestTask(project, "war", projectInfo)
} else {
addManifestTask(project, "jar", projectInfo)
}
}
}
private fun validateNoSubprojects(project: Project) {
if (project.parent != null) {
throw Exception("This plugin cannot handle subprojects!")
}
}
private fun isWarProject(project: Project): Boolean {
return project.layout.projectDirectory.file("src/main/webapp/WEB-INF").asFile.exists()
}
private fun getOptionalExtra(project: Project, key: String): String {
return try {
project.extra[key]?.toString() ?: ""
} catch (e: Exception) {
""
}
}
private fun addManifestTask(project: Project, taskType: String, projectInfo: ProjectInfo) {
val countFile = project.layout.projectDirectory.file(BUILDNUMBER_FILE)
if (taskType == "war") {
try {
project.tasks.named<War>("war") {
filesMatching("**/${versionFileName}") {
val num = buildNumber(countFile)
project.extra[buildNumProp] = num
expand(project.properties)
project.tasks.named<War>(taskType) {
doFirst {
applyManifestAttributes(manifest, countFile, projectInfo)
}
}
} catch (e: Exception) {
println("\n*** Falsche Reihenfolge ***\n\nWAR-Plugin muss vor dem Versions-Plugin eingetragen werden!\n")
println("\n*** Falsche Reihenfolge ***\n\nwar-Plugin muss vor dem Versions-Plugin eingetragen werden!\n")
throw e
}
} else {
project.tasks.named<Jar>("jar") {
dependsOn(project.tasks.named(addTaskName))
}
project.tasks.register(addTaskName, AddVersionTask::class.java) {
group = "net.keinekekse"
description = "Adds version information to the project."
outputs.upToDateWhen { false }
mustRunAfter(project.tasks.named("classes"))
onlyIf {
val cj by project.tasks.named("compileJava")
val pr by project.tasks.named("processResources")
// (cj.state.didWork || pr.didWork)
((cj.state.didWork && !cj.state.upToDate) || (pr.didWork && !pr.state.upToDate))
}
from(jarSource)
into(targetDir)
filesMatching("*") {
val num = buildNumber(countFile)
project.extra[buildNumProp] = num
expand(project.properties)
} else if (taskType == "jar") {
project.tasks.named<Jar>(taskType) {
doFirst {
applyManifestAttributes(manifest, countFile, projectInfo)
}
}
}
}
/**
* Increment build number
*/
private fun buildNumber(propFile: RegularFile): String {
val propName = "build.number"
val props = Properties()
private fun applyManifestAttributes(
manifest: Manifest,
countFile: RegularFile,
projectInfo: ProjectInfo,
) {
val buildNumber = incrementBuildNumber(countFile)
with(manifest.attributes) {
this["module-name"] = projectInfo.name
this["displayname"] = projectInfo.displayName
this["description"] = projectInfo.description
this["copyright"] = projectInfo.copyright
this["version"] = projectInfo.version
this["build-number"] = buildNumber
this["build-timestamp"] = Instant.now().toString()
}
println("build ${projectInfo.version}-$buildNumber")
}
private fun incrementBuildNumber(propFile: RegularFile): String {
val props = Properties()
try {
FileInputStream(propFile.asFile).use { props.load(it) }
} catch (e: Exception) {
// noop
}
val numStr: String? = props.getProperty(propName)
var num = numStr?.toLongOrNull() ?: 0
num++
println("build number ${num}")
val currentBuildNumber = props.getProperty(BUILD_NUMBER_KEY)?.toLongOrNull() ?: 0
val newBuildNumber = currentBuildNumber + 1
props.setProperty(propName, num.toString())
props.store(FileOutputStream(propFile.asFile, false), "auto generated")
return num.toString()
props.setProperty(BUILD_NUMBER_KEY, newBuildNumber.toString())
props.store(FileOutputStream(propFile.asFile, false), GENERATED_COMMENT)
return newBuildNumber.toString()
}
/**
* Create version properties file if it doesn't exist
*/
private fun checkVersionFile(file: RegularFile) {
if (!file.asFile.exists()) {
val content = """
|name=${'$'}{name}
|displayname=${'$'}{displayname}
|description=${'$'}{description}
|copyright=${'$'}{copyright}
|version=${'$'}{version}
|build.number=${'$'}{${buildNumProp}}
|build.timestamp=${'$'}{buildTimestamp}
""".trimMargin()
val outfile = OutputStreamWriter(FileOutputStream(file.asFile))
outfile.write(content)
outfile.close()
}
}
data class ProjectInfo(
val version: String,
val displayName: String,
val copyright: String,
val name: String,
val description: String,
)
}
@@ -2,14 +2,4 @@ package net.keinekekse.version
import org.gradle.api.provider.Property
interface VersionPluginExtension {
/**
* Name for the version properties file
* (JAR: src/main/properties, WAR: src/main/webapp/WEB-INF/classes)
* Will be copied to the classpath root.
*
* Default: <project.name>.properties
*/
val propertiesFilename: Property<String>
}
interface VersionPluginExtension