diff --git a/src/applications/diffusion/query/pathid/base/DiffusionPathIDQuery.php b/src/applications/diffusion/query/pathid/base/DiffusionPathIDQuery.php index ae8208df92..e47d5497e1 100644 --- a/src/applications/diffusion/query/pathid/base/DiffusionPathIDQuery.php +++ b/src/applications/diffusion/query/pathid/base/DiffusionPathIDQuery.php @@ -16,6 +16,9 @@ * limitations under the License. */ +/** + * @task pathutil Path Utilities + */ final class DiffusionPathIDQuery { public function __construct(array $paths) { @@ -49,13 +52,55 @@ final class DiffusionPathIDQuery { return $result; } + + /** + * Convert a path to the canonical, absolute representation used by Diffusion. + * + * @param string Some repository path. + * @return string Canonicalized Diffusion path. + * @task pathutil + */ public static function normalizePath($path) { + + // Normalize to single slashes, e.g. "///" => "/". + $path = preg_replace('@[/]{2,}@', '/', $path); + return '/'.trim($path, '/'); } + + /** + * Return the canonical parent directory for a path. Note, returns "/" when + * passed "/". + * + * @param string Some repository path. + * @return string That path's canonical parent directory. + * @task pathutil + */ public static function getParentPath($path) { $path = self::normalizePath($path); return dirname($path); } + + /** + * Generate a list of parents for a repository path. The path itself is + * included. + * + * @param string Some repository path. + * @return list List of canonical paths between the path and the root. + * @task pathutil + */ + public static function expandPathToRoot($path) { + $path = self::normalizePath($path); + $parents = array($path); + $parts = explode('/', trim($path, '/')); + while (count($parts) >= 1) { + if (array_pop($parts)) { + $parents[] = '/'.implode('/', $parts); + } + } + return $parents; + } + } diff --git a/src/applications/diffusion/query/pathid/base/__tests__/DiffusionPathQueryTestCase.php b/src/applications/diffusion/query/pathid/base/__tests__/DiffusionPathQueryTestCase.php index 5a3c0cbbcd..760f4e0409 100644 --- a/src/applications/diffusion/query/pathid/base/__tests__/DiffusionPathQueryTestCase.php +++ b/src/applications/diffusion/query/pathid/base/__tests__/DiffusionPathQueryTestCase.php @@ -31,6 +31,28 @@ final class DiffusionPathQueryTestCase extends PhabricatorTestCase { '/a', DiffusionPathIDQuery::getParentPath('/a/b'), 'Parent of /a/b'); + $this->assertEqual( + '/a', + DiffusionPathIDQuery::getParentPath('/a///b'), + 'Parent of /a///b'); + } + + public function testExpandEdgeCases() { + $this->assertEqual( + array('/'), + DiffusionPathIDQuery::expandPathToRoot('/')); + $this->assertEqual( + array('/'), + DiffusionPathIDQuery::expandPathToRoot('//')); + $this->assertEqual( + array('/a/b', '/a', '/'), + DiffusionPathIDQuery::expandPathToRoot('/a/b')); + $this->assertEqual( + array('/a/b', '/a', '/'), + DiffusionPathIDQuery::expandPathToRoot('/a//b')); + $this->assertEqual( + array('/a/b', '/a', '/'), + DiffusionPathIDQuery::expandPathToRoot('a/b')); } }