diff options
author | Rémi Verschelde <rverschelde@gmail.com> | 2024-04-29 13:00:30 +0200 |
---|---|---|
committer | Rémi Verschelde <rverschelde@gmail.com> | 2024-04-29 13:00:30 +0200 |
commit | 1f303e00193e1b351669b4a7f541af4504d07ec0 (patch) | |
tree | ea7baac941e1fc2f5cb8dafdd2c8d913357e1075 | |
parent | 77caf02802be9f3a14042243f6da8286e9f836e6 (diff) | |
parent | b3043674f6b1c331835e3c805d29cb0adc5579b1 (diff) | |
download | redot-engine-1f303e00193e1b351669b4a7f541af4504d07ec0.tar.gz |
Merge pull request #89790 from bruvzg/ios_safe_delete
[iOS Export] Check directory content before deleting old export leftovers.
-rw-r--r-- | platform/ios/doc_classes/EditorExportPlatformIOS.xml | 3 | ||||
-rw-r--r-- | platform/ios/export/export_plugin.cpp | 64 |
2 files changed, 62 insertions, 5 deletions
diff --git a/platform/ios/doc_classes/EditorExportPlatformIOS.xml b/platform/ios/doc_classes/EditorExportPlatformIOS.xml index eb226c7993..20c1647843 100644 --- a/platform/ios/doc_classes/EditorExportPlatformIOS.xml +++ b/platform/ios/doc_classes/EditorExportPlatformIOS.xml @@ -29,6 +29,9 @@ <member name="application/code_sign_identity_release" type="String" setter="" getter=""> The "Full Name", "Common Name" or SHA-1 hash of the signing identity used for release export. </member> + <member name="application/delete_old_export_files_unconditionally" type="bool" setter="" getter=""> + If [code]true[/code], existing "project name" and "project name.xcodeproj" in the export destination directory will be unconditionally deleted during export. + </member> <member name="application/export_method_debug" type="int" setter="" getter=""> Application distribution target (debug export). </member> diff --git a/platform/ios/export/export_plugin.cpp b/platform/ios/export/export_plugin.cpp index ab0018d321..c35c72d093 100644 --- a/platform/ios/export/export_plugin.cpp +++ b/platform/ios/export/export_plugin.cpp @@ -287,6 +287,7 @@ void EditorExportPlatformIOS::get_export_options(List<ExportOption> *r_options) 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::BOOL, "application/export_project_only"), false)); + r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "application/delete_old_export_files_unconditionally"), false)); Vector<PluginConfigIOS> found_plugins = get_plugins(); for (int i = 0; i < found_plugins.size(); i++) { @@ -1856,19 +1857,72 @@ Error EditorExportPlatformIOS::_export_project_helper(const Ref<EditorExportPres } { + bool delete_old = p_preset->get("application/delete_old_export_files_unconditionally"); Ref<DirAccess> da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); if (da.is_valid()) { String current_dir = da->get_current_dir(); - // remove leftovers from last export so they don't interfere - // in case some files are no longer needed + // Remove leftovers from last export so they don't interfere in case some files are no longer needed. if (da->change_dir(binary_dir + ".xcodeproj") == OK) { - da->erase_contents_recursive(); + // Check directory content before deleting. + int expected_files = 0; + int total_files = 0; + if (!delete_old) { + da->list_dir_begin(); + for (String n = da->get_next(); !n.is_empty(); n = da->get_next()) { + if (!n.begins_with(".")) { // Ignore ".", ".." and hidden files. + if (da->current_is_dir()) { + if (n == "xcshareddata" || n == "project.xcworkspace") { + expected_files++; + } + } else { + if (n == "project.pbxproj") { + expected_files++; + } + } + total_files++; + } + } + da->list_dir_end(); + } + if ((total_files == 0) || (expected_files >= Math::floor(total_files * 0.8))) { + da->erase_contents_recursive(); + } else { + add_message(EXPORT_MESSAGE_ERROR, TTR("Export"), vformat(TTR("Unexpected files found in the export destination directory \"%s.xcodeproj\", delete it manually or select another destination."), binary_dir)); + return ERR_CANT_CREATE; + } } + da->change_dir(current_dir); + if (da->change_dir(binary_dir) == OK) { - da->erase_contents_recursive(); + // Check directory content before deleting. + int expected_files = 0; + int total_files = 0; + if (!delete_old) { + da->list_dir_begin(); + for (String n = da->get_next(); !n.is_empty(); n = da->get_next()) { + if (!n.begins_with(".")) { // Ignore ".", ".." and hidden files. + if (da->current_is_dir()) { + if (n == "dylibs" || n == "Images.xcassets" || n.ends_with(".lproj") || n == "godot-publish-dotnet" || n.ends_with(".xcframework") || n.ends_with(".framework")) { + expected_files++; + } + } else { + if (n == binary_name + "-Info.plist" || n == binary_name + ".entitlements" || n == "Launch Screen.storyboard" || n == "export_options.plist" || n.begins_with("dummy.") || n.ends_with(".gdip")) { + expected_files++; + } + } + total_files++; + } + } + da->list_dir_end(); + } + if ((total_files == 0) || (expected_files >= Math::floor(total_files * 0.8))) { + da->erase_contents_recursive(); + } else { + add_message(EXPORT_MESSAGE_ERROR, TTR("Export"), vformat(TTR("Unexpected files found in the export destination directory \"%s\", delete it manually or select another destination."), binary_dir)); + return ERR_CANT_CREATE; + } } - da->change_dir(current_dir); if (!da->dir_exists(binary_dir)) { |