Skip to content

Commit 8981c97

Browse files
committed
Adapt code to deal with case-insensitivity through realpath and renames
1 parent 69422bc commit 8981c97

2 files changed

Lines changed: 76 additions & 4 deletions

File tree

features/core-update.feature

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,25 @@ Feature: Update WordPress core
246246
File removed: wp-content
247247
"""
248248

249+
When I run `wp option add str_opt 'bar'`
250+
Then STDOUT should not be empty
251+
When I run `wp post create --post_title='Test post' --porcelain`
252+
Then STDOUT should be a number
253+
254+
Scenario: Make sure files are cleaned up with mixed case
255+
Given a WP install
256+
And I try `wp theme install twentytwenty --activate`
257+
258+
When I run `wp core update --version=5.8 --force`
259+
Then the wp-includes/Requests/Transport/cURL.php file should exist
260+
Then the wp-includes/Requests/Exception/Transport/cURL.php file should exist
261+
Then the wp-includes/Requests/Exception/HTTP/502.php file should exist
262+
Then the wp-includes/Requests/IRI.php file should exist
263+
Then the wp-includes/Requests/Transport/Curl.php file should not exist
264+
Then the wp-includes/Requests/Exception/Transport/Curl.php file should not exist
265+
Then the wp-includes/Requests/Exception/Http/Status502.php file should not exist
266+
Then the wp-includes/Requests/Iri.php file should not exist
267+
249268
When I run `wp core update --version=5.9-beta1 --force`
250269
Then the wp-includes/Requests/Transport/cURL.php file should not exist
251270
Then the wp-includes/Requests/Exception/Transport/cURL.php file should not exist

src/Core_Command.php

Lines changed: 57 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1375,10 +1375,63 @@ private function cleanup_extra_files( $version_from, $version_to, $locale, $inse
13751375
// Compare the files from the old version and the new version in a case-insensitive manner,
13761376
// to prevent files being incorrectly deleted on systems with case-insensitive filesystems
13771377
// when core changes the case of filenames.
1378-
$files_to_remove = array_diff(
1379-
array_map( 'strtolower', array_keys( $old_checksums ) ),
1380-
array_map( 'strtolower', array_keys( $new_checksums ) )
1381-
);
1378+
// The main logic for this was taken from the Joomla project and adapted for WP.
1379+
// See: https://github.com/joomla/joomla-cms/blob/bb5368c7ef9c20270e6e9fcc4b364cd0849082a5/administrator/components/com_admin/script.php#L8158
1380+
1381+
$old_filepaths = array_keys( $old_checksums );
1382+
$new_filepaths = array_keys( $new_checksums );
1383+
1384+
$new_filepaths = array_combine( array_map( 'strtolower', $new_filepaths ), $new_filepaths );
1385+
1386+
$old_filepaths_to_check = array_diff( $old_filepaths, $new_filepaths );
1387+
1388+
foreach ( $old_filepaths_to_check as $old_filepath_to_check ) {
1389+
$old_realpath = realpath( ABSPATH . $old_filepath_to_check );
1390+
1391+
// On Unix without incorrectly cased file.
1392+
if ( false === $old_realpath ) {
1393+
continue;
1394+
}
1395+
1396+
$lowercase_old_filepath_to_check = strtolower( $old_filepath_to_check );
1397+
1398+
if ( ! array_key_exists( $lowercase_old_filepath_to_check, $new_filepaths ) ) {
1399+
$files_to_remove[] = $old_filepath_to_check;
1400+
continue;
1401+
}
1402+
1403+
// We are now left with only the files that are similar from old to new except for their case.
1404+
1405+
$old_basename = basename( $old_realpath );
1406+
$expected_basename = basename( $new_filepaths[ $lowercase_old_filepath_to_check ] );
1407+
$new_realpath = realpath( ABSPATH . $new_filepaths[ $lowercase_old_filepath_to_check ] );
1408+
$new_basename = basename( $new_realpath );
1409+
1410+
// On Windows or Unix with only the incorrectly cased file.
1411+
if ( $new_basename !== $expected_basename ) {
1412+
// Rename the file.
1413+
rename( ABSPATH . $old_filepath_to_check, ABSPATH . $old_filepath_to_check . '.tmp' );
1414+
rename( ABSPATH . $old_filepath_to_check . '.tmp', ABSPATH . $new_filepaths[ $lowercase_old_filepath_to_check ] );
1415+
1416+
continue;
1417+
}
1418+
1419+
// There might still be an incorrectly cased file on other OS than Windows.
1420+
if ( basename( $old_filepath_to_check ) === $old_basename ) {
1421+
// Check if case-insensitive file system, eg on OSX.
1422+
if ( fileinode( $old_realpath ) === fileinode( $new_realpath ) ) {
1423+
// Check deeper because even realpath or glob might not return the actual case.
1424+
if ( ! in_array( $expected_basename, scandir( dirname( $new_realpath ) ), true ) ) {
1425+
// Rename the file.
1426+
rename( ABSPATH . $old_filepath_to_check, ABSPATH . $old_filepath_to_check . '.tmp' );
1427+
rename( ABSPATH . $old_filepath_to_check . '.tmp', ABSPATH . $expected );
1428+
}
1429+
} else {
1430+
// On Unix with both files: Delete the incorrectly cased file.
1431+
$files_to_remove[] = $old_filepath_to_check;
1432+
}
1433+
}
1434+
}
13821435

13831436
if ( ! empty( $files_to_remove ) ) {
13841437
WP_CLI::log( 'Cleaning up files...' );

0 commit comments

Comments
 (0)