Skip to content

Commit 67e9ccd

Browse files
committed
Display the build date in the editor and when starting the engine
This can be used to quickly see how recent a development build is, without having to look up the commit date manually. When juggling around with various builds (e.g. for benchmarking), this can also be used to ensure that you're actually running the binary you intended to run. The date stored is the date of the Git commit that is built, not the current date at the time of building the binary. This ensures binaries can remain reproducible. The version timestamp can be accessed using the `timestamp` key of the `Engine.get_version_info()` return value.
1 parent 8f3e2a6 commit 67e9ccd

File tree

9 files changed

+69
-7
lines changed

9 files changed

+69
-7
lines changed

core/config/engine.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,8 @@ Dictionary Engine::get_version_info() const {
114114
String hash = String(VERSION_HASH);
115115
dict["hash"] = hash.is_empty() ? String("unknown") : hash;
116116

117+
dict["timestamp"] = VERSION_TIMESTAMP;
118+
117119
String stringver = String(dict["major"]) + "." + String(dict["minor"]);
118120
if ((int)dict["patch"] != 0) {
119121
stringver += "." + String(dict["patch"]);

core/version.h

+6
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@
3333

3434
#include "core/version_generated.gen.h"
3535

36+
#include <stdint.h>
37+
3638
// Copied from typedefs.h to stay lean.
3739
#ifndef _STR
3840
#define _STR(m_x) #m_x
@@ -77,4 +79,8 @@
7779
// Git commit hash, generated at build time in `core/version_hash.gen.cpp`.
7880
extern const char *const VERSION_HASH;
7981

82+
// Git commit date UNIX timestamp (in seconds), generated at build time in `core/version_hash.gen.cpp`.
83+
// Set to 0 if unknown.
84+
extern const uint64_t VERSION_TIMESTAMP;
85+
8086
#endif // VERSION_H

doc/classes/Engine.xml

+2-1
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,7 @@
180180
- [code]status[/code] - Status (such as "beta", "rc1", "rc2", "stable", etc.) as a String;
181181
- [code]build[/code] - Build name (e.g. "custom_build") as a String;
182182
- [code]hash[/code] - Full Git commit hash as a String;
183+
- [code]timestamp[/code] - Holds the Git commit date UNIX timestamp in seconds as an int, or [code]0[/code] if unavailable;
183184
- [code]string[/code] - [code]major[/code], [code]minor[/code], [code]patch[/code], [code]status[/code], and [code]build[/code] in a single String.
184185
The [code]hex[/code] value is encoded as follows, from left to right: one byte for the major, one byte for the minor, one byte for the patch version. For example, "3.1.12" would be [code]0x03010C[/code].
185186
[b]Note:[/b] The [code]hex[/code] value is still an [int] internally, and printing it will give you its decimal representation, which is not particularly meaningful. Use hexadecimal literals for quick version comparisons from code:
@@ -261,7 +262,7 @@
261262
func _enter_tree():
262263
# Depending on when the node is added to the tree,
263264
# prints either "true" or "false".
264-
print(Engine.is_in_physics_frame())
265+
print(Engine.is_in_physics_frame())
265266

266267
func _process(delta):
267268
print(Engine.is_in_physics_frame()) # Prints false

editor/editor_about.cpp

+9-1
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#include "core/authors.gen.h"
3434
#include "core/donors.gen.h"
3535
#include "core/license.gen.h"
36+
#include "core/os/time.h"
3637
#include "core/version.h"
3738
#include "editor/editor_string_names.h"
3839
#include "editor/themes/editor_scale.h"
@@ -206,7 +207,14 @@ EditorAbout::EditorAbout() {
206207
// Set the text to copy in metadata as it slightly differs from the button's text.
207208
version_btn->set_meta(META_TEXT_TO_COPY, "v" VERSION_FULL_BUILD + hash);
208209
version_btn->set_underline_mode(LinkButton::UNDERLINE_MODE_ON_HOVER);
209-
version_btn->set_tooltip_text(TTR("Click to copy."));
210+
String build_date;
211+
if (VERSION_TIMESTAMP > 0) {
212+
build_date = Time::get_singleton()->get_datetime_string_from_unix_time(VERSION_TIMESTAMP, true) + " UTC";
213+
} else {
214+
build_date = TTR("(unknown)");
215+
}
216+
version_btn->set_tooltip_text(vformat(TTR("Git commit date: %s\nClick to copy the version number."), build_date));
217+
210218
version_btn->connect("pressed", callable_mp(this, &EditorAbout::_version_button_pressed));
211219
version_info_vbc->add_child(version_btn);
212220

editor/gui/editor_bottom_panel.cpp

+8-1
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030

3131
#include "editor_bottom_panel.h"
3232

33+
#include "core/os/time.h"
3334
#include "core/version.h"
3435
#include "editor/debugger/editor_debugger_node.h"
3536
#include "editor/editor_about.h"
@@ -253,7 +254,13 @@ EditorBottomPanel::EditorBottomPanel() {
253254
// Fade out the version label to be less prominent, but still readable.
254255
version_btn->set_self_modulate(Color(1, 1, 1, 0.65));
255256
version_btn->set_underline_mode(LinkButton::UNDERLINE_MODE_ON_HOVER);
256-
version_btn->set_tooltip_text(TTR("Click to copy."));
257+
String build_date;
258+
if (VERSION_TIMESTAMP > 0) {
259+
build_date = Time::get_singleton()->get_datetime_string_from_unix_time(VERSION_TIMESTAMP, true) + " UTC";
260+
} else {
261+
build_date = TTR("(unknown)");
262+
}
263+
version_btn->set_tooltip_text(vformat(TTR("Git commit date: %s\nClick to copy the version information."), build_date));
257264
version_btn->connect("pressed", callable_mp(this, &EditorBottomPanel::_version_button_pressed));
258265
version_info_vbox->add_child(version_btn);
259266

editor/project_manager.cpp

+8-1
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
#include "core/io/stream_peer_tls.h"
3939
#include "core/os/keyboard.h"
4040
#include "core/os/os.h"
41+
#include "core/os/time.h"
4142
#include "core/version.h"
4243
#include "editor/editor_about.h"
4344
#include "editor/editor_settings.h"
@@ -1350,7 +1351,13 @@ ProjectManager::ProjectManager() {
13501351
// Fade the version label to be less prominent, but still readable.
13511352
version_btn->set_self_modulate(Color(1, 1, 1, 0.6));
13521353
version_btn->set_underline_mode(LinkButton::UNDERLINE_MODE_ON_HOVER);
1353-
version_btn->set_tooltip_text(TTR("Click to copy the version information."));
1354+
String build_date;
1355+
if (VERSION_TIMESTAMP > 0) {
1356+
build_date = Time::get_singleton()->get_datetime_string_from_unix_time(VERSION_TIMESTAMP, true) + " UTC";
1357+
} else {
1358+
build_date = TTR("(unknown)");
1359+
}
1360+
version_btn->set_tooltip_text(vformat(TTR("Git commit date: %s\nClick to copy the version information."), build_date));
13541361
version_btn->connect("pressed", callable_mp(this, &ProjectManager::_version_button_pressed));
13551362
footer_bar->add_child(version_btn);
13561363
}

main/main.cpp

+20-3
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,23 @@ void finalize_theme_db() {
393393
#define MAIN_PRINT(m_txt)
394394
#endif
395395

396+
void Main::print_header(bool p_rich) {
397+
if (VERSION_TIMESTAMP > 0) {
398+
// Version timestamp available.
399+
if (p_rich) {
400+
print_line_rich("\u001b[38;5;39m" + String(VERSION_NAME) + "\u001b[0m v" + get_full_version_string() + " (" + Time::get_singleton()->get_datetime_string_from_unix_time(VERSION_TIMESTAMP, true) + " UTC) - \u001b[4m" + String(VERSION_WEBSITE));
401+
} else {
402+
print_line(String(VERSION_NAME) + " v" + get_full_version_string() + " (" + Time::get_singleton()->get_datetime_string_from_unix_time(VERSION_TIMESTAMP, true) + " UTC) - " + String(VERSION_WEBSITE));
403+
}
404+
} else {
405+
if (p_rich) {
406+
print_line_rich("\u001b[38;5;39m" + String(VERSION_NAME) + "\u001b[0m v" + get_full_version_string() + " - \u001b[4m" + String(VERSION_WEBSITE));
407+
} else {
408+
print_line(String(VERSION_NAME) + " v" + get_full_version_string() + " - " + String(VERSION_WEBSITE));
409+
}
410+
}
411+
}
412+
396413
/**
397414
* Prints a copyright notice in the command-line help with colored text. A newline is
398415
* automatically added at the end.
@@ -463,7 +480,7 @@ void Main::print_help_option(const char *p_option, const char *p_description, CL
463480
}
464481

465482
void Main::print_help(const char *p_binary) {
466-
print_line("\u001b[38;5;39m" + String(VERSION_NAME) + "\u001b[0m v" + get_full_version_string() + " - \u001b[4m" + String(VERSION_WEBSITE) + "\u001b[0m");
483+
print_header(true);
467484
print_help_copyright("Free and open source software under the terms of the MIT license.");
468485
print_help_copyright("(c) 2014-present Godot Engine contributors. (c) 2007-present Juan Linietsky, Ariel Manzur.");
469486

@@ -2468,8 +2485,8 @@ Error Main::setup2() {
24682485
Thread::make_main_thread(); // Make whatever thread call this the main thread.
24692486
set_current_thread_safe_for_nodes(true);
24702487

2471-
// Print engine name and version
2472-
Engine::get_singleton()->print_header(String(VERSION_NAME) + " v" + get_full_version_string() + " - " + String(VERSION_WEBSITE));
2488+
// Don't use rich formatting to prevent ANSI escape codes from being written to log files.
2489+
print_header(false);
24732490

24742491
#ifdef TOOLS_ENABLED
24752492
if (editor || project_manager || cmdline_tool) {

main/main.h

+1
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ class Main {
4646
CLI_OPTION_AVAILABILITY_HIDDEN,
4747
};
4848

49+
static void print_header(bool p_rich);
4950
static void print_help_copyright(const char *p_notice);
5051
static void print_help_title(const char *p_title);
5152
static void print_help_option(const char *p_option, const char *p_description, CLIOptionAvailability p_availability = CLI_OPTION_AVAILABILITY_TEMPLATE_RELEASE);

methods.py

+13
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,18 @@ def get_version_info(module_version_string="", silent=False):
209209
githash = head
210210

211211
version_info["git_hash"] = githash
212+
# Fallback to 0 as a timestamp (will be treated as "unknown" in the engine).
213+
version_info["git_timestamp"] = 0
214+
215+
# Get the UNIX timestamp of the build commit.
216+
if os.path.exists(".git"):
217+
try:
218+
version_info["git_timestamp"] = subprocess.check_output(
219+
["git", "log", "-1", "--pretty=format:%ct", githash]
220+
).decode("utf-8")
221+
except (subprocess.CalledProcessError, OSError):
222+
# `git` not found in PATH.
223+
pass
212224

213225
return version_info
214226

@@ -246,6 +258,7 @@ def generate_version_header(module_version_string=""):
246258
"""/* THIS FILE IS GENERATED DO NOT EDIT */
247259
#include "core/version.h"
248260
const char *const VERSION_HASH = "{git_hash}";
261+
const uint64_t VERSION_TIMESTAMP = {git_timestamp};
249262
""".format(
250263
**version_info
251264
)

0 commit comments

Comments
 (0)