From f67dd35102a849e7f4c0388499af4503f78a7db8 Mon Sep 17 00:00:00 2001 From: h4cc Date: Wed, 25 Jun 2014 13:27:13 +0200 Subject: [PATCH] Added check:src command. Added --allow-empty flags. Added PHP 5.6 to Travis. --- .travis.yml | 11 +-- Command/CheckDistCommand.php | 23 ++++-- Command/CheckSrcCommand.php | 149 +++++++++++++++++++++++++++++++++++ README.md | 15 ++++ bin/composer-checker | 4 +- test/composer.json | 35 ++++++++ test/composer.lock | 138 ++++++++++++++++++++++++++++++++ 7 files changed, 361 insertions(+), 14 deletions(-) create mode 100644 Command/CheckSrcCommand.php create mode 100644 test/composer.json create mode 100644 test/composer.lock diff --git a/.travis.yml b/.travis.yml index ded0723..62925dc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,9 +15,10 @@ before_script: script: # Check Script. - - php bin/composer-checker check:dist -p github composer.lock | grep "All urls valid." - - php bin/composer-checker check:dist -p giub composer.lock | grep "Invalid urls found" + - php bin/composer-checker check:dist -p github test/composer.lock | grep "Invalid urls found" + - php bin/composer-checker check:dist -p github -p "jquery.com" test/composer.lock | grep "Invalid urls found" + - php bin/composer-checker check:dist -p github -p "jquery.com" --allow-empty test/composer.lock | grep "All urls valid" # Check PHAR. - - sh -c 'if [ "$TRAVIS_PHP_VERSION" != "hhvm" ]; then php composer-checker.phar check:dist -p github composer.lock | grep "All urls valid."; fi;' - - sh -c 'if [ "$TRAVIS_PHP_VERSION" != "hhvm" ]; then php composer-checker.phar check:dist -p giub composer.lock | grep "Invalid urls found"; fi;' - + - sh -c 'if [ "$TRAVIS_PHP_VERSION" != "hhvm" ]; then php composer-checker.phar check:dist -p github test/composer.lock | grep "Invalid urls found"; fi;' + - sh -c 'if [ "$TRAVIS_PHP_VERSION" != "hhvm" ]; then php composer-checker.phar check:dist -p github -p "jquery.com" test/composer.lock | grep "Invalid urls found"; fi;' + - sh -c 'if [ "$TRAVIS_PHP_VERSION" != "hhvm" ]; then php composer-checker.phar check:dist -p github -p "jquery.com" --allow-empty test/composer.lock | grep "All urls valid"; fi;' diff --git a/Command/CheckDistCommand.php b/Command/CheckDistCommand.php index b7681c9..cb91188 100644 --- a/Command/CheckDistCommand.php +++ b/Command/CheckDistCommand.php @@ -31,11 +31,12 @@ protected function configure() ->setDescription('Matching the dist urls in a composer.lock file against some patterns.') ->addArgument('file', InputArgument::REQUIRED, 'composer.lock file to check') ->addOption( - 'url-pattern', + 'url-pattern', 'p', - InputOption::VALUE_IS_ARRAY | InputOption::VALUE_REQUIRED, + InputOption::VALUE_IS_ARRAY | InputOption::VALUE_REQUIRED, 'Regex-Patterns for dist-urls.' - ); + ) + ->addOption('allow-empty', null, InputOption::VALUE_NONE, 'Will allow empty dist urls.'); } protected function execute(InputInterface $input, OutputInterface $output) @@ -47,6 +48,10 @@ protected function execute(InputInterface $input, OutputInterface $output) return 1; } + if($input->getOption('allow-empty')) { + $patterns[] = '^$'; + } + $content = @file_get_contents($input->getArgument('file')); if (!$content) { $output->writeln('File not found.'); @@ -95,9 +100,11 @@ protected function searchUrlPatterns(\stdClass $json, array $patterns, OutputInt $errors = array(); foreach ($json->packages as $package) { if (!isset($package->dist)) { - $output->writeln('Dist not found in "' . $package->name . '"'); + $this->verbose($output, 'Dist not found in "' . $package->name . "\"\n", OutputInterface::VERBOSITY_VERBOSE); + $url = ''; + }else{ + $url = $package->dist->url; } - $dist = $package->dist; $matched = false; @@ -105,10 +112,10 @@ protected function searchUrlPatterns(\stdClass $json, array $patterns, OutputInt $regex = '|' . $pattern . '|'; $this->verbose( $output, - "Checking dist url '" . $dist->url . "' with regex '" . $regex . "' -> ", + "Checking dist url '" . $url . "' with regex '" . $regex . "' -> ", OutputInterface::VERBOSITY_VERBOSE ); - if (preg_match($regex, $dist->url)) { + if (preg_match($regex, $url)) { $this->verbose($output, "MATCHED\n", OutputInterface::VERBOSITY_VERBOSE); $matched = true; break; @@ -118,7 +125,7 @@ protected function searchUrlPatterns(\stdClass $json, array $patterns, OutputInt } if (!$matched) { - $errors[$package->name] = $dist->url; + $errors[$package->name] = $url; } } diff --git a/Command/CheckSrcCommand.php b/Command/CheckSrcCommand.php new file mode 100644 index 0000000..a1c214c --- /dev/null +++ b/Command/CheckSrcCommand.php @@ -0,0 +1,149 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Silpion\ComposerChecker\Command; + +use Symfony\Component\Console\Command\Command; +use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Input\InputOption; +use Symfony\Component\Console\Output\OutputInterface; + +/** + * Command for checking the src urls. + * + * @author Julius Beckmann + */ +class CheckSrcCommand extends Command +{ + protected function configure() + { + $this + ->setName('check:src') + ->setDescription('Matching the src urls in a composer.lock file against some patterns.') + ->addArgument('file', InputArgument::REQUIRED, 'composer.lock file to check') + ->addOption( + 'url-pattern', + 'p', + InputOption::VALUE_IS_ARRAY | InputOption::VALUE_REQUIRED, + 'Regex-Patterns for src-urls.' + ) + ->addOption('allow-empty', null, InputOption::VALUE_NONE, 'Will allow empty src urls.'); + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + $patterns = $input->getOption('url-pattern'); + if (!$patterns) { + $output->writeln('Need at least one url-pattern.'); + + return 1; + } + + if($input->getOption('allow-empty')) { + $patterns[] = '^$'; + } + + $content = @file_get_contents($input->getArgument('file')); + if (!$content) { + $output->writeln('File not found.'); + + return 1; + } + + $json = @json_decode($content); + if (!is_object($json) || json_last_error() != JSON_ERROR_NONE) { + $output->writeln('Invalid JSON in file.'); + + return 1; + } + + $errors = $this->searchUrlPatterns($json, $patterns, $output); + if ($errors) { + $rows = array(); + foreach ($errors as $package => $url) { + $rows[] = array($package, $url); + } + + /** @var \Symfony\Component\Console\Helper\TableHelper $table */ + $table = $this->getApplication()->getHelperSet()->get('table'); + $table->setHeaders(array('Package', 'Src-URL'))->setRows($rows); + + $output->writeln(' --- Invalid urls found --- '); + $table->render($output); + + return 1; + } + + $output->writeln('All urls valid.'); + } + + /** + * Will return a array of invalid packages and their urls determined by the given patterns. + * A url is invalid if NONE of the given patterns has matched. + * + * @param \stdClass $json + * @param array $patterns + * @param \Symfony\Component\Console\Output\OutputInterface $output + * @return array + */ + protected function searchUrlPatterns(\stdClass $json, array $patterns, OutputInterface $output) + { + $errors = array(); + foreach ($json->packages as $package) { + if (!isset($package->source)) { + $this->verbose($output, 'Source not found in "' . $package->name . "\"\n", OutputInterface::VERBOSITY_VERBOSE); + $url = ''; + }else{ + $url = $package->source->url; + } + + $matched = false; + + foreach ($patterns as $pattern) { + $regex = '|' . $pattern . '|'; + $this->verbose( + $output, + "Checking src url '" . $url . "' with regex '" . $regex . "' -> ", + OutputInterface::VERBOSITY_VERBOSE + ); + if (preg_match($regex, $url)) { + $this->verbose($output, "MATCHED\n", OutputInterface::VERBOSITY_VERBOSE); + $matched = true; + break; + } else { + $this->verbose($output, "NOT matched\n", OutputInterface::VERBOSITY_VERBOSE); + } + } + + if (!$matched) { + $errors[$package->name] = $url; + } + } + + return $errors; + } + + /** + * Verbose output helper. + * + * @param OutputInterface $output + * @param $message + * @param $level + */ + private function verbose(OutputInterface $output, $message, $level) + { + if ($output->getVerbosity() >= $level) { + $output->write($message); + } + } +} + \ No newline at end of file diff --git a/README.md b/README.md index 01457ee..f3553d3 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,7 @@ Usage list Lists commands check check:dist Matching the dist urls in a composer.lock file against some patterns. + check:src Matching the src urls in a composer.lock file against some patterns. Check: Dist-Urls @@ -43,6 +44,20 @@ It is also possible to enforce to use only "https" dist-urls with a pattern like $ php bin/composer-checker check:dist -p "^https://" composer.lock +Allowing empty or missing dist urls can be done with the `--allow-empty` switch. + + +Check: Source-Urls +--------------------- + +Parallel to the dist urls, the source urls can be checked too. + + $ php bin/composer-checker check:src -p "git@git.example.com/foo.git" composer.lock + + +Allowing empty or missing source urls can be done with the `--allow-empty` switch. + + LICENSE ------- diff --git a/bin/composer-checker b/bin/composer-checker index 862fe42..da12a18 100644 --- a/bin/composer-checker +++ b/bin/composer-checker @@ -28,10 +28,12 @@ require_once call_user_func(function() { }); use Silpion\ComposerChecker\Command\CheckDistCommand; +use Silpion\ComposerChecker\Command\CheckSrcCommand; use Symfony\Component\Console\Application; $application = new Application(); $application->setName('Composer Checker'); -$application->setVersion('1.0'); +$application->setVersion('0.1'); $application->add(new CheckDistCommand()); +$application->add(new CheckSrcCommand()); $application->run(); diff --git a/test/composer.json b/test/composer.json new file mode 100644 index 0000000..36390d5 --- /dev/null +++ b/test/composer.json @@ -0,0 +1,35 @@ +{ + "require": { + "symfony/console": "*", + "smarty/smarty": "*", + "javascript/jquery": "*" + }, + "repositories": [ + { + "type": "package", + "package": { + "name": "smarty/smarty", + "version": "3.1.7", + "source": { + "url": "http://smarty-php.googlecode.com/svn/", + "type": "svn", + "reference": "tags/Smarty_3_1_7/distribution/" + }, + "autoload": { + "classmap": ["libs/"] + } + } + }, + { + "type": "package", + "package": { + "name": "javascript/jquery", + "version": "1.7.2", + "dist": { + "url": "http://code.jquery.com/jquery-1.7.2.js", + "type": "file" + } + } + } + ] +} diff --git a/test/composer.lock b/test/composer.lock new file mode 100644 index 0000000..b2865e1 --- /dev/null +++ b/test/composer.lock @@ -0,0 +1,138 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", + "This file is @generated automatically" + ], + "hash": "3f1c7ec3d5d7c6db42821ff15b497b4d", + "packages": [ + { + "name": "javascript/jquery", + "version": "1.7.2", + "dist": { + "type": "file", + "url": "http://code.jquery.com/jquery-1.7.2.js", + "reference": null, + "shasum": null + }, + "type": "library" + }, + { + "name": "smarty/smarty", + "version": "v3.1.18", + "source": { + "type": "svn", + "url": "http://smarty-php.googlecode.com/svn", + "reference": "/tags/v3.1.18/@4839" + }, + "require": { + "php": ">=5.2" + }, + "type": "library", + "autoload": { + "classmap": [ + "distribution/libs/Smarty.class.php", + "distribution/libs/SmartyBC.class.php", + "distribution/libs/sysplugins/smarty_security.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "LGPL-3.0" + ], + "authors": [ + { + "name": "Monte Ohrt", + "email": "monte@ohrt.com" + }, + { + "name": "Uwe Tews", + "email": "uwe.tews@googlemail.com" + }, + { + "name": "Rodney Rehm", + "email": "rodney.rehm@medialize.de" + } + ], + "description": "Smarty - the compiling PHP template engine", + "homepage": "http://www.smarty.net", + "keywords": [ + "templating" + ], + "time": "2014-05-08 18:38:30" + }, + { + "name": "symfony/console", + "version": "v2.5.0", + "target-dir": "Symfony/Component/Console", + "source": { + "type": "git", + "url": "https://github.com/symfony/Console.git", + "reference": "ef4ca73b0b3a10cbac653d3ca482d0cdd4502b2c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/Console/zipball/ef4ca73b0b3a10cbac653d3ca482d0cdd4502b2c", + "reference": "ef4ca73b0b3a10cbac653d3ca482d0cdd4502b2c", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "psr/log": "~1.0", + "symfony/event-dispatcher": "~2.1" + }, + "suggest": { + "psr/log": "For using the console logger", + "symfony/event-dispatcher": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.5-dev" + } + }, + "autoload": { + "psr-0": { + "Symfony\\Component\\Console\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com", + "homepage": "http://fabien.potencier.org", + "role": "Lead Developer" + }, + { + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" + } + ], + "description": "Symfony Console Component", + "homepage": "http://symfony.com", + "time": "2014-05-22 08:54:24" + } + ], + "packages-dev": [ + + ], + "aliases": [ + + ], + "minimum-stability": "stable", + "stability-flags": [ + + ], + "platform": [ + + ], + "platform-dev": [ + + ] +}