Merge pull request #34887 from akien-mga/cli-export-usability

Export: Improve usability of command line interface
This commit is contained in:
Rémi Verschelde 2020-01-08 08:19:39 +01:00 committed by GitHub
commit 6fa716c67b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 160 additions and 177 deletions

View file

@ -1485,41 +1485,29 @@ Ref<Texture> EditorExportPlatformPC::get_logo() const {
bool EditorExportPlatformPC::can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const { bool EditorExportPlatformPC::can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const {
String err; String err;
bool valid = true; bool valid = false;
// Look for export templates (first official, and if defined custom templates).
bool use64 = p_preset->get("binary_format/64_bits"); bool use64 = p_preset->get("binary_format/64_bits");
bool dvalid = exists_export_template(use64 ? debug_file_64 : debug_file_32, &err);
bool rvalid = exists_export_template(use64 ? release_file_64 : release_file_32, &err);
if (use64 && (!exists_export_template(debug_file_64, &err) || !exists_export_template(release_file_64, &err))) { if (p_preset->get("custom_template/debug") != "") {
valid = false; dvalid = FileAccess::exists(p_preset->get("custom_template/debug"));
if (!dvalid) {
err += TTR("Custom debug template not found.") + "\n";
}
} }
if (p_preset->get("custom_template/release") != "") {
if (!use64 && (!exists_export_template(debug_file_32, &err) || !exists_export_template(release_file_32, &err))) { rvalid = FileAccess::exists(p_preset->get("custom_template/release"));
valid = false; if (!rvalid) {
} err += TTR("Custom release template not found.") + "\n";
}
String custom_debug_binary = p_preset->get("custom_template/debug");
String custom_release_binary = p_preset->get("custom_template/release");
if (custom_debug_binary == "" && custom_release_binary == "") {
if (!err.empty())
r_error = err;
r_missing_templates = !valid;
return valid;
}
bool dvalid = true;
bool rvalid = true;
if (!FileAccess::exists(custom_debug_binary)) {
dvalid = false;
err += TTR("Custom debug template not found.") + "\n";
}
if (!FileAccess::exists(custom_release_binary)) {
rvalid = false;
err += TTR("Custom release template not found.") + "\n";
} }
valid = dvalid || rvalid; valid = dvalid || rvalid;
r_missing_templates = !valid;
if (!err.empty()) if (!err.empty())
r_error = err; r_error = err;
@ -1600,7 +1588,7 @@ Error EditorExportPlatformPC::export_project(const Ref<EditorExportPreset> &p_pr
if (embedded_size >= 0x100000000 && !p_preset->get("binary_format/64_bits")) { if (embedded_size >= 0x100000000 && !p_preset->get("binary_format/64_bits")) {
EditorNode::get_singleton()->show_warning(TTR("On 32-bit exports the embedded PCK cannot be bigger than 4 GiB.")); EditorNode::get_singleton()->show_warning(TTR("On 32-bit exports the embedded PCK cannot be bigger than 4 GiB."));
return ERR_UNAVAILABLE; return ERR_INVALID_PARAMETER;
} }
FixUpEmbeddedPckFunc fixup_func = get_fixup_embedded_pck_func(); FixUpEmbeddedPckFunc fixup_func = get_fixup_embedded_pck_func();

View file

@ -562,46 +562,68 @@ void EditorNode::_fs_changed() {
_mark_unsaved_scenes(); _mark_unsaved_scenes();
// FIXME: Move this to a cleaner location, it's hacky to do this is _fs_changed.
String export_error;
if (export_defer.preset != "" && !EditorFileSystem::get_singleton()->is_scanning()) { if (export_defer.preset != "" && !EditorFileSystem::get_singleton()->is_scanning()) {
String preset_name = export_defer.preset;
// Ensures export_project does not loop infinitely, because notifications may
// come during the export.
export_defer.preset = "";
Ref<EditorExportPreset> preset; Ref<EditorExportPreset> preset;
for (int i = 0; i < EditorExport::get_singleton()->get_export_preset_count(); ++i) { for (int i = 0; i < EditorExport::get_singleton()->get_export_preset_count(); ++i) {
preset = EditorExport::get_singleton()->get_export_preset(i); preset = EditorExport::get_singleton()->get_export_preset(i);
if (preset->get_name() == export_defer.preset) { if (preset->get_name() == preset_name) {
break; break;
} }
preset.unref(); preset.unref();
} }
if (preset.is_null()) { if (preset.is_null()) {
String errstr = "Unknown export preset: " + export_defer.preset; export_error = vformat("Invalid export preset name: %s.", preset_name);
ERR_PRINTS(errstr);
OS::get_singleton()->set_exit_code(EXIT_FAILURE);
} else { } else {
Ref<EditorExportPlatform> platform = preset->get_platform(); Ref<EditorExportPlatform> platform = preset->get_platform();
if (platform.is_null()) { if (platform.is_null()) {
String errstr = "Preset \"" + export_defer.preset + "\" doesn't have a platform."; export_error = vformat("Export preset '%s' doesn't have a matching platform.", preset_name);
ERR_PRINTS(errstr);
OS::get_singleton()->set_exit_code(EXIT_FAILURE);
} else { } else {
// ensures export_project does not loop infinitely, because notifications may
// come during the export
export_defer.preset = "";
Error err = OK; Error err = OK;
// FIXME: This way to export only resources .pck or .zip is pretty hacky
// and undocumented, and might be problematic for platforms where .zip is
// a valid project export format (e.g. macOS).
if (export_defer.path.ends_with(".pck") || export_defer.path.ends_with(".zip")) { if (export_defer.path.ends_with(".pck") || export_defer.path.ends_with(".zip")) {
if (export_defer.path.ends_with(".zip")) { if (export_defer.path.ends_with(".zip")) {
err = platform->export_zip(preset, export_defer.debug, export_defer.path); err = platform->export_zip(preset, export_defer.debug, export_defer.path);
} else if (export_defer.path.ends_with(".pck")) { } else if (export_defer.path.ends_with(".pck")) {
err = platform->export_pack(preset, export_defer.debug, export_defer.path); err = platform->export_pack(preset, export_defer.debug, export_defer.path);
} }
} else { } else { // Normal project export.
err = platform->export_project(preset, export_defer.debug, export_defer.path); String config_error;
bool missing_templates;
if (!platform->can_export(preset, config_error, missing_templates)) {
ERR_PRINT(vformat("Cannot export project with preset '%s' due to configuration errors:\n%s", preset_name, config_error));
err = missing_templates ? ERR_FILE_NOT_FOUND : ERR_UNCONFIGURED;
} else {
err = platform->export_project(preset, export_defer.debug, export_defer.path);
}
} }
if (err != OK) { switch (err) {
ERR_PRINTS(vformat(TTR("Project export failed with error code %d."), (int)err)); case OK:
OS::get_singleton()->set_exit_code(EXIT_FAILURE); break;
case ERR_FILE_NOT_FOUND:
export_error = vformat("Project export failed for preset '%s', the export template appears to be missing.", preset_name);
break;
case ERR_FILE_BAD_PATH:
export_error = vformat("Project export failed for preset '%s', the target path '%s' appears to be invalid.", preset_name, export_defer.path);
break;
default:
export_error = vformat("Project export failed with error code %d for preset '%s'.", (int)err, preset_name);
break;
} }
} }
} }
if (!export_error.empty()) {
ERR_PRINT(export_error);
OS::get_singleton()->set_exit_code(EXIT_FAILURE);
}
_exit_editor(); _exit_editor();
} }
} }
@ -3920,12 +3942,11 @@ void EditorNode::_editor_file_dialog_unregister(EditorFileDialog *p_dialog) {
Vector<EditorNodeInitCallback> EditorNode::_init_callbacks; Vector<EditorNodeInitCallback> EditorNode::_init_callbacks;
Error EditorNode::export_preset(const String &p_preset, const String &p_path, bool p_debug, const String &p_password, bool p_quit_after) { Error EditorNode::export_preset(const String &p_preset, const String &p_path, bool p_debug) {
export_defer.preset = p_preset; export_defer.preset = p_preset;
export_defer.path = p_path; export_defer.path = p_path;
export_defer.debug = p_debug; export_defer.debug = p_debug;
export_defer.password = p_password;
disable_progress_dialog = true; disable_progress_dialog = true;
return OK; return OK;
} }
@ -6531,12 +6552,6 @@ EditorNode::EditorNode() {
gui_base->add_child(file); gui_base->add_child(file);
file->set_current_dir("res://"); file->set_current_dir("res://");
file_export = memnew(EditorFileDialog);
file_export->set_access(EditorFileDialog::ACCESS_FILESYSTEM);
gui_base->add_child(file_export);
file_export->set_title(TTR("Export Project"));
file_export->connect("file_selected", this, "_dialog_action");
file_export_lib = memnew(EditorFileDialog); file_export_lib = memnew(EditorFileDialog);
file_export_lib->set_title(TTR("Export Library")); file_export_lib->set_title(TTR("Export Library"));
file_export_lib->set_mode(EditorFileDialog::MODE_SAVE_FILE); file_export_lib->set_mode(EditorFileDialog::MODE_SAVE_FILE);
@ -6547,11 +6562,6 @@ EditorNode::EditorNode() {
file_export_lib->get_vbox()->add_child(file_export_lib_merge); file_export_lib->get_vbox()->add_child(file_export_lib_merge);
gui_base->add_child(file_export_lib); gui_base->add_child(file_export_lib);
file_export_password = memnew(LineEdit);
file_export_password->set_secret(true);
file_export_password->set_editable(false);
file_export->get_vbox()->add_margin_child(TTR("Password:"), file_export_password);
file_script = memnew(EditorFileDialog); file_script = memnew(EditorFileDialog);
file_script->set_title(TTR("Open & Run a Script")); file_script->set_title(TTR("Open & Run a Script"));
file_script->set_access(EditorFileDialog::ACCESS_FILESYSTEM); file_script->set_access(EditorFileDialog::ACCESS_FILESYSTEM);

View file

@ -325,18 +325,13 @@ private:
ExportTemplateManager *export_template_manager; ExportTemplateManager *export_template_manager;
EditorFeatureProfileManager *feature_profile_manager; EditorFeatureProfileManager *feature_profile_manager;
EditorFileDialog *file_templates; EditorFileDialog *file_templates;
EditorFileDialog *file_export;
EditorFileDialog *file_export_lib; EditorFileDialog *file_export_lib;
EditorFileDialog *file_script; EditorFileDialog *file_script;
CheckBox *file_export_lib_merge; CheckBox *file_export_lib_merge;
LineEdit *file_export_password;
String current_path; String current_path;
MenuButton *update_spinner; MenuButton *update_spinner;
String defer_load_scene; String defer_load_scene;
String defer_export;
String defer_export_platform;
bool defer_export_debug;
Node *_last_instanced_scene; Node *_last_instanced_scene;
EditorLog *log; EditorLog *log;
@ -563,8 +558,6 @@ private:
String preset; String preset;
String path; String path;
bool debug; bool debug;
String password;
} export_defer; } export_defer;
bool disable_progress_dialog; bool disable_progress_dialog;
@ -786,7 +779,7 @@ public:
void _copy_warning(const String &p_str); void _copy_warning(const String &p_str);
Error export_preset(const String &p_preset, const String &p_path, bool p_debug, const String &p_password, bool p_quit_after = false); Error export_preset(const String &p_preset, const String &p_path, bool p_debug);
static void register_editor_types(); static void register_editor_types();
static void unregister_editor_types(); static void unregister_editor_types();

View file

@ -286,8 +286,10 @@ void Main::print_help(const char *p_binary) {
OS::get_singleton()->print(" -s, --script <script> Run a script.\n"); OS::get_singleton()->print(" -s, --script <script> Run a script.\n");
OS::get_singleton()->print(" --check-only Only parse for errors and quit (use with --script).\n"); OS::get_singleton()->print(" --check-only Only parse for errors and quit (use with --script).\n");
#ifdef TOOLS_ENABLED #ifdef TOOLS_ENABLED
OS::get_singleton()->print(" --export <target> <path> Export the project using the given export target. Export only main pack if path ends with .pck or .zip. <path> is relative to the project directory.\n"); OS::get_singleton()->print(" --export <preset> <path> Export the project using the given preset and matching release template. The preset name should match one defined in export_presets.cfg.\n");
OS::get_singleton()->print(" --export-debug <target> <path> Like --export, but use debug template.\n"); OS::get_singleton()->print(" <path> should be absolute or relative to the project directory, and include the filename for the binary (e.g. 'builds/game.exe').\n");
OS::get_singleton()->print(" The target directory should exist. Only the data pack is exported if <path> ends with .pck or .zip.\n");
OS::get_singleton()->print(" --export-debug <preset> <path> Same as --export, but using the debug template.\n");
OS::get_singleton()->print(" --doctool <path> Dump the engine API reference to the given <path> in XML format, merging if existing files are found.\n"); OS::get_singleton()->print(" --doctool <path> Dump the engine API reference to the given <path> in XML format, merging if existing files are found.\n");
OS::get_singleton()->print(" --no-docbase Disallow dumping the base types (used with --doctool).\n"); OS::get_singleton()->print(" --no-docbase Disallow dumping the base types (used with --doctool).\n");
OS::get_singleton()->print(" --build-solutions Build the scripting solutions (e.g. for C# projects).\n"); OS::get_singleton()->print(" --build-solutions Build the scripting solutions (e.g. for C# projects).\n");
@ -1513,11 +1515,11 @@ bool Main::start() {
if (_export_preset != "") { if (_export_preset != "") {
if (game_path == "") { if (game_path == "") {
String err = "Command line param "; String err = "Command line parameter ";
err += export_debug ? "--export-debug" : "--export"; err += export_debug ? "--export-debug" : "--export";
err += " passed but no destination path given.\n"; err += " passed but no destination path given.\n";
err += "Please specify the binary's file path to export to. Aborting export."; err += "Please specify the binary's file path to export to. Aborting export.";
ERR_PRINT(err.utf8().get_data()); ERR_PRINT(err);
return false; return false;
} }
} }
@ -1698,20 +1700,14 @@ bool Main::start() {
} }
#ifdef TOOLS_ENABLED #ifdef TOOLS_ENABLED
EditorNode *editor_node = NULL; EditorNode *editor_node = NULL;
if (editor) { if (editor) {
editor_node = memnew(EditorNode); editor_node = memnew(EditorNode);
sml->get_root()->add_child(editor_node); sml->get_root()->add_child(editor_node);
//root_node->set_editor(editor);
//startup editor
if (_export_preset != "") { if (_export_preset != "") {
editor_node->export_preset(_export_preset, game_path, export_debug);
editor_node->export_preset(_export_preset, game_path, export_debug, "", true); game_path = ""; // Do not load anything.
game_path = ""; //no load anything
} }
} }
#endif #endif

View file

@ -1299,9 +1299,9 @@ public:
r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "graphics/degrees_of_freedom", PROPERTY_HINT_ENUM, "None,3DOF and 6DOF,6DOF"), 0)); r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "graphics/degrees_of_freedom", PROPERTY_HINT_ENUM, "None,3DOF and 6DOF,6DOF"), 0));
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "graphics/32_bits_framebuffer"), true)); r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "graphics/32_bits_framebuffer"), true));
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "one_click_deploy/clear_previous_install"), false)); r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "one_click_deploy/clear_previous_install"), false));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_package/debug", PROPERTY_HINT_GLOBAL_FILE, "*.apk"), "")); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_template/debug", PROPERTY_HINT_GLOBAL_FILE, "*.apk"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_package/release", PROPERTY_HINT_GLOBAL_FILE, "*.apk"), "")); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_template/release", PROPERTY_HINT_GLOBAL_FILE, "*.apk"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "custom_package/use_custom_build"), false)); r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "custom_template/use_custom_build"), false));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "command_line/extra_args"), "")); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "command_line/extra_args"), ""));
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::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"), "1.0"));
@ -1577,29 +1577,34 @@ public:
virtual bool can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const { virtual bool can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const {
String err; String err;
bool valid = false;
if (!bool(p_preset->get("custom_package/use_custom_build"))) { // Look for export templates (first official, and if defined custom templates).
r_missing_templates = find_export_template("android_debug.apk") == String() || find_export_template("android_release.apk") == String(); if (!bool(p_preset->get("custom_template/use_custom_build"))) {
bool dvalid = exists_export_template("android_debug.apk", &err);
bool rvalid = exists_export_template("android_release.apk", &err);
if (p_preset->get("custom_package/debug") != "") { if (p_preset->get("custom_template/debug") != "") {
if (FileAccess::exists(p_preset->get("custom_package/debug"))) { dvalid = FileAccess::exists(p_preset->get("custom_template/debug"));
r_missing_templates = false; if (!dvalid) {
} else {
err += TTR("Custom debug template not found.") + "\n"; err += TTR("Custom debug template not found.") + "\n";
} }
} }
if (p_preset->get("custom_template/release") != "") {
if (p_preset->get("custom_package/release") != "") { rvalid = FileAccess::exists(p_preset->get("custom_template/release"));
if (FileAccess::exists(p_preset->get("custom_package/release"))) { if (!rvalid) {
r_missing_templates = false;
} else {
err += TTR("Custom release template not found.") + "\n"; err += TTR("Custom release template not found.") + "\n";
} }
} }
}
bool valid = !r_missing_templates; valid = dvalid || rvalid;
} else {
valid = exists_export_template("android_source.zip", &err);
}
r_missing_templates = !valid;
// Validate the rest of the configuration.
String adb = EditorSettings::get_singleton()->get("export/android/adb"); String adb = EditorSettings::get_singleton()->get("export/android/adb");
@ -1628,7 +1633,7 @@ public:
} }
} }
if (bool(p_preset->get("custom_package/use_custom_build"))) { if (bool(p_preset->get("custom_template/use_custom_build"))) {
String sdk_path = EditorSettings::get_singleton()->get("export/android/custom_build_sdk_path"); String sdk_path = EditorSettings::get_singleton()->get("export/android/custom_build_sdk_path");
if (sdk_path == "") { if (sdk_path == "") {
err += TTR("Custom build requires a valid Android SDK path in Editor Settings.") + "\n"; err += TTR("Custom build requires a valid Android SDK path in Editor Settings.") + "\n";
@ -1949,7 +1954,7 @@ public:
EditorProgress ep("export", "Exporting for Android", 105, true); EditorProgress ep("export", "Exporting for Android", 105, true);
if (bool(p_preset->get("custom_package/use_custom_build"))) { //custom build if (bool(p_preset->get("custom_template/use_custom_build"))) { //custom build
//re-generate build.gradle and AndroidManifest.xml //re-generate build.gradle and AndroidManifest.xml
{ //test that installed build version is alright { //test that installed build version is alright
@ -2017,9 +2022,9 @@ public:
} else { } else {
if (p_debug) if (p_debug)
src_apk = p_preset->get("custom_package/debug"); src_apk = p_preset->get("custom_template/debug");
else else
src_apk = p_preset->get("custom_package/release"); src_apk = p_preset->get("custom_template/release");
src_apk = src_apk.strip_edges(); src_apk = src_apk.strip_edges();
if (src_apk == "") { if (src_apk == "") {

View file

@ -206,8 +206,8 @@ static const LoadingScreenInfo loading_screen_infos[] = {
void EditorExportPlatformIOS::get_export_options(List<ExportOption> *r_options) { void EditorExportPlatformIOS::get_export_options(List<ExportOption> *r_options) {
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_package/debug", PROPERTY_HINT_GLOBAL_FILE, "*.zip"), "")); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_template/debug", PROPERTY_HINT_GLOBAL_FILE, "*.zip"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_package/release", PROPERTY_HINT_GLOBAL_FILE, "*.zip"), "")); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_template/release", PROPERTY_HINT_GLOBAL_FILE, "*.zip"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/app_store_team_id"), "")); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/app_store_team_id"), ""));
@ -848,9 +848,9 @@ Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_p
ERR_FAIL_COND_V_MSG(team_id.length() == 0, ERR_CANT_OPEN, "App Store Team ID not specified - cannot configure the project."); ERR_FAIL_COND_V_MSG(team_id.length() == 0, ERR_CANT_OPEN, "App Store Team ID not specified - cannot configure the project.");
if (p_debug) if (p_debug)
src_pkg_name = p_preset->get("custom_package/debug"); src_pkg_name = p_preset->get("custom_template/debug");
else else
src_pkg_name = p_preset->get("custom_package/release"); src_pkg_name = p_preset->get("custom_template/release");
if (src_pkg_name == "") { if (src_pkg_name == "") {
String err; String err;
@ -1156,25 +1156,30 @@ Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_p
bool EditorExportPlatformIOS::can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const { bool EditorExportPlatformIOS::can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const {
String err; String err;
r_missing_templates = find_export_template("iphone.zip") == String(); bool valid = false;
if (p_preset->get("custom_package/debug") != "") { // Look for export templates (first official, and if defined custom templates).
if (FileAccess::exists(p_preset->get("custom_package/debug"))) {
r_missing_templates = false; bool dvalid = exists_export_template("iphone.zip", &err);
} else { bool rvalid = dvalid; // Both in the same ZIP.
if (p_preset->get("custom_template/debug") != "") {
dvalid = FileAccess::exists(p_preset->get("custom_template/debug"));
if (!dvalid) {
err += TTR("Custom debug template not found.") + "\n"; err += TTR("Custom debug template not found.") + "\n";
} }
} }
if (p_preset->get("custom_template/release") != "") {
if (p_preset->get("custom_package/release") != "") { rvalid = FileAccess::exists(p_preset->get("custom_template/release"));
if (FileAccess::exists(p_preset->get("custom_package/release"))) { if (!rvalid) {
r_missing_templates = false;
} else {
err += TTR("Custom release template not found.") + "\n"; err += TTR("Custom release template not found.") + "\n";
} }
} }
bool valid = !r_missing_templates; valid = dvalid || rvalid;
r_missing_templates = !valid;
// Validate the rest of the configuration.
String team_id = p_preset->get("application/app_store_team_id"); String team_id = p_preset->get("application/app_store_team_id");
if (team_id.length() == 0) { if (team_id.length() == 0) {

View file

@ -288,32 +288,32 @@ Ref<Texture> EditorExportPlatformJavaScript::get_logo() const {
bool EditorExportPlatformJavaScript::can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const { bool EditorExportPlatformJavaScript::can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const {
bool valid = false;
String err; String err;
bool valid = false;
if (find_export_template(EXPORT_TEMPLATE_WEBASSEMBLY_RELEASE) != "") // Look for export templates (first official, and if defined custom templates).
valid = true;
else if (find_export_template(EXPORT_TEMPLATE_WEBASSEMBLY_DEBUG) != "") bool dvalid = exists_export_template(EXPORT_TEMPLATE_WEBASSEMBLY_DEBUG, &err);
valid = true; bool rvalid = exists_export_template(EXPORT_TEMPLATE_WEBASSEMBLY_RELEASE, &err);
if (p_preset->get("custom_template/debug") != "") { if (p_preset->get("custom_template/debug") != "") {
if (FileAccess::exists(p_preset->get("custom_template/debug"))) { dvalid = FileAccess::exists(p_preset->get("custom_template/debug"));
valid = true; if (!dvalid) {
} else {
err += TTR("Custom debug template not found.") + "\n"; err += TTR("Custom debug template not found.") + "\n";
} }
} }
if (p_preset->get("custom_template/release") != "") { if (p_preset->get("custom_template/release") != "") {
if (FileAccess::exists(p_preset->get("custom_template/release"))) { rvalid = FileAccess::exists(p_preset->get("custom_template/release"));
valid = true; if (!rvalid) {
} else {
err += TTR("Custom release template not found.") + "\n"; err += TTR("Custom release template not found.") + "\n";
} }
} }
valid = dvalid || rvalid;
r_missing_templates = !valid; r_missing_templates = !valid;
// Validate the rest of the configuration.
if (p_preset->get("vram_texture_compression/for_mobile")) { if (p_preset->get("vram_texture_compression/for_mobile")) {
String etc_error = test_etc2(); String etc_error = test_etc2();
if (etc_error != String()) { if (etc_error != String()) {

View file

@ -118,8 +118,8 @@ void EditorExportPlatformOSX::get_preset_features(const Ref<EditorExportPreset>
void EditorExportPlatformOSX::get_export_options(List<ExportOption> *r_options) { void EditorExportPlatformOSX::get_export_options(List<ExportOption> *r_options) {
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_package/debug", PROPERTY_HINT_GLOBAL_FILE, "*.zip"), "")); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_template/debug", PROPERTY_HINT_GLOBAL_FILE, "*.zip"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_package/release", PROPERTY_HINT_GLOBAL_FILE, "*.zip"), "")); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_template/release", PROPERTY_HINT_GLOBAL_FILE, "*.zip"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/name", PROPERTY_HINT_PLACEHOLDER_TEXT, "Game Name"), "")); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/name", PROPERTY_HINT_PLACEHOLDER_TEXT, "Game Name"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/info"), "Made with Godot Engine")); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/info"), "Made with Godot Engine"));
@ -459,9 +459,9 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p
EditorProgress ep("export", "Exporting for OSX", 3, true); EditorProgress ep("export", "Exporting for OSX", 3, true);
if (p_debug) if (p_debug)
src_pkg_name = p_preset->get("custom_package/debug"); src_pkg_name = p_preset->get("custom_template/debug");
else else
src_pkg_name = p_preset->get("custom_package/release"); src_pkg_name = p_preset->get("custom_template/release");
if (src_pkg_name == "") { if (src_pkg_name == "") {
String err; String err;
@ -796,33 +796,32 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p
bool EditorExportPlatformOSX::can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const { bool EditorExportPlatformOSX::can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const {
bool valid = false;
String err; String err;
bool valid = false;
if (exists_export_template("osx.zip", &err)) { // Look for export templates (first official, and if defined custom templates).
valid = true;
}
if (p_preset->get("custom_package/debug") != "") { bool dvalid = exists_export_template("osx.zip", &err);
if (FileAccess::exists(p_preset->get("custom_package/debug"))) { bool rvalid = dvalid; // Both in the same ZIP.
valid = true;
} else { if (p_preset->get("custom_template/debug") != "") {
dvalid = FileAccess::exists(p_preset->get("custom_template/debug"));
if (!dvalid) {
err += TTR("Custom debug template not found.") + "\n"; err += TTR("Custom debug template not found.") + "\n";
} }
} }
if (p_preset->get("custom_template/release") != "") {
if (p_preset->get("custom_package/release") != "") { rvalid = FileAccess::exists(p_preset->get("custom_template/release"));
if (FileAccess::exists(p_preset->get("custom_package/release"))) { if (!rvalid) {
valid = true;
} else {
err += TTR("Custom release template not found.") + "\n"; err += TTR("Custom release template not found.") + "\n";
} }
} }
valid = dvalid || rvalid;
r_missing_templates = !valid;
if (!err.empty()) if (!err.empty())
r_error = err; r_error = err;
r_missing_templates = !valid;
return valid; return valid;
} }

View file

@ -1090,15 +1090,14 @@ public:
} }
virtual bool can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const { virtual bool can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const {
String err; String err;
bool valid = true; bool valid = false;
// Look for export templates (first official, and if defined custom templates).
Platform arch = (Platform)(int)(p_preset->get("architecture/target")); Platform arch = (Platform)(int)(p_preset->get("architecture/target"));
String custom_debug_binary = p_preset->get("custom_template/debug");
String custom_release_binary = p_preset->get("custom_template/release");
String platform_infix; String platform_infix;
switch (arch) { switch (arch) {
case EditorExportPlatformUWP::ARM: { case EditorExportPlatformUWP::ARM: {
platform_infix = "arm"; platform_infix = "arm";
@ -1111,38 +1110,26 @@ public:
} break; } break;
} }
if (!exists_export_template("uwp_" + platform_infix + "_debug.zip", &err) || !exists_export_template("uwp_" + platform_infix + "_release.zip", &err)) { bool dvalid = exists_export_template("uwp_" + platform_infix + "_debug.zip", &err);
valid = false; bool rvalid = exists_export_template("uwp_" + platform_infix + "_release.zip", &err);
r_missing_templates = true;
}
if (!valid && custom_debug_binary == "" && custom_release_binary == "") { if (p_preset->get("custom_template/debug") != "") {
if (!err.empty()) { dvalid = FileAccess::exists(p_preset->get("custom_template/debug"));
r_error = err; if (!dvalid) {
err += TTR("Custom debug template not found.") + "\n";
}
}
if (p_preset->get("custom_template/release") != "") {
rvalid = FileAccess::exists(p_preset->get("custom_template/release"));
if (!rvalid) {
err += TTR("Custom release template not found.") + "\n";
} }
return valid;
} }
bool dvalid = true; valid = dvalid || rvalid;
bool rvalid = true; r_missing_templates = !valid;
if (!FileAccess::exists(custom_debug_binary)) { // Validate the rest of the configuration.
dvalid = false;
err += TTR("Custom debug template not found.") + "\n";
}
if (!FileAccess::exists(custom_release_binary)) {
rvalid = false;
err += TTR("Custom release template not found.") + "\n";
}
if (dvalid || rvalid)
valid = true;
if (!valid) {
r_error = err;
return valid;
}
if (!_valid_resource_name(p_preset->get("package/short_name"))) { if (!_valid_resource_name(p_preset->get("package/short_name"))) {
valid = false; valid = false;