Skip to content
Permalink
Browse files

Helpers: added findCommonDirectory()

  • Loading branch information...
milo authored and dg committed Feb 20, 2019
1 parent 5787f67 commit 7921975497b74631537ac456c8edb979b136b07a
@@ -36,6 +36,35 @@ public static function purge(string $dir): void
}
/**
* Find common directory for given paths. All files or directories must exist.
* @return string Empty when not found. Slash and back slash chars normalized to DIRECTORY_SEPARATOR.
*/
public static function findCommonDirectory(array $paths): string
{
$splitPaths = array_map(function ($s) {
$real = realpath($s);
if ($s === '') {
throw new \RuntimeException('Path must not be empty.');
} elseif ($real === false) {
throw new \RuntimeException("File or directory '$s' does not exist.");
}
return explode(DIRECTORY_SEPARATOR, $real);
}, $paths);
$first = (array) array_shift($splitPaths);
for ($i = 0; $i < count($first); $i++) {
foreach ($splitPaths as $s) {
if ($first[$i] !== ($s[$i] ?? null)) {
break 2;
}
}
}
$common = implode(DIRECTORY_SEPARATOR, array_slice($first, 0, $i));
return is_dir($common) ? $common : dirname($common);
}
/**
* Parse phpDoc comment.
* @internal
@@ -0,0 +1,56 @@
<?php
declare(strict_types=1);
use Tester\Assert;
use Tester\Helpers;
require __DIR__ . '/../bootstrap.php';
Assert::same('', Helpers::findCommonDirectory([]));
Assert::match(__DIR__ . DIRECTORY_SEPARATOR . 'fixtures.helpers', Helpers::findCommonDirectory([
__DIR__ . '/fixtures.helpers/a',
__DIR__ . '/fixtures.helpers/aa',
]));
Assert::match(__DIR__ . DIRECTORY_SEPARATOR . 'fixtures.helpers', Helpers::findCommonDirectory([
__DIR__ . '/fixtures.helpers/a/file.txt',
__DIR__ . '/fixtures.helpers/aa/file.txt',
]));
Assert::match(__DIR__ . DIRECTORY_SEPARATOR . 'fixtures.helpers' . DIRECTORY_SEPARATOR . 'a', Helpers::findCommonDirectory([
__DIR__ . '/fixtures.helpers/a/',
__DIR__ . '/fixtures.helpers/a/file.txt',
]));
Assert::match(getcwd(), Helpers::findCommonDirectory([
'.',
]));
Assert::match(dirname(getcwd()), Helpers::findCommonDirectory([
'..',
]));
// Root directories always end by directory separator.
if (is_dir('C:/')) {
Assert::match('C:\\', Helpers::findCommonDirectory([
'C:',
]));
}
if (is_dir('/')) {
Assert::match(realpath('/'), Helpers::findCommonDirectory([ // realpath() - may point to C:\ in Cygwin
'/',
]));
}
Assert::exception(function () {
Helpers::findCommonDirectory(['']);
}, RuntimeException::class, 'Path must not be empty.');
Assert::exception(function () {
Helpers::findCommonDirectory(['does-not-exist']);
}, RuntimeException::class, "File or directory 'does-not-exist' does not exist.");

0 comments on commit 7921975

Please sign in to comment.
You can’t perform that action at this time.