Skip to content

Commit b304367

Browse files
committed
[iOS Export] Check directory content before deleting old export leftovers.
1 parent fe01776 commit b304367

File tree

2 files changed

+62
-5
lines changed

2 files changed

+62
-5
lines changed

platform/ios/doc_classes/EditorExportPlatformIOS.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@
2929
<member name="application/code_sign_identity_release" type="String" setter="" getter="">
3030
The "Full Name", "Common Name" or SHA-1 hash of the signing identity used for release export.
3131
</member>
32+
<member name="application/delete_old_export_files_unconditionally" type="bool" setter="" getter="">
33+
If [code]true[/code], existing "project name" and "project name.xcodeproj" in the export destination directory will be unconditionally deleted during export.
34+
</member>
3235
<member name="application/export_method_debug" type="int" setter="" getter="">
3336
Application distribution target (debug export).
3437
</member>

platform/ios/export/export_plugin.cpp

Lines changed: 59 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,7 @@ void EditorExportPlatformIOS::get_export_options(List<ExportOption> *r_options)
170170
r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "application/icon_interpolation", PROPERTY_HINT_ENUM, "Nearest neighbor,Bilinear,Cubic,Trilinear,Lanczos"), 4));
171171

172172
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "application/export_project_only"), false));
173+
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "application/delete_old_export_files_unconditionally"), false));
173174

174175
Vector<PluginConfigIOS> found_plugins = get_plugins();
175176
for (int i = 0; i < found_plugins.size(); i++) {
@@ -1627,19 +1628,72 @@ Error EditorExportPlatformIOS::_export_project_helper(const Ref<EditorExportPres
16271628
}
16281629

16291630
{
1631+
bool delete_old = p_preset->get("application/delete_old_export_files_unconditionally");
16301632
Ref<DirAccess> da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
16311633
if (da.is_valid()) {
16321634
String current_dir = da->get_current_dir();
16331635

1634-
// remove leftovers from last export so they don't interfere
1635-
// in case some files are no longer needed
1636+
// Remove leftovers from last export so they don't interfere in case some files are no longer needed.
16361637
if (da->change_dir(binary_dir + ".xcodeproj") == OK) {
1637-
da->erase_contents_recursive();
1638+
// Check directory content before deleting.
1639+
int expected_files = 0;
1640+
int total_files = 0;
1641+
if (!delete_old) {
1642+
da->list_dir_begin();
1643+
for (String n = da->get_next(); !n.is_empty(); n = da->get_next()) {
1644+
if (!n.begins_with(".")) { // Ignore ".", ".." and hidden files.
1645+
if (da->current_is_dir()) {
1646+
if (n == "xcshareddata" || n == "project.xcworkspace") {
1647+
expected_files++;
1648+
}
1649+
} else {
1650+
if (n == "project.pbxproj") {
1651+
expected_files++;
1652+
}
1653+
}
1654+
total_files++;
1655+
}
1656+
}
1657+
da->list_dir_end();
1658+
}
1659+
if ((total_files == 0) || (expected_files >= Math::floor(total_files * 0.8))) {
1660+
da->erase_contents_recursive();
1661+
} else {
1662+
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));
1663+
return ERR_CANT_CREATE;
1664+
}
16381665
}
1666+
da->change_dir(current_dir);
1667+
16391668
if (da->change_dir(binary_dir) == OK) {
1640-
da->erase_contents_recursive();
1669+
// Check directory content before deleting.
1670+
int expected_files = 0;
1671+
int total_files = 0;
1672+
if (!delete_old) {
1673+
da->list_dir_begin();
1674+
for (String n = da->get_next(); !n.is_empty(); n = da->get_next()) {
1675+
if (!n.begins_with(".")) { // Ignore ".", ".." and hidden files.
1676+
if (da->current_is_dir()) {
1677+
if (n == "dylibs" || n == "Images.xcassets" || n.ends_with(".lproj") || n == "godot-publish-dotnet" || n.ends_with(".xcframework") || n.ends_with(".framework")) {
1678+
expected_files++;
1679+
}
1680+
} else {
1681+
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")) {
1682+
expected_files++;
1683+
}
1684+
}
1685+
total_files++;
1686+
}
1687+
}
1688+
da->list_dir_end();
1689+
}
1690+
if ((total_files == 0) || (expected_files >= Math::floor(total_files * 0.8))) {
1691+
da->erase_contents_recursive();
1692+
} else {
1693+
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));
1694+
return ERR_CANT_CREATE;
1695+
}
16411696
}
1642-
16431697
da->change_dir(current_dir);
16441698

16451699
if (!da->dir_exists(binary_dir)) {

0 commit comments

Comments
 (0)