Passed
Push — master ( e708d7...ee2e9a )
by Théo
03:48
created

canonicalize()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 4
c 0
b 0
f 0
dl 0
loc 9
rs 10
cc 2
nc 2
nop 1
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the box project.
7
 *
8
 * (c) Kevin Herrera <[email protected]>
9
 *     Théo Fidry <[email protected]>
10
 *
11
 * This source file is subject to the MIT license that is bundled
12
 * with this source code in the file LICENSE.
13
 */
14
15
namespace KevinGH\Box\FileSystem;
16
17
use Symfony\Component\Filesystem\Exception\FileNotFoundException;
18
use Symfony\Component\Filesystem\Exception\IOException;
19
use Traversable;
20
use Webmozart\PathUtil\Path;
21
22
/**
23
 * Canonicalizes the given path.
24
 *
25
 * During normalization, all slashes are replaced by forward slashes ("/").
26
 * Furthermore, all "." and ".." segments are removed as far as possible.
27
 * ".." segments at the beginning of relative paths are not removed.
28
 *
29
 * ```php
30
 * echo Path::canonicalize("\webmozart\puli\..\css\style.css");
31
 * // => /webmozart/css/style.css
32
 *
33
 * echo Path::canonicalize("../css/./style.css");
34
 * // => ../css/style.css
35
 * ```
36
 *
37
 * This method is able to deal with both UNIX and Windows paths.
38
 *
39
 * @param string $path A path string
40
 *
41
 * @return string The canonical path
42
 *
43
 * @private
44
 */
45
function canonicalize(string $path): string
46
{
47
    static $fileSystem;
48
49
    if (null === $fileSystem) {
50
        $fileSystem = new FileSystem();
51
    }
52
53
    return $fileSystem->canonicalize($path);
54
}
55
56
/**
57
 * Normalizes the given path.
58
 *
59
 * During normalization, all slashes are replaced by forward slashes ("/").
60
 * Contrary to {@link canonicalize()}, this method does not remove invalid
61
 * or dot path segments. Consequently, it is much more efficient and should
62
 * be used whenever the given path is known to be a valid, absolute system
63
 * path.
64
 *
65
 * This method is able to deal with both UNIX and Windows paths.
66
 *
67
 * @param string $path a path string
68
 *
69
 * @return string the normalized path
70
 *
71
 * @private
72
 */
73
function normalize(string $path): string
74
{
75
    static $fileSystem;
76
77
    if (null === $fileSystem) {
78
        $fileSystem = new FileSystem();
79
    }
80
81
    return $fileSystem->normalize($path);
82
}
83
84
/**
85
 * Returns the directory part of the path.
86
 *
87
 * This method is similar to PHP's dirname(), but handles various cases
88
 * where dirname() returns a weird result:
89
 *
90
 *  - dirname() does not accept backslashes on UNIX
91
 *  - dirname("C:/webmozart") returns "C:", not "C:/"
92
 *  - dirname("C:/") returns ".", not "C:/"
93
 *  - dirname("C:") returns ".", not "C:/"
94
 *  - dirname("webmozart") returns ".", not ""
95
 *  - dirname() does not canonicalize the result
96
 *
97
 * This method fixes these shortcomings and behaves like dirname()
98
 * otherwise.
99
 *
100
 * The result is a canonical path.
101
 *
102
 * @param string $path a path string
103
 *
104
 * @return string The canonical directory part. Returns the root directory
105
 *                if the root directory is passed. Returns an empty string
106
 *                if a relative path is passed that contains no slashes.
107
 *                Returns an empty string if an empty string is passed.
108
 *
109
 * @private
110
 */
111
function directory(string $path): string
112
{
113
    static $fileSystem;
114
115
    if (null === $fileSystem) {
116
        $fileSystem = new FileSystem();
117
    }
118
119
    return $fileSystem->getDirectory($path);
120
}
121
122
/**
123
 * Returns canonical path of the user's home directory.
124
 *
125
 * Supported operating systems:
126
 *
127
 *  - UNIX
128
 *  - Windows8 and upper
129
 *
130
 * If your operation system or environment isn't supported, an exception is thrown.
131
 *
132
 * The result is a canonical path.
133
 *
134
 * @return string The canonical home directory
135
 *
136
 * @private
137
 */
138
function home_directory(): string
139
{
140
    static $fileSystem;
141
142
    if (null === $fileSystem) {
143
        $fileSystem = new FileSystem();
144
    }
145
146
    return $fileSystem->getHomeDirectory();
147
}
148
149
/**
150
 * Returns the root directory of a path.
151
 *
152
 * The result is a canonical path.
153
 *
154
 * @param string $path a path string
155
 *
156
 * @return string The canonical root directory. Returns an empty string if
157
 *                the given path is relative or empty.
158
 *
159
 * @private
160
 */
161
function root(string $path): string
162
{
163
    static $fileSystem;
164
165
    if (null === $fileSystem) {
166
        $fileSystem = new FileSystem();
167
    }
168
169
    return $fileSystem->getRoot($path);
170
}
171
172
/**
173
 * Returns the file name from a file path.
174
 *
175
 * @param string $path the path string
176
 *
177
 * @return string The file name
178
 *
179
 * @private
180
 */
181
function filename(string $path): string
182
{
183
    static $fileSystem;
184
185
    if (null === $fileSystem) {
186
        $fileSystem = new FileSystem();
187
    }
188
189
    return $fileSystem->getFilename($path);
190
}
191
192
/**
193
 * Returns the file name without the extension from a file path.
194
 *
195
 * @param string      $path      the path string
196
 * @param null|string $extension if specified, only that extension is cut
197
 *                               off (may contain leading dot)
198
 *
199
 * @return string the file name without extension
200
 *
201
 * @private
202
 */
203
function filename_without_extension($path, $extension = null): string
204
{
205
    static $fileSystem;
206
207
    if (null === $fileSystem) {
208
        $fileSystem = new FileSystem();
209
    }
210
211
    return $fileSystem->getFilenameWithoutExtension($path, $extension);
212
}
213
214
/**
215
 * Returns the extension from a file path.
216
 *
217
 * @param string $path           the path string
218
 * @param bool   $forceLowerCase forces the extension to be lower-case
219
 *                               (requires mbstring extension for correct
220
 *                               multi-byte character handling in extension)
221
 *
222
 * @return string the extension of the file path (without leading dot)
223
 *
224
 * @private
225
 */
226
function extension(string $path, bool $forceLowerCase = false): string
227
{
228
    static $fileSystem;
229
230
    if (null === $fileSystem) {
231
        $fileSystem = new FileSystem();
232
    }
233
234
    return $fileSystem->getExtension($path, $forceLowerCase);
235
}
236
237
/**
238
 * Returns whether the path has an extension.
239
 *
240
 * @param string            $path       the path string
241
 * @param null|array|string $extensions if null or not provided, checks if
242
 *                                      an extension exists, otherwise
243
 *                                      checks for the specified extension
244
 *                                      or array of extensions (with or
245
 *                                      without leading dot)
246
 * @param bool              $ignoreCase whether to ignore case-sensitivity
247
 *                                      (requires mbstring extension for
248
 *                                      correct multi-byte character
249
 *                                      handling in the extension)
250
 *
251
 * @return bool returns `true` if the path has an (or the specified)
252
 *              extension and `false` otherwise
253
 *
254
 * @private
255
 */
256
function has_extension(string $path, $extensions = null, bool $ignoreCase = false): bool
257
{
258
    static $fileSystem;
259
260
    if (null === $fileSystem) {
261
        $fileSystem = new FileSystem();
262
    }
263
264
    return $fileSystem->hasExtension($path, $extensions, $ignoreCase);
265
}
266
267
/**
268
 * Changes the extension of a path string.
269
 *
270
 * @param string $path      The path string with filename.ext to change.
271
 * @param string $extension new extension (with or without leading dot)
272
 *
273
 * @return string the path string with new file extension
274
 *
275
 * @private
276
 */
277
function change_extension(string $path, string $extension): string
278
{
279
    static $fileSystem;
280
281
    if (null === $fileSystem) {
282
        $fileSystem = new FileSystem();
283
    }
284
285
    return $fileSystem->changeExtension($path, $extension);
286
}
287
288
/**
289
 * Returns whether the file path is an absolute path.
290
 *
291
 * @param string $path a path string
292
 *
293
 * @private
294
 */
295
function is_absolute_path(string $path): bool
296
{
297
    return Path::isAbsolute($path);
298
}
299
300
/**
301
 * Returns whether a path is relative.
302
 *
303
 * @param string $path a path string
304
 *
305
 * @return bool returns true if the path is relative or empty, false if
306
 *              it is absolute
307
 *
308
 * @private
309
 */
310
function is_relative_path(string $path): bool
311
{
312
    static $fileSystem;
313
314
    if (null === $fileSystem) {
315
        $fileSystem = new FileSystem();
316
    }
317
318
    return $fileSystem->isRelativePath($path);
319
}
320
321
/**
322
 * Turns a relative path into an absolute path.
323
 *
324
 * Usually, the relative path is appended to the given base path. Dot
325
 * segments ("." and "..") are removed/collapsed and all slashes turned
326
 * into forward slashes.
327
 *
328
 * ```php
329
 * echo Path::makeAbsolute("../style.css", "/webmozart/puli/css");
330
 * // => /webmozart/puli/style.css
331
 * ```
332
 *
333
 * If an absolute path is passed, that path is returned unless its root
334
 * directory is different than the one of the base path. In that case, an
335
 * exception is thrown.
336
 *
337
 * ```php
338
 * Path::makeAbsolute("/style.css", "/webmozart/puli/css");
339
 * // => /style.css
340
 *
341
 * Path::makeAbsolute("C:/style.css", "C:/webmozart/puli/css");
342
 * // => C:/style.css
343
 *
344
 * Path::makeAbsolute("C:/style.css", "/webmozart/puli/css");
345
 * // InvalidArgumentException
346
 * ```
347
 *
348
 * If the base path is not an absolute path, an exception is thrown.
349
 *
350
 * The result is a canonical path.
351
 *
352
 * @param string $path     a path to make absolute
353
 * @param string $basePath an absolute base path
354
 *
355
 * @return string an absolute path in canonical form
356
 *
357
 * @private
358
 */
359
function make_path_absolute(string $path, string $basePath): string
360
{
361
    static $fileSystem;
362
363
    if (null === $fileSystem) {
364
        $fileSystem = new FileSystem();
365
    }
366
367
    return $fileSystem->makeAbsolute($path, $basePath);
368
}
369
370
/**
371
 * Turns a path into a relative path.
372
 *
373
 * The relative path is created relative to the given base path:
374
 *
375
 * ```php
376
 * echo Path::makeRelative("/webmozart/style.css", "/webmozart/puli");
377
 * // => ../style.css
378
 * ```
379
 *
380
 * If a relative path is passed and the base path is absolute, the relative
381
 * path is returned unchanged:
382
 *
383
 * ```php
384
 * Path::makeRelative("style.css", "/webmozart/puli/css");
385
 * // => style.css
386
 * ```
387
 *
388
 * If both paths are relative, the relative path is created with the
389
 * assumption that both paths are relative to the same directory:
390
 *
391
 * ```php
392
 * Path::makeRelative("style.css", "webmozart/puli/css");
393
 * // => ../../../style.css
394
 * ```
395
 *
396
 * If both paths are absolute, their root directory must be the same,
397
 * otherwise an exception is thrown:
398
 *
399
 * ```php
400
 * Path::makeRelative("C:/webmozart/style.css", "/webmozart/puli");
401
 * // InvalidArgumentException
402
 * ```
403
 *
404
 * If the passed path is absolute, but the base path is not, an exception
405
 * is thrown as well:
406
 *
407
 * ```php
408
 * Path::makeRelative("/webmozart/style.css", "webmozart/puli");
409
 * // InvalidArgumentException
410
 * ```
411
 *
412
 * If the base path is not an absolute path, an exception is thrown.
413
 *
414
 * The result is a canonical path.
415
 *
416
 * @param string $path     a path to make relative
417
 * @param string $basePath a base path
418
 *
419
 * @return string a relative path in canonical form
420
 *
421
 * @private
422
 */
423
function make_path_relative(string $path, string $basePath): string
424
{
425
    static $fileSystem;
426
427
    if (null === $fileSystem) {
428
        $fileSystem = new FileSystem();
429
    }
430
431
    return $fileSystem->makeRelative($path, $basePath);
432
}
433
434
/**
435
 * Returns whether the given path is on the local filesystem.
436
 *
437
 * @param string $path a path string
438
 *
439
 * @return bool returns true if the path is local, false for a URL
440
 *
441
 * @private
442
 */
443
function is_local(string $path): bool
444
{
445
    static $fileSystem;
446
447
    if (null === $fileSystem) {
448
        $fileSystem = new FileSystem();
449
    }
450
451
    return $fileSystem->isLocal($path);
452
}
453
454
/**
455
 * Returns the longest common base path of a set of paths.
456
 *
457
 * Dot segments ("." and "..") are removed/collapsed and all slashes turned
458
 * into forward slashes.
459
 *
460
 * ```php
461
 * $basePath = Path::getLongestCommonBasePath(array(
462
 *     '/webmozart/css/style.css',
463
 *     '/webmozart/css/..'
464
 * ));
465
 * // => /webmozart
466
 * ```
467
 *
468
 * The root is returned if no common base path can be found:
469
 *
470
 * ```php
471
 * $basePath = Path::getLongestCommonBasePath(array(
472
 *     '/webmozart/css/style.css',
473
 *     '/puli/css/..'
474
 * ));
475
 * // => /
476
 * ```
477
 *
478
 * If the paths are located on different Windows partitions, `null` is
479
 * returned.
480
 *
481
 * ```php
482
 * $basePath = Path::getLongestCommonBasePath(array(
483
 *     'C:/webmozart/css/style.css',
484
 *     'D:/webmozart/css/..'
485
 * ));
486
 * // => null
487
 * ```
488
 *
489
 * @param array $paths a list of paths
490
 *
491
 * @return null|string the longest common base path in canonical form or
492
 *                     `null` if the paths are on different Windows
493
 *                     partitions
494
 *
495
 * @private
496
 */
497
function longest_common_base_path(array $paths): ?string
498
{
499
    static $fileSystem;
500
501
    if (null === $fileSystem) {
502
        $fileSystem = new FileSystem();
503
    }
504
505
    return $fileSystem->getLongestCommonBasePath($paths);
506
}
507
508
/**
509
 * Joins two or more path strings.
510
 *
511
 * The result is a canonical path.
512
 *
513
 * @param string|string[] $paths path parts as parameters or array
514
 *
515
 * @return string the joint path
516
 *
517
 * @private
518
 */
519
function join($paths): string
520
{
521
    static $fileSystem;
522
523
    if (null === $fileSystem) {
524
        $fileSystem = new FileSystem();
525
    }
526
527
    return $fileSystem->join($paths);
528
}
529
530
/**
531
 * Returns whether a path is a base path of another path.
532
 *
533
 * Dot segments ("." and "..") are removed/collapsed and all slashes turned
534
 * into forward slashes.
535
 *
536
 * ```php
537
 * Path::isBasePath('/webmozart', '/webmozart/css');
538
 * // => true
539
 *
540
 * Path::isBasePath('/webmozart', '/webmozart');
541
 * // => true
542
 *
543
 * Path::isBasePath('/webmozart', '/webmozart/..');
544
 * // => false
545
 *
546
 * Path::isBasePath('/webmozart', '/puli');
547
 * // => false
548
 * ```
549
 *
550
 * @param string $basePath the base path to test
551
 * @param string $ofPath   the other path
552
 *
553
 * @return bool whether the base path is a base path of the other path
554
 *
555
 * @private
556
 */
557
function is_base_path(string $basePath, string $ofPath): bool
558
{
559
    static $fileSystem;
560
561
    if (null === $fileSystem) {
562
        $fileSystem = new FileSystem();
563
    }
564
565
    return $fileSystem->isBasePath($basePath, $ofPath);
566
}
567
568
function escape_path(string $path): string
569
{
570
    static $fileSystem;
571
572
    if (null === $fileSystem) {
573
        $fileSystem = new FileSystem();
574
    }
575
576
    return $fileSystem->escapePath($path);
577
}
578
579
/**
580
 * Gets the contents of a file.
581
 *
582
 * @param string $file File path
583
 *
584
 * @throws IOException If the file cannot be read
585
 *
586
 * @return string File contents
587
 *
588
 * @private
589
 */
590
function file_contents(string $file): string
591
{
592
    static $fileSystem;
593
594
    if (null === $fileSystem) {
595
        $fileSystem = new FileSystem();
596
    }
597
598
    return $fileSystem->getFileContents($file);
599
}
600
601
/**
602
 * Copies a file.
603
 *
604
 * If the target file is older than the origin file, it's always overwritten.
605
 * If the target file is newer, it is overwritten only when the
606
 * $overwriteNewerFiles option is set to true.
607
 *
608
 * @param string $originFile          The original filename
609
 * @param string $targetFile          The target filename
610
 * @param bool   $overwriteNewerFiles If true, target files newer than origin files are overwritten
611
 *
612
 * @throws FileNotFoundException When originFile doesn't exist
613
 * @throws IOException           When copy fails
614
 *
615
 * @private
616
 */
617
function copy(string $originFile, string $targetFile, bool $overwriteNewerFiles = false): void
618
{
619
    static $fileSystem;
620
621
    if (null === $fileSystem) {
622
        $fileSystem = new FileSystem();
623
    }
624
625
    $fileSystem->copy($originFile, $targetFile, $overwriteNewerFiles);
626
}
627
628
/**
629
 * Creates a directory recursively.
630
 *
631
 * @param iterable|string $dirs The directory path
632
 * @param int             $mode The directory mode
633
 *
634
 * @throws IOException On any directory creation failure
635
 *
636
 * @private
637
 */
638
function mkdir($dirs, int $mode = 0777): void
639
{
640
    static $fileSystem;
641
642
    if (null === $fileSystem) {
643
        $fileSystem = new FileSystem();
644
    }
645
646
    $fileSystem->mkdir($dirs, $mode);
647
}
648
649
/**
650
 * Removes files or directories.
651
 *
652
 * @param iterable|string $files A filename, an array of files, or a \Traversable instance to remove
653
 *
654
 * @throws IOException When removal fails
655
 *
656
 * @private
657
 */
658
function remove($files): void
659
{
660
    static $fileSystem;
661
662
    if (null === $fileSystem) {
663
        $fileSystem = new FileSystem();
664
    }
665
666
    $fileSystem->remove($files);
667
}
668
669
/**
670
 * Checks the existence of files or directories.
671
 *
672
 * @param iterable|string $files A filename, an array of files, or a \Traversable instance to check
673
 *
674
 * @return bool true if the file exists, false otherwise
675
 *
676
 * @private
677
 */
678
function exists($files): bool
679
{
680
    static $fileSystem;
681
682
    if (null === $fileSystem) {
683
        $fileSystem = new FileSystem();
684
    }
685
686
    return $fileSystem->exists($files);
687
}
688
689
/**
690
 * Sets access and modification time of file.
691
 *
692
 * @param iterable|string $files A filename, an array of files, or a \Traversable instance to create
693
 * @param int             $time  The touch time as a Unix timestamp
694
 * @param int             $atime The access time as a Unix timestamp
695
 *
696
 * @throws IOException When touch fails
697
 *
698
 * @private
699
 */
700
function touch($files, ?int $time = null, ?int $atime = null): void
701
{
702
    static $fileSystem;
703
704
    if (null === $fileSystem) {
705
        $fileSystem = new FileSystem();
706
    }
707
708
    $fileSystem->touch($files, $time, $atime);
709
}
710
711
/**
712
 * Change mode for an array of files or directories.
713
 *
714
 * @param iterable|string $files     A filename, an array of files, or a \Traversable instance to change mode
715
 * @param int             $mode      The new mode (octal)
716
 * @param int             $umask     The mode mask (octal)
717
 * @param bool            $recursive Whether change the mod recursively or not
718
 *
719
 * @throws IOException When the change fail
720
 *
721
 * @private
722
 */
723
function chmod($files, int $mode, int $umask = 0000, bool $recursive = false): void
724
{
725
    static $fileSystem;
726
727
    if (null === $fileSystem) {
728
        $fileSystem = new FileSystem();
729
    }
730
731
    $fileSystem->chmod($files, $mode, $umask, $recursive);
732
}
733
734
/**
735
 * Change the owner of an array of files or directories.
736
 *
737
 * @param iterable|string $files     A filename, an array of files, or a \Traversable instance to change owner
738
 * @param string          $user      The new owner user name
739
 * @param bool            $recursive Whether change the owner recursively or not
740
 *
741
 * @throws IOException When the change fail
742
 *
743
 * @private
744
 */
745
function chown($files, string $user, bool $recursive = false): void
746
{
747
    static $fileSystem;
748
749
    if (null === $fileSystem) {
750
        $fileSystem = new FileSystem();
751
    }
752
753
    $fileSystem->chown($files, $user, $recursive);
754
}
755
756
/**
757
 * Change the group of an array of files or directories.
758
 *
759
 * @param iterable|string $files     A filename, an array of files, or a \Traversable instance to change group
760
 * @param string          $group     The group name
761
 * @param bool            $recursive Whether change the group recursively or not
762
 *
763
 * @throws IOException When the change fail
764
 *
765
 * @private
766
 */
767
function chgrp($files, string $group, bool $recursive = false): void
768
{
769
    static $fileSystem;
770
771
    if (null === $fileSystem) {
772
        $fileSystem = new FileSystem();
773
    }
774
775
    $fileSystem->chgrp($files, $group, $recursive);
776
}
777
778
/**
779
 * Renames a file or a directory.
780
 *
781
 * @param string $origin    The origin filename or directory
782
 * @param string $target    The new filename or directory
783
 * @param bool   $overwrite Whether to overwrite the target if it already exists
784
 *
785
 * @throws IOException When target file or directory already exists
786
 * @throws IOException When origin cannot be renamed
787
 *
788
 * @private
789
 */
790
function rename(string $origin, string $target, bool $overwrite = false): void
791
{
792
    static $fileSystem;
793
794
    if (null === $fileSystem) {
795
        $fileSystem = new FileSystem();
796
    }
797
798
    $fileSystem->rename($origin, $target, $overwrite);
799
}
800
801
/**
802
 * Creates a symbolic link or copy a directory.
803
 *
804
 * @param string $originDir     The origin directory path
805
 * @param string $targetDir     The symbolic link name
806
 * @param bool   $copyOnWindows Whether to copy files if on Windows
807
 *
808
 * @throws IOException When symlink fails
809
 *
810
 * @private
811
 */
812
function symlink(string $originDir, string $targetDir, bool $copyOnWindows = false): void
813
{
814
    static $fileSystem;
815
816
    if (null === $fileSystem) {
817
        $fileSystem = new FileSystem();
818
    }
819
820
    $fileSystem->symlink($originDir, $targetDir, $copyOnWindows);
821
}
822
823
/**
824
 * Creates a hard link, or several hard links to a file.
825
 *
826
 * @param string          $originFile  The original file
827
 * @param string|string[] $targetFiles The target file(s)
828
 *
829
 * @throws FileNotFoundException When original file is missing or not a file
830
 * @throws IOException           When link fails, including if link already exists
831
 *
832
 * @private
833
 */
834
function hardlink(string $originFile, string $targetFiles): void
835
{
836
    static $fileSystem;
837
838
    if (null === $fileSystem) {
839
        $fileSystem = new FileSystem();
840
    }
841
842
    $fileSystem->hardlink($originFile, $targetFiles);
843
}
844
845
/**
846
 * Resolves links in paths.
847
 *
848
 * With $canonicalize = false (default)
849
 *      - if $path does not exist or is not a link, returns null
850
 *      - if $path is a link, returns the next direct target of the link without considering the existence of the target
851
 *
852
 * With $canonicalize = true
853
 *      - if $path does not exist, returns null
854
 *      - if $path exists, returns its absolute fully resolved final version
855
 *
856
 * @param string $path         A filesystem path
857
 * @param bool   $canonicalize Whether or not to return a canonicalized path
858
 *
859
 * @private
860
 */
861
function readlink(string $path, bool $canonicalize = false): ?string
862
{
863
    static $fileSystem;
864
865
    if (null === $fileSystem) {
866
        $fileSystem = new FileSystem();
867
    }
868
869
    return $fileSystem->readlink($path, $canonicalize);
870
}
871
872
/**
873
 * Mirrors a directory to another.
874
 *
875
 * @param string      $originDir The origin directory
876
 * @param string      $targetDir The target directory
877
 * @param Traversable $iterator  A Traversable instance
878
 * @param array       $options   An array of boolean options
879
 *                               Valid options are:
880
 *                               - $options['override'] Whether to override an existing file on copy or not (see copy())
881
 *                               - $options['copy_on_windows'] Whether to copy files instead of links on Windows (see symlink())
882
 *                               - $options['delete'] Whether to delete files that are not in the source directory (defaults to false)
883
 *
884
 * @throws IOException When file type is unknown
885
 *
886
 * @private
887
 */
888
function mirror(string $originDir, string $targetDir, ?Traversable $iterator = null, array $options = []): void
889
{
890
    static $fileSystem;
891
892
    if (null === $fileSystem) {
893
        $fileSystem = new FileSystem();
894
    }
895
896
    $fileSystem->mirror($originDir, $targetDir, $iterator, $options);
897
}
898
899
/**
900
 * Creates a temporary directory.
901
 *
902
 * @param string $namespace the directory path in the system's temporary directory
903
 * @param string $className the name of the test class
904
 *
905
 * @return string the path to the created directory
906
 *
907
 * @private
908
 */
909
function make_tmp_dir(string $namespace, string $className): string
910
{
911
    static $fileSystem;
912
913
    if (null === $fileSystem) {
914
        $fileSystem = new FileSystem();
915
    }
916
917
    return $fileSystem->makeTmpDir($namespace, $className);
918
}
919
920
/**
921
 * Creates a temporary file with support for custom stream wrappers.
922
 *
923
 * @param string $dir    The directory where the temporary filename will be created
924
 * @param string $prefix The prefix of the generated temporary filename
925
 *                       Note: Windows uses only the first three characters of prefix
926
 *
927
 * @return string The new temporary filename (with path), or throw an exception on failure
928
 *
929
 * @private
930
 */
931
function tempnam($dir, $prefix): string
932
{
933
    static $fileSystem;
934
935
    if (null === $fileSystem) {
936
        $fileSystem = new FileSystem();
937
    }
938
939
    return $fileSystem->tempnam($dir, $prefix);
940
}
941
942
/**
943
 * Atomically dumps content into a file.
944
 *
945
 * @param string      $filename The file to be written to
946
 * @param null|string $content  The data to write into the file
947
 *
948
 * @throws IOException if the file cannot be written to
949
 *
950
 * @private
951
 */
952
function dump_file(string $filename, ?string $content = null): void
953
{
954
    static $fileSystem;
955
956
    if (null === $fileSystem) {
957
        $fileSystem = new FileSystem();
958
    }
959
960
    $fileSystem->dumpFile($filename, $content);
961
}
962
963
/**
964
 * Appends content to an existing file.
965
 *
966
 * @param string $filename The file to which to append content
967
 * @param string $content  The content to append
968
 *
969
 * @throws IOException If the file is not writable
970
 *
971
 * @private
972
 */
973
function append_to_file(string $filename, string $content): void
974
{
975
    static $fileSystem;
976
977
    if (null === $fileSystem) {
978
        $fileSystem = new FileSystem();
979
    }
980
981
    $fileSystem->appendToFile($filename, $content);
982
}
983