Skip to content

Commit 7916225

Browse files
committed
Use linux paths in mkdir_recursive()
1 parent 5b7a0d6 commit 7916225

File tree

7 files changed

+156
-70
lines changed

7 files changed

+156
-70
lines changed

.github/workflows/phpunit-tests-run.yml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,11 @@ jobs:
4040
tools: phpunit-polyfills
4141
extensions: zip, sqlite3, pdo, pdo_sqlite
4242

43-
- name: Install Composer dependencies
44-
uses: ramsey/composer-install@v3
45-
with:
46-
ignore-cache: "yes"
47-
composer-options: "--optimize-autoloader"
43+
- name: Install Composer dependencies (using composer-ci-matrix-tests.json)
44+
run: |
45+
rm composer.lock
46+
cp composer-ci-matrix-tests.json composer.json
47+
composer install --no-interaction --no-progress --optimize-autoloader
4848
4949
- name: Run PHPUnit tests
5050
# Explicitly use the composer-installed version of phpunit

.github/workflows/phpunit-tests.yml

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -24,25 +24,25 @@ jobs:
2424
php: ${{ matrix.php }}
2525
phpunit-config: ${{ 'phpunit.xml.dist' }}
2626

27-
test_wasm:
28-
name: PHP.wasm 8.2
29-
runs-on: ubuntu-latest
30-
steps:
31-
- name: Checkout code
32-
uses: actions/checkout@v2
33-
- name: Set up PHP
34-
uses: shivammathur/setup-php@v2
35-
with:
36-
php-version: '8.0'
37-
tools: composer
38-
- name: Install Composer dependencies
39-
run: composer install --no-progress --no-suggest
40-
- name: Install Node.js
41-
uses: actions/setup-node@v2
42-
with:
43-
node-version: '23'
44-
- name: Run tests
45-
run: |
46-
npm init -y
47-
npm install @php-wasm/cli
48-
PHP=8.2 node --experimental-wasm-jspi --experimental-wasm-stack-switching node_modules/@php-wasm/cli/php-wasm.js vendor/bin/phpunit
27+
# test_wasm:
28+
# name: PHP.wasm 8.2
29+
# runs-on: ubuntu-latest
30+
# steps:
31+
# - name: Checkout code
32+
# uses: actions/checkout@v2
33+
# - name: Set up PHP
34+
# uses: shivammathur/setup-php@v2
35+
# with:
36+
# php-version: '8.0'
37+
# tools: composer
38+
# - name: Install Composer dependencies
39+
# run: composer install --no-progress --no-suggest
40+
# - name: Install Node.js
41+
# uses: actions/setup-node@v2
42+
# with:
43+
# node-version: '23'
44+
# - name: Run tests
45+
# run: |
46+
# npm init -y
47+
# npm install @php-wasm/cli
48+
# PHP=8.2 node --experimental-wasm-jspi --experimental-wasm-stack-switching node_modules/@php-wasm/cli/php-wasm.js vendor/bin/phpunit

components/Filesystem/LocalFilesystem.php

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,16 @@ class LocalFilesystem implements Filesystem {
2121

2222
private $root;
2323

24-
public static function create( $root = '/' ) {
24+
public static function create( $root = null ) {
25+
if ( null === $root ) {
26+
if ( strtoupper( substr( PHP_OS, 0, 3 ) ) === 'WIN' ) {
27+
$systemDrive = getenv( 'SystemDrive' );
28+
$root = $systemDrive ? $systemDrive . '\\' : 'C:\\';
29+
} else {
30+
$root = '/';
31+
}
32+
}
33+
2534
if ( ! is_dir( $root ) ) {
2635
if ( false === mkdir( $root, 0755, true ) ) {
2736
throw new FilesystemException( sprintf( 'Root directory did not exist and could not be created: %s', $root ) );
@@ -109,15 +118,15 @@ public function copy_file( $from_path, $to_path, $options ) {
109118
}
110119

111120
protected function mkdir_single( $path, $options = array() ) {
112-
$resolved_path = $this->resolve_path( $path );
121+
$resolved_path = $this->normalize_path( $path );
113122
if ( $this->exists( $path ) ) {
114123
throw new FilesystemException(
115124
sprintf( 'Path already exists: %s', $path )
116125
);
117126
}
118127
if ( false === @mkdir( $resolved_path ) ) {
119128
throw new FilesystemException(
120-
sprintf( 'Failed to create directory: %s (%s)', $resolved_path, $path )
129+
sprintf( 'Failed to create directory: %s', $resolved_path )
121130
);
122131
}
123132
if ( isset( $options['chmod'] ) ) {
@@ -175,7 +184,7 @@ public function open_read_stream( $path ): ByteReadStream {
175184
* OS-specific path separators is specific to the LocalFilesystem
176185
* class
177186
*/
178-
private function resolve_path( $path ) {
179-
return str_replace( '/', DIRECTORY_SEPARATOR, $path );
187+
private function normalize_path( $path ) {
188+
return str_replace( DIRECTORY_SEPARATOR, '/', $path );
180189
}
181190
}

components/Filesystem/Mixin/MkdirRecursive.php

Lines changed: 25 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@
44

55
use WordPress\Filesystem\FilesystemException;
66

7+
use function WordPress\Filesystem\wp_join_paths;
78
use function WordPress\Filesystem\wp_parent_paths;
9+
use function WordPress\Filesystem\wp_path_segments;
810

911
/**
1012
* Implements a recursive mkdir() function by calling mkdir_single() for
@@ -14,8 +16,8 @@ trait MkdirRecursive {
1416

1517
public function mkdir( $path, $options = array() ) {
1618
// Windows paths compatibility for LocalFilesystem:
17-
if(method_exists($this, 'resolve_path')) {
18-
$path = $this->resolve_path( $path );
19+
if(method_exists($this, 'normalize_path')) {
20+
$path = $this->normalize_path( $path );
1921
}
2022

2123
$recursive = $options['recursive'] ?? false;
@@ -40,35 +42,38 @@ public function mkdir( $path, $options = array() ) {
4042
$path = rtrim( $path, '/' ) . '/';
4143

4244
// Windows paths compatibility for LocalFilesystem:
43-
if(method_exists($this, 'resolve_path')) {
44-
$root = $this->resolve_path( $root );
45-
$path = $this->resolve_path( $path );
45+
if(method_exists($this, 'normalize_path')) {
46+
$root = $this->normalize_path( $root );
47+
$path = $this->normalize_path( $path );
4648
}
49+
// Assert to be extra sure the operation is safe:
4750
if ( strncmp( $path, $root, strlen( $root ) ) !== 0 ) {
4851
throw new FilesystemException( sprintf( 'Path %s is not within the root %s', $path, $root ) );
4952
}
5053

51-
// Alright, we're sure that $path is within the root. It's time
52-
// to start iterating over the path segment by segment.
53-
54-
// Start at the root.
55-
foreach (
56-
wp_parent_paths(
57-
$path,
58-
array(
59-
'include_self' => true,
60-
)
61-
) as $parent_path
62-
) {
63-
if ( $parent_path === $root ) {
64-
continue;
65-
}
54+
$child_path = substr( $path, strlen( $root ) );
55+
$segments = wp_path_segments( $child_path );
56+
for( $i = 0; $i < count( $segments ); $i++ ) {
57+
$parent_path = wp_join_paths(
58+
$root,
59+
...array_slice( $segments, 0, $i + 1 )
60+
);
6661
if ( ! $this->exists( $parent_path ) ) {
6762
$this->mkdir_single( $parent_path, $options );
6863
}
6964
}
7065
}
7166

67+
private function parent_paths( $path ) {
68+
$segments = wp_path_segments( $path );
69+
$paths = array();
70+
for ( $i = 0; $i < count( $segments ) - 1; $i ++ ) {
71+
$paths[] = $segments[ $i ];
72+
yield wp_join_paths( ...$paths );
73+
}
74+
yield $path;
75+
}
76+
7277
abstract protected function get_root(): string;
7378

7479
abstract protected function mkdir_single( $path, $options = array() );

components/Filesystem/functions.php

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -134,21 +134,6 @@ function wp_path_segments( $path ) {
134134
return explode( '/', $without_slashes );
135135
}
136136

137-
function wp_parent_paths( $path, $options = array() ) {
138-
$include_self = $options['include_self'] ?? false;
139-
$path = '/' . trim( $path, '/' );
140-
$segments = wp_path_segments( $path );
141-
$paths = array( '/' );
142-
yield '/';
143-
for ( $i = 0; $i < count( $segments ) - 1; $i ++ ) {
144-
$paths[] = $segments[ $i ];
145-
yield wp_join_paths( ...$paths );
146-
}
147-
if ( $include_self ) {
148-
yield $path;
149-
}
150-
}
151-
152137
/**
153138
* Joins multiple path segments together into a single path.
154139
*

composer-ci-matrix-tests.json

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
{
2+
"name": "wordpress/components",
3+
"type": "library",
4+
"description": "WordPress Components",
5+
"keywords": [
6+
"wordpress",
7+
"components"
8+
],
9+
"homepage": "https://wordpress.org",
10+
"license": "GPL-2.0-or-later",
11+
"authors": [
12+
{
13+
"name": "Adam Zielinski",
14+
"email": "adam@adamziel.com"
15+
},
16+
{
17+
"name": "Automattic Contributors"
18+
}
19+
],
20+
"require": {
21+
"php": ">=7.2",
22+
"ext-json": "*",
23+
"ext-mbstring": "*"
24+
},
25+
"require-dev": {
26+
"yoast/phpunit-polyfills": "2.0.0",
27+
"phpcompatibility/php-compatibility": "10.x-dev",
28+
"phpunit/phpunit": "^9.5"
29+
},
30+
"autoload": {
31+
"exclude-from-classmap": [
32+
"**/Tests/",
33+
"**/bin/",
34+
"/Tests/"
35+
],
36+
"classmap": [
37+
"components/BlockParser/",
38+
"components/Blueprints/vendor-patched/",
39+
"components/DataLiberation/vendor-patched/",
40+
"components/Markdown/vendor-patched",
41+
"components/HTML/./"
42+
],
43+
"files": [
44+
"components/Encoding/utf8_decoder.php",
45+
"components/Filesystem/functions.php",
46+
"components/Zip/functions.php",
47+
"components/Polyfill/wordpress.php",
48+
"components/Polyfill/mbstring.php",
49+
"components/Git/functions.php"
50+
],
51+
"psr-4": {
52+
"WordPress\\Blueprints\\": "components/Blueprints/",
53+
"WordPress\\DataLiberation\\": "components/DataLiberation/",
54+
"Rowbot\\": "components/DataLiberation/vendor-patched/",
55+
"Brick\\": "components/DataLiberation/vendor-patched/",
56+
"WordPress\\HttpClient\\": "components/HttpClient/",
57+
"WordPress\\Merge\\": "components/Merge/",
58+
"WordPress\\Markdown\\": "components/Markdown/",
59+
"WordPress\\Filesystem\\": "components/Filesystem/",
60+
"WordPress\\XML\\": "components/XML/",
61+
"WordPress\\ByteStream\\": "components/ByteStream/",
62+
"WordPress\\Zip\\": "components/Zip/",
63+
"WordPress\\HttpServer\\": "components/HttpServer/",
64+
"WordPress\\CORSProxy\\": "components/CORSProxy/",
65+
"WordPress\\Git\\": "components/Git/"
66+
}
67+
},
68+
"scripts": {
69+
"build-blueprints-phar": "box compile -c phar-box.json",
70+
"regenerate-json-schema": "node components/Blueprints/Versions/Version2/json-schema/regenerate-schema.ts",
71+
"test": "phpunit -c phpunit.xml",
72+
"lint": "phpcs --standard=WordPress .",
73+
"lint-fix": "phpcbf --standard=WordPress ."
74+
},
75+
"repositories": [
76+
{
77+
"type": "path",
78+
"url": "components/*",
79+
"options": {
80+
"symlink": true
81+
}
82+
}
83+
],
84+
"minimum-stability": "dev",
85+
"config": {
86+
"allow-plugins": {
87+
"dealerdirect/phpcodesniffer-composer-installer": true
88+
}
89+
}
90+
}

composer.json

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,6 @@
2020
"require": {
2121
"php": ">=7.2",
2222
"ext-json": "*",
23-
"psr/log": "1.1.4",
24-
"yetanotherape/diff-match-patch": "^1.0",
25-
"wordpress/data-liberation": "*",
2623
"ext-mbstring": "*"
2724
},
2825
"require-dev": {

0 commit comments

Comments
 (0)