Skip to content

Commit

Permalink
feat(core): add JooqxVersion to get runtime library version
Browse files Browse the repository at this point in the history
  • Loading branch information
zero88 committed Jun 24, 2024
1 parent 272fd81 commit 0dff504
Show file tree
Hide file tree
Showing 4 changed files with 134 additions and 2 deletions.
15 changes: 14 additions & 1 deletion core/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,17 @@ val bridges = setOf(
setOf("**/datatype/BridgeConverter.java")
)
)
val createVersionFile = tasks.register("createVersionFile") {
group = "build"
// Register the project version as a task input, so Gradle can cache the task
inputs.property("projectVersion", project.version)
// tell Gradle about the output directory
outputs.dir(temporaryDir)

doLast {
File(temporaryDir, "jooqx-version.txt").writeText(project.version.toString(), Charsets.UTF_8)
}
}

sourceSets {
bridges.forEach {
Expand All @@ -73,6 +84,9 @@ sourceSets {
java {
bridges.filter { it.versionConstraint }.forEach { exclude(it.excludes) }
}
resources {
srcDir(createVersionFile.map { it.outputs })
}
}
}

Expand Down Expand Up @@ -102,5 +116,4 @@ tasks {
testFixturesJavadoc {
title = "jOOQx Testing ${project.version} API"
}

}
116 changes: 116 additions & 0 deletions core/src/main/java/io/github/zero88/jooqx/JooqxVersion.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
package io.github.zero88.jooqx;

import static io.github.zero88.jooqx.Utils.brackets;

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.nio.charset.StandardCharsets;
import java.util.Objects;
import java.util.Scanner;

import org.jetbrains.annotations.ApiStatus.Internal;
import org.jooq.Constants;

import io.vertx.core.impl.launcher.commands.VersionCommand;
import io.vertx.core.impl.logging.Logger;
import io.vertx.core.impl.logging.LoggerFactory;
import io.vertx.core.json.JsonObject;

/**
* JOOQ.X version
*
* @since 2.0.0
*/
public final class JooqxVersion {

private static final Logger LOGGER = LoggerFactory.getLogger(JooqxVersion.class);
private static String version;
private static String jooqVersion;

private JooqxVersion() { }

/**
* @return {@code jooq.x} version
*/
@Internal
public static String getVersion() {
if (version == null) {
version = loadFromFile();
}
return version;
}

/**
* Query version from the direct dependent libraries: {@code jOOQ}, {@code vert.x}, and combine with {@code jooq.x}
* version
*
* @return versions in JSON format
* @see #getVersion()
*/
public static JsonObject versionComponents() {
return JsonObject.of("jOOQ", getJooqVersion(), "Vert.x", VersionCommand.getVersion(), "jooq.x", getVersion());
}

/**
* Validate the version compatibility between {@code jooq.x} and the direct dependent libraries
*/
public static void validate() {
final String jooqxVer = getVersion();
final String jooqVer = getJooqVersion();
try {
boolean isJvm8 = jooqxVer.contains("+jvm8");
String[] versions = jooqVer.split("\\.", 3);
boolean isMajor3 = Objects.equals(versions[0], "3");
int jooqMinor = Integer.parseInt(versions[1]);
if (isMajor3 && isJvm8 == (jooqMinor >= 18)) {
LOGGER.warn(
"jOOQ.x version" + brackets(jooqxVer) + " is not compatible with jOOQ version" + brackets(jooqVer) +
". Please refer the documentation: " + docUrl(jooqxVer) + " for more details.");
}
} catch (Exception ex) {
LOGGER.trace("Validate compatibility version failed", ex);
}
}

private static String docUrl(String jooqxVer) {
String releaseVer = jooqxVer.replaceAll("\\+jvm8", "");
releaseVer = releaseVer.contains("-SNAPSHOT") ? "main" : releaseVer;
return "https://zero88.github.io/webdocs/jooqx/" + releaseVer + "/core-usage.html#_compatibility_matrix";
}

private static String getJooqVersion() {
if (jooqVersion == null) {
try {
final Class<?> aClass = JooqxVersion.class.getClassLoader().loadClass("org.jooq.Constants");
final Field versionField = aClass.getDeclaredField("VERSION");
jooqVersion = (String) versionField.get(null);
} catch (ClassNotFoundException | NoSuchFieldException | IllegalAccessException ex) {
LOGGER.debug("Unable to load runtime jOOQ version, fallback to build version", ex);
jooqVersion = Constants.VERSION;
}
}
return jooqVersion;
}

private static String loadFromFile() {
// in build process, version will be auto-inject to manifest by
// `JooqxVersion.class.getPackage().getImplementationVersion()`
// however, fat-jar will override the package version by itself application version
// so load from file is safe choice
LOGGER.debug("Loading `jooq.x` version from file `jooqx-version.txt`...");
try (InputStream is = JooqxVersion.class.getClassLoader().getResourceAsStream("jooqx-version.txt")) {
if (is == null) {
LOGGER.warn("Cannot find jooqx-version.txt on classpath");
return null;
}
try (Scanner scanner = new Scanner(is, StandardCharsets.UTF_8.name()).useDelimiter("\\A")) {
return scanner.hasNext() ? scanner.next().trim() : "";
}
} catch (IOException ex) {
LOGGER.warn("Cannot read jooqx-version.txt on classpath", ex);
return null;
}
}

}
1 change: 1 addition & 0 deletions core/src/main/java/io/github/zero88/jooqx/SQLImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ abstract static class SQLEI<S, B, PQ extends SQLPreparedQuery<B>, RC extends SQL

protected SQLEI(Vertx vertx, DSLContext dsl, S sqlClient, PQ preparedQuery, RC resultCollector,
SQLErrorConverter errorConverter, DataTypeMapperRegistry typeMapperRegistry) {
JooqxVersion.validate();
this.vertx = vertx;
this.dsl = dsl;
this.sqlClient = sqlClient;
Expand Down
4 changes: 3 additions & 1 deletion docs/asciidoc/src/antora/pages/core-usage.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,9 @@ dependencies {
}
----

== Matrix support
== Compatibility Matrix

The table below describe `jooq.x` compatibility with several integrations.

|===
|Java |jOOQ |Vert.x |jooq.x
Expand Down

0 comments on commit 0dff504

Please sign in to comment.