summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHugo Locurcio <hugo.locurcio@hugo.pro>2023-07-17 09:53:45 +0200
committerHugo Locurcio <hugo.locurcio@hugo.pro>2023-08-04 10:29:33 +0200
commitad4480bf2e6c0ff0c4694c7ce8f302376d84be69 (patch)
tree864440acdb66cf3a605210f11d75b65af3df2895
parenteb4301b941fa211de204e37bd4d701f7e490a945 (diff)
downloadredot-engine-ad4480bf2e6c0ff0c4694c7ce8f302376d84be69.tar.gz
Add a "version" project setting and use it in new export presets
This makes it easy to retrieve the project version at runtime for display purposes, while simplifying the export preset configuration. You can now leave the version empty unless you need to override it on a per-preset basis. Since export presets save the values of default values to the `export_presets.cfg` file, this change only affects export presets created after this commit was merged.
-rw-r--r--core/config/project_settings.cpp1
-rw-r--r--doc/classes/ProjectSettings.xml3
-rw-r--r--editor/export/editor_export_preset.cpp33
-rw-r--r--editor/export/editor_export_preset.h7
-rw-r--r--platform/android/doc_classes/EditorExportPlatformAndroid.xml4
-rw-r--r--platform/android/export/export_plugin.cpp10
-rw-r--r--platform/ios/doc_classes/EditorExportPlatformIOS.xml4
-rw-r--r--platform/ios/export/export_plugin.cpp4
-rw-r--r--platform/macos/doc_classes/EditorExportPlatformMacOS.xml4
-rw-r--r--platform/macos/export/export_plugin.cpp4
-rw-r--r--platform/windows/doc_classes/EditorExportPlatformWindows.xml4
-rw-r--r--platform/windows/export/export_plugin.cpp8
12 files changed, 65 insertions, 21 deletions
diff --git a/core/config/project_settings.cpp b/core/config/project_settings.cpp
index 715ed61770..973162a066 100644
--- a/core/config/project_settings.cpp
+++ b/core/config/project_settings.cpp
@@ -1260,6 +1260,7 @@ ProjectSettings::ProjectSettings() {
GLOBAL_DEF_BASIC("application/config/name", "");
GLOBAL_DEF_BASIC(PropertyInfo(Variant::DICTIONARY, "application/config/name_localized", PROPERTY_HINT_LOCALIZABLE_STRING), Dictionary());
GLOBAL_DEF_BASIC(PropertyInfo(Variant::STRING, "application/config/description", PROPERTY_HINT_MULTILINE_TEXT), "");
+ GLOBAL_DEF_BASIC("application/config/version", "");
GLOBAL_DEF_INTERNAL(PropertyInfo(Variant::STRING, "application/config/tags"), PackedStringArray());
GLOBAL_DEF_BASIC(PropertyInfo(Variant::STRING, "application/run/main_scene", PROPERTY_HINT_FILE, "*.tscn,*.scn,*.res"), "");
GLOBAL_DEF("application/run/disable_stdout", false);
diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml
index d240b6ef48..3c4b8837f8 100644
--- a/doc/classes/ProjectSettings.xml
+++ b/doc/classes/ProjectSettings.xml
@@ -297,6 +297,9 @@
[b]Note:[/b] Restart the application after changing this setting.
[b]Note:[/b] Changing this value can help on platforms or with third-party tools where hidden directory patterns are disallowed. Only modify this setting if you know that your environment requires it, as changing the default can impact compatibility with some external tools or plugins which expect the default [code].godot[/code] folder.
</member>
+ <member name="application/config/version" type="String" setter="" getter="" default="&quot;&quot;">
+ The project's human-readable version identifier. This should always be set to a non-empty string, as some exporters rely on this value being defined.
+ </member>
<member name="application/config/windows_native_icon" type="String" setter="" getter="" default="&quot;&quot;">
Icon set in [code].ico[/code] format used on Windows to set the game's icon. This is done automatically on start by calling [method DisplayServer.set_native_icon].
</member>
diff --git a/editor/export/editor_export_preset.cpp b/editor/export/editor_export_preset.cpp
index dfc0c23afc..29a31c0470 100644
--- a/editor/export/editor_export_preset.cpp
+++ b/editor/export/editor_export_preset.cpp
@@ -30,6 +30,8 @@
#include "editor_export.h"
+#include "core/config/project_settings.h"
+
bool EditorExportPreset::_set(const StringName &p_name, const Variant &p_value) {
values[p_name] = p_value;
EditorExport::singleton->save_presets();
@@ -332,4 +334,35 @@ Variant EditorExportPreset::get_or_env(const StringName &p_name, const String &p
return get(p_name, r_valid);
}
+String EditorExportPreset::get_version(const StringName &p_preset_string, bool p_windows_version) const {
+ String result = get(p_preset_string);
+ if (result.is_empty()) {
+ result = GLOBAL_GET("application/config/version");
+
+ if (p_windows_version) {
+ // Modify version number to match Windows constraints (version numbers must have 4 components).
+ const PackedStringArray result_split = result.split(".");
+ String windows_version;
+ if (result_split.is_empty()) {
+ // Use a valid fallback if the version string is empty, as a version number must be specified.
+ result = "1.0.0.0";
+ } else if (result_split.size() == 1) {
+ result = result + ".0.0.0";
+ } else if (result_split.size() == 2) {
+ result = result + ".0.0";
+ } else if (result_split.size() == 3) {
+ result = result + ".0";
+ } else {
+ // 4 components or more in the version string. Trim to contain only the first 4 components.
+ result = vformat("%s.%s.%s.%s", result_split[0] + result_split[1] + result_split[2] + result_split[3]);
+ }
+ } else if (result.is_empty()) {
+ // Use a valid fallback if the version string is empty, as a version number must be specified.
+ result = "1.0.0";
+ }
+ }
+
+ return result;
+}
+
EditorExportPreset::EditorExportPreset() {}
diff --git a/editor/export/editor_export_preset.h b/editor/export/editor_export_preset.h
index 8b59da06dd..025e7603f3 100644
--- a/editor/export/editor_export_preset.h
+++ b/editor/export/editor_export_preset.h
@@ -154,6 +154,13 @@ public:
Variant get_or_env(const StringName &p_name, const String &p_env_var, bool *r_valid = nullptr) const;
+ // Return the preset's version number, or fall back to the
+ // `application/config/version` project setting if set to an empty string.
+ // If `p_windows_version` is `true`, formats the returned version number to
+ // be compatible with Windows executable metadata (which requires a
+ // 4-component format).
+ String get_version(const StringName &p_name, bool p_windows_version = false) const;
+
const HashMap<StringName, PropertyInfo> &get_properties() const { return properties; }
const HashMap<StringName, Variant> &get_values() const { return values; }
diff --git a/platform/android/doc_classes/EditorExportPlatformAndroid.xml b/platform/android/doc_classes/EditorExportPlatformAndroid.xml
index d61d63d242..5031af1027 100644
--- a/platform/android/doc_classes/EditorExportPlatformAndroid.xml
+++ b/platform/android/doc_classes/EditorExportPlatformAndroid.xml
@@ -579,10 +579,10 @@
If [code]true[/code], allows the application to participate in the backup and restore infrastructure.
</member>
<member name="version/code" type="int" setter="" getter="">
- Machine-readable application version.
+ Machine-readable application version. This must be incremented for every new release pushed to the Play Store.
</member>
<member name="version/name" type="String" setter="" getter="">
- Application version visible to the user.
+ Application version visible to the user. Falls back to [member ProjectSettings.application/config/version] if left empty.
</member>
<member name="xr_features/xr_mode" type="int" setter="" getter="">
</member>
diff --git a/platform/android/export/export_plugin.cpp b/platform/android/export/export_plugin.cpp
index 4eb516fb63..9e46085b2a 100644
--- a/platform/android/export/export_plugin.cpp
+++ b/platform/android/export/export_plugin.cpp
@@ -904,7 +904,7 @@ void EditorExportPlatformAndroid::_fix_manifest(const Ref<EditorExportPreset> &p
uint32_t string_table_ends = 0;
Vector<uint8_t> stable_extra;
- String version_name = p_preset->get("version/name");
+ String version_name = p_preset->get_version("version/name");
int version_code = p_preset->get("version/code");
String package_name = p_preset->get("package/unique_name");
@@ -1829,7 +1829,7 @@ void EditorExportPlatformAndroid::get_export_options(List<ExportOption> *r_optio
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "keystore/release_password", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_SECRET), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "version/code", PROPERTY_HINT_RANGE, "1,4096,1,or_greater"), 1));
- r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "version/name"), "1.0"));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "version/name", PROPERTY_HINT_PLACEHOLDER_TEXT, "Leave empty to use project version"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "package/unique_name", PROPERTY_HINT_PLACEHOLDER_TEXT, "ext.domain.name"), "org.godotengine.$genname", false, true));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "package/name", PROPERTY_HINT_PLACEHOLDER_TEXT, "Game Name [default if blank]"), ""));
@@ -1980,7 +1980,7 @@ Error EditorExportPlatformAndroid::run(const Ref<EditorExportPreset> &p_preset,
String output;
bool remove_prev = EDITOR_GET("export/android/one_click_deploy_clear_previous_install");
- String version_name = p_preset->get("version/name");
+ String version_name = p_preset->get_version("version/name");
String package_name = p_preset->get("package/unique_name");
if (remove_prev) {
@@ -2893,7 +2893,7 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP
String package_name = get_package_name(p_preset->get("package/unique_name"));
String version_code = itos(p_preset->get("version/code"));
- String version_name = p_preset->get("version/name");
+ String version_name = p_preset->get_version("version/name");
String min_sdk_version = p_preset->get("gradle_build/min_sdk");
if (!min_sdk_version.is_valid_int()) {
min_sdk_version = itos(VULKAN_MIN_SDK_VERSION);
@@ -3111,7 +3111,7 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP
String cmdline = p_preset->get("command_line/extra_args");
- String version_name = p_preset->get("version/name");
+ String version_name = p_preset->get_version("version/name");
String package_name = p_preset->get("package/unique_name");
String apk_expansion_pkey = p_preset->get("apk_expansion/public_key");
diff --git a/platform/ios/doc_classes/EditorExportPlatformIOS.xml b/platform/ios/doc_classes/EditorExportPlatformIOS.xml
index 84bc0e1277..563c057266 100644
--- a/platform/ios/doc_classes/EditorExportPlatformIOS.xml
+++ b/platform/ios/doc_classes/EditorExportPlatformIOS.xml
@@ -45,7 +45,7 @@
Can be overridden with the environment variable [code]GODOT_IOS_PROVISIONING_PROFILE_UUID_RELEASE[/code].
</member>
<member name="application/short_version" type="String" setter="" getter="">
- Application version visible to the user, can only contain numeric characters ([code]0-9[/code]) and periods ([code].[/code]).
+ Application version visible to the user, can only contain numeric characters ([code]0-9[/code]) and periods ([code].[/code]). Falls back to [member ProjectSettings.application/config/version] if left empty.
</member>
<member name="application/signature" type="String" setter="" getter="">
A four-character creator code that is specific to the bundle. Optional.
@@ -54,7 +54,7 @@
Supported device family.
</member>
<member name="application/version" type="String" setter="" getter="">
- Machine-readable application version, in the [code]major.minor.patch[/code] format, can only contain numeric characters ([code]0-9[/code]) and periods ([code].[/code]).
+ Machine-readable application version, in the [code]major.minor.patch[/code] format, can only contain numeric characters ([code]0-9[/code]) and periods ([code].[/code]). This must be incremented on every new release pushed to the App Store.
</member>
<member name="architectures/arm64" type="bool" setter="" getter="">
If [code]true[/code], [code]arm64[/code] binaries are included into exported project.
diff --git a/platform/ios/export/export_plugin.cpp b/platform/ios/export/export_plugin.cpp
index 544bfb71e0..3d63b7bb55 100644
--- a/platform/ios/export/export_plugin.cpp
+++ b/platform/ios/export/export_plugin.cpp
@@ -177,7 +177,7 @@ void EditorExportPlatformIOS::get_export_options(List<ExportOption> *r_options)
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/bundle_identifier", PROPERTY_HINT_PLACEHOLDER_TEXT, "com.example.game"), "", false, true));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/signature"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/short_version"), "1.0"));
- r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/version"), "1.0"));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/version", PROPERTY_HINT_PLACEHOLDER_TEXT, "Leave empty to use project version"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "application/icon_interpolation", PROPERTY_HINT_ENUM, "Nearest neighbor,Bilinear,Cubic,Trilinear,Lanczos"), 4));
r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "application/launch_screens_interpolation", PROPERTY_HINT_ENUM, "Nearest neighbor,Bilinear,Cubic,Trilinear,Lanczos"), 4));
@@ -284,7 +284,7 @@ void EditorExportPlatformIOS::_fix_config_file(const Ref<EditorExportPreset> &p_
} else if (lines[i].find("$short_version") != -1) {
strnew += lines[i].replace("$short_version", p_preset->get("application/short_version")) + "\n";
} else if (lines[i].find("$version") != -1) {
- strnew += lines[i].replace("$version", p_preset->get("application/version")) + "\n";
+ strnew += lines[i].replace("$version", p_preset->get_version("application/version")) + "\n";
} else if (lines[i].find("$signature") != -1) {
strnew += lines[i].replace("$signature", p_preset->get("application/signature")) + "\n";
} else if (lines[i].find("$team_id") != -1) {
diff --git a/platform/macos/doc_classes/EditorExportPlatformMacOS.xml b/platform/macos/doc_classes/EditorExportPlatformMacOS.xml
index 6af816989d..0e9e2ca43a 100644
--- a/platform/macos/doc_classes/EditorExportPlatformMacOS.xml
+++ b/platform/macos/doc_classes/EditorExportPlatformMacOS.xml
@@ -32,13 +32,13 @@
Minimum version of macOS required for this application to run in the [code]major.minor.patch[/code] or [code]major.minor[/code] format, can only contain numeric characters ([code]0-9[/code]) and periods ([code].[/code]).
</member>
<member name="application/short_version" type="String" setter="" getter="">
- Application version visible to the user, can only contain numeric characters ([code]0-9[/code]) and periods ([code].[/code]).
+ Application version visible to the user, can only contain numeric characters ([code]0-9[/code]) and periods ([code].[/code]). Falls back to [member ProjectSettings.application/config/version] if left empty.
</member>
<member name="application/signature" type="String" setter="" getter="">
A four-character creator code that is specific to the bundle. Optional.
</member>
<member name="application/version" type="String" setter="" getter="">
- Machine-readable application version, in the [code]major.minor.patch[/code] format, can only contain numeric characters ([code]0-9[/code]) and periods ([code].[/code]).
+ Machine-readable application version, in the [code]major.minor.patch[/code] format, can only contain numeric characters ([code]0-9[/code]) and periods ([code].[/code]). This must be incremented on every new release pushed to the App Store.
</member>
<member name="binary_format/architecture" type="String" setter="" getter="">
Application executable architecture.
diff --git a/platform/macos/export/export_plugin.cpp b/platform/macos/export/export_plugin.cpp
index 1afcedc576..e788ff1eec 100644
--- a/platform/macos/export/export_plugin.cpp
+++ b/platform/macos/export/export_plugin.cpp
@@ -378,7 +378,7 @@ void EditorExportPlatformMacOS::get_export_options(List<ExportOption> *r_options
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/signature"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/app_category", PROPERTY_HINT_ENUM, "Business,Developer-tools,Education,Entertainment,Finance,Games,Action-games,Adventure-games,Arcade-games,Board-games,Card-games,Casino-games,Dice-games,Educational-games,Family-games,Kids-games,Music-games,Puzzle-games,Racing-games,Role-playing-games,Simulation-games,Sports-games,Strategy-games,Trivia-games,Word-games,Graphics-design,Healthcare-fitness,Lifestyle,Medical,Music,News,Photography,Productivity,Reference,Social-networking,Sports,Travel,Utilities,Video,Weather"), "Games"));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/short_version"), "1.0"));
- r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/version"), "1.0"));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/version", PROPERTY_HINT_PLACEHOLDER_TEXT, "Leave empty to use project version"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/copyright"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::DICTIONARY, "application/copyright_localized", PROPERTY_HINT_LOCALIZABLE_STRING), Dictionary()));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/min_macos_version"), "10.12"));
@@ -672,7 +672,7 @@ void EditorExportPlatformMacOS::_fix_plist(const Ref<EditorExportPreset> &p_pres
} else if (lines[i].find("$short_version") != -1) {
strnew += lines[i].replace("$short_version", p_preset->get("application/short_version")) + "\n";
} else if (lines[i].find("$version") != -1) {
- strnew += lines[i].replace("$version", p_preset->get("application/version")) + "\n";
+ strnew += lines[i].replace("$version", p_preset->get_version("application/version")) + "\n";
} else if (lines[i].find("$signature") != -1) {
strnew += lines[i].replace("$signature", p_preset->get("application/signature")) + "\n";
} else if (lines[i].find("$app_category") != -1) {
diff --git a/platform/windows/doc_classes/EditorExportPlatformWindows.xml b/platform/windows/doc_classes/EditorExportPlatformWindows.xml
index 80928d7418..64ae9180b6 100644
--- a/platform/windows/doc_classes/EditorExportPlatformWindows.xml
+++ b/platform/windows/doc_classes/EditorExportPlatformWindows.xml
@@ -22,7 +22,7 @@
File description to be presented to users. Required. See [url=https://learn.microsoft.com/en-us/windows/win32/menurc/stringfileinfo-block]StringFileInfo[/url].
</member>
<member name="application/file_version" type="String" setter="" getter="">
- Version number of the file. Required. See [url=https://learn.microsoft.com/en-us/windows/win32/menurc/stringfileinfo-block]StringFileInfo[/url].
+ Version number of the file. Falls back to [member ProjectSettings.application/config/version] if left empty. See [url=https://learn.microsoft.com/en-us/windows/win32/menurc/stringfileinfo-block]StringFileInfo[/url].
</member>
<member name="application/icon" type="String" setter="" getter="">
Application icon file. If left empty, it will fallback to [member ProjectSettings.application/config/windows_native_icon], and then to [member ProjectSettings.application/config/icon].
@@ -37,7 +37,7 @@
Name of the application. Required. See [url=https://learn.microsoft.com/en-us/windows/win32/menurc/stringfileinfo-block]StringFileInfo[/url].
</member>
<member name="application/product_version" type="String" setter="" getter="">
- Application version visible to the user. Required. See [url=https://learn.microsoft.com/en-us/windows/win32/menurc/stringfileinfo-block]StringFileInfo[/url].
+ Application version visible to the user. Falls back to [member ProjectSettings.application/config/version] if left empty. See [url=https://learn.microsoft.com/en-us/windows/win32/menurc/stringfileinfo-block]StringFileInfo[/url].
</member>
<member name="application/trademarks" type="String" setter="" getter="">
Trademarks and registered trademarks that apply to the file. Optional. See [url=https://learn.microsoft.com/en-us/windows/win32/menurc/stringfileinfo-block]StringFileInfo[/url].
diff --git a/platform/windows/export/export_plugin.cpp b/platform/windows/export/export_plugin.cpp
index 0ef07c3275..07c6a8d6e4 100644
--- a/platform/windows/export/export_plugin.cpp
+++ b/platform/windows/export/export_plugin.cpp
@@ -342,8 +342,8 @@ void EditorExportPlatformWindows::get_export_options(List<ExportOption> *r_optio
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/icon", PROPERTY_HINT_FILE, "*.ico,*.png,*.webp,*.svg"), "", false, true));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/console_wrapper_icon", PROPERTY_HINT_FILE, "*.ico,*.png,*.webp,*.svg"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "application/icon_interpolation", PROPERTY_HINT_ENUM, "Nearest neighbor,Bilinear,Cubic,Trilinear,Lanczos"), 4));
- r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/file_version", PROPERTY_HINT_PLACEHOLDER_TEXT, "1.0.0.0"), "", false, true));
- r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/product_version", PROPERTY_HINT_PLACEHOLDER_TEXT, "1.0.0.0"), "", false, true));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/file_version", PROPERTY_HINT_PLACEHOLDER_TEXT, "Leave empty to use project version"), ""));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/product_version", PROPERTY_HINT_PLACEHOLDER_TEXT, "Leave empty to use project version"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/company_name", PROPERTY_HINT_PLACEHOLDER_TEXT, "Company Name"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/product_name", PROPERTY_HINT_PLACEHOLDER_TEXT, "Game Name"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/file_description"), ""));
@@ -425,8 +425,8 @@ Error EditorExportPlatformWindows::_rcedit_add_data(const Ref<EditorExportPreset
}
}
- String file_verion = p_preset->get("application/file_version");
- String product_version = p_preset->get("application/product_version");
+ String file_verion = p_preset->get_version("application/file_version", true);
+ String product_version = p_preset->get_version("application/product_version", true);
String company_name = p_preset->get("application/company_name");
String product_name = p_preset->get("application/product_name");
String file_description = p_preset->get("application/file_description");