Add Version Provider for v3
MODIFY
codyze-v3/build.gradle.kts
codyze-v3/build.gradle.kts
allprojects {
group = "de.fraunhofer.aisec.codyze"
- version = System.getProperty("version") ?: "0.0.0-SNAPSHOT"
+ version = if(version != Project.DEFAULT_VERSION) version else "0.0.0-SNAPSHOT"
}
plugins {

MODIFY
codyze-v3/buildSrc/src/main/kotlin/module.gradle.kts
codyze-v3/buildSrc/src/main/kotlin/module.gradle.kts
@@ -10,10 +10,13 @@ plugins {
id("com.diffplug.spotless")
}
-// bundle codyze's version for all jars to use it at runtime
+// configure shared attributes for JAR file manifests
tasks.withType<Jar>().configureEach {
manifest {
- attributes(mapOf("CodyzeVersion" to project.version))
+ attributes(
+ "Implementation-Version" to project.version,
+ "Implementation-Vendor" to "Fraunhofer AISEC"
+ )
}
}

MODIFY
codyze-v3/codyze-core/build.gradle.kts
codyze-v3/codyze-core/build.gradle.kts
@@ -17,3 +17,11 @@ dependencies {
// The code in it was generated using https://app.quicktype.io/ with minor manual additions
implementation(libs.sarif4k)
}
+
+tasks {
+ jar {
+ manifest {
+ attributes("Implementation-Title" to "Codyze v3 - Core Library")
+ }
+ }
+}
\ No newline at end of file

MODIFY
codyze-v3/codyze-specification-languages/mark/build.gradle.kts
codyze-v3/codyze-specification-languages/mark/build.gradle.kts
@@ -27,3 +27,11 @@ dependencies {
// LSP interface support
//api("org.eclipse.lsp4j:org.eclipse.lsp4j:0.12.0") // ok
}
+
+tasks {
+ jar {
+ manifest {
+ attributes("Implementation-Title" to "Codyze v3 - Specification Language MARK")
+ }
+ }
+}

MODIFY
codyze-v3/codyze/build.gradle.kts
codyze-v3/codyze/build.gradle.kts
@@ -33,3 +33,20 @@ dependencies {
application {
mainClass.set("de.fraunhofer.aisec.codyze.MainKt")
}
+
+tasks {
+ jar {
+ manifest {
+ attributes("Implementation-Title" to "Codyze v3")
+ }
+ }
+}
+
+/**
+ * Set version as system property when using run task, because there isn't a JAR file manifest.
+ *
+ * We already defined a sensible version in our parent project for all modules.
+ */
+tasks.named<JavaExec>("run") {
+ systemProperty("codyze-v3-version", project.version)
+}
\ No newline at end of file

MODIFY
codyze-v3/codyze/src/main/kotlin/Main.kt
codyze-v3/codyze/src/main/kotlin/Main.kt
@@ -9,7 +9,12 @@ import com.github.ajalt.clikt.parameters.arguments.multiple
import com.github.ajalt.clikt.parameters.options.*
import de.fraunhofer.aisec.codyze.options.configFileOption
import de.fraunhofer.aisec.codyze.source.JsonValueSource
+import java.io.IOException
+import java.net.URL
import java.nio.file.Path
+import java.util.*
+import java.util.jar.Attributes
+import java.util.jar.Manifest
import kotlin.io.path.Path
import mu.KotlinLogging
import org.koin.core.context.startKoin
@@ -43,7 +48,7 @@ class ConfigFileParser : CliktCommand(treatUnknownOptionsAsArgs = true) {
class CodyzeCli(val configFile: Path? = null) :
CliktCommand(help = "Codyze finds security flaws in source code", printHelpOnEmptyArgs = true) {
init {
- versionOption("1.0", names = setOf("--version", "-V")) // TODO get actual version
+ versionOption(Codyze.version, names = setOf("--version", "-V"))
context {
if (configFile != null)
valueSource = JsonValueSource.from(configFile, requireValid = true)
@@ -51,6 +56,53 @@ class CodyzeCli(val configFile: Path? = null) :
}
}
+ /**
+ * Storage for constant application information.
+ *
+ * Note: Using `object` to keep information as singleton and prevent initialization on each
+ * object creation of [CodyzeCli].
+ */
+ private object Codyze {
+ /** Name of our application. */
+ private const val IMPLEMENTATION_TITLE: String = "Codyze v3"
+
+ /** Default version to use, when no explicit version has been set. */
+ private const val DEFAULT_VERSION: String = "0.0.0-SNAPSHOT"
+
+ /**
+ * Determine version from system property `codyze-v3-version` or from Codyzes' JAR file
+ * manifests.
+ *
+ * Note: Using `lazy` delegate to calculate property once, when it is needed. Reduces
+ * overhead by not reading in all manifests on the classpath multiple times.
+ */
+ val version: String by lazy {
+ System.getProperty("codyze-v3-version")
+ ?: run {
+ val resources: Enumeration<URL> =
+ CodyzeCli::class.java.classLoader.getResources("META-INF/MANIFEST.MF")
+ while (resources.hasMoreElements()) {
+ val url = resources.nextElement()
+ try {
+ val manifest = Manifest(url.openStream())
+ val mainAttributes = manifest.mainAttributes
+ if (
+ IMPLEMENTATION_TITLE ==
+ mainAttributes.getValue(Attributes.Name.IMPLEMENTATION_TITLE)
+ ) {
+ return@run mainAttributes.getValue(
+ Attributes.Name.IMPLEMENTATION_VERSION
+ )
+ }
+ } catch (ex: IOException) {
+ logger.trace { "Unable to read from $url: $ex" }
+ }
+ }
+ DEFAULT_VERSION
+ }
+ }
+ }
+
override fun run() {
echo("In CodyzeCli")
} // TODO: change to NoOpCliktCommand?

Add Version Provider for v3 (#570)

Co-authored-by: Florian Wendland <florian.wendland@aisec.fraunhofer.de>