Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F15416766
D13202.id31991.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
4 KB
Referenced Files
None
Subscribers
None
D13202.id31991.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D13202: Allow `Filesystem::walkToRoot` to walk to a given root directory
Attached
Detach File
Event Timeline
Log In to Comment