diff --git a/build.gradle b/build.gradle
index d69d6a8..7ed8c0e 100644
--- a/build.gradle
+++ b/build.gradle
@@ -3,8 +3,11 @@
*/
plugins {
- // Apply the java-library plugin to add support for Java Library
- id 'java-library'
+ id 'java'
+
+ // GrGit
+ // A JGit wrapper for Groovy used to access git commit info
+ id 'org.ajoberstar.grgit' version '4.1.1'
/*
* Uncomment the following line to enable the Eclipse plugin.
@@ -237,12 +240,44 @@ task specifyLocalManifest {
if (classPath.size() == configurations.runtimeClasspath.size()) {
println "Nothing removed from JAR classpath"
}
-
+
+ def version = "dev";
+ def commit = "-";
+ def branch = "-";
+ def buildId = project.findProperty('buildId') ?: "-";
+
+ try {
+ def git = org.ajoberstar.grgit.Grgit.open()
+ def head = git.head()
+
+ commit = head.id
+ branch = git.branch.current().name
+
+ def newestTag = git.tag.list().findAll { it.commit == head } ?.max { it.dateTime } ?.name
+ if (newestTag != null) {
+ version = newestTag;
+ } else if (project.hasProperty('buildId')) {
+ version = project.buildId;
+ } else {
+ version = head.dateTime.format(java.time.format.DateTimeFormatter.ISO_LOCAL_DATE);
+ }
+ } catch (org.eclipse.jgit.errors.RepositoryNotFoundException e) {
+ println "No Git repository found in project root"
+ }
+
jar {
manifest {
attributes(
"Main-Class": "ru.windcorp.progressia.client.ProgressiaClientMain",
- "Class-Path": configurations.runtimeClasspath.collect { "lib/" + it.getName() } .findAll { isDependencyRequested(it) } .join(' ')
+ "Class-Path": configurations.runtimeClasspath.collect { "lib/" + it.getName() } .findAll { isDependencyRequested(it) } .join(' '),
+
+ "Specification-Title": "Progressia",
+
+ "Implementation-Title": "Progressia",
+ "Implementation-Version": version,
+ "Implementation-Version-Git-Commit": commit,
+ "Implementation-Version-Git-Branch": branch,
+ "Implementation-Version-BuildId": buildId,
)
}
}
diff --git a/src/main/java/ru/windcorp/progressia/Progressia.java b/src/main/java/ru/windcorp/progressia/Progressia.java
index db899ea..45d64c6 100644
--- a/src/main/java/ru/windcorp/progressia/Progressia.java
+++ b/src/main/java/ru/windcorp/progressia/Progressia.java
@@ -15,9 +15,180 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
-
+
package ru.windcorp.progressia;
+import java.io.IOException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Enumeration;
+import java.util.jar.Attributes;
+import java.util.jar.Manifest;
+
+import org.apache.logging.log4j.LogManager;
+
+import ru.windcorp.progressia.common.util.crash.CrashReports;
+
+/**
+ * A class providing access to build metadata.
+ */
public class Progressia {
+ private static final String NAME = "Progressia";
+ private static String version;
+ private static String gitCommit;
+ private static String gitBranch;
+ private static String buildId;
+
+ static {
+ try {
+ Manifest manifest = findManifest();
+
+ if (manifest == null) {
+ setDevelopmentMetadata();
+ LogManager.getLogger().info(
+ "Manifest with Specification-Title not found. "
+ + "Either you are in a development environment or something has gone horribly wrong with classloaders."
+ );
+ } else {
+ fillMetadata(manifest);
+ }
+ } catch (Throwable t) {
+ CrashReports.crash(t, "Something went wrong while loading metadata");
+ }
+ }
+
+ private static Manifest findManifest() {
+ try {
+ Enumeration resources = Progressia.class.getClassLoader().getResources("META-INF/MANIFEST.MF");
+ Collection exceptions = new ArrayList<>();
+
+ while (resources.hasMoreElements()) {
+ URL url = resources.nextElement();
+
+ try {
+
+ Manifest manifest = new Manifest(url.openStream());
+ Attributes mainAttributes = manifest.getMainAttributes();
+ if (NAME.equals(mainAttributes.getValue("Specification-Title"))) {
+ return manifest;
+ }
+
+ } catch (IOException e) {
+ exceptions.add(e);
+ }
+ }
+
+ if (exceptions.isEmpty()) {
+ return null;
+ }
+
+ IOException scapegoat = null;
+ for (IOException e : exceptions) {
+ if (scapegoat == null) {
+ scapegoat = e;
+ } else {
+ scapegoat.addSuppressed(e);
+ }
+ }
+
+ throw CrashReports.report(scapegoat, "Could not read manifest");
+ } catch (IOException e) {
+ throw CrashReports.report(e, "Could not read manifest");
+ }
+ }
+
+ private static void setDevelopmentMetadata() {
+ version = "dev";
+ gitCommit = "-";
+ gitBranch = "-";
+ buildId = "-";
+ }
+
+ private static void fillMetadata(Manifest manifest) {
+ version = getAttributeOrCrash(manifest, "Implementation-Version");
+ gitCommit = getAttributeOrCrash(manifest, "Implementation-Version-Git-Commit");
+ gitBranch = getAttributeOrCrash(manifest, "Implementation-Version-Git-Branch");
+ buildId = getAttributeOrCrash(manifest, "Implementation-Version-BuildId");
+ }
+
+ private static String getAttributeOrCrash(Manifest manifest, String key) {
+ String result = manifest.getMainAttributes().getValue(key);
+ if (result == null) {
+ throw CrashReports.report(null, "Manifest exists but attribute " + key + " not found");
+ }
+ return result;
+ }
+
+ public static String getName() {
+ return NAME;
+ }
+
+ /**
+ * Returns the version of the game as a String. Version data is retrieved
+ * from a {@code META-INF/MANIFEST.MF} file located in the main JAR. Version
+ * format depends on way the game was built:
+ *
+ * dev
if no matching manifest was found, e.g. when launching from an IDE
+ * - The value of
Implementation-Version
specified in the manifest:
+ *
+ * - [Stage-]Major.Minor.Patch, e.g.
alpha-0.3.2
or 1.4.2
, for released versions
+ * - BuildId, e.g.
WJ7
, for snapshots built by automation systems
+ * - YYYY-MM-DD, e.g.
2021-12-32
, for snapshots built manually
+ *
+ *
+ *
+ *
+ * @return the version
+ */
+ public static String getVersion() {
+ return version;
+ }
+
+ public static String getFullerVersion() {
+ if (isDefaultGitBranch() || "-".equals(gitBranch)) {
+ return version;
+ } else {
+ return String.format("%s/%s", version, gitBranch);
+ }
+ }
+
+ /**
+ * @return the buildId or "-"
+ */
+ public static String getBuildId() {
+ return buildId;
+ }
+
+ /**
+ * @return the Git commit or "-"
+ */
+ public static String getGitCommit() {
+ return gitCommit;
+ }
+
+ public static String getGitCommitShort() {
+ if (gitCommit == null || "-".equals(gitCommit)) {
+ return gitCommit;
+ }
+
+ return gitCommit.substring(0, Math.min(7, gitCommit.length()));
+ }
+
+ /**
+ * @return the Git branch or "-"
+ */
+ public static String getGitBranch() {
+ return gitBranch;
+ }
+
+ public static boolean isDefaultGitBranch() {
+ return "master".equals(gitBranch) || "main".equals(gitBranch);
+ }
+
+ public static String getFullVersion() {
+ return String.format("%s/%s/%s/%s", version, gitBranch, getGitCommitShort(), buildId);
+ }
+
}
diff --git a/src/main/java/ru/windcorp/progressia/ProgressiaLauncher.java b/src/main/java/ru/windcorp/progressia/ProgressiaLauncher.java
index 099d378..2190677 100644
--- a/src/main/java/ru/windcorp/progressia/ProgressiaLauncher.java
+++ b/src/main/java/ru/windcorp/progressia/ProgressiaLauncher.java
@@ -18,6 +18,8 @@
package ru.windcorp.progressia;
+import org.apache.logging.log4j.LogManager;
+
import ru.windcorp.progressia.client.graphics.GUI;
import ru.windcorp.progressia.common.util.crash.CrashReports;
import ru.windcorp.progressia.common.util.crash.analyzers.OutOfMemoryAnalyzer;
@@ -32,6 +34,8 @@ public class ProgressiaLauncher {
public static void launch(String[] args, Proxy proxy) {
arguments = args.clone();
setupCrashReports();
+
+ LogManager.getRootLogger().info("Launching " + Progressia.getName() + " version " + Progressia.getFullVersion());
proxy.initialize();
ProgressiaLauncher.proxy = proxy;
@@ -44,6 +48,7 @@ public class ProgressiaLauncher {
private static void setupCrashReports() {
// Context providers
+ CrashReports.registerProvider(new VersionProvider());
CrashReports.registerProvider(new OSContextProvider());
CrashReports.registerProvider(new RAMContextProvider());
CrashReports.registerProvider(new JavaVersionContextProvider());
diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/backend/LWJGLInitializer.java b/src/main/java/ru/windcorp/progressia/client/graphics/backend/LWJGLInitializer.java
index 9bc280e..cff7421 100644
--- a/src/main/java/ru/windcorp/progressia/client/graphics/backend/LWJGLInitializer.java
+++ b/src/main/java/ru/windcorp/progressia/client/graphics/backend/LWJGLInitializer.java
@@ -26,6 +26,7 @@ import org.lwjgl.opengl.GL;
import com.google.common.eventbus.Subscribe;
+import ru.windcorp.progressia.Progressia;
import ru.windcorp.progressia.client.graphics.GUI;
import ru.windcorp.progressia.client.graphics.input.FrameResizeEvent;
import ru.windcorp.progressia.client.graphics.input.InputEvent;
@@ -62,8 +63,8 @@ class LWJGLInitializer {
glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE);
glfwWindowHint(GLFW_FOCUSED, GLFW_TRUE);
glfwWindowHint(GLFW_MAXIMIZED, GLFW_TRUE);
-
- long handle = glfwCreateWindow(900, 900, "ProgressiaTest", NULL, NULL);
+
+ long handle = glfwCreateWindow(800, 600, Progressia.getName() + " " + Progressia.getFullerVersion(), NULL, NULL);
// TODO Check that handle != NULL
diff --git a/src/main/java/ru/windcorp/progressia/common/util/crash/providers/VersionProvider.java b/src/main/java/ru/windcorp/progressia/common/util/crash/providers/VersionProvider.java
new file mode 100644
index 0000000..f53d26e
--- /dev/null
+++ b/src/main/java/ru/windcorp/progressia/common/util/crash/providers/VersionProvider.java
@@ -0,0 +1,40 @@
+/*
+ * Progressia
+ * Copyright (C) 2020-2021 Wind Corporation and contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package ru.windcorp.progressia.common.util.crash.providers;
+
+import java.util.Map;
+
+import ru.windcorp.progressia.Progressia;
+import ru.windcorp.progressia.common.util.crash.ContextProvider;
+
+public class VersionProvider implements ContextProvider {
+
+ @Override
+ public void provideContext(Map output) {
+ output.put("Version", Progressia.getVersion());
+ output.put("Git commit", Progressia.getGitCommit());
+ output.put("Git branch", Progressia.getGitBranch());
+ output.put("Build ID", Progressia.getBuildId());
+ }
+
+ @Override
+ public String getName() {
+ return "Version Provider";
+ }
+
+}
diff --git a/src/main/java/ru/windcorp/progressia/test/LayerAbout.java b/src/main/java/ru/windcorp/progressia/test/LayerAbout.java
index fae2357..0011985 100644
--- a/src/main/java/ru/windcorp/progressia/test/LayerAbout.java
+++ b/src/main/java/ru/windcorp/progressia/test/LayerAbout.java
@@ -18,6 +18,7 @@
package ru.windcorp.progressia.test;
+import ru.windcorp.progressia.Progressia;
import ru.windcorp.progressia.client.graphics.Colors;
import ru.windcorp.progressia.client.graphics.font.Font;
import ru.windcorp.progressia.client.graphics.font.Typeface;
@@ -50,7 +51,7 @@ public class LayerAbout extends GUILayer {
new Label(
"Version",
font,
- new MutableStringLocalized("LayerAbout.Version").format("pre-alpha 3")
+ new MutableStringLocalized("LayerAbout.Version").format(Progressia.getFullerVersion())
)
);