Ori.livneh has uploaded a new change for review. https://gerrit.wikimedia.org/r/242217
Change subject: Add mediawiki/relpath 1.0.1 ...................................................................... Add mediawiki/relpath 1.0.1 Corresponding mediawiki/core change: If29924908 Change-Id: Ia3d5364854002fd626d50a3cc3fc1edf98f55a87 --- M composer.json M composer.lock M composer/autoload_files.php M composer/installed.json A mediawiki/relpath/.editorconfig A mediawiki/relpath/.gitignore A mediawiki/relpath/.gitreview A mediawiki/relpath/.travis.yml A mediawiki/relpath/Doxyfile A mediawiki/relpath/LICENSE A mediawiki/relpath/README.md A mediawiki/relpath/composer.json A mediawiki/relpath/phpcs.xml A mediawiki/relpath/phpunit.xml.dist A mediawiki/relpath/src/RelPath.php A mediawiki/relpath/tests/RelPathTest.php 16 files changed, 456 insertions(+), 1 deletion(-) git pull ssh://gerrit.wikimedia.org:29418/mediawiki/vendor refs/changes/17/242217/1 diff --git a/composer.json b/composer.json index 1a94486..6bc4792 100644 --- a/composer.json +++ b/composer.json @@ -15,6 +15,7 @@ "kzykhys/pygments": "1.0", "liuggio/statsd-php-client": "1.0.16", "mediawiki/at-ease": "1.1.0", + "mediawiki/relpath": "1.0.1" "monolog/monolog": "1.14.0", "nmred/kafka-php": "0.1.4", "oojs/oojs-ui": "0.12.9", diff --git a/composer.lock b/composer.lock index 5069119..b800247 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "9cf7e0b192195daad37f81c2ed18760f", + "hash": "ba828ae7f1adacc17882c52da021f7c2", "packages": [ { "name": "composer/semver", @@ -274,6 +274,48 @@ "time": "2015-09-18 07:02:06" }, { + "name": "mediawiki/relpath", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/wikimedia/RelPath.git", + "reference": "3fbcb7b2f43b05cf8dab085a63729e47dd3d5e5c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/wikimedia/RelPath/zipball/3fbcb7b2f43b05cf8dab085a63729e47dd3d5e5c", + "reference": "3fbcb7b2f43b05cf8dab085a63729e47dd3d5e5c", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "jakub-onderka/php-parallel-lint": "^0.9.0.0", + "mediawiki/mediawiki-codesniffer": "^0.4.0.0", + "phpunit/phpunit": "^4.8.9.0" + }, + "type": "library", + "autoload": { + "files": [ + "src/RelPath.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ori Livneh", + "email": "o...@wikimedia.org" + } + ], + "description": "Compute a relative filepath to some path either from the current directory or from an optional start directory.", + "homepage": "https://www.mediawiki.org/wiki/RelPath", + "time": "2015-09-29 07:30:57" + }, + { "name": "monolog/monolog", "version": "1.14.0", "source": { diff --git a/composer/autoload_files.php b/composer/autoload_files.php index fba07a7..76032be 100644 --- a/composer/autoload_files.php +++ b/composer/autoload_files.php @@ -7,4 +7,5 @@ return array( $vendorDir . '/mediawiki/at-ease/src/Functions.php', + $vendorDir . '/mediawiki/relpath/src/RelPath.php', ); diff --git a/composer/installed.json b/composer/installed.json index 33f6a1a..8e20974 100644 --- a/composer/installed.json +++ b/composer/installed.json @@ -1095,5 +1095,49 @@ "php", "stylesheet" ] + }, + { + "name": "mediawiki/relpath", + "version": "1.0.1", + "version_normalized": "1.0.1.0", + "source": { + "type": "git", + "url": "https://github.com/wikimedia/RelPath.git", + "reference": "3fbcb7b2f43b05cf8dab085a63729e47dd3d5e5c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/wikimedia/RelPath/zipball/3fbcb7b2f43b05cf8dab085a63729e47dd3d5e5c", + "reference": "3fbcb7b2f43b05cf8dab085a63729e47dd3d5e5c", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "jakub-onderka/php-parallel-lint": "^0.9.0.0", + "mediawiki/mediawiki-codesniffer": "^0.4.0.0", + "phpunit/phpunit": "^4.8.9.0" + }, + "time": "2015-09-29 07:30:57", + "type": "library", + "installation-source": "dist", + "autoload": { + "files": [ + "src/RelPath.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ori Livneh", + "email": "o...@wikimedia.org" + } + ], + "description": "Compute a relative filepath to some path either from the current directory or from an optional start directory.", + "homepage": "https://www.mediawiki.org/wiki/RelPath" } ] diff --git a/mediawiki/relpath/.editorconfig b/mediawiki/relpath/.editorconfig new file mode 100644 index 0000000..7c8c7ab --- /dev/null +++ b/mediawiki/relpath/.editorconfig @@ -0,0 +1,5 @@ +# http://editorconfig.org +root = true + +[*] +indent_style = tab diff --git a/mediawiki/relpath/.gitignore b/mediawiki/relpath/.gitignore new file mode 100644 index 0000000..c760786 --- /dev/null +++ b/mediawiki/relpath/.gitignore @@ -0,0 +1,4 @@ +/coverage +/doc +/vendor +/composer.lock diff --git a/mediawiki/relpath/.gitreview b/mediawiki/relpath/.gitreview new file mode 100644 index 0000000..e12fd8b --- /dev/null +++ b/mediawiki/relpath/.gitreview @@ -0,0 +1,6 @@ +[gerrit] +host=gerrit.wikimedia.org +port=29418 +project=RelPath.git +defaultbranch=master +defaultrebase=0 diff --git a/mediawiki/relpath/.travis.yml b/mediawiki/relpath/.travis.yml new file mode 100644 index 0000000..c25a516 --- /dev/null +++ b/mediawiki/relpath/.travis.yml @@ -0,0 +1,13 @@ +sudo: false +language: php +php: + - "5.3.3" + - "5.3" + - "5.4" + - "5.5" + - "5.6" + - "hhvm" +install: + - composer install +script: + - composer test diff --git a/mediawiki/relpath/Doxyfile b/mediawiki/relpath/Doxyfile new file mode 100644 index 0000000..f4ce8b2 --- /dev/null +++ b/mediawiki/relpath/Doxyfile @@ -0,0 +1,26 @@ +# Doxyfile for RelPath +# +# See <http://www.stack.nl/~dimitri/doxygen/manual/config.html> +# for help on how to use this file to configure Doxygen. + +PROJECT_NAME = "RelPath" +PROJECT_BRIEF = "Compute a relative filepath between two paths" +OUTPUT_DIRECTORY = doc +JAVADOC_AUTOBRIEF = YES +QT_AUTOBRIEF = YES +WARN_NO_PARAMDOC = YES +INPUT = README.md src/ +FILE_PATTERNS = *.php +RECURSIVE = YES +USE_MDFILE_AS_MAINPAGE = README.md +HTML_DYNAMIC_SECTIONS = YES +GENERATE_TREEVIEW = YES +TREEVIEW_WIDTH = 250 +GENERATE_LATEX = NO +HAVE_DOT = YES +DOT_FONTNAME = Helvetica +DOT_FONTSIZE = 10 +TEMPLATE_RELATIONS = YES +CALL_GRAPH = NO +CALLER_GRAPH = NO +DOT_MULTI_TARGETS = YES diff --git a/mediawiki/relpath/LICENSE b/mediawiki/relpath/LICENSE new file mode 100644 index 0000000..ad55c12 --- /dev/null +++ b/mediawiki/relpath/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2015 Ori Livneh <o...@wikimedia.org> + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/mediawiki/relpath/README.md b/mediawiki/relpath/README.md new file mode 100644 index 0000000..c34562c --- /dev/null +++ b/mediawiki/relpath/README.md @@ -0,0 +1,23 @@ +RelPath +======= + +RelPath is a small PHP library for computing a relative filepath to some path, +either from the current directory or from an optional start directory. + +Here is how you use it: + +```php + +$relPath = RelPath\getRelativePath( '/srv/mediawiki/resources/src/startup.js', '/srv/mediawiki' ); +// Result: string(24) "resources/src/startup.js" + +$fullPath = RelPath\joinPath( '/srv/mediawiki', 'resources/src/startup.js' ); +// Result: string(39) "/srv/mediawiki/resources/src/startup.js" + + +``` + +License +------- + +MIT diff --git a/mediawiki/relpath/composer.json b/mediawiki/relpath/composer.json new file mode 100644 index 0000000..8775be0 --- /dev/null +++ b/mediawiki/relpath/composer.json @@ -0,0 +1,32 @@ +{ + "name": "mediawiki/relpath", + "description": "Compute a relative filepath to some path either from the current directory or from an optional start directory.", + "license": "MIT", + "homepage": "https://www.mediawiki.org/wiki/RelPath", + "authors": [ + { + "name": "Ori Livneh", + "email": "o...@wikimedia.org" + } + ], + "autoload": { + "files": [ + "src/RelPath.php" + ] + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "jakub-onderka/php-parallel-lint": "^0.9.0.0", + "phpunit/phpunit": "^4.8.9.0", + "mediawiki/mediawiki-codesniffer": "^0.4.0.0" + }, + "scripts": { + "test": [ + "parallel-lint . --exclude vendor", + "phpunit $PHPUNIT_ARGS", + "phpcs -p" + ] + } +} diff --git a/mediawiki/relpath/phpcs.xml b/mediawiki/relpath/phpcs.xml new file mode 100644 index 0000000..a55f518 --- /dev/null +++ b/mediawiki/relpath/phpcs.xml @@ -0,0 +1,11 @@ +<?xml version="1.0"?> +<ruleset> + <rule ref="vendor/mediawiki/mediawiki-codesniffer/MediaWiki"/> + + <file>.</file> + <arg name="encoding" value="UTF-8"/> + <arg name="extensions" value="php"/> + <exclude-pattern>coverage</exclude-pattern> + <exclude-pattern>vendor</exclude-pattern> + <exclude-pattern>doc/html</exclude-pattern> +</ruleset> diff --git a/mediawiki/relpath/phpunit.xml.dist b/mediawiki/relpath/phpunit.xml.dist new file mode 100644 index 0000000..5127b29 --- /dev/null +++ b/mediawiki/relpath/phpunit.xml.dist @@ -0,0 +1,14 @@ +<phpunit colors="true" + beStrictAboutTestsThatDoNotTestAnything="true" + beStrictAboutOutputDuringTests="true"> + <testsuites> + <testsuite name="RelPath Tests"> + <directory>./tests</directory> + </testsuite> + </testsuites> + <filter> + <whitelist addUncoveredFilesFromWhitelist="true"> + <directory suffix=".php">./src</directory> + </whitelist> + </filter> +</phpunit> diff --git a/mediawiki/relpath/src/RelPath.php b/mediawiki/relpath/src/RelPath.php new file mode 100644 index 0000000..d54b502 --- /dev/null +++ b/mediawiki/relpath/src/RelPath.php @@ -0,0 +1,127 @@ +<?php +/** + * Copyright (c) 2015 Ori Livneh <o...@wikimedia.org> + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * @file + * @author Ori Livneh <o...@wikimedia.org> + */ + +namespace RelPath; + +/** + * Split a path into path components. + * + * @param string $path File path. + * @return array Array of path components. + */ +function splitPath( $path ) { + $fragments = array(); + while ( true ) { + $cur = dirname( $path ); + if ( $cur === $path || ( $cur === '.' && basename( $path ) === $path ) ) { + break; + } + $fragments[] = trim( substr( $path, strlen( $cur ) ), '/' ); + $path = $cur; + } + if ( $path !== '' ) { + $fragments[] = trim( $path, '/' ); + } + return array_reverse( $fragments ); +} + +/** + * Return a relative filepath to path either from the current directory or from + * an optional start directory. Both paths must be absolute. + * + * @param string $path File path. + * @param string $start Start directory. Optional; if not specified, the current + * working directory will be used. + * @return array|bool Array of path components or false if file does not exist. + */ +function getRelativePath( $path, $start = null ) { + if ( $start === null ) { + $start = getcwd(); + } + + if ( substr( $path, 0, 1 ) !== '/' || substr( $start, 0, 1 ) !== '/' ) { + return false; + } + + $pathParts = splitPath( $path ); + $countPathParts = count( $pathParts ); + + $startParts = splitPath( $start ); + $countStartParts = count( $startParts ); + + $commonLength = min( $countPathParts, $countStartParts ); + for ( $i = 0; $i < $commonLength; $i++ ) { + if ( $startParts[$i] !== $pathParts[$i] ) { + break; + } + } + + $relList = ( $countStartParts > $i ) + ? array_fill( 0, $countStartParts - $i, '..' ) + : array(); + + $relList = array_merge( $relList, array_slice( $pathParts, $i ) ); + + return implode( '/', $relList ) ?: '.'; +} + + +/** + * Join path components. + * + * @param string $base Base path. + * @param string $path File path to join to base path. + * @return string + */ +function joinPath( $base, $path ) { + if ( substr( $path, 0, 1 ) === '/' ) { + return $path; // $path is absolute. + } + + if ( substr( $base, 0, 1 ) !== '/' ) { + return false; + } + + $pathParts = splitPath( $path ); + $resultParts = splitPath( $base ); + + while ( ( $part = array_shift( $pathParts ) ) !== null ) { + switch ( $part ) { + case '.': + break; + case '..': + if ( count( $resultParts ) > 1 ) { + array_pop( $resultParts ); + } + break; + default: + $resultParts[] = $part; + break; + } + } + return implode( '/', $resultParts ); +} diff --git a/mediawiki/relpath/tests/RelPathTest.php b/mediawiki/relpath/tests/RelPathTest.php new file mode 100644 index 0000000..8b83c12 --- /dev/null +++ b/mediawiki/relpath/tests/RelPathTest.php @@ -0,0 +1,87 @@ +<?php +/** + * Copyright (c) 2015 Ori Livneh <o...@wikimedia.org> + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * @file + * @author Ori Livneh <o...@wikimedia.org> + */ + +class RelPathTest extends \PHPUnit_Framework_TestCase { + + public function provideRelPathTestCases() { + return array( + array( '/foo/bar/', '/foo/bar/baz/', '..' ), + array( '/foo/bar/', '/foo/bar/baz.txt', '..' ), + array( '/foo/bar/', '/foo/bar/', '.' ), + array( '/foo/bar/', '/foo/bar/', '.' ), + array( '/', '/foo/', '..' ), + array( '/', '/foo/bar.txt', '../..' ), + array( '/', '/foo/bar/baz.txt', '../../..' ), + array( '/foo/bar/', '/foo/baz/', '../bar' ), + array( '/foo/bar/', '/foo/baz.txt', '../bar' ), + array( '/foo/bar/baz/', '/foo/bar/', 'baz' ), + array( '/foo/bar/baz', '/foo/bar', 'baz' ), + array( '/foo/bar.txt', '/foo/baz/', '../bar.txt' ), + array( '/foo/bar.txt', '/foo/baz.txt', '../bar.txt' ), + array( '/foo/bar', '/foo/baz/', '../bar' ), + array( '/foo/bar', '/foo/baz.txt', '../bar' ), + array( '/foo/bar', '/foo/bar/baz/', '..' ), + array( '/foo/bar', '/foo/bar/baz.txt', '..' ), + array( '/foo/bar/bat', '/x/y/z', '../../../foo/bar/bat' ), + array( '/foo/bar/bat', '/foo/bar', 'bat' ), + array( '/foo/bar/bat', '/', 'foo/bar/bat' ), + array( '/', '/foo/bar/bat', '../../..' ), + array( '/foo/bar/bat', '/x', '../foo/bar/bat' ), + array( '/x', '/foo/bar/bat', '../../../x' ), + array( '/', '/', '.' ), + array( '/a', '/a', '.' ), + array( '/a/b', '/a/b', '.' ), + ); + } + + public function provideJoinPathTestCases() { + return array( + array( '/foo/bar', './baz', '/foo/bar/baz' ), + array( '/foo/bar', '/tmp/file/', '/tmp/file/' ), + array( '/foo/bar', 'file', '/foo/bar/file' ), + array( '/foo/bar', '.file', '/foo/bar/.file' ), + array( '/foo//bar', '../baz', '/foo/baz' ), + array( '/foo//bar', '../../baz', '/baz' ), + array( '/foo//bar', '../../../baz', '/baz' ), + array( '/', '../../../baz', '/baz' ), + ); + } + + /** + * @dataProvider provideRelPathTestCases + */ + public function testRelPath( $path, $start, $expected ) { + $this->assertEquals( $expected, RelPath\getRelativePath( $path, $start ) ); + } + + /** + * @dataProvider provideJoinPathTestCases + */ + public function testJoinPath( $base, $path, $expected ) { + $this->assertEquals( $expected, RelPath\joinPath( $base, $path ) ); + } +} -- To view, visit https://gerrit.wikimedia.org/r/242217 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ia3d5364854002fd626d50a3cc3fc1edf98f55a87 Gerrit-PatchSet: 1 Gerrit-Project: mediawiki/vendor Gerrit-Branch: master Gerrit-Owner: Ori.livneh <o...@wikimedia.org> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits