Page MenuHomePhabricator

D13202.id31991.diff
No OneTemporary

D13202.id31991.diff

diff --git a/src/filesystem/Filesystem.php b/src/filesystem/Filesystem.php
--- a/src/filesystem/Filesystem.php
+++ b/src/filesystem/Filesystem.php
@@ -731,20 +731,26 @@
/**
- * Return all directories between a path and "/". Iterating over them walks
- * from the path to the root.
+ * Return all directories between a path and the specified root directory
+ * (defaulting to "/"). Iterating over them walks from the path to the root.
*
- * @param string Path, absolute or relative to PWD.
- * @return list List of parent paths, including the provided path.
+ * @param string Path, absolute or relative to PWD.
+ * @param string The root directory.
+ * @return list<string> List of parent paths, including the provided path.
* @task directory
*/
- public static function walkToRoot($path) {
+ public static function walkToRoot($path, $root = '/') {
$path = self::resolvePath($path);
+ $root = self::resolvePath($root);
if (is_link($path)) {
$path = realpath($path);
}
+ if (is_link($root)) {
+ $root = realpath($root);
+ }
+
$walk = array();
$parts = explode(DIRECTORY_SEPARATOR, $path);
foreach ($parts as $k => $part) {
@@ -752,18 +758,23 @@
unset($parts[$k]);
}
}
- do {
+
+ if (!self::isDescendant($path, $root)) {
+ return array();
+ }
+
+ while ($parts &&
+ DIRECTORY_SEPARATOR.implode(DIRECTORY_SEPARATOR, $parts) != $root) {
if (phutil_is_windows()) {
$walk[] = implode(DIRECTORY_SEPARATOR, $parts);
} else {
$walk[] = DIRECTORY_SEPARATOR.implode(DIRECTORY_SEPARATOR, $parts);
}
- if (empty($parts)) {
- break;
- }
+
array_pop($parts);
- } while (true);
+ }
+ $walk[] = $root;
return $walk;
}
@@ -851,7 +862,6 @@
* @task path
*/
public static function isDescendant($path, $root) {
-
try {
self::assertExists($path);
self::assertExists($root);
diff --git a/src/filesystem/__tests__/FilesystemTestCase.php b/src/filesystem/__tests__/FilesystemTestCase.php
--- a/src/filesystem/__tests__/FilesystemTestCase.php
+++ b/src/filesystem/__tests__/FilesystemTestCase.php
@@ -73,4 +73,84 @@
$this->assertTrue($caught instanceof Exception);
}
+ public function testWalkToRoot() {
+ $test_cases = array(
+ array(
+ dirname(__FILE__).'/data/include_dir.txt/subdir.txt',
+ dirname(__FILE__),
+ array(
+ dirname(__FILE__).'/data/include_dir.txt/subdir.txt',
+ dirname(__FILE__).'/data/include_dir.txt',
+ dirname(__FILE__).'/data',
+ dirname(__FILE__),
+ ),
+ ),
+ array(
+ dirname(__FILE__).'/data/include_dir.txt/subdir.txt',
+ dirname(__FILE__),
+ array(
+ dirname(__FILE__).'/data/include_dir.txt/subdir.txt',
+ dirname(__FILE__).'/data/include_dir.txt',
+ dirname(__FILE__).'/data',
+ dirname(__FILE__),
+ ),
+ ),
+ array(
+ dirname(__FILE__),
+ dirname(__FILE__).'/data/include_dir.txt/subdir.txt',
+ array(),
+ ),
+ );
+
+ foreach ($test_cases as $test_case) {
+ list($path, $root, $expected) = $test_case;
+
+ $this->assertEqual(
+ $expected,
+ Filesystem::walkToRoot($path, $root));
+ }
+ }
+
+ public function testisDescendant() {
+ $test_cases = array(
+ array(
+ __FILE__,
+ dirname(__FILE__),
+ true,
+ ),
+ array(
+ dirname(__FILE__),
+ dirname(dirname(__FILE__)),
+ true,
+ ),
+ array(
+ dirname(__FILE__),
+ phutil_get_library_root_for_path(__FILE__),
+ true,
+ ),
+ array(
+ dirname(dirname(__FILE__)),
+ dirname(__FILE__),
+ false,
+ ),
+ array(
+ dirname(__FILE__).'/quack',
+ dirname(__FILE__),
+ false,
+ ),
+ );
+
+ foreach ($test_cases as $test_case) {
+ list($path, $root, $expected) = $test_case;
+
+ $this->assertEqual(
+ $expected,
+ Filesystem::isDescendant($path, $root),
+ sprintf(
+ 'Filesystem::isDescendant(%s, %s)',
+ phutil_var_export($path),
+ phutil_var_export($root)));
+ }
+ }
+
}

File Metadata

Mime Type
text/plain
Expires
Fri, Mar 21, 1:21 PM (2 h, 3 m)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7715499
Default Alt Text
D13202.id31991.diff (4 KB)

Event Timeline