Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
58 changes: 58 additions & 0 deletions buildSrc/src/main/kotlin/org/kopi/galite/gradle/Utils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,16 @@
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/

package org.kopi.galite.gradle

import java.io.ByteArrayOutputStream
import java.io.File
import java.time.Instant
import java.time.ZoneOffset
import java.time.format.DateTimeFormatter

import org.gradle.api.Project
import org.gradle.api.artifacts.ExternalModuleDependency
import org.gradle.kotlin.dsl.exclude

Expand All @@ -25,3 +33,53 @@ fun ExternalModuleDependency.excludeWebJars() {
"org.webjars.bowergithub.vaadin", "org.webjars.bowergithub.webcomponents")
.forEach { group -> exclude(group = group) }
}

/**
* Returns the latest release name : Latest git tag.
*/
fun getLatestReleaseName(project: Project): String {
return try {
listOf("git", "describe", "--tags", "--abbrev=0").runCommand(project.rootDir).trim()
} catch (_: Exception) {
project.version.toString()
}
}

/**
* Returns the latest release date : Latest git tag commit date.
*/
fun getLatestReleaseDate(project: Project, tag: String): String {
val formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss 'UTC'").withZone(ZoneOffset.UTC)

return try {
// Step 1: get commit date of that tag
val commitDate = listOf("git", "log", "-1", "--format=%aI", tag).runCommand(project.rootDir)
// Step 2: parse and format with timezone as "yyyy-MM-dd HH:mm:ss UTC"
val instant = Instant.parse(commitDate)
val releaseDate = formatter.format(instant)

releaseDate
} catch (_: Exception) {
formatter.format(Instant.now())
}
}

/**
* Runs a command line.
*/
private fun List<String>.runCommand(workingDir: File): String {
val output = ByteArrayOutputStream()
val process = ProcessBuilder(this)
.directory(workingDir)
.redirectErrorStream(true)
.start()
val exitCode = process.waitFor()

process.inputStream.copyTo(output)

val result = output.toString().trim()

if (exitCode != 0) throw RuntimeException("Command failed with exit code $exitCode: $result")

return result
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
package org.kopi.galite.database

import org.kopi.galite.util.base.Options
import org.kopi.galite.util.base.Utils

import gnu.getopt.Getopt
import gnu.getopt.LongOpt
Expand Down Expand Up @@ -92,20 +93,19 @@ open class ConnectionOptions @JvmOverloads constructor(name: String = "Connectio
get() {
val parent = super.options
val total = arrayOfNulls<String>(parent.size + 11)

System.arraycopy(parent, 0, total, 0, parent.size)
total[parent.size + 0] = " --database, -b<String>: The URL of the database"
total[parent.size + 1] = " --driver, -d<String>: The JDBC driver to use to access the database"
total[parent.size + 2] = " --username, -u<String>: The username for the database"
total[parent.size + 3] = " --password, -p<String>: The password for the database"
total[parent.size + 4] = " --lookupUserId, -U: Lookup user ID in database? [true]"
total[parent.size + 5] =
" --trace, -t<int>: Set the trace level to print database queries before execution (0: none, 1: all but FETCH, 2: all) [0]"
total[parent.size + 6] =
" --properties, -q<String>: These properties override or complete the properties stored in the database."
total[parent.size + 7] = " --schema, -s<String>: The current database schema to be set."
total[parent.size + 8] = " --maxRetries, -r<Int>: Set the number of maximum retries if a transaction fails."
total[parent.size + 9] = " --waitMin, -n<Long>: The minimum number (inclusive) of milliseconds to wait before retrying a transaction after it has aborted."
total[parent.size + 10] = " --waitMax, -x<Long>: The maximum number (inclusive) of milliseconds to wait before retrying a transaction after it has aborted (it has to be greater or equal to waitMin)."
total[parent.size + 0] = " --database, -b<String>: The URL of the database"
total[parent.size + 1] = " --driver, -d<String>: The JDBC driver to use to access the database"
total[parent.size + 2] = " --username, -u<String>: The username for the database"
total[parent.size + 3] = " --password, -p<String>: The password for the database"
total[parent.size + 4] = " --lookupUserId, -U: Lookup user ID in database? [true]"
total[parent.size + 5] = " --trace, -t<int>: Set the trace level to print database queries before execution (0: none, 1: all but FETCH, 2: all) [0]"
total[parent.size + 6] = " --properties, -q<String>: These properties override or complete the properties stored in the database."
total[parent.size + 7] = " --schema, -s<String>: The current database schema to be set."
total[parent.size + 8] = " --maxRetries, -r<Int>: Set the number of maximum retries if a transaction fails."
total[parent.size + 9] = " --waitMin, -n<Long>: The minimum number (inclusive) of milliseconds to wait before retrying a transaction after it has aborted."
total[parent.size + 10] = " --waitMax, -x<Long>: The maximum number (inclusive) of milliseconds to wait before retrying a transaction after it has aborted (it has to be greater or equal to waitMin)."

return total
}
Expand All @@ -114,7 +114,9 @@ open class ConnectionOptions @JvmOverloads constructor(name: String = "Connectio
get() = "b:d:u:p:Ut::q:s:r:n:x:" + super.shortOptions

public override fun version() {
println("Version 2.3B released 17 September 2007")
val releaseInfo = Utils.readReleaseInfo()

println("Version ${releaseInfo["version"]?.toString().orEmpty()} released at ${releaseInfo["releaseDate"]?.toString().orEmpty()}.")
}

public override fun usage() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2013-2025 kopiLeft Services SARL, Tunis TN
* Copyright (c) 1990-2025 kopiRight Managed Solutions GmbH, Wien AT
* Copyright (c) 2013-2026 kopiLeft Services SARL, Tunis TN
* Copyright (c) 1990-2026 kopiRight Managed Solutions GmbH, Wien AT
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
Expand All @@ -25,7 +25,7 @@ import org.apache.tools.ant.taskdefs.condition.Os

import org.gradle.api.Project

open class GradleExtensions(private val project: Project) {
open class GaliteGradleExtensions(private val project: Project) {
/**
* removes the file with name [fileName] existing in [folder]
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ open class GradleExtensionsPlugin: Plugin<Project> {
* Register the [projectExtensions] extension function for use in the consuming project
*/
override fun apply(project: Project) {
project.extensions.create("projectExtensions", GradleExtensions::class.java, project)
val projectExtensions = project.extensions.findByType(GaliteGradleExtensions::class.java)
?: project.extensions.create("projectExtensions", GaliteGradleExtensions::class.java)
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import org.gradle.kotlin.dsl.register

import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

import org.kopi.galite.plugins.common.GradleExtensions
import org.kopi.galite.plugins.common.GaliteGradleExtensions
import org.kopi.galite.plugins.common.GradleExtensionsPlugin

class DBSchemaGeneratorPlugin : GradleExtensionsPlugin() {
Expand All @@ -41,7 +41,7 @@ class DBSchemaGeneratorPlugin : GradleExtensionsPlugin() {
}
named("clean") {
doLast {
project.extensions.getByType<GradleExtensions>().clean(
project.extensions.getByType<GaliteGradleExtensions>().clean(
project.layout.projectDirectory.dir(GENERATED_DIRECTORY).asFile.path
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import org.gradle.kotlin.dsl.get
import org.gradle.kotlin.dsl.the

import org.kopi.galite.plugins.common.GradleExtensionsPlugin
import org.kopi.galite.plugins.generator.DBSchemaGenerator

abstract class DBSchemaGeneratorTask : JavaExec() {
init {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ package org.kopi.galite.plugins
import org.gradle.api.Project
import org.gradle.kotlin.dsl.getByType
import org.gradle.kotlin.dsl.register
import org.kopi.galite.plugins.common.GradleExtensions

import org.kopi.galite.plugins.common.GaliteGradleExtensions
import org.kopi.galite.plugins.common.GradleExtensionsPlugin

class FactoryGeneratorPlugin : GradleExtensionsPlugin() {
Expand All @@ -36,7 +36,7 @@ class FactoryGeneratorPlugin : GradleExtensionsPlugin() {
register<FactoryGeneratorTask>("generateFactory")
named("clean") {
doLast {
project.extensions.getByType<GradleExtensions>().clean(
project.extensions.getByType<GaliteGradleExtensions>().clean(
project.layout.projectDirectory.dir(GENERATED_DIRECTORY).asFile.path
)
}
Expand Down
30 changes: 30 additions & 0 deletions galite-plugins/galite-optgen/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* Copyright (c) 2013-2026 kopiLeft Services SARL, Tunis TN
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License version 2.1 as published by the Free Software Foundation.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/

plugins {
`kotlin-dsl`
id("java-gradle-plugin")
}

gradlePlugin {
plugins {
create("") {
id = "org.kopi.galite-optgen" // Unique plugin ID
implementationClass = "org.kopi.galite.plugins.OptgenPlugin" // The main plugin class
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* Copyright (c) 2013-2026 kopiLeft Services SARL, Tunis TN
* Copyright (c) 1990-2026 kopiRight Managed Solutions GmbH, Wien AT
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License version 2.1 as published by the Free Software Foundation.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/

package org.kopi.galite.plugins

import org.gradle.api.file.FileCollection
import javax.inject.Inject

import org.gradle.api.model.ObjectFactory
import org.gradle.api.provider.ListProperty
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.InputFiles
import org.gradle.work.Incremental

open class OptgenExtention @Inject constructor(objectFactory: ObjectFactory) {
@Input
val parameters: ListProperty<OptionParam> = objectFactory.listProperty(OptionParam::class.java)
}

data class OptionParam(@Input
var release: String, // The release version of the program
@Incremental @InputFiles
var optionFiles: FileCollection) // *Options.xml files to be parsed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* Copyright (c) 2013-2026 kopiLeft Services SARL, Tunis TN
* Copyright (c) 1990-2026 kopiRight Managed Solutions GmbH, Wien AT
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License version 2.1 as published by the Free Software Foundation.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/

package org.kopi.galite.plugins

import org.gradle.api.Project
import org.gradle.kotlin.dsl.getByType
import org.gradle.kotlin.dsl.register
import org.kopi.galite.plugins.common.GaliteGradleExtensions

import org.kopi.galite.plugins.common.GradleExtensionsPlugin

class OptgenPlugin : GradleExtensionsPlugin() {
override fun apply(project: Project) {
super.apply(project)

createGeneratedSourceSet(project)

project.extensions.create("optionGen", OptgenExtention::class.java)
project.tasks.apply {
register<OptgenTask>("generateOptions")
named("clean") {
doLast {
project.extensions.getByType<GaliteGradleExtensions>().clean(
project.layout.projectDirectory.dir(GENERATED_DIRECTORY).asFile.path
)
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/*
* Copyright (c) 2013-2026 kopiLeft Services SARL, Tunis TN
* Copyright (c) 1990-2026 kopiRight Managed Solutions GmbH, Wien AT
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License version 2.1 as published by the Free Software Foundation.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/

package org.kopi.galite.plugins

import org.gradle.api.tasks.*
import org.gradle.kotlin.dsl.get
import org.gradle.kotlin.dsl.the

import org.kopi.galite.plugins.common.GradleExtensionsPlugin

abstract class OptgenTask : JavaExec() {
init {
description = "Task to generate java classes to parse *Options.xml files."
mainClass.set("org.kopi.galite.util.optgen.Main")
}
@OutputDirectory
val src = project.layout.projectDirectory.dir(GradleExtensionsPlugin.GENERATED_JAVA_DIRECTORY)

@TaskAction
override fun exec() {
val extension = project.extensions.getByType(OptgenExtention::class.java)

if (extension.parameters.getOrElse(emptyList()).isEmpty()) {
project.logger.lifecycle("No Options.xml defined for option parser generation.")
return
}
// Check if generated directory is created
if (!src.asFile.exists()) { src.asFile.mkdirs() }

// Generate an option parser class per each parameter element
extension.parameters.get().forEach { param ->
if (!param.optionFiles.isEmpty) {
val argsList = buildList {
if (param.release.isNotBlank()) {
add("--release=${param.release}")
}
addAll(param.optionFiles.files.map { it.absolutePath })
}


project.javaexec {
workingDir = project.file(src)
mainClass.set("org.kopi.galite.util.optgen.Main")
classpath = project.the<SourceSetContainer>()["main"].runtimeClasspath
args(*argsList.toTypedArray())
}
}
}
}
}
Loading
Loading