├── .gitignore ├── .php_cs ├── LICENSE ├── README.md ├── bin └── phpqa ├── composer.json ├── composer.lock ├── config ├── .php_cs ├── drupal │ └── config.yml ├── messages.yml └── phpunit.xml.dist ├── phpqa.yml ├── phpunit.xml.dist ├── src ├── Application.php ├── Command │ ├── AnalyzeCommand.php │ └── InitCommand.php ├── Input │ └── FilesOption.php ├── Style │ └── SymfonyStyle.php └── Utils │ └── Config.php └── tests ├── integration └── Command │ └── AnalyzeCommandTest.php └── unit └── Input └── FilesOptionTest.php /.gitignore: -------------------------------------------------------------------------------- 1 | # Composer 2 | /vendor 3 | /bin/pdepend 4 | /bin/php-cs-fixer 5 | /bin/phpcbf 6 | /bin/phpcpd 7 | /bin/phpcs 8 | /bin/phpdcd 9 | /bin/phpunit 10 | /bin/phploc 11 | /bin/phpmd 12 | /bin/parallel-lint 13 | -------------------------------------------------------------------------------- /.php_cs: -------------------------------------------------------------------------------- 1 | setRules( 5 | [ 6 | '@PSR2' => true, 7 | 'array_syntax' => ['syntax' => 'short'], 8 | ] 9 | ) 10 | ->setUsingCache(false); 11 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2015-2017 Jesus Manuel Olivas 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | PHPQA 2 | ============================================= 3 | PHPQA Analyzer CLI tool 4 | 5 | 6 | 7 | 8 | - [Overview](#overview) 9 | - [Available Analyzers](#available-analyzers) 10 | - [Install](#install) 11 | - [Usage](#usage) 12 | - [Override configuration](#override-configuration) 13 | - [Nice to have features](#nice-to-have-features) 14 | 15 | 16 | 17 | ## Overview 18 | This project aims to serve as a CLI tool to make easy the use of different PHP tools related to Quality Assurance and code analysis in PHP. 19 | 20 | Every analyzer tool handles arguments and options using different formats, the goal of this project is to provide a single way to interact with those projects, you can also set options and arguments using a default configuration file when the project supports it. 21 | 22 | > This project was originally developed as part of [Drupal Console](https://github.com/hechoendrupal/DrupalConsole) and based on the blog post [Write your git hooks in PHP and keep them under git control](http://carlosbuenosvinos.com/write-your-git-hooks-in-php-and-keep-them-under-git-control/). 23 | 24 | ## Available Analyzers 25 | 26 | - [PHP Parallel Lint](https://github.com/JakubOnderka/PHP-Parallel-Lint) 27 | 28 | This tool check syntax of PHP files faster then serial check with fancier output. 29 | 30 | ![PHP-Parallel-Lint](http://i.imgur.com/F3BZsCP.png) 31 | 32 | - [PHP Coding Standards Fixer](https://github.com/FriendsOfPHP/PHP-CS-Fixer) 33 | 34 | The PHP Coding Standards Fixer tool fixes most issues in your code when you want to follow the PHP coding standards as defined in the PSR-1 and PSR-2 documents. 35 | 36 | ![PHP-CS-Fixer](http://i.imgur.com/IU5pDhf.png) 37 | 38 | - [PHP_CodeSniffer](https://github.com/squizlabs/PHP_CodeSniffer) 39 | 40 | PHP_CodeSniffer is a set of two PHP scripts; the main `phpcs` script that tokenizes PHP, JavaScript and CSS files to detect violations of a defined coding standard, and a second `phpcbf` script to automatically correct coding standard violations. 41 | 42 | ![PHPCBF](http://i.imgur.com/0wiB36B.png) 43 | 44 | ![PHPCS](http://i.imgur.com/h8PLm4f.png) 45 | 46 | - [PHPMD - PHP Mess Detector](http://phpmd.org/) 47 | 48 | It is a spin-off project of PHP Depend and aims to be a PHP equivalent of the well known Java tool PMD. PHPMD can be seen as an user friendly and easy to configure frontend for the raw metrics measured by PHP Depend. 49 | 50 | ![PHPMD](http://i.imgur.com/LhA4swF.png) 51 | 52 | - [PHPLOC](https://github.com/sebastianbergmann/phploc) 53 | 54 | `phploc` is a tool for quickly measuring the size and analyzing the structure of a PHP project. 55 | 56 | ![PHPLOC](http://i.imgur.com/8Ewc07T.png) 57 | 58 | - [PHPDCD - PHP Dead Code Detector](https://github.com/sebastianbergmann/phpdcd) 59 | 60 | `phpdcd` is a Dead Code Detector (DCD) for PHP code. It scans a PHP project for all declared functions and methods and reports those as being "dead code" that are not called at least once. 61 | 62 | ![PHPDCD](http://i.imgur.com/WPoDgcs.png) 63 | 64 | - [PHPCPD - PHP Copy/Paste Detector](https://github.com/sebastianbergmann/phpcpd) 65 | 66 | `phpcpd` is a Copy/Paste Detector (CPD) for PHP code. 67 | 68 | ![PHPCPD](http://i.imgur.com/McvqmKJ.png) 69 | 70 | - [PHPUnit](https://phpunit.de/) 71 | 72 | PHPUnit is a programmer-oriented testing framework for PHP. It is an instance of the xUnit architecture for unit testing frameworks. 73 | 74 | ![PHPUnit](http://i.imgur.com/80Q3pGm.png) 75 | 76 | ## Install 77 | 78 | ### Cloning the project 79 | ``` 80 | $ git clone git@github.com:jmolivas/phpqa.git 81 | $ cd phpqa 82 | # download dependencies 83 | $ composer install 84 | # make phpqa globally accessible creating a symlink 85 | $ ln -s /path/to/phpqa/bin/phpqa /usr/local/bin/phpqa 86 | ``` 87 | 88 | ## Usage 89 | 90 | ### Copy configuration file(s) 91 | ``` 92 | $ cd to/project/path 93 | $ phpqa init --project=PROJECT --override 94 | $ phpqa init --global --override 95 | ``` 96 | | Option | Description | 97 | | -------- | ----------------------------- | 98 | | project | Available values `php`, `symfony` and `drupal`. | 99 | | global | Copy configuration files to user home directory, instead of current working directory. | 100 | | override | If this option is set, files are copied using override flag. | 101 | 102 | **NOTES:** 103 | - Option `global` does not accept a value must be set as `--global`. 104 | - Option `override` does not accept a value must be set as `--override`. 105 | - Options `project` and `global` can not used in combination. 106 | 107 | ### Analyze a project 108 | ``` 109 | $ cd to/project/path 110 | $ phpqa analyze --project=PROJECT --files=FILES 111 | $ phpqa analyze --project=PROJECT --git 112 | ``` 113 | 114 | | Option | Description | 115 | | ------- | ----------------------------- | 116 | | project | Available values `php`, `symfony` and `drupal` | 117 | | files | Files or directories to analyze. | 118 | | git | If this option is set, all files added to git index will be scanned. This is useful when setting executing this tool on a pre-commit git-hook. | 119 | 120 | **NOTES:** 121 | - Option `git` does not accept a value must be set as `--git`. 122 | - Option `project` could be omitted if a `phpqa.yml` or `phpqa.yml.dist` file is available at current working directory. 123 | - Options `files` and `git` can not used in combination. 124 | 125 | ## Override configuration 126 | This project was built to be fully customizable, you can enable/disable analyzers and modify arguments/options passed to analyzers by updating the `phpqa.yml` or `phpqa.yml.dist` file on your project root copied when running `init` command, or the files `~/.phpqa/php/config.yml`, `~/.phpqa/symfony/config.yml` or `~/.phpqa/drupal/config.yml` copied when running `init` command using `--global` option. 127 | 128 | ## Nice to have features 129 | - Add command to create new project. 130 | - Add more analyzers: 131 | - https://github.com/pdepend/pdepend 132 | - https://github.com/sensiolabs/security-checker 133 | - https://github.com/sensiolabs/insight 134 | - https://github.com/Halleck45/PhpMetrics 135 | - Add analyzer via config and not as composer dependency. 136 | - Detect if analyzer is already loaded on the local machine and use that instead of download. 137 | - Add custom analyzers. 138 | - Add SaaS analyzers via API. 139 | 140 | > This project is a work-in-progress and needs some love related to code clean up, test coverage and documentation. 141 | -------------------------------------------------------------------------------- /bin/phpqa: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | add(new AnalyzeCommand()); 25 | $application->add(new InitCommand()); 26 | $application->run(); 27 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jmolivas/phpqa", 3 | "description": "PHP QA Analyzer", 4 | "keywords": ["PHP", "QA", "Development"], 5 | "type": "project", 6 | "license": "MIT", 7 | "authors": [ 8 | { 9 | "name": "Jesus Manuel Olivas", 10 | "email": "jesus.olivas@gmail.com", 11 | "homepage": "http://jmolivas.com" 12 | } 13 | ], 14 | "require": { 15 | "php": ">=5.4.5", 16 | "symfony/console": ">=2.8 <3.2", 17 | "symfony/config":">=2.8 <3.2", 18 | "symfony/process": ">=2.8 <3.2", 19 | "jakub-onderka/php-parallel-lint": "0.9.*", 20 | "jakub-onderka/php-console-highlighter": "0.3.*", 21 | "friendsofphp/php-cs-fixer": "2.0.*", 22 | "drupal/coder": ">=8.2.3", 23 | "phpmd/phpmd" : "@stable", 24 | "phploc/phploc": "@stable", 25 | "sebastian/phpcpd": "@stable", 26 | "sebastian/phpdcd": "@stable", 27 | "phpunit/phpunit": "4.*" 28 | }, 29 | "bin": ["bin/phpqa"], 30 | "config": { 31 | "bin-dir": "bin/", 32 | "secure-http" : false 33 | }, 34 | "autoload": { 35 | "psr-4": {"JMOlivas\\Phpqa\\": "src"} 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /composer.lock: -------------------------------------------------------------------------------- 1 | { 2 | "_readme": [ 3 | "This file locks the dependencies of your project to a known state", 4 | "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", 5 | "This file is @generated automatically" 6 | ], 7 | "content-hash": "31a6a1535b3fdb100ecbcdbdc46c2762", 8 | "packages": [ 9 | { 10 | "name": "doctrine/instantiator", 11 | "version": "1.0.5", 12 | "source": { 13 | "type": "git", 14 | "url": "https://github.com/doctrine/instantiator.git", 15 | "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d" 16 | }, 17 | "dist": { 18 | "type": "zip", 19 | "url": "https://api.github.com/repos/doctrine/instantiator/zipball/8e884e78f9f0eb1329e445619e04456e64d8051d", 20 | "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d", 21 | "shasum": "" 22 | }, 23 | "require": { 24 | "php": ">=5.3,<8.0-DEV" 25 | }, 26 | "require-dev": { 27 | "athletic/athletic": "~0.1.8", 28 | "ext-pdo": "*", 29 | "ext-phar": "*", 30 | "phpunit/phpunit": "~4.0", 31 | "squizlabs/php_codesniffer": "~2.0" 32 | }, 33 | "type": "library", 34 | "extra": { 35 | "branch-alias": { 36 | "dev-master": "1.0.x-dev" 37 | } 38 | }, 39 | "autoload": { 40 | "psr-4": { 41 | "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" 42 | } 43 | }, 44 | "notification-url": "https://packagist.org/downloads/", 45 | "license": [ 46 | "MIT" 47 | ], 48 | "authors": [ 49 | { 50 | "name": "Marco Pivetta", 51 | "email": "ocramius@gmail.com", 52 | "homepage": "http://ocramius.github.com/" 53 | } 54 | ], 55 | "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", 56 | "homepage": "https://github.com/doctrine/instantiator", 57 | "keywords": [ 58 | "constructor", 59 | "instantiate" 60 | ], 61 | "time": "2015-06-14T21:17:01+00:00" 62 | }, 63 | { 64 | "name": "drupal/coder", 65 | "version": "8.2.10", 66 | "source": { 67 | "type": "git", 68 | "url": "https://github.com/klausi/coder.git", 69 | "reference": "c835ff5c1733676fe0d3f3b861e814d570baaa6f" 70 | }, 71 | "dist": { 72 | "type": "zip", 73 | "url": "https://api.github.com/repos/klausi/coder/zipball/c835ff5c1733676fe0d3f3b861e814d570baaa6f", 74 | "reference": "c835ff5c1733676fe0d3f3b861e814d570baaa6f", 75 | "shasum": "" 76 | }, 77 | "require": { 78 | "ext-mbstring": "*", 79 | "php": ">=5.4.0", 80 | "squizlabs/php_codesniffer": ">=2.7.0 <3.0", 81 | "symfony/yaml": ">=2.0.0" 82 | }, 83 | "require-dev": { 84 | "phpunit/phpunit": ">=3.7" 85 | }, 86 | "type": "library", 87 | "notification-url": "https://packagist.org/downloads/", 88 | "license": [ 89 | "GPL-2.0+" 90 | ], 91 | "description": "Coder is a library to review Drupal code.", 92 | "homepage": "https://www.drupal.org/project/coder", 93 | "keywords": [ 94 | "code review", 95 | "phpcs", 96 | "standards" 97 | ], 98 | "time": "2016-12-09T21:57:53+00:00" 99 | }, 100 | { 101 | "name": "friendsofphp/php-cs-fixer", 102 | "version": "v2.0.0", 103 | "source": { 104 | "type": "git", 105 | "url": "https://github.com/FriendsOfPHP/PHP-CS-Fixer.git", 106 | "reference": "f3baf72eb2f58bf275b372540f5b47d25aed910f" 107 | }, 108 | "dist": { 109 | "type": "zip", 110 | "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/f3baf72eb2f58bf275b372540f5b47d25aed910f", 111 | "reference": "f3baf72eb2f58bf275b372540f5b47d25aed910f", 112 | "shasum": "" 113 | }, 114 | "require": { 115 | "ext-tokenizer": "*", 116 | "php": "^5.3.6 || >=7.0 <7.2", 117 | "sebastian/diff": "^1.1", 118 | "symfony/console": "^2.3 || ^3.0", 119 | "symfony/event-dispatcher": "^2.1 || ^3.0", 120 | "symfony/filesystem": "^2.4 || ^3.0", 121 | "symfony/finder": "^2.2 || ^3.0", 122 | "symfony/polyfill-php54": "^1.0", 123 | "symfony/process": "^2.3 || ^3.0", 124 | "symfony/stopwatch": "^2.5 || ^3.0" 125 | }, 126 | "conflict": { 127 | "hhvm": "<3.9" 128 | }, 129 | "require-dev": { 130 | "gecko-packages/gecko-php-unit": "^2.0", 131 | "phpunit/phpunit": "^4.5|^5", 132 | "satooshi/php-coveralls": "^1.0" 133 | }, 134 | "bin": [ 135 | "php-cs-fixer" 136 | ], 137 | "type": "application", 138 | "extra": { 139 | "branch-alias": { 140 | "dev-master": "2.0-dev" 141 | } 142 | }, 143 | "autoload": { 144 | "psr-4": { 145 | "PhpCsFixer\\": "src/" 146 | } 147 | }, 148 | "notification-url": "https://packagist.org/downloads/", 149 | "license": [ 150 | "MIT" 151 | ], 152 | "authors": [ 153 | { 154 | "name": "Dariusz Rumiński", 155 | "email": "dariusz.ruminski@gmail.com" 156 | }, 157 | { 158 | "name": "Fabien Potencier", 159 | "email": "fabien@symfony.com" 160 | } 161 | ], 162 | "description": "A tool to automatically fix PHP code style", 163 | "time": "2016-12-01T06:18:06+00:00" 164 | }, 165 | { 166 | "name": "jakub-onderka/php-console-color", 167 | "version": "0.1", 168 | "source": { 169 | "type": "git", 170 | "url": "https://github.com/JakubOnderka/PHP-Console-Color.git", 171 | "reference": "e0b393dacf7703fc36a4efc3df1435485197e6c1" 172 | }, 173 | "dist": { 174 | "type": "zip", 175 | "url": "https://api.github.com/repos/JakubOnderka/PHP-Console-Color/zipball/e0b393dacf7703fc36a4efc3df1435485197e6c1", 176 | "reference": "e0b393dacf7703fc36a4efc3df1435485197e6c1", 177 | "shasum": "" 178 | }, 179 | "require": { 180 | "php": ">=5.3.2" 181 | }, 182 | "require-dev": { 183 | "jakub-onderka/php-code-style": "1.0", 184 | "jakub-onderka/php-parallel-lint": "0.*", 185 | "jakub-onderka/php-var-dump-check": "0.*", 186 | "phpunit/phpunit": "3.7.*", 187 | "squizlabs/php_codesniffer": "1.*" 188 | }, 189 | "type": "library", 190 | "autoload": { 191 | "psr-0": { 192 | "JakubOnderka\\PhpConsoleColor": "src/" 193 | } 194 | }, 195 | "notification-url": "https://packagist.org/downloads/", 196 | "license": [ 197 | "BSD-2-Clause" 198 | ], 199 | "authors": [ 200 | { 201 | "name": "Jakub Onderka", 202 | "email": "jakub.onderka@gmail.com", 203 | "homepage": "http://www.acci.cz" 204 | } 205 | ], 206 | "time": "2014-04-08T15:00:19+00:00" 207 | }, 208 | { 209 | "name": "jakub-onderka/php-console-highlighter", 210 | "version": "v0.3.2", 211 | "source": { 212 | "type": "git", 213 | "url": "https://github.com/JakubOnderka/PHP-Console-Highlighter.git", 214 | "reference": "7daa75df45242c8d5b75a22c00a201e7954e4fb5" 215 | }, 216 | "dist": { 217 | "type": "zip", 218 | "url": "https://api.github.com/repos/JakubOnderka/PHP-Console-Highlighter/zipball/7daa75df45242c8d5b75a22c00a201e7954e4fb5", 219 | "reference": "7daa75df45242c8d5b75a22c00a201e7954e4fb5", 220 | "shasum": "" 221 | }, 222 | "require": { 223 | "jakub-onderka/php-console-color": "~0.1", 224 | "php": ">=5.3.0" 225 | }, 226 | "require-dev": { 227 | "jakub-onderka/php-code-style": "~1.0", 228 | "jakub-onderka/php-parallel-lint": "~0.5", 229 | "jakub-onderka/php-var-dump-check": "~0.1", 230 | "phpunit/phpunit": "~4.0", 231 | "squizlabs/php_codesniffer": "~1.5" 232 | }, 233 | "type": "library", 234 | "autoload": { 235 | "psr-0": { 236 | "JakubOnderka\\PhpConsoleHighlighter": "src/" 237 | } 238 | }, 239 | "notification-url": "https://packagist.org/downloads/", 240 | "license": [ 241 | "MIT" 242 | ], 243 | "authors": [ 244 | { 245 | "name": "Jakub Onderka", 246 | "email": "acci@acci.cz", 247 | "homepage": "http://www.acci.cz/" 248 | } 249 | ], 250 | "time": "2015-04-20T18:58:01+00:00" 251 | }, 252 | { 253 | "name": "jakub-onderka/php-parallel-lint", 254 | "version": "v0.9.2", 255 | "source": { 256 | "type": "git", 257 | "url": "https://github.com/JakubOnderka/PHP-Parallel-Lint.git", 258 | "reference": "2ead2e4043ab125bee9554f356e0a86742c2d4fa" 259 | }, 260 | "dist": { 261 | "type": "zip", 262 | "url": "https://api.github.com/repos/JakubOnderka/PHP-Parallel-Lint/zipball/2ead2e4043ab125bee9554f356e0a86742c2d4fa", 263 | "reference": "2ead2e4043ab125bee9554f356e0a86742c2d4fa", 264 | "shasum": "" 265 | }, 266 | "require": { 267 | "php": ">=5.3.3" 268 | }, 269 | "require-dev": { 270 | "jakub-onderka/php-console-highlighter": "~0.3", 271 | "nette/tester": "~1.3" 272 | }, 273 | "suggest": { 274 | "jakub-onderka/php-console-highlighter": "Highlight syntax in code snippet" 275 | }, 276 | "bin": [ 277 | "parallel-lint" 278 | ], 279 | "type": "library", 280 | "autoload": { 281 | "classmap": [ 282 | "./" 283 | ] 284 | }, 285 | "notification-url": "https://packagist.org/downloads/", 286 | "license": [ 287 | "BSD-2-Clause" 288 | ], 289 | "authors": [ 290 | { 291 | "name": "Jakub Onderka", 292 | "email": "jakub.onderka@gmail.com" 293 | } 294 | ], 295 | "description": "This tool check syntax of PHP files about 20x faster than serial check.", 296 | "homepage": "https://github.com/JakubOnderka/PHP-Parallel-Lint", 297 | "time": "2015-12-15T10:42:16+00:00" 298 | }, 299 | { 300 | "name": "pdepend/pdepend", 301 | "version": "2.5.0", 302 | "source": { 303 | "type": "git", 304 | "url": "https://github.com/pdepend/pdepend.git", 305 | "reference": "0c50874333149c0dad5a2877801aed148f2767ff" 306 | }, 307 | "dist": { 308 | "type": "zip", 309 | "url": "https://api.github.com/repos/pdepend/pdepend/zipball/0c50874333149c0dad5a2877801aed148f2767ff", 310 | "reference": "0c50874333149c0dad5a2877801aed148f2767ff", 311 | "shasum": "" 312 | }, 313 | "require": { 314 | "php": ">=5.3.7", 315 | "symfony/config": "^2.3.0|^3", 316 | "symfony/dependency-injection": "^2.3.0|^3", 317 | "symfony/filesystem": "^2.3.0|^3" 318 | }, 319 | "require-dev": { 320 | "phpunit/phpunit": "^4.4.0,<4.8", 321 | "squizlabs/php_codesniffer": "^2.0.0" 322 | }, 323 | "bin": [ 324 | "src/bin/pdepend" 325 | ], 326 | "type": "library", 327 | "autoload": { 328 | "psr-4": { 329 | "PDepend\\": "src/main/php/PDepend" 330 | } 331 | }, 332 | "notification-url": "https://packagist.org/downloads/", 333 | "license": [ 334 | "BSD-3-Clause" 335 | ], 336 | "description": "Official version of pdepend to be handled with Composer", 337 | "time": "2017-01-19T14:23:36+00:00" 338 | }, 339 | { 340 | "name": "phpdocumentor/reflection-common", 341 | "version": "1.0", 342 | "source": { 343 | "type": "git", 344 | "url": "https://github.com/phpDocumentor/ReflectionCommon.git", 345 | "reference": "144c307535e82c8fdcaacbcfc1d6d8eeb896687c" 346 | }, 347 | "dist": { 348 | "type": "zip", 349 | "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/144c307535e82c8fdcaacbcfc1d6d8eeb896687c", 350 | "reference": "144c307535e82c8fdcaacbcfc1d6d8eeb896687c", 351 | "shasum": "" 352 | }, 353 | "require": { 354 | "php": ">=5.5" 355 | }, 356 | "require-dev": { 357 | "phpunit/phpunit": "^4.6" 358 | }, 359 | "type": "library", 360 | "extra": { 361 | "branch-alias": { 362 | "dev-master": "1.0.x-dev" 363 | } 364 | }, 365 | "autoload": { 366 | "psr-4": { 367 | "phpDocumentor\\Reflection\\": [ 368 | "src" 369 | ] 370 | } 371 | }, 372 | "notification-url": "https://packagist.org/downloads/", 373 | "license": [ 374 | "MIT" 375 | ], 376 | "authors": [ 377 | { 378 | "name": "Jaap van Otterdijk", 379 | "email": "opensource@ijaap.nl" 380 | } 381 | ], 382 | "description": "Common reflection classes used by phpdocumentor to reflect the code structure", 383 | "homepage": "http://www.phpdoc.org", 384 | "keywords": [ 385 | "FQSEN", 386 | "phpDocumentor", 387 | "phpdoc", 388 | "reflection", 389 | "static analysis" 390 | ], 391 | "time": "2015-12-27T11:43:31+00:00" 392 | }, 393 | { 394 | "name": "phpdocumentor/reflection-docblock", 395 | "version": "3.1.1", 396 | "source": { 397 | "type": "git", 398 | "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", 399 | "reference": "8331b5efe816ae05461b7ca1e721c01b46bafb3e" 400 | }, 401 | "dist": { 402 | "type": "zip", 403 | "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/8331b5efe816ae05461b7ca1e721c01b46bafb3e", 404 | "reference": "8331b5efe816ae05461b7ca1e721c01b46bafb3e", 405 | "shasum": "" 406 | }, 407 | "require": { 408 | "php": ">=5.5", 409 | "phpdocumentor/reflection-common": "^1.0@dev", 410 | "phpdocumentor/type-resolver": "^0.2.0", 411 | "webmozart/assert": "^1.0" 412 | }, 413 | "require-dev": { 414 | "mockery/mockery": "^0.9.4", 415 | "phpunit/phpunit": "^4.4" 416 | }, 417 | "type": "library", 418 | "autoload": { 419 | "psr-4": { 420 | "phpDocumentor\\Reflection\\": [ 421 | "src/" 422 | ] 423 | } 424 | }, 425 | "notification-url": "https://packagist.org/downloads/", 426 | "license": [ 427 | "MIT" 428 | ], 429 | "authors": [ 430 | { 431 | "name": "Mike van Riel", 432 | "email": "me@mikevanriel.com" 433 | } 434 | ], 435 | "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", 436 | "time": "2016-09-30T07:12:33+00:00" 437 | }, 438 | { 439 | "name": "phpdocumentor/type-resolver", 440 | "version": "0.2.1", 441 | "source": { 442 | "type": "git", 443 | "url": "https://github.com/phpDocumentor/TypeResolver.git", 444 | "reference": "e224fb2ea2fba6d3ad6fdaef91cd09a172155ccb" 445 | }, 446 | "dist": { 447 | "type": "zip", 448 | "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/e224fb2ea2fba6d3ad6fdaef91cd09a172155ccb", 449 | "reference": "e224fb2ea2fba6d3ad6fdaef91cd09a172155ccb", 450 | "shasum": "" 451 | }, 452 | "require": { 453 | "php": ">=5.5", 454 | "phpdocumentor/reflection-common": "^1.0" 455 | }, 456 | "require-dev": { 457 | "mockery/mockery": "^0.9.4", 458 | "phpunit/phpunit": "^5.2||^4.8.24" 459 | }, 460 | "type": "library", 461 | "extra": { 462 | "branch-alias": { 463 | "dev-master": "1.0.x-dev" 464 | } 465 | }, 466 | "autoload": { 467 | "psr-4": { 468 | "phpDocumentor\\Reflection\\": [ 469 | "src/" 470 | ] 471 | } 472 | }, 473 | "notification-url": "https://packagist.org/downloads/", 474 | "license": [ 475 | "MIT" 476 | ], 477 | "authors": [ 478 | { 479 | "name": "Mike van Riel", 480 | "email": "me@mikevanriel.com" 481 | } 482 | ], 483 | "time": "2016-11-25T06:54:22+00:00" 484 | }, 485 | { 486 | "name": "phploc/phploc", 487 | "version": "3.0.1", 488 | "source": { 489 | "type": "git", 490 | "url": "https://github.com/sebastianbergmann/phploc.git", 491 | "reference": "74f917e6f80f291856989960d31afa44a4196859" 492 | }, 493 | "dist": { 494 | "type": "zip", 495 | "url": "https://api.github.com/repos/sebastianbergmann/phploc/zipball/74f917e6f80f291856989960d31afa44a4196859", 496 | "reference": "74f917e6f80f291856989960d31afa44a4196859", 497 | "shasum": "" 498 | }, 499 | "require": { 500 | "php": ">=5.6", 501 | "sebastian/finder-facade": "~1.1", 502 | "sebastian/git": "~2.1", 503 | "sebastian/version": "~1.0.3|~2.0", 504 | "symfony/console": "~2.5|~3.0" 505 | }, 506 | "require-dev": { 507 | "phpunit/phpunit": "~5" 508 | }, 509 | "bin": [ 510 | "phploc" 511 | ], 512 | "type": "library", 513 | "extra": { 514 | "branch-alias": { 515 | "dev-master": "3.0-dev" 516 | } 517 | }, 518 | "autoload": { 519 | "classmap": [ 520 | "src/" 521 | ] 522 | }, 523 | "notification-url": "https://packagist.org/downloads/", 524 | "license": [ 525 | "BSD-3-Clause" 526 | ], 527 | "authors": [ 528 | { 529 | "name": "Sebastian Bergmann", 530 | "email": "sebastian@phpunit.de", 531 | "role": "lead" 532 | } 533 | ], 534 | "description": "A tool for quickly measuring the size of a PHP project.", 535 | "homepage": "https://github.com/sebastianbergmann/phploc", 536 | "time": "2016-04-25T08:11:21+00:00" 537 | }, 538 | { 539 | "name": "phpmd/phpmd", 540 | "version": "2.6.0", 541 | "source": { 542 | "type": "git", 543 | "url": "https://github.com/phpmd/phpmd.git", 544 | "reference": "4e9924b2c157a3eb64395460fcf56b31badc8374" 545 | }, 546 | "dist": { 547 | "type": "zip", 548 | "url": "https://api.github.com/repos/phpmd/phpmd/zipball/4e9924b2c157a3eb64395460fcf56b31badc8374", 549 | "reference": "4e9924b2c157a3eb64395460fcf56b31badc8374", 550 | "shasum": "" 551 | }, 552 | "require": { 553 | "ext-xml": "*", 554 | "pdepend/pdepend": "^2.5", 555 | "php": ">=5.3.9" 556 | }, 557 | "require-dev": { 558 | "phpunit/phpunit": "^4.0", 559 | "squizlabs/php_codesniffer": "^2.0" 560 | }, 561 | "bin": [ 562 | "src/bin/phpmd" 563 | ], 564 | "type": "project", 565 | "autoload": { 566 | "psr-0": { 567 | "PHPMD\\": "src/main/php" 568 | } 569 | }, 570 | "notification-url": "https://packagist.org/downloads/", 571 | "license": [ 572 | "BSD-3-Clause" 573 | ], 574 | "authors": [ 575 | { 576 | "name": "Manuel Pichler", 577 | "email": "github@manuel-pichler.de", 578 | "homepage": "https://github.com/manuelpichler", 579 | "role": "Project Founder" 580 | }, 581 | { 582 | "name": "Other contributors", 583 | "homepage": "https://github.com/phpmd/phpmd/graphs/contributors", 584 | "role": "Contributors" 585 | }, 586 | { 587 | "name": "Marc Würth", 588 | "email": "ravage@bluewin.ch", 589 | "homepage": "https://github.com/ravage84", 590 | "role": "Project Maintainer" 591 | } 592 | ], 593 | "description": "PHPMD is a spin-off project of PHP Depend and aims to be a PHP equivalent of the well known Java tool PMD.", 594 | "homepage": "http://phpmd.org/", 595 | "keywords": [ 596 | "mess detection", 597 | "mess detector", 598 | "pdepend", 599 | "phpmd", 600 | "pmd" 601 | ], 602 | "time": "2017-01-20T14:41:10+00:00" 603 | }, 604 | { 605 | "name": "phpspec/prophecy", 606 | "version": "v1.6.2", 607 | "source": { 608 | "type": "git", 609 | "url": "https://github.com/phpspec/prophecy.git", 610 | "reference": "6c52c2722f8460122f96f86346600e1077ce22cb" 611 | }, 612 | "dist": { 613 | "type": "zip", 614 | "url": "https://api.github.com/repos/phpspec/prophecy/zipball/6c52c2722f8460122f96f86346600e1077ce22cb", 615 | "reference": "6c52c2722f8460122f96f86346600e1077ce22cb", 616 | "shasum": "" 617 | }, 618 | "require": { 619 | "doctrine/instantiator": "^1.0.2", 620 | "php": "^5.3|^7.0", 621 | "phpdocumentor/reflection-docblock": "^2.0|^3.0.2", 622 | "sebastian/comparator": "^1.1", 623 | "sebastian/recursion-context": "^1.0|^2.0" 624 | }, 625 | "require-dev": { 626 | "phpspec/phpspec": "^2.0", 627 | "phpunit/phpunit": "^4.8 || ^5.6.5" 628 | }, 629 | "type": "library", 630 | "extra": { 631 | "branch-alias": { 632 | "dev-master": "1.6.x-dev" 633 | } 634 | }, 635 | "autoload": { 636 | "psr-0": { 637 | "Prophecy\\": "src/" 638 | } 639 | }, 640 | "notification-url": "https://packagist.org/downloads/", 641 | "license": [ 642 | "MIT" 643 | ], 644 | "authors": [ 645 | { 646 | "name": "Konstantin Kudryashov", 647 | "email": "ever.zet@gmail.com", 648 | "homepage": "http://everzet.com" 649 | }, 650 | { 651 | "name": "Marcello Duarte", 652 | "email": "marcello.duarte@gmail.com" 653 | } 654 | ], 655 | "description": "Highly opinionated mocking framework for PHP 5.3+", 656 | "homepage": "https://github.com/phpspec/prophecy", 657 | "keywords": [ 658 | "Double", 659 | "Dummy", 660 | "fake", 661 | "mock", 662 | "spy", 663 | "stub" 664 | ], 665 | "time": "2016-11-21T14:58:47+00:00" 666 | }, 667 | { 668 | "name": "phpunit/php-code-coverage", 669 | "version": "2.2.4", 670 | "source": { 671 | "type": "git", 672 | "url": "https://github.com/sebastianbergmann/php-code-coverage.git", 673 | "reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979" 674 | }, 675 | "dist": { 676 | "type": "zip", 677 | "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/eabf68b476ac7d0f73793aada060f1c1a9bf8979", 678 | "reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979", 679 | "shasum": "" 680 | }, 681 | "require": { 682 | "php": ">=5.3.3", 683 | "phpunit/php-file-iterator": "~1.3", 684 | "phpunit/php-text-template": "~1.2", 685 | "phpunit/php-token-stream": "~1.3", 686 | "sebastian/environment": "^1.3.2", 687 | "sebastian/version": "~1.0" 688 | }, 689 | "require-dev": { 690 | "ext-xdebug": ">=2.1.4", 691 | "phpunit/phpunit": "~4" 692 | }, 693 | "suggest": { 694 | "ext-dom": "*", 695 | "ext-xdebug": ">=2.2.1", 696 | "ext-xmlwriter": "*" 697 | }, 698 | "type": "library", 699 | "extra": { 700 | "branch-alias": { 701 | "dev-master": "2.2.x-dev" 702 | } 703 | }, 704 | "autoload": { 705 | "classmap": [ 706 | "src/" 707 | ] 708 | }, 709 | "notification-url": "https://packagist.org/downloads/", 710 | "license": [ 711 | "BSD-3-Clause" 712 | ], 713 | "authors": [ 714 | { 715 | "name": "Sebastian Bergmann", 716 | "email": "sb@sebastian-bergmann.de", 717 | "role": "lead" 718 | } 719 | ], 720 | "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", 721 | "homepage": "https://github.com/sebastianbergmann/php-code-coverage", 722 | "keywords": [ 723 | "coverage", 724 | "testing", 725 | "xunit" 726 | ], 727 | "time": "2015-10-06T15:47:00+00:00" 728 | }, 729 | { 730 | "name": "phpunit/php-file-iterator", 731 | "version": "1.4.2", 732 | "source": { 733 | "type": "git", 734 | "url": "https://github.com/sebastianbergmann/php-file-iterator.git", 735 | "reference": "3cc8f69b3028d0f96a9078e6295d86e9bf019be5" 736 | }, 737 | "dist": { 738 | "type": "zip", 739 | "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/3cc8f69b3028d0f96a9078e6295d86e9bf019be5", 740 | "reference": "3cc8f69b3028d0f96a9078e6295d86e9bf019be5", 741 | "shasum": "" 742 | }, 743 | "require": { 744 | "php": ">=5.3.3" 745 | }, 746 | "type": "library", 747 | "extra": { 748 | "branch-alias": { 749 | "dev-master": "1.4.x-dev" 750 | } 751 | }, 752 | "autoload": { 753 | "classmap": [ 754 | "src/" 755 | ] 756 | }, 757 | "notification-url": "https://packagist.org/downloads/", 758 | "license": [ 759 | "BSD-3-Clause" 760 | ], 761 | "authors": [ 762 | { 763 | "name": "Sebastian Bergmann", 764 | "email": "sb@sebastian-bergmann.de", 765 | "role": "lead" 766 | } 767 | ], 768 | "description": "FilterIterator implementation that filters files based on a list of suffixes.", 769 | "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", 770 | "keywords": [ 771 | "filesystem", 772 | "iterator" 773 | ], 774 | "time": "2016-10-03T07:40:28+00:00" 775 | }, 776 | { 777 | "name": "phpunit/php-text-template", 778 | "version": "1.2.1", 779 | "source": { 780 | "type": "git", 781 | "url": "https://github.com/sebastianbergmann/php-text-template.git", 782 | "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686" 783 | }, 784 | "dist": { 785 | "type": "zip", 786 | "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686", 787 | "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686", 788 | "shasum": "" 789 | }, 790 | "require": { 791 | "php": ">=5.3.3" 792 | }, 793 | "type": "library", 794 | "autoload": { 795 | "classmap": [ 796 | "src/" 797 | ] 798 | }, 799 | "notification-url": "https://packagist.org/downloads/", 800 | "license": [ 801 | "BSD-3-Clause" 802 | ], 803 | "authors": [ 804 | { 805 | "name": "Sebastian Bergmann", 806 | "email": "sebastian@phpunit.de", 807 | "role": "lead" 808 | } 809 | ], 810 | "description": "Simple template engine.", 811 | "homepage": "https://github.com/sebastianbergmann/php-text-template/", 812 | "keywords": [ 813 | "template" 814 | ], 815 | "time": "2015-06-21T13:50:34+00:00" 816 | }, 817 | { 818 | "name": "phpunit/php-timer", 819 | "version": "1.0.8", 820 | "source": { 821 | "type": "git", 822 | "url": "https://github.com/sebastianbergmann/php-timer.git", 823 | "reference": "38e9124049cf1a164f1e4537caf19c99bf1eb260" 824 | }, 825 | "dist": { 826 | "type": "zip", 827 | "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/38e9124049cf1a164f1e4537caf19c99bf1eb260", 828 | "reference": "38e9124049cf1a164f1e4537caf19c99bf1eb260", 829 | "shasum": "" 830 | }, 831 | "require": { 832 | "php": ">=5.3.3" 833 | }, 834 | "require-dev": { 835 | "phpunit/phpunit": "~4|~5" 836 | }, 837 | "type": "library", 838 | "autoload": { 839 | "classmap": [ 840 | "src/" 841 | ] 842 | }, 843 | "notification-url": "https://packagist.org/downloads/", 844 | "license": [ 845 | "BSD-3-Clause" 846 | ], 847 | "authors": [ 848 | { 849 | "name": "Sebastian Bergmann", 850 | "email": "sb@sebastian-bergmann.de", 851 | "role": "lead" 852 | } 853 | ], 854 | "description": "Utility class for timing", 855 | "homepage": "https://github.com/sebastianbergmann/php-timer/", 856 | "keywords": [ 857 | "timer" 858 | ], 859 | "time": "2016-05-12T18:03:57+00:00" 860 | }, 861 | { 862 | "name": "phpunit/php-token-stream", 863 | "version": "1.4.9", 864 | "source": { 865 | "type": "git", 866 | "url": "https://github.com/sebastianbergmann/php-token-stream.git", 867 | "reference": "3b402f65a4cc90abf6e1104e388b896ce209631b" 868 | }, 869 | "dist": { 870 | "type": "zip", 871 | "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/3b402f65a4cc90abf6e1104e388b896ce209631b", 872 | "reference": "3b402f65a4cc90abf6e1104e388b896ce209631b", 873 | "shasum": "" 874 | }, 875 | "require": { 876 | "ext-tokenizer": "*", 877 | "php": ">=5.3.3" 878 | }, 879 | "require-dev": { 880 | "phpunit/phpunit": "~4.2" 881 | }, 882 | "type": "library", 883 | "extra": { 884 | "branch-alias": { 885 | "dev-master": "1.4-dev" 886 | } 887 | }, 888 | "autoload": { 889 | "classmap": [ 890 | "src/" 891 | ] 892 | }, 893 | "notification-url": "https://packagist.org/downloads/", 894 | "license": [ 895 | "BSD-3-Clause" 896 | ], 897 | "authors": [ 898 | { 899 | "name": "Sebastian Bergmann", 900 | "email": "sebastian@phpunit.de" 901 | } 902 | ], 903 | "description": "Wrapper around PHP's tokenizer extension.", 904 | "homepage": "https://github.com/sebastianbergmann/php-token-stream/", 905 | "keywords": [ 906 | "tokenizer" 907 | ], 908 | "time": "2016-11-15T14:06:22+00:00" 909 | }, 910 | { 911 | "name": "phpunit/phpunit", 912 | "version": "4.8.32", 913 | "source": { 914 | "type": "git", 915 | "url": "https://github.com/sebastianbergmann/phpunit.git", 916 | "reference": "f5e1941a8dacf0d904753ff2895c6f68e54bcee1" 917 | }, 918 | "dist": { 919 | "type": "zip", 920 | "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/f5e1941a8dacf0d904753ff2895c6f68e54bcee1", 921 | "reference": "f5e1941a8dacf0d904753ff2895c6f68e54bcee1", 922 | "shasum": "" 923 | }, 924 | "require": { 925 | "ext-dom": "*", 926 | "ext-json": "*", 927 | "ext-pcre": "*", 928 | "ext-reflection": "*", 929 | "ext-spl": "*", 930 | "php": ">=5.3.3", 931 | "phpspec/prophecy": "^1.3.1", 932 | "phpunit/php-code-coverage": "~2.1", 933 | "phpunit/php-file-iterator": "~1.4", 934 | "phpunit/php-text-template": "~1.2", 935 | "phpunit/php-timer": "^1.0.6", 936 | "phpunit/phpunit-mock-objects": "~2.3", 937 | "sebastian/comparator": "~1.2.2", 938 | "sebastian/diff": "~1.2", 939 | "sebastian/environment": "~1.3", 940 | "sebastian/exporter": "~1.2", 941 | "sebastian/global-state": "~1.0", 942 | "sebastian/version": "~1.0", 943 | "symfony/yaml": "~2.1|~3.0" 944 | }, 945 | "suggest": { 946 | "phpunit/php-invoker": "~1.1" 947 | }, 948 | "bin": [ 949 | "phpunit" 950 | ], 951 | "type": "library", 952 | "extra": { 953 | "branch-alias": { 954 | "dev-master": "4.8.x-dev" 955 | } 956 | }, 957 | "autoload": { 958 | "classmap": [ 959 | "src/" 960 | ] 961 | }, 962 | "notification-url": "https://packagist.org/downloads/", 963 | "license": [ 964 | "BSD-3-Clause" 965 | ], 966 | "authors": [ 967 | { 968 | "name": "Sebastian Bergmann", 969 | "email": "sebastian@phpunit.de", 970 | "role": "lead" 971 | } 972 | ], 973 | "description": "The PHP Unit Testing framework.", 974 | "homepage": "https://phpunit.de/", 975 | "keywords": [ 976 | "phpunit", 977 | "testing", 978 | "xunit" 979 | ], 980 | "time": "2017-01-22T08:37:05+00:00" 981 | }, 982 | { 983 | "name": "phpunit/phpunit-mock-objects", 984 | "version": "2.3.8", 985 | "source": { 986 | "type": "git", 987 | "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", 988 | "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983" 989 | }, 990 | "dist": { 991 | "type": "zip", 992 | "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/ac8e7a3db35738d56ee9a76e78a4e03d97628983", 993 | "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983", 994 | "shasum": "" 995 | }, 996 | "require": { 997 | "doctrine/instantiator": "^1.0.2", 998 | "php": ">=5.3.3", 999 | "phpunit/php-text-template": "~1.2", 1000 | "sebastian/exporter": "~1.2" 1001 | }, 1002 | "require-dev": { 1003 | "phpunit/phpunit": "~4.4" 1004 | }, 1005 | "suggest": { 1006 | "ext-soap": "*" 1007 | }, 1008 | "type": "library", 1009 | "extra": { 1010 | "branch-alias": { 1011 | "dev-master": "2.3.x-dev" 1012 | } 1013 | }, 1014 | "autoload": { 1015 | "classmap": [ 1016 | "src/" 1017 | ] 1018 | }, 1019 | "notification-url": "https://packagist.org/downloads/", 1020 | "license": [ 1021 | "BSD-3-Clause" 1022 | ], 1023 | "authors": [ 1024 | { 1025 | "name": "Sebastian Bergmann", 1026 | "email": "sb@sebastian-bergmann.de", 1027 | "role": "lead" 1028 | } 1029 | ], 1030 | "description": "Mock Object library for PHPUnit", 1031 | "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/", 1032 | "keywords": [ 1033 | "mock", 1034 | "xunit" 1035 | ], 1036 | "time": "2015-10-02T06:51:40+00:00" 1037 | }, 1038 | { 1039 | "name": "psr/log", 1040 | "version": "1.0.2", 1041 | "source": { 1042 | "type": "git", 1043 | "url": "https://github.com/php-fig/log.git", 1044 | "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d" 1045 | }, 1046 | "dist": { 1047 | "type": "zip", 1048 | "url": "https://api.github.com/repos/php-fig/log/zipball/4ebe3a8bf773a19edfe0a84b6585ba3d401b724d", 1049 | "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d", 1050 | "shasum": "" 1051 | }, 1052 | "require": { 1053 | "php": ">=5.3.0" 1054 | }, 1055 | "type": "library", 1056 | "extra": { 1057 | "branch-alias": { 1058 | "dev-master": "1.0.x-dev" 1059 | } 1060 | }, 1061 | "autoload": { 1062 | "psr-4": { 1063 | "Psr\\Log\\": "Psr/Log/" 1064 | } 1065 | }, 1066 | "notification-url": "https://packagist.org/downloads/", 1067 | "license": [ 1068 | "MIT" 1069 | ], 1070 | "authors": [ 1071 | { 1072 | "name": "PHP-FIG", 1073 | "homepage": "http://www.php-fig.org/" 1074 | } 1075 | ], 1076 | "description": "Common interface for logging libraries", 1077 | "homepage": "https://github.com/php-fig/log", 1078 | "keywords": [ 1079 | "log", 1080 | "psr", 1081 | "psr-3" 1082 | ], 1083 | "time": "2016-10-10T12:19:37+00:00" 1084 | }, 1085 | { 1086 | "name": "sebastian/comparator", 1087 | "version": "1.2.2", 1088 | "source": { 1089 | "type": "git", 1090 | "url": "https://github.com/sebastianbergmann/comparator.git", 1091 | "reference": "6a1ed12e8b2409076ab22e3897126211ff8b1f7f" 1092 | }, 1093 | "dist": { 1094 | "type": "zip", 1095 | "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/6a1ed12e8b2409076ab22e3897126211ff8b1f7f", 1096 | "reference": "6a1ed12e8b2409076ab22e3897126211ff8b1f7f", 1097 | "shasum": "" 1098 | }, 1099 | "require": { 1100 | "php": ">=5.3.3", 1101 | "sebastian/diff": "~1.2", 1102 | "sebastian/exporter": "~1.2 || ~2.0" 1103 | }, 1104 | "require-dev": { 1105 | "phpunit/phpunit": "~4.4" 1106 | }, 1107 | "type": "library", 1108 | "extra": { 1109 | "branch-alias": { 1110 | "dev-master": "1.2.x-dev" 1111 | } 1112 | }, 1113 | "autoload": { 1114 | "classmap": [ 1115 | "src/" 1116 | ] 1117 | }, 1118 | "notification-url": "https://packagist.org/downloads/", 1119 | "license": [ 1120 | "BSD-3-Clause" 1121 | ], 1122 | "authors": [ 1123 | { 1124 | "name": "Jeff Welch", 1125 | "email": "whatthejeff@gmail.com" 1126 | }, 1127 | { 1128 | "name": "Volker Dusch", 1129 | "email": "github@wallbash.com" 1130 | }, 1131 | { 1132 | "name": "Bernhard Schussek", 1133 | "email": "bschussek@2bepublished.at" 1134 | }, 1135 | { 1136 | "name": "Sebastian Bergmann", 1137 | "email": "sebastian@phpunit.de" 1138 | } 1139 | ], 1140 | "description": "Provides the functionality to compare PHP values for equality", 1141 | "homepage": "http://www.github.com/sebastianbergmann/comparator", 1142 | "keywords": [ 1143 | "comparator", 1144 | "compare", 1145 | "equality" 1146 | ], 1147 | "time": "2016-11-19T09:18:40+00:00" 1148 | }, 1149 | { 1150 | "name": "sebastian/diff", 1151 | "version": "1.4.1", 1152 | "source": { 1153 | "type": "git", 1154 | "url": "https://github.com/sebastianbergmann/diff.git", 1155 | "reference": "13edfd8706462032c2f52b4b862974dd46b71c9e" 1156 | }, 1157 | "dist": { 1158 | "type": "zip", 1159 | "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/13edfd8706462032c2f52b4b862974dd46b71c9e", 1160 | "reference": "13edfd8706462032c2f52b4b862974dd46b71c9e", 1161 | "shasum": "" 1162 | }, 1163 | "require": { 1164 | "php": ">=5.3.3" 1165 | }, 1166 | "require-dev": { 1167 | "phpunit/phpunit": "~4.8" 1168 | }, 1169 | "type": "library", 1170 | "extra": { 1171 | "branch-alias": { 1172 | "dev-master": "1.4-dev" 1173 | } 1174 | }, 1175 | "autoload": { 1176 | "classmap": [ 1177 | "src/" 1178 | ] 1179 | }, 1180 | "notification-url": "https://packagist.org/downloads/", 1181 | "license": [ 1182 | "BSD-3-Clause" 1183 | ], 1184 | "authors": [ 1185 | { 1186 | "name": "Kore Nordmann", 1187 | "email": "mail@kore-nordmann.de" 1188 | }, 1189 | { 1190 | "name": "Sebastian Bergmann", 1191 | "email": "sebastian@phpunit.de" 1192 | } 1193 | ], 1194 | "description": "Diff implementation", 1195 | "homepage": "https://github.com/sebastianbergmann/diff", 1196 | "keywords": [ 1197 | "diff" 1198 | ], 1199 | "time": "2015-12-08T07:14:41+00:00" 1200 | }, 1201 | { 1202 | "name": "sebastian/environment", 1203 | "version": "1.3.8", 1204 | "source": { 1205 | "type": "git", 1206 | "url": "https://github.com/sebastianbergmann/environment.git", 1207 | "reference": "be2c607e43ce4c89ecd60e75c6a85c126e754aea" 1208 | }, 1209 | "dist": { 1210 | "type": "zip", 1211 | "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/be2c607e43ce4c89ecd60e75c6a85c126e754aea", 1212 | "reference": "be2c607e43ce4c89ecd60e75c6a85c126e754aea", 1213 | "shasum": "" 1214 | }, 1215 | "require": { 1216 | "php": "^5.3.3 || ^7.0" 1217 | }, 1218 | "require-dev": { 1219 | "phpunit/phpunit": "^4.8 || ^5.0" 1220 | }, 1221 | "type": "library", 1222 | "extra": { 1223 | "branch-alias": { 1224 | "dev-master": "1.3.x-dev" 1225 | } 1226 | }, 1227 | "autoload": { 1228 | "classmap": [ 1229 | "src/" 1230 | ] 1231 | }, 1232 | "notification-url": "https://packagist.org/downloads/", 1233 | "license": [ 1234 | "BSD-3-Clause" 1235 | ], 1236 | "authors": [ 1237 | { 1238 | "name": "Sebastian Bergmann", 1239 | "email": "sebastian@phpunit.de" 1240 | } 1241 | ], 1242 | "description": "Provides functionality to handle HHVM/PHP environments", 1243 | "homepage": "http://www.github.com/sebastianbergmann/environment", 1244 | "keywords": [ 1245 | "Xdebug", 1246 | "environment", 1247 | "hhvm" 1248 | ], 1249 | "time": "2016-08-18T05:49:44+00:00" 1250 | }, 1251 | { 1252 | "name": "sebastian/exporter", 1253 | "version": "1.2.2", 1254 | "source": { 1255 | "type": "git", 1256 | "url": "https://github.com/sebastianbergmann/exporter.git", 1257 | "reference": "42c4c2eec485ee3e159ec9884f95b431287edde4" 1258 | }, 1259 | "dist": { 1260 | "type": "zip", 1261 | "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/42c4c2eec485ee3e159ec9884f95b431287edde4", 1262 | "reference": "42c4c2eec485ee3e159ec9884f95b431287edde4", 1263 | "shasum": "" 1264 | }, 1265 | "require": { 1266 | "php": ">=5.3.3", 1267 | "sebastian/recursion-context": "~1.0" 1268 | }, 1269 | "require-dev": { 1270 | "ext-mbstring": "*", 1271 | "phpunit/phpunit": "~4.4" 1272 | }, 1273 | "type": "library", 1274 | "extra": { 1275 | "branch-alias": { 1276 | "dev-master": "1.3.x-dev" 1277 | } 1278 | }, 1279 | "autoload": { 1280 | "classmap": [ 1281 | "src/" 1282 | ] 1283 | }, 1284 | "notification-url": "https://packagist.org/downloads/", 1285 | "license": [ 1286 | "BSD-3-Clause" 1287 | ], 1288 | "authors": [ 1289 | { 1290 | "name": "Jeff Welch", 1291 | "email": "whatthejeff@gmail.com" 1292 | }, 1293 | { 1294 | "name": "Volker Dusch", 1295 | "email": "github@wallbash.com" 1296 | }, 1297 | { 1298 | "name": "Bernhard Schussek", 1299 | "email": "bschussek@2bepublished.at" 1300 | }, 1301 | { 1302 | "name": "Sebastian Bergmann", 1303 | "email": "sebastian@phpunit.de" 1304 | }, 1305 | { 1306 | "name": "Adam Harvey", 1307 | "email": "aharvey@php.net" 1308 | } 1309 | ], 1310 | "description": "Provides the functionality to export PHP variables for visualization", 1311 | "homepage": "http://www.github.com/sebastianbergmann/exporter", 1312 | "keywords": [ 1313 | "export", 1314 | "exporter" 1315 | ], 1316 | "time": "2016-06-17T09:04:28+00:00" 1317 | }, 1318 | { 1319 | "name": "sebastian/finder-facade", 1320 | "version": "1.2.1", 1321 | "source": { 1322 | "type": "git", 1323 | "url": "https://github.com/sebastianbergmann/finder-facade.git", 1324 | "reference": "2a6f7f57efc0aa2d23297d9fd9e2a03111a8c0b9" 1325 | }, 1326 | "dist": { 1327 | "type": "zip", 1328 | "url": "https://api.github.com/repos/sebastianbergmann/finder-facade/zipball/2a6f7f57efc0aa2d23297d9fd9e2a03111a8c0b9", 1329 | "reference": "2a6f7f57efc0aa2d23297d9fd9e2a03111a8c0b9", 1330 | "shasum": "" 1331 | }, 1332 | "require": { 1333 | "symfony/finder": "~2.3|~3.0", 1334 | "theseer/fdomdocument": "~1.3" 1335 | }, 1336 | "type": "library", 1337 | "autoload": { 1338 | "classmap": [ 1339 | "src/" 1340 | ] 1341 | }, 1342 | "notification-url": "https://packagist.org/downloads/", 1343 | "license": [ 1344 | "BSD-3-Clause" 1345 | ], 1346 | "authors": [ 1347 | { 1348 | "name": "Sebastian Bergmann", 1349 | "email": "sebastian@phpunit.de", 1350 | "role": "lead" 1351 | } 1352 | ], 1353 | "description": "FinderFacade is a convenience wrapper for Symfony's Finder component.", 1354 | "homepage": "https://github.com/sebastianbergmann/finder-facade", 1355 | "time": "2016-02-17T07:02:23+00:00" 1356 | }, 1357 | { 1358 | "name": "sebastian/git", 1359 | "version": "2.1.3", 1360 | "source": { 1361 | "type": "git", 1362 | "url": "https://github.com/sebastianbergmann/git.git", 1363 | "reference": "5100bc50cd9e70f424c643618e142214225024f3" 1364 | }, 1365 | "dist": { 1366 | "type": "zip", 1367 | "url": "https://api.github.com/repos/sebastianbergmann/git/zipball/5100bc50cd9e70f424c643618e142214225024f3", 1368 | "reference": "5100bc50cd9e70f424c643618e142214225024f3", 1369 | "shasum": "" 1370 | }, 1371 | "require": { 1372 | "php": ">=5.3.3" 1373 | }, 1374 | "type": "library", 1375 | "extra": { 1376 | "branch-alias": { 1377 | "dev-master": "2.1-dev" 1378 | } 1379 | }, 1380 | "autoload": { 1381 | "classmap": [ 1382 | "src/" 1383 | ] 1384 | }, 1385 | "notification-url": "https://packagist.org/downloads/", 1386 | "license": [ 1387 | "BSD-3-Clause" 1388 | ], 1389 | "authors": [ 1390 | { 1391 | "name": "Sebastian Bergmann", 1392 | "email": "sebastian@phpunit.de" 1393 | } 1394 | ], 1395 | "description": "Simple wrapper for Git", 1396 | "homepage": "http://www.github.com/sebastianbergmann/git", 1397 | "keywords": [ 1398 | "git" 1399 | ], 1400 | "time": "2016-06-15T09:30:19+00:00" 1401 | }, 1402 | { 1403 | "name": "sebastian/global-state", 1404 | "version": "1.1.1", 1405 | "source": { 1406 | "type": "git", 1407 | "url": "https://github.com/sebastianbergmann/global-state.git", 1408 | "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4" 1409 | }, 1410 | "dist": { 1411 | "type": "zip", 1412 | "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bc37d50fea7d017d3d340f230811c9f1d7280af4", 1413 | "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4", 1414 | "shasum": "" 1415 | }, 1416 | "require": { 1417 | "php": ">=5.3.3" 1418 | }, 1419 | "require-dev": { 1420 | "phpunit/phpunit": "~4.2" 1421 | }, 1422 | "suggest": { 1423 | "ext-uopz": "*" 1424 | }, 1425 | "type": "library", 1426 | "extra": { 1427 | "branch-alias": { 1428 | "dev-master": "1.0-dev" 1429 | } 1430 | }, 1431 | "autoload": { 1432 | "classmap": [ 1433 | "src/" 1434 | ] 1435 | }, 1436 | "notification-url": "https://packagist.org/downloads/", 1437 | "license": [ 1438 | "BSD-3-Clause" 1439 | ], 1440 | "authors": [ 1441 | { 1442 | "name": "Sebastian Bergmann", 1443 | "email": "sebastian@phpunit.de" 1444 | } 1445 | ], 1446 | "description": "Snapshotting of global state", 1447 | "homepage": "http://www.github.com/sebastianbergmann/global-state", 1448 | "keywords": [ 1449 | "global state" 1450 | ], 1451 | "time": "2015-10-12T03:26:01+00:00" 1452 | }, 1453 | { 1454 | "name": "sebastian/phpcpd", 1455 | "version": "2.0.4", 1456 | "source": { 1457 | "type": "git", 1458 | "url": "https://github.com/sebastianbergmann/phpcpd.git", 1459 | "reference": "24d9a880deadb0b8c9680e9cfe78e30b704225db" 1460 | }, 1461 | "dist": { 1462 | "type": "zip", 1463 | "url": "https://api.github.com/repos/sebastianbergmann/phpcpd/zipball/24d9a880deadb0b8c9680e9cfe78e30b704225db", 1464 | "reference": "24d9a880deadb0b8c9680e9cfe78e30b704225db", 1465 | "shasum": "" 1466 | }, 1467 | "require": { 1468 | "php": ">=5.3.3", 1469 | "phpunit/php-timer": ">=1.0.6", 1470 | "sebastian/finder-facade": "~1.1", 1471 | "sebastian/version": "~1.0|~2.0", 1472 | "symfony/console": "~2.7|^3.0", 1473 | "theseer/fdomdocument": "~1.4" 1474 | }, 1475 | "bin": [ 1476 | "phpcpd" 1477 | ], 1478 | "type": "library", 1479 | "extra": { 1480 | "branch-alias": { 1481 | "dev-master": "2.0-dev" 1482 | } 1483 | }, 1484 | "autoload": { 1485 | "classmap": [ 1486 | "src/" 1487 | ] 1488 | }, 1489 | "notification-url": "https://packagist.org/downloads/", 1490 | "license": [ 1491 | "BSD-3-Clause" 1492 | ], 1493 | "authors": [ 1494 | { 1495 | "name": "Sebastian Bergmann", 1496 | "email": "sebastian@phpunit.de", 1497 | "role": "lead" 1498 | } 1499 | ], 1500 | "description": "Copy/Paste Detector (CPD) for PHP code.", 1501 | "homepage": "https://github.com/sebastianbergmann/phpcpd", 1502 | "time": "2016-04-17T19:32:49+00:00" 1503 | }, 1504 | { 1505 | "name": "sebastian/phpdcd", 1506 | "version": "1.0.2", 1507 | "source": { 1508 | "type": "git", 1509 | "url": "https://github.com/sebastianbergmann/phpdcd.git", 1510 | "reference": "10246f167713d0bd0b74540ca81e4caf30b72157" 1511 | }, 1512 | "dist": { 1513 | "type": "zip", 1514 | "url": "https://api.github.com/repos/sebastianbergmann/phpdcd/zipball/10246f167713d0bd0b74540ca81e4caf30b72157", 1515 | "reference": "10246f167713d0bd0b74540ca81e4caf30b72157", 1516 | "shasum": "" 1517 | }, 1518 | "require": { 1519 | "php": ">=5.3.3", 1520 | "phpunit/php-timer": ">=1.0.4", 1521 | "phpunit/php-token-stream": ">=1.1.3", 1522 | "sebastian/finder-facade": ">=1.1.0", 1523 | "sebastian/version": ">=1.0.3", 1524 | "symfony/console": ">=2.2.0" 1525 | }, 1526 | "require-dev": { 1527 | "phpunit/phpunit": "~3.7" 1528 | }, 1529 | "bin": [ 1530 | "phpdcd" 1531 | ], 1532 | "type": "library", 1533 | "extra": { 1534 | "branch-alias": { 1535 | "dev-master": "1.0-dev" 1536 | } 1537 | }, 1538 | "autoload": { 1539 | "classmap": [ 1540 | "src/" 1541 | ] 1542 | }, 1543 | "notification-url": "https://packagist.org/downloads/", 1544 | "license": [ 1545 | "BSD-3-Clause" 1546 | ], 1547 | "authors": [ 1548 | { 1549 | "name": "Sebastian Bergmann", 1550 | "email": "sebastian@phpunit.de", 1551 | "role": "lead" 1552 | } 1553 | ], 1554 | "description": "Dead Code Detector (DCD) for PHP code.", 1555 | "homepage": "https://github.com/sebastianbergmann/phpdcd", 1556 | "abandoned": true, 1557 | "time": "2014-04-27T06:42:32+00:00" 1558 | }, 1559 | { 1560 | "name": "sebastian/recursion-context", 1561 | "version": "1.0.2", 1562 | "source": { 1563 | "type": "git", 1564 | "url": "https://github.com/sebastianbergmann/recursion-context.git", 1565 | "reference": "913401df809e99e4f47b27cdd781f4a258d58791" 1566 | }, 1567 | "dist": { 1568 | "type": "zip", 1569 | "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/913401df809e99e4f47b27cdd781f4a258d58791", 1570 | "reference": "913401df809e99e4f47b27cdd781f4a258d58791", 1571 | "shasum": "" 1572 | }, 1573 | "require": { 1574 | "php": ">=5.3.3" 1575 | }, 1576 | "require-dev": { 1577 | "phpunit/phpunit": "~4.4" 1578 | }, 1579 | "type": "library", 1580 | "extra": { 1581 | "branch-alias": { 1582 | "dev-master": "1.0.x-dev" 1583 | } 1584 | }, 1585 | "autoload": { 1586 | "classmap": [ 1587 | "src/" 1588 | ] 1589 | }, 1590 | "notification-url": "https://packagist.org/downloads/", 1591 | "license": [ 1592 | "BSD-3-Clause" 1593 | ], 1594 | "authors": [ 1595 | { 1596 | "name": "Jeff Welch", 1597 | "email": "whatthejeff@gmail.com" 1598 | }, 1599 | { 1600 | "name": "Sebastian Bergmann", 1601 | "email": "sebastian@phpunit.de" 1602 | }, 1603 | { 1604 | "name": "Adam Harvey", 1605 | "email": "aharvey@php.net" 1606 | } 1607 | ], 1608 | "description": "Provides functionality to recursively process PHP variables", 1609 | "homepage": "http://www.github.com/sebastianbergmann/recursion-context", 1610 | "time": "2015-11-11T19:50:13+00:00" 1611 | }, 1612 | { 1613 | "name": "sebastian/version", 1614 | "version": "1.0.6", 1615 | "source": { 1616 | "type": "git", 1617 | "url": "https://github.com/sebastianbergmann/version.git", 1618 | "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6" 1619 | }, 1620 | "dist": { 1621 | "type": "zip", 1622 | "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/58b3a85e7999757d6ad81c787a1fbf5ff6c628c6", 1623 | "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6", 1624 | "shasum": "" 1625 | }, 1626 | "type": "library", 1627 | "autoload": { 1628 | "classmap": [ 1629 | "src/" 1630 | ] 1631 | }, 1632 | "notification-url": "https://packagist.org/downloads/", 1633 | "license": [ 1634 | "BSD-3-Clause" 1635 | ], 1636 | "authors": [ 1637 | { 1638 | "name": "Sebastian Bergmann", 1639 | "email": "sebastian@phpunit.de", 1640 | "role": "lead" 1641 | } 1642 | ], 1643 | "description": "Library that helps with managing the version number of Git-hosted PHP projects", 1644 | "homepage": "https://github.com/sebastianbergmann/version", 1645 | "time": "2015-06-21T13:59:46+00:00" 1646 | }, 1647 | { 1648 | "name": "squizlabs/php_codesniffer", 1649 | "version": "2.7.1", 1650 | "source": { 1651 | "type": "git", 1652 | "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", 1653 | "reference": "9b324f3a1132459a7274a0ace2e1b766ba80930f" 1654 | }, 1655 | "dist": { 1656 | "type": "zip", 1657 | "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/9b324f3a1132459a7274a0ace2e1b766ba80930f", 1658 | "reference": "9b324f3a1132459a7274a0ace2e1b766ba80930f", 1659 | "shasum": "" 1660 | }, 1661 | "require": { 1662 | "ext-simplexml": "*", 1663 | "ext-tokenizer": "*", 1664 | "ext-xmlwriter": "*", 1665 | "php": ">=5.1.2" 1666 | }, 1667 | "require-dev": { 1668 | "phpunit/phpunit": "~4.0" 1669 | }, 1670 | "bin": [ 1671 | "scripts/phpcs", 1672 | "scripts/phpcbf" 1673 | ], 1674 | "type": "library", 1675 | "extra": { 1676 | "branch-alias": { 1677 | "dev-master": "2.x-dev" 1678 | } 1679 | }, 1680 | "autoload": { 1681 | "classmap": [ 1682 | "CodeSniffer.php", 1683 | "CodeSniffer/CLI.php", 1684 | "CodeSniffer/Exception.php", 1685 | "CodeSniffer/File.php", 1686 | "CodeSniffer/Fixer.php", 1687 | "CodeSniffer/Report.php", 1688 | "CodeSniffer/Reporting.php", 1689 | "CodeSniffer/Sniff.php", 1690 | "CodeSniffer/Tokens.php", 1691 | "CodeSniffer/Reports/", 1692 | "CodeSniffer/Tokenizers/", 1693 | "CodeSniffer/DocGenerators/", 1694 | "CodeSniffer/Standards/AbstractPatternSniff.php", 1695 | "CodeSniffer/Standards/AbstractScopeSniff.php", 1696 | "CodeSniffer/Standards/AbstractVariableSniff.php", 1697 | "CodeSniffer/Standards/IncorrectPatternException.php", 1698 | "CodeSniffer/Standards/Generic/Sniffs/", 1699 | "CodeSniffer/Standards/MySource/Sniffs/", 1700 | "CodeSniffer/Standards/PEAR/Sniffs/", 1701 | "CodeSniffer/Standards/PSR1/Sniffs/", 1702 | "CodeSniffer/Standards/PSR2/Sniffs/", 1703 | "CodeSniffer/Standards/Squiz/Sniffs/", 1704 | "CodeSniffer/Standards/Zend/Sniffs/" 1705 | ] 1706 | }, 1707 | "notification-url": "https://packagist.org/downloads/", 1708 | "license": [ 1709 | "BSD-3-Clause" 1710 | ], 1711 | "authors": [ 1712 | { 1713 | "name": "Greg Sherwood", 1714 | "role": "lead" 1715 | } 1716 | ], 1717 | "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.", 1718 | "homepage": "http://www.squizlabs.com/php-codesniffer", 1719 | "keywords": [ 1720 | "phpcs", 1721 | "standards" 1722 | ], 1723 | "time": "2016-11-30T04:02:31+00:00" 1724 | }, 1725 | { 1726 | "name": "symfony/config", 1727 | "version": "v3.1.9", 1728 | "source": { 1729 | "type": "git", 1730 | "url": "https://github.com/symfony/config.git", 1731 | "reference": "1e1b722057b8e8595bd1253e134ac7b5e25b79b8" 1732 | }, 1733 | "dist": { 1734 | "type": "zip", 1735 | "url": "https://api.github.com/repos/symfony/config/zipball/1e1b722057b8e8595bd1253e134ac7b5e25b79b8", 1736 | "reference": "1e1b722057b8e8595bd1253e134ac7b5e25b79b8", 1737 | "shasum": "" 1738 | }, 1739 | "require": { 1740 | "php": ">=5.5.9", 1741 | "symfony/filesystem": "~2.8|~3.0" 1742 | }, 1743 | "require-dev": { 1744 | "symfony/yaml": "~2.7|~3.0" 1745 | }, 1746 | "suggest": { 1747 | "symfony/yaml": "To use the yaml reference dumper" 1748 | }, 1749 | "type": "library", 1750 | "extra": { 1751 | "branch-alias": { 1752 | "dev-master": "3.1-dev" 1753 | } 1754 | }, 1755 | "autoload": { 1756 | "psr-4": { 1757 | "Symfony\\Component\\Config\\": "" 1758 | }, 1759 | "exclude-from-classmap": [ 1760 | "/Tests/" 1761 | ] 1762 | }, 1763 | "notification-url": "https://packagist.org/downloads/", 1764 | "license": [ 1765 | "MIT" 1766 | ], 1767 | "authors": [ 1768 | { 1769 | "name": "Fabien Potencier", 1770 | "email": "fabien@symfony.com" 1771 | }, 1772 | { 1773 | "name": "Symfony Community", 1774 | "homepage": "https://symfony.com/contributors" 1775 | } 1776 | ], 1777 | "description": "Symfony Config Component", 1778 | "homepage": "https://symfony.com", 1779 | "time": "2017-01-02T20:31:54+00:00" 1780 | }, 1781 | { 1782 | "name": "symfony/console", 1783 | "version": "v3.1.9", 1784 | "source": { 1785 | "type": "git", 1786 | "url": "https://github.com/symfony/console.git", 1787 | "reference": "047f16485d68c083bd5d9b73ff16f9cb9c1a9f52" 1788 | }, 1789 | "dist": { 1790 | "type": "zip", 1791 | "url": "https://api.github.com/repos/symfony/console/zipball/047f16485d68c083bd5d9b73ff16f9cb9c1a9f52", 1792 | "reference": "047f16485d68c083bd5d9b73ff16f9cb9c1a9f52", 1793 | "shasum": "" 1794 | }, 1795 | "require": { 1796 | "php": ">=5.5.9", 1797 | "symfony/debug": "~2.8|~3.0", 1798 | "symfony/polyfill-mbstring": "~1.0" 1799 | }, 1800 | "require-dev": { 1801 | "psr/log": "~1.0", 1802 | "symfony/event-dispatcher": "~2.8|~3.0", 1803 | "symfony/process": "~2.8|~3.0" 1804 | }, 1805 | "suggest": { 1806 | "psr/log": "For using the console logger", 1807 | "symfony/event-dispatcher": "", 1808 | "symfony/process": "" 1809 | }, 1810 | "type": "library", 1811 | "extra": { 1812 | "branch-alias": { 1813 | "dev-master": "3.1-dev" 1814 | } 1815 | }, 1816 | "autoload": { 1817 | "psr-4": { 1818 | "Symfony\\Component\\Console\\": "" 1819 | }, 1820 | "exclude-from-classmap": [ 1821 | "/Tests/" 1822 | ] 1823 | }, 1824 | "notification-url": "https://packagist.org/downloads/", 1825 | "license": [ 1826 | "MIT" 1827 | ], 1828 | "authors": [ 1829 | { 1830 | "name": "Fabien Potencier", 1831 | "email": "fabien@symfony.com" 1832 | }, 1833 | { 1834 | "name": "Symfony Community", 1835 | "homepage": "https://symfony.com/contributors" 1836 | } 1837 | ], 1838 | "description": "Symfony Console Component", 1839 | "homepage": "https://symfony.com", 1840 | "time": "2017-01-08T20:43:43+00:00" 1841 | }, 1842 | { 1843 | "name": "symfony/debug", 1844 | "version": "v3.2.2", 1845 | "source": { 1846 | "type": "git", 1847 | "url": "https://github.com/symfony/debug.git", 1848 | "reference": "810ba5c1c5352a4ddb15d4719e8936751dff0b05" 1849 | }, 1850 | "dist": { 1851 | "type": "zip", 1852 | "url": "https://api.github.com/repos/symfony/debug/zipball/810ba5c1c5352a4ddb15d4719e8936751dff0b05", 1853 | "reference": "810ba5c1c5352a4ddb15d4719e8936751dff0b05", 1854 | "shasum": "" 1855 | }, 1856 | "require": { 1857 | "php": ">=5.5.9", 1858 | "psr/log": "~1.0" 1859 | }, 1860 | "conflict": { 1861 | "symfony/http-kernel": ">=2.3,<2.3.24|~2.4.0|>=2.5,<2.5.9|>=2.6,<2.6.2" 1862 | }, 1863 | "require-dev": { 1864 | "symfony/class-loader": "~2.8|~3.0", 1865 | "symfony/http-kernel": "~2.8|~3.0" 1866 | }, 1867 | "type": "library", 1868 | "extra": { 1869 | "branch-alias": { 1870 | "dev-master": "3.2-dev" 1871 | } 1872 | }, 1873 | "autoload": { 1874 | "psr-4": { 1875 | "Symfony\\Component\\Debug\\": "" 1876 | }, 1877 | "exclude-from-classmap": [ 1878 | "/Tests/" 1879 | ] 1880 | }, 1881 | "notification-url": "https://packagist.org/downloads/", 1882 | "license": [ 1883 | "MIT" 1884 | ], 1885 | "authors": [ 1886 | { 1887 | "name": "Fabien Potencier", 1888 | "email": "fabien@symfony.com" 1889 | }, 1890 | { 1891 | "name": "Symfony Community", 1892 | "homepage": "https://symfony.com/contributors" 1893 | } 1894 | ], 1895 | "description": "Symfony Debug Component", 1896 | "homepage": "https://symfony.com", 1897 | "time": "2017-01-02T20:32:22+00:00" 1898 | }, 1899 | { 1900 | "name": "symfony/dependency-injection", 1901 | "version": "v3.2.2", 1902 | "source": { 1903 | "type": "git", 1904 | "url": "https://github.com/symfony/dependency-injection.git", 1905 | "reference": "22b2c97cffc6a612db82084f9e7823b095958751" 1906 | }, 1907 | "dist": { 1908 | "type": "zip", 1909 | "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/22b2c97cffc6a612db82084f9e7823b095958751", 1910 | "reference": "22b2c97cffc6a612db82084f9e7823b095958751", 1911 | "shasum": "" 1912 | }, 1913 | "require": { 1914 | "php": ">=5.5.9" 1915 | }, 1916 | "conflict": { 1917 | "symfony/yaml": "<3.2" 1918 | }, 1919 | "require-dev": { 1920 | "symfony/config": "~2.8|~3.0", 1921 | "symfony/expression-language": "~2.8|~3.0", 1922 | "symfony/yaml": "~3.2" 1923 | }, 1924 | "suggest": { 1925 | "symfony/config": "", 1926 | "symfony/expression-language": "For using expressions in service container configuration", 1927 | "symfony/proxy-manager-bridge": "Generate service proxies to lazy load them", 1928 | "symfony/yaml": "" 1929 | }, 1930 | "type": "library", 1931 | "extra": { 1932 | "branch-alias": { 1933 | "dev-master": "3.2-dev" 1934 | } 1935 | }, 1936 | "autoload": { 1937 | "psr-4": { 1938 | "Symfony\\Component\\DependencyInjection\\": "" 1939 | }, 1940 | "exclude-from-classmap": [ 1941 | "/Tests/" 1942 | ] 1943 | }, 1944 | "notification-url": "https://packagist.org/downloads/", 1945 | "license": [ 1946 | "MIT" 1947 | ], 1948 | "authors": [ 1949 | { 1950 | "name": "Fabien Potencier", 1951 | "email": "fabien@symfony.com" 1952 | }, 1953 | { 1954 | "name": "Symfony Community", 1955 | "homepage": "https://symfony.com/contributors" 1956 | } 1957 | ], 1958 | "description": "Symfony DependencyInjection Component", 1959 | "homepage": "https://symfony.com", 1960 | "time": "2017-01-10T14:21:25+00:00" 1961 | }, 1962 | { 1963 | "name": "symfony/event-dispatcher", 1964 | "version": "v3.2.2", 1965 | "source": { 1966 | "type": "git", 1967 | "url": "https://github.com/symfony/event-dispatcher.git", 1968 | "reference": "9137eb3a3328e413212826d63eeeb0217836e2b6" 1969 | }, 1970 | "dist": { 1971 | "type": "zip", 1972 | "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/9137eb3a3328e413212826d63eeeb0217836e2b6", 1973 | "reference": "9137eb3a3328e413212826d63eeeb0217836e2b6", 1974 | "shasum": "" 1975 | }, 1976 | "require": { 1977 | "php": ">=5.5.9" 1978 | }, 1979 | "require-dev": { 1980 | "psr/log": "~1.0", 1981 | "symfony/config": "~2.8|~3.0", 1982 | "symfony/dependency-injection": "~2.8|~3.0", 1983 | "symfony/expression-language": "~2.8|~3.0", 1984 | "symfony/stopwatch": "~2.8|~3.0" 1985 | }, 1986 | "suggest": { 1987 | "symfony/dependency-injection": "", 1988 | "symfony/http-kernel": "" 1989 | }, 1990 | "type": "library", 1991 | "extra": { 1992 | "branch-alias": { 1993 | "dev-master": "3.2-dev" 1994 | } 1995 | }, 1996 | "autoload": { 1997 | "psr-4": { 1998 | "Symfony\\Component\\EventDispatcher\\": "" 1999 | }, 2000 | "exclude-from-classmap": [ 2001 | "/Tests/" 2002 | ] 2003 | }, 2004 | "notification-url": "https://packagist.org/downloads/", 2005 | "license": [ 2006 | "MIT" 2007 | ], 2008 | "authors": [ 2009 | { 2010 | "name": "Fabien Potencier", 2011 | "email": "fabien@symfony.com" 2012 | }, 2013 | { 2014 | "name": "Symfony Community", 2015 | "homepage": "https://symfony.com/contributors" 2016 | } 2017 | ], 2018 | "description": "Symfony EventDispatcher Component", 2019 | "homepage": "https://symfony.com", 2020 | "time": "2017-01-02T20:32:22+00:00" 2021 | }, 2022 | { 2023 | "name": "symfony/filesystem", 2024 | "version": "v3.2.2", 2025 | "source": { 2026 | "type": "git", 2027 | "url": "https://github.com/symfony/filesystem.git", 2028 | "reference": "a0c6ef2dc78d33b58d91d3a49f49797a184d06f4" 2029 | }, 2030 | "dist": { 2031 | "type": "zip", 2032 | "url": "https://api.github.com/repos/symfony/filesystem/zipball/a0c6ef2dc78d33b58d91d3a49f49797a184d06f4", 2033 | "reference": "a0c6ef2dc78d33b58d91d3a49f49797a184d06f4", 2034 | "shasum": "" 2035 | }, 2036 | "require": { 2037 | "php": ">=5.5.9" 2038 | }, 2039 | "type": "library", 2040 | "extra": { 2041 | "branch-alias": { 2042 | "dev-master": "3.2-dev" 2043 | } 2044 | }, 2045 | "autoload": { 2046 | "psr-4": { 2047 | "Symfony\\Component\\Filesystem\\": "" 2048 | }, 2049 | "exclude-from-classmap": [ 2050 | "/Tests/" 2051 | ] 2052 | }, 2053 | "notification-url": "https://packagist.org/downloads/", 2054 | "license": [ 2055 | "MIT" 2056 | ], 2057 | "authors": [ 2058 | { 2059 | "name": "Fabien Potencier", 2060 | "email": "fabien@symfony.com" 2061 | }, 2062 | { 2063 | "name": "Symfony Community", 2064 | "homepage": "https://symfony.com/contributors" 2065 | } 2066 | ], 2067 | "description": "Symfony Filesystem Component", 2068 | "homepage": "https://symfony.com", 2069 | "time": "2017-01-08T20:47:33+00:00" 2070 | }, 2071 | { 2072 | "name": "symfony/finder", 2073 | "version": "v3.2.2", 2074 | "source": { 2075 | "type": "git", 2076 | "url": "https://github.com/symfony/finder.git", 2077 | "reference": "8c71141cae8e2957946b403cc71a67213c0380d6" 2078 | }, 2079 | "dist": { 2080 | "type": "zip", 2081 | "url": "https://api.github.com/repos/symfony/finder/zipball/8c71141cae8e2957946b403cc71a67213c0380d6", 2082 | "reference": "8c71141cae8e2957946b403cc71a67213c0380d6", 2083 | "shasum": "" 2084 | }, 2085 | "require": { 2086 | "php": ">=5.5.9" 2087 | }, 2088 | "type": "library", 2089 | "extra": { 2090 | "branch-alias": { 2091 | "dev-master": "3.2-dev" 2092 | } 2093 | }, 2094 | "autoload": { 2095 | "psr-4": { 2096 | "Symfony\\Component\\Finder\\": "" 2097 | }, 2098 | "exclude-from-classmap": [ 2099 | "/Tests/" 2100 | ] 2101 | }, 2102 | "notification-url": "https://packagist.org/downloads/", 2103 | "license": [ 2104 | "MIT" 2105 | ], 2106 | "authors": [ 2107 | { 2108 | "name": "Fabien Potencier", 2109 | "email": "fabien@symfony.com" 2110 | }, 2111 | { 2112 | "name": "Symfony Community", 2113 | "homepage": "https://symfony.com/contributors" 2114 | } 2115 | ], 2116 | "description": "Symfony Finder Component", 2117 | "homepage": "https://symfony.com", 2118 | "time": "2017-01-02T20:32:22+00:00" 2119 | }, 2120 | { 2121 | "name": "symfony/polyfill-mbstring", 2122 | "version": "v1.3.0", 2123 | "source": { 2124 | "type": "git", 2125 | "url": "https://github.com/symfony/polyfill-mbstring.git", 2126 | "reference": "e79d363049d1c2128f133a2667e4f4190904f7f4" 2127 | }, 2128 | "dist": { 2129 | "type": "zip", 2130 | "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/e79d363049d1c2128f133a2667e4f4190904f7f4", 2131 | "reference": "e79d363049d1c2128f133a2667e4f4190904f7f4", 2132 | "shasum": "" 2133 | }, 2134 | "require": { 2135 | "php": ">=5.3.3" 2136 | }, 2137 | "suggest": { 2138 | "ext-mbstring": "For best performance" 2139 | }, 2140 | "type": "library", 2141 | "extra": { 2142 | "branch-alias": { 2143 | "dev-master": "1.3-dev" 2144 | } 2145 | }, 2146 | "autoload": { 2147 | "psr-4": { 2148 | "Symfony\\Polyfill\\Mbstring\\": "" 2149 | }, 2150 | "files": [ 2151 | "bootstrap.php" 2152 | ] 2153 | }, 2154 | "notification-url": "https://packagist.org/downloads/", 2155 | "license": [ 2156 | "MIT" 2157 | ], 2158 | "authors": [ 2159 | { 2160 | "name": "Nicolas Grekas", 2161 | "email": "p@tchwork.com" 2162 | }, 2163 | { 2164 | "name": "Symfony Community", 2165 | "homepage": "https://symfony.com/contributors" 2166 | } 2167 | ], 2168 | "description": "Symfony polyfill for the Mbstring extension", 2169 | "homepage": "https://symfony.com", 2170 | "keywords": [ 2171 | "compatibility", 2172 | "mbstring", 2173 | "polyfill", 2174 | "portable", 2175 | "shim" 2176 | ], 2177 | "time": "2016-11-14T01:06:16+00:00" 2178 | }, 2179 | { 2180 | "name": "symfony/polyfill-php54", 2181 | "version": "v1.3.0", 2182 | "source": { 2183 | "type": "git", 2184 | "url": "https://github.com/symfony/polyfill-php54.git", 2185 | "reference": "90e085822963fdcc9d1c5b73deb3d2e5783b16a0" 2186 | }, 2187 | "dist": { 2188 | "type": "zip", 2189 | "url": "https://api.github.com/repos/symfony/polyfill-php54/zipball/90e085822963fdcc9d1c5b73deb3d2e5783b16a0", 2190 | "reference": "90e085822963fdcc9d1c5b73deb3d2e5783b16a0", 2191 | "shasum": "" 2192 | }, 2193 | "require": { 2194 | "php": ">=5.3.3" 2195 | }, 2196 | "type": "library", 2197 | "extra": { 2198 | "branch-alias": { 2199 | "dev-master": "1.3-dev" 2200 | } 2201 | }, 2202 | "autoload": { 2203 | "psr-4": { 2204 | "Symfony\\Polyfill\\Php54\\": "" 2205 | }, 2206 | "files": [ 2207 | "bootstrap.php" 2208 | ], 2209 | "classmap": [ 2210 | "Resources/stubs" 2211 | ] 2212 | }, 2213 | "notification-url": "https://packagist.org/downloads/", 2214 | "license": [ 2215 | "MIT" 2216 | ], 2217 | "authors": [ 2218 | { 2219 | "name": "Nicolas Grekas", 2220 | "email": "p@tchwork.com" 2221 | }, 2222 | { 2223 | "name": "Symfony Community", 2224 | "homepage": "https://symfony.com/contributors" 2225 | } 2226 | ], 2227 | "description": "Symfony polyfill backporting some PHP 5.4+ features to lower PHP versions", 2228 | "homepage": "https://symfony.com", 2229 | "keywords": [ 2230 | "compatibility", 2231 | "polyfill", 2232 | "portable", 2233 | "shim" 2234 | ], 2235 | "time": "2016-11-14T01:06:16+00:00" 2236 | }, 2237 | { 2238 | "name": "symfony/process", 2239 | "version": "v3.1.9", 2240 | "source": { 2241 | "type": "git", 2242 | "url": "https://github.com/symfony/process.git", 2243 | "reference": "b525066a9efe372f0910296e486aa61741b09025" 2244 | }, 2245 | "dist": { 2246 | "type": "zip", 2247 | "url": "https://api.github.com/repos/symfony/process/zipball/b525066a9efe372f0910296e486aa61741b09025", 2248 | "reference": "b525066a9efe372f0910296e486aa61741b09025", 2249 | "shasum": "" 2250 | }, 2251 | "require": { 2252 | "php": ">=5.5.9" 2253 | }, 2254 | "type": "library", 2255 | "extra": { 2256 | "branch-alias": { 2257 | "dev-master": "3.1-dev" 2258 | } 2259 | }, 2260 | "autoload": { 2261 | "psr-4": { 2262 | "Symfony\\Component\\Process\\": "" 2263 | }, 2264 | "exclude-from-classmap": [ 2265 | "/Tests/" 2266 | ] 2267 | }, 2268 | "notification-url": "https://packagist.org/downloads/", 2269 | "license": [ 2270 | "MIT" 2271 | ], 2272 | "authors": [ 2273 | { 2274 | "name": "Fabien Potencier", 2275 | "email": "fabien@symfony.com" 2276 | }, 2277 | { 2278 | "name": "Symfony Community", 2279 | "homepage": "https://symfony.com/contributors" 2280 | } 2281 | ], 2282 | "description": "Symfony Process Component", 2283 | "homepage": "https://symfony.com", 2284 | "time": "2017-01-02T20:31:54+00:00" 2285 | }, 2286 | { 2287 | "name": "symfony/stopwatch", 2288 | "version": "v3.2.2", 2289 | "source": { 2290 | "type": "git", 2291 | "url": "https://github.com/symfony/stopwatch.git", 2292 | "reference": "9aa0b51889c01bca474853ef76e9394b02264464" 2293 | }, 2294 | "dist": { 2295 | "type": "zip", 2296 | "url": "https://api.github.com/repos/symfony/stopwatch/zipball/9aa0b51889c01bca474853ef76e9394b02264464", 2297 | "reference": "9aa0b51889c01bca474853ef76e9394b02264464", 2298 | "shasum": "" 2299 | }, 2300 | "require": { 2301 | "php": ">=5.5.9" 2302 | }, 2303 | "type": "library", 2304 | "extra": { 2305 | "branch-alias": { 2306 | "dev-master": "3.2-dev" 2307 | } 2308 | }, 2309 | "autoload": { 2310 | "psr-4": { 2311 | "Symfony\\Component\\Stopwatch\\": "" 2312 | }, 2313 | "exclude-from-classmap": [ 2314 | "/Tests/" 2315 | ] 2316 | }, 2317 | "notification-url": "https://packagist.org/downloads/", 2318 | "license": [ 2319 | "MIT" 2320 | ], 2321 | "authors": [ 2322 | { 2323 | "name": "Fabien Potencier", 2324 | "email": "fabien@symfony.com" 2325 | }, 2326 | { 2327 | "name": "Symfony Community", 2328 | "homepage": "https://symfony.com/contributors" 2329 | } 2330 | ], 2331 | "description": "Symfony Stopwatch Component", 2332 | "homepage": "https://symfony.com", 2333 | "time": "2017-01-02T20:32:22+00:00" 2334 | }, 2335 | { 2336 | "name": "symfony/yaml", 2337 | "version": "v3.2.2", 2338 | "source": { 2339 | "type": "git", 2340 | "url": "https://github.com/symfony/yaml.git", 2341 | "reference": "50eadbd7926e31842893c957eca362b21592a97d" 2342 | }, 2343 | "dist": { 2344 | "type": "zip", 2345 | "url": "https://api.github.com/repos/symfony/yaml/zipball/50eadbd7926e31842893c957eca362b21592a97d", 2346 | "reference": "50eadbd7926e31842893c957eca362b21592a97d", 2347 | "shasum": "" 2348 | }, 2349 | "require": { 2350 | "php": ">=5.5.9" 2351 | }, 2352 | "require-dev": { 2353 | "symfony/console": "~2.8|~3.0" 2354 | }, 2355 | "suggest": { 2356 | "symfony/console": "For validating YAML files using the lint command" 2357 | }, 2358 | "type": "library", 2359 | "extra": { 2360 | "branch-alias": { 2361 | "dev-master": "3.2-dev" 2362 | } 2363 | }, 2364 | "autoload": { 2365 | "psr-4": { 2366 | "Symfony\\Component\\Yaml\\": "" 2367 | }, 2368 | "exclude-from-classmap": [ 2369 | "/Tests/" 2370 | ] 2371 | }, 2372 | "notification-url": "https://packagist.org/downloads/", 2373 | "license": [ 2374 | "MIT" 2375 | ], 2376 | "authors": [ 2377 | { 2378 | "name": "Fabien Potencier", 2379 | "email": "fabien@symfony.com" 2380 | }, 2381 | { 2382 | "name": "Symfony Community", 2383 | "homepage": "https://symfony.com/contributors" 2384 | } 2385 | ], 2386 | "description": "Symfony Yaml Component", 2387 | "homepage": "https://symfony.com", 2388 | "time": "2017-01-03T13:51:32+00:00" 2389 | }, 2390 | { 2391 | "name": "theseer/fdomdocument", 2392 | "version": "1.6.1", 2393 | "source": { 2394 | "type": "git", 2395 | "url": "https://github.com/theseer/fDOMDocument.git", 2396 | "reference": "d9ad139d6c2e8edf5e313ffbe37ff13344cf0684" 2397 | }, 2398 | "dist": { 2399 | "type": "zip", 2400 | "url": "https://api.github.com/repos/theseer/fDOMDocument/zipball/d9ad139d6c2e8edf5e313ffbe37ff13344cf0684", 2401 | "reference": "d9ad139d6c2e8edf5e313ffbe37ff13344cf0684", 2402 | "shasum": "" 2403 | }, 2404 | "require": { 2405 | "ext-dom": "*", 2406 | "lib-libxml": "*", 2407 | "php": ">=5.3.3" 2408 | }, 2409 | "type": "library", 2410 | "autoload": { 2411 | "classmap": [ 2412 | "src/" 2413 | ] 2414 | }, 2415 | "notification-url": "https://packagist.org/downloads/", 2416 | "license": [ 2417 | "BSD-3-Clause" 2418 | ], 2419 | "authors": [ 2420 | { 2421 | "name": "Arne Blankerts", 2422 | "email": "arne@blankerts.de", 2423 | "role": "lead" 2424 | } 2425 | ], 2426 | "description": "The classes contained within this repository extend the standard DOM to use exceptions at all occasions of errors instead of PHP warnings or notices. They also add various custom methods and shortcuts for convenience and to simplify the usage of DOM.", 2427 | "homepage": "https://github.com/theseer/fDOMDocument", 2428 | "time": "2015-05-27T22:58:02+00:00" 2429 | }, 2430 | { 2431 | "name": "webmozart/assert", 2432 | "version": "1.2.0", 2433 | "source": { 2434 | "type": "git", 2435 | "url": "https://github.com/webmozart/assert.git", 2436 | "reference": "2db61e59ff05fe5126d152bd0655c9ea113e550f" 2437 | }, 2438 | "dist": { 2439 | "type": "zip", 2440 | "url": "https://api.github.com/repos/webmozart/assert/zipball/2db61e59ff05fe5126d152bd0655c9ea113e550f", 2441 | "reference": "2db61e59ff05fe5126d152bd0655c9ea113e550f", 2442 | "shasum": "" 2443 | }, 2444 | "require": { 2445 | "php": "^5.3.3 || ^7.0" 2446 | }, 2447 | "require-dev": { 2448 | "phpunit/phpunit": "^4.6", 2449 | "sebastian/version": "^1.0.1" 2450 | }, 2451 | "type": "library", 2452 | "extra": { 2453 | "branch-alias": { 2454 | "dev-master": "1.3-dev" 2455 | } 2456 | }, 2457 | "autoload": { 2458 | "psr-4": { 2459 | "Webmozart\\Assert\\": "src/" 2460 | } 2461 | }, 2462 | "notification-url": "https://packagist.org/downloads/", 2463 | "license": [ 2464 | "MIT" 2465 | ], 2466 | "authors": [ 2467 | { 2468 | "name": "Bernhard Schussek", 2469 | "email": "bschussek@gmail.com" 2470 | } 2471 | ], 2472 | "description": "Assertions to validate method input/output with nice error messages.", 2473 | "keywords": [ 2474 | "assert", 2475 | "check", 2476 | "validate" 2477 | ], 2478 | "time": "2016-11-23T20:04:58+00:00" 2479 | } 2480 | ], 2481 | "packages-dev": [], 2482 | "aliases": [], 2483 | "minimum-stability": "stable", 2484 | "stability-flags": { 2485 | "phpmd/phpmd": 0, 2486 | "phploc/phploc": 0, 2487 | "sebastian/phpcpd": 0, 2488 | "sebastian/phpdcd": 0 2489 | }, 2490 | "prefer-stable": false, 2491 | "prefer-lowest": false, 2492 | "platform": { 2493 | "php": ">=5.4.5" 2494 | }, 2495 | "platform-dev": [] 2496 | } 2497 | -------------------------------------------------------------------------------- /config/.php_cs: -------------------------------------------------------------------------------- 1 | setRules( 5 | [ 6 | '@PSR2' => true, 7 | 'array_syntax' => ['syntax' => 'short'], 8 | ] 9 | ) 10 | ->setUsingCache(false); 11 | -------------------------------------------------------------------------------- /config/drupal/config.yml: -------------------------------------------------------------------------------- 1 | application: 2 | method: 3 | git: 4 | enabled: true 5 | exception: false 6 | composer: 7 | enabled: true 8 | exception: false 9 | analyzer: 10 | parallel-lint: 11 | enabled: true 12 | exception: true 13 | php-cs-fixer: 14 | enabled: false 15 | exception: false 16 | phpcbf: 17 | enabled: true 18 | exception: false 19 | file: 20 | standard: ../vendor/drupal/coder/coder_sniffer/Drupal/ruleset.xml 21 | phpcs: 22 | enabled: true 23 | exception: false 24 | file: 25 | standard: ../vendor/drupal/coder/coder_sniffer/Drupal/ruleset.xml 26 | phpmd: 27 | enabled: false 28 | exception: false 29 | phploc: 30 | enabled: false 31 | exception: false 32 | phpcpd: 33 | enabled: false 34 | exception: false 35 | phpdcd: 36 | enabled: false 37 | exception: false 38 | phpunit: 39 | enabled: true 40 | exception: true 41 | -------------------------------------------------------------------------------- /config/messages.yml: -------------------------------------------------------------------------------- 1 | application: 2 | messages: 3 | files: 4 | info: Files to analyze 5 | git: 6 | info: Extracting files to be committed 7 | parallel-lint: 8 | info: Running Paralell Lint 9 | error: PHP Parallel Lint found errors! 10 | composer: 11 | info: Check composer.json & composer.lock files 12 | error: composer.lock should be commited if composer.json is modified! 13 | php-cs-fixer: 14 | info: Running PHP-CS-Fixer 15 | error: PHP-CS-Fixer found errors! 16 | phpcbf: 17 | info: Running PHPCBF 18 | error: PHPCBF found errors! 19 | phpcs: 20 | info: Running PHPCS 21 | error: PHPCS found errors! 22 | phpmd: 23 | info: Running PHPMD 24 | error: PHPMD found errors! 25 | phploc: 26 | info: Running PHPLOC 27 | error: PHPLOC found errors! 28 | phpcpd: 29 | info: PHP PHPCPD Copy/Paste Detector 30 | error: PHPCPD found errors! 31 | phpdcd: 32 | info: Running PHPDCD Dead Code Detector 33 | error: PHPDCD found errors! 34 | phpunit: 35 | info: Running PHPUnit 36 | error: PHPUnit test failed! 37 | completed: Analysis Completed! 38 | -------------------------------------------------------------------------------- /config/phpunit.xml.dist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 12 | 13 | 14 | 15 | Test 16 | 17 | 18 | 19 | 20 | 21 | ./ 22 | 23 | ./Test 24 | ./vendor 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /phpqa.yml: -------------------------------------------------------------------------------- 1 | application: 2 | method: 3 | git: 4 | enabled: true 5 | exception: false 6 | composer: 7 | enabled: true 8 | exception: false 9 | analyzer: 10 | parallel-lint: 11 | enabled: true 12 | exception: true 13 | options: 14 | e: 'php' 15 | exclude: /vendor 16 | arguments: 17 | php-cs-fixer: 18 | enabled: true 19 | exception: false 20 | options: 21 | level: psr2 22 | arguments: 23 | prefixes: 24 | - fix 25 | postfixes: 26 | phpcbf: 27 | enabled: true 28 | exception: false 29 | options: 30 | standard: PSR2 31 | severity: 0 32 | ignore: /vendor 33 | arguments: 34 | - '-n' 35 | phpcs: 36 | enabled: false 37 | exception: false 38 | options: 39 | standard: PSR2 40 | severity: 0 41 | ignore: /vendor 42 | arguments: 43 | - '-n' 44 | phpmd: 45 | enabled: false 46 | exception: false 47 | options: 48 | arguments: 49 | prefixes: 50 | postfixes: 51 | - 'text' 52 | - 'cleancode,codesize,unusedcode,naming,controversial,design' 53 | phploc: 54 | enabled: false 55 | exception: false 56 | phpcpd: 57 | enabled: false 58 | exception: false 59 | phpdcd: 60 | enabled: false 61 | exception: false 62 | phpunit: 63 | enabled: true 64 | exception: true 65 | file: 66 | configuration: phpunit.xml.dist 67 | single-execution: true 68 | options: 69 | arguments: 70 | -------------------------------------------------------------------------------- /phpunit.xml.dist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 13 | 14 | 15 | 16 | tests/unit 17 | 18 | 19 | tests/integration 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /src/Application.php: -------------------------------------------------------------------------------- 1 | config = new Config(); 29 | } 30 | 31 | /** 32 | * @return \JMOlivas\Phpqa\Utils\Config 33 | */ 34 | public function getConfig() 35 | { 36 | return $this->config; 37 | } 38 | 39 | /** 40 | * @return string 41 | */ 42 | public function getApplicationDirectory() 43 | { 44 | return __DIR__ . '/../'; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/Command/AnalyzeCommand.php: -------------------------------------------------------------------------------- 1 | 'jakub-onderka/php-parallel-lint/parallel-lint', 42 | 'pdepend' => 'pdepend/pdepend/src/bin/pdepend', 43 | 'php-cs-fixer' => 'fabpot/php-cs-fixer/php-cs-fixer', 44 | 'phpcbf' =>'squizlabs/php_codesniffer/scripts/phpcbf', 45 | 'phpcpd' => 'sebastian/phpcpd/phpcpd', 46 | 'phpcs' => 'squizlabs/php_codesniffer/scripts/phpcs', 47 | 'phpdcd' => 'sebastian/phpdcd/phpdcd', 48 | 'phploc' => 'phploc/phploc/phploc', 49 | 'phpmd' => 'phpmd/phpmd/src/bin/phpmd', 50 | 'phpunit' => 'phpunit/phpunit/phpunit' 51 | ]; 52 | 53 | /** 54 | * {@inheritdoc} 55 | */ 56 | protected function configure() 57 | { 58 | $this 59 | ->setName('analyze') 60 | ->setDescription('Analyze code') 61 | ->addOption( 62 | 'project', 63 | null, 64 | InputOption::VALUE_OPTIONAL, 65 | sprintf( 66 | 'Project name must be (%s) or could be empty if a phpqa.yml or phpqa.yml.dist exists at current directory.', 67 | implode(',', $this->projects) 68 | ) 69 | ) 70 | ->addOption( 71 | 'files', 72 | null, 73 | InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, 74 | 'File(s) to analyze' 75 | )->addOption( 76 | 'git', 77 | null, 78 | InputOption::VALUE_NONE, 79 | 'All files added to git index will be analyzed.' 80 | ); 81 | } 82 | 83 | /** 84 | * {@inheritdoc} 85 | */ 86 | protected function execute(InputInterface $input, OutputInterface $output) 87 | { 88 | $io = new SymfonyStyle($input, $output); 89 | $project = $input->getOption('project'); 90 | 91 | /** 92 | * @var \JMOlivas\Phpqa\Console\Application $application 93 | */ 94 | $application = $this->getApplication(); 95 | 96 | /** 97 | * @var \JMOlivas\Phpqa\Utils\Config $config 98 | */ 99 | $config = $application->getConfig(); 100 | 101 | if (!$config->isCustom() && !$project) { 102 | throw new Exception( 103 | sprintf( 104 | 'No local phpqa.yml or phpqa.yml.dist at current working directory ' . 105 | 'you must provide a valid project value (%s)', 106 | implode(',', $this->projects) 107 | ) 108 | ); 109 | } 110 | 111 | if (!$config->isCustom() && !in_array($project, $this->projects)) { 112 | throw new Exception( 113 | sprintf( 114 | 'You must provide a valid project value (%s)', 115 | implode(',', $this->projects) 116 | ) 117 | ); 118 | } 119 | 120 | $config->loadProjectConfiguration($project); 121 | 122 | $this->directory = $application->getApplicationDirectory(); 123 | 124 | $io->section($application->getName()); 125 | 126 | $filesOption = new FilesOption($input->getOption('files')); 127 | $git = $input->getOption('git'); 128 | 129 | if (!$filesOption->isAbsent() && $git) { 130 | throw new Exception('Options `files` and `git` cannot be used in combination.'); 131 | } 132 | 133 | if ($filesOption->isAbsent() && !$git) { 134 | throw new Exception('You must set `files` or `git` options.'); 135 | } 136 | 137 | if (!$filesOption->isAbsent() && $filesOption->isEmpty()) { 138 | throw new Exception('Options `files` needs at least one file.'); 139 | } 140 | 141 | if ($git) { 142 | $files = $this->extractCommitedFiles($io, $config); 143 | } else { 144 | $files = $filesOption->normalize(); 145 | } 146 | 147 | $io->info($config->get('application.messages.files.info')); 148 | $io->listing($files); 149 | $this->checkComposer($io, $files, $config); 150 | $analyzers = array_keys($config->get('application.analyzer')); 151 | 152 | foreach ($analyzers as $analyzer) { 153 | $this->analyzer($io, $analyzer, $files, $config, $project); 154 | } 155 | 156 | $io->writeln( 157 | sprintf( 158 | '%s', 159 | $config->get('application.messages.completed.info') 160 | ) 161 | ); 162 | } 163 | 164 | /** 165 | * @param $io 166 | * @param $config 167 | * @return array 168 | */ 169 | private function extractCommitedFiles(SymfonyStyle $io, $config) 170 | { 171 | $io->info($config->get('application.messages.git.info')); 172 | 173 | $files = []; 174 | $result = 0; 175 | 176 | exec('git rev-parse --verify HEAD 2> /dev/null', $files, $result); 177 | 178 | $against = '4b825dc642cb6eb9a060e54bf8d69288fbee4904'; 179 | if ($result == 0) { 180 | $against = 'HEAD'; 181 | } 182 | 183 | exec("git diff-index --cached --name-status $against | egrep '^(A|M)' | awk '{print $2;}'", $files); 184 | 185 | unset($files[0]); 186 | 187 | return $files; 188 | } 189 | 190 | /** 191 | * @param $io 192 | * @param $files 193 | * @param $config 194 | * @throws \Exception 195 | */ 196 | private function checkComposer(SymfonyStyle $io, $files, $config) 197 | { 198 | if (!$config->get('application.method.composer.enabled')) { 199 | return; 200 | } 201 | 202 | $io->info($config->get('application.messages.composer.info')); 203 | 204 | $composerJsonDetected = false; 205 | $composerLockDetected = false; 206 | 207 | foreach ($files as $file) { 208 | if ($file === 'composer.json') { 209 | $composerJsonDetected = true; 210 | } 211 | 212 | if ($file === 'composer.lock') { 213 | $composerLockDetected = true; 214 | } 215 | } 216 | 217 | if ($config->get('application.method.composer.exception')) { 218 | if ($composerJsonDetected && !$composerLockDetected) { 219 | throw new Exception($config->get('application.messages.composer.error')); 220 | } 221 | 222 | $io->error($config->get('application.messages.composer.error')); 223 | } 224 | } 225 | 226 | /** 227 | * @param $io 228 | * @param $analyzer 229 | * @param $files 230 | * @param $config 231 | * @param $project 232 | * @throws \Exception 233 | */ 234 | private function analyzer(SymfonyStyle $io, $analyzer, $files, $config, $project) 235 | { 236 | if (!$config->get('application.analyzer.'.$analyzer.'.enabled', false)) { 237 | return; 238 | } 239 | 240 | $analyzerBinary = $this->calculateBinary($analyzer); 241 | 242 | $configFile = $config->getProjectAnalyzerConfigFile($project, $analyzer); 243 | 244 | $exception = $config->get('application.analyzer.'.$analyzer.'.exception', false); 245 | $options = $config->get('application.analyzer.'.$analyzer.'.options', []); 246 | $arguments = $config->get('application.analyzer.'.$analyzer.'.arguments', []); 247 | $prefixes = $config->get('application.analyzer.'.$analyzer.'.prefixes', []); 248 | $postfixes = $config->get('application.analyzer.'.$analyzer.'.postfixes', []); 249 | 250 | $success = true; 251 | 252 | $io->info($config->get('application.messages.'.$analyzer.'.info')); 253 | 254 | $processArguments = [ 255 | 'php', 256 | $this->directory.$analyzerBinary 257 | ]; 258 | 259 | if ($configFile) { 260 | $singleExecution = $config->get('application.analyzer.'.$analyzer.'.file.single-execution'); 261 | 262 | if ($singleExecution) { 263 | $process = $this->executeProcess( 264 | $io, 265 | $processArguments, 266 | $configFile, 267 | $prefixes, 268 | $postfixes, 269 | $arguments, 270 | $options 271 | ); 272 | $success = $process->isSuccessful(); 273 | $files = []; 274 | } 275 | 276 | $processArguments[] = $configFile; 277 | } 278 | 279 | foreach ($files as $file) { 280 | if (!preg_match($this->needle, $file) && !is_dir(realpath($file))) { 281 | continue; 282 | } 283 | 284 | $process = $this->executeProcess( 285 | $io, 286 | $processArguments, 287 | $file, 288 | $prefixes, 289 | $postfixes, 290 | $arguments, 291 | $options 292 | ); 293 | 294 | if ($success) { 295 | $success = $process->isSuccessful(); 296 | } 297 | } 298 | 299 | if ($exception && !$success) { 300 | throw new Exception($config->get('application.messages.'.$analyzer.'.error')); 301 | } 302 | } 303 | 304 | /** 305 | * @param $io 306 | * @param $processArguments 307 | * @param $file 308 | * @param $prefixes 309 | * @param $postfixes 310 | * @param $arguments 311 | * @param $options 312 | * @return \Symfony\Component\Process\Process 313 | */ 314 | public function executeProcess(SymfonyStyle $io, $processArguments, $file, $prefixes, $postfixes, $arguments, $options) 315 | { 316 | foreach ($prefixes as $prefix) { 317 | $processArguments[] = $prefix; 318 | } 319 | 320 | $processArguments[] = $file; 321 | 322 | foreach ($postfixes as $postfix) { 323 | $processArguments[] = $postfix; 324 | } 325 | 326 | $processBuilder = new ProcessBuilder($processArguments); 327 | 328 | foreach ($arguments as $argument) { 329 | $processBuilder->add($argument); 330 | } 331 | 332 | foreach ($options as $optionName => $optionValue) { 333 | $processBuilder->setOption($optionName, $optionValue); 334 | } 335 | 336 | $process = $processBuilder->getProcess(); 337 | $process->run(); 338 | 339 | if (!$process->isSuccessful()) { 340 | $io->error(trim($process->getErrorOutput())); 341 | } 342 | 343 | if ($process->getOutput()) { 344 | $io->writeln($process->getOutput()); 345 | } 346 | 347 | return $process; 348 | } 349 | 350 | /** 351 | * @param $analyzer 352 | * @throws \Exception 353 | */ 354 | private function calculateBinary($analyzer) 355 | { 356 | $binaries = [ 357 | '/bin/'.$analyzer 358 | ]; 359 | 360 | if (array_key_exists($analyzer, $this->analyzerBinaries)) { 361 | $binaries[] = '/../../'.$this->analyzerBinaries[$analyzer]; 362 | $binaries[] = '/../../../'.$this->analyzerBinaries[$analyzer]; 363 | } 364 | 365 | foreach ($binaries as $binary) { 366 | if (file_exists($this->directory.$binary)) { 367 | return $binary; 368 | } 369 | } 370 | 371 | throw new Exception( 372 | sprintf('%s do not exist!', $analyzer) 373 | ); 374 | } 375 | } 376 | -------------------------------------------------------------------------------- /src/Command/InitCommand.php: -------------------------------------------------------------------------------- 1 | '.php_cs', 15 | 'destination' => '.php_cs', 16 | ], 17 | [ 18 | 'source' => 'drupal/config.yml', 19 | 'destination' => 'drupal/config.yml', 20 | ], 21 | [ 22 | 'source' => '/../phpqa.yml', 23 | 'destination' => 'php/config.yml', 24 | ], 25 | [ 26 | 'source' => '/../phpqa.yml', 27 | 'destination' => 'symfony/config.yml', 28 | ], 29 | [ 30 | 'source' => 'messages.yml', 31 | 'destination' => 'messages.yml', 32 | ], 33 | [ 34 | 'source' => 'phpunit.xml.dist', 35 | 'destination' => 'phpunit.xml.dist', 36 | ], 37 | ]; 38 | 39 | private $projects = [ 40 | 'php', 41 | 'symfony', 42 | 'drupal' 43 | ]; 44 | 45 | protected function configure() 46 | { 47 | $this 48 | ->setName('init') 49 | ->setDescription('Copy configuration files to user home directory') 50 | ->addOption( 51 | 'project', 52 | null, 53 | InputOption::VALUE_REQUIRED, 54 | sprintf( 55 | 'Project name to copy config from, should be (%s).', 56 | implode(',', $this->projects) 57 | ) 58 | ) 59 | ->addOption( 60 | 'global', 61 | null, 62 | InputOption::VALUE_NONE, 63 | 'Copy configuration files to user home directory, instead of current working directory.' 64 | ) 65 | ->addOption( 66 | 'override', 67 | null, 68 | InputOption::VALUE_NONE, 69 | 'Copy files using override flag.' 70 | ); 71 | } 72 | 73 | protected function execute(InputInterface $input, OutputInterface $output) 74 | { 75 | $application = $this->getApplication(); 76 | $config = $application->getConfig(); 77 | 78 | $global = false; 79 | if ($input->hasOption('global')) { 80 | $global = $input->getOption('global'); 81 | } 82 | 83 | $project = $input->getOption('project'); 84 | 85 | if ($global && $project) { 86 | throw new \Exception('Options `project` and `global` can not used in combination.'); 87 | } 88 | 89 | if (!$global && (!$project || !in_array($project, $this->projects))) { 90 | throw new \Exception( 91 | sprintf( 92 | 'You must provide a valid project value (%s)', 93 | implode(',', $this->projects) 94 | ) 95 | ); 96 | } 97 | 98 | $override = false; 99 | if ($input->hasOption('override')) { 100 | $override = $input->getOption('override'); 101 | } 102 | 103 | if ($global) { 104 | $this->copyHomeDirectory($output, $config, $override); 105 | } 106 | 107 | if (!$global) { 108 | $this->copyCurrentDirectory($output, $config, $override, $project); 109 | } 110 | } 111 | 112 | private function copyCurrentDirectory($output, $config, $override, $project) 113 | { 114 | $baseConfigDirectory = $config->getBaseConfigDirectory(); 115 | $currentDirectory = $config->getApplicationDirectory(); 116 | 117 | $source = $baseConfigDirectory.'/../phpqa.yml'; 118 | 119 | $configFile = $baseConfigDirectory.$project.'/config.yml'; 120 | if (file_exists($configFile)) { 121 | $source = $configFile; 122 | } 123 | 124 | $destination = $currentDirectory.'phpqa.yml'; 125 | 126 | if ($this->copyFile($source, $destination, $override)) { 127 | $output->writeln('Copied file(s):'); 128 | $output->writeln( 129 | sprintf( 130 | '1 - %s', 131 | $destination 132 | ) 133 | ); 134 | } 135 | } 136 | 137 | private function copyHomeDirectory($output, $config, $override) 138 | { 139 | $baseConfigDirectory = $config->getBaseConfigDirectory(); 140 | $customConfigDirectory = $config->getUserHomeDirectory().'/.phpqa'; 141 | 142 | if (!is_dir($customConfigDirectory)) { 143 | mkdir($customConfigDirectory); 144 | } 145 | 146 | $index = 1; 147 | $copiedMessage = true; 148 | foreach ($this->files as $file) { 149 | $source = $baseConfigDirectory.$file['source']; 150 | $destination = $customConfigDirectory.'/'.$file['destination']; 151 | if ($this->copyFile($source, $destination, $override)) { 152 | if ($copiedMessage) { 153 | $output->writeln('Copied file(s):'); 154 | } 155 | $copiedMessage = false; 156 | $output->writeln( 157 | sprintf( 158 | '%s - %s', 159 | $index, 160 | $destination 161 | ) 162 | ); 163 | $index++; 164 | } 165 | } 166 | } 167 | 168 | private function copyFile($source, $destination, $override) 169 | { 170 | if (file_exists($destination) && !$override) { 171 | return false; 172 | } 173 | 174 | $filePath = dirname($destination); 175 | if (!is_dir($filePath)) { 176 | mkdir($filePath); 177 | } 178 | 179 | return copy( 180 | $source, 181 | $destination 182 | ); 183 | } 184 | } 185 | -------------------------------------------------------------------------------- /src/Input/FilesOption.php: -------------------------------------------------------------------------------- 1 | files = $files; 18 | } 19 | 20 | /** 21 | * Returns true if this option is provided but has no values 22 | * 23 | * @return bool 24 | */ 25 | public function isEmpty() 26 | { 27 | return count($this->files) === 1 && $this->files[0] === null; 28 | } 29 | 30 | /** 31 | * Returns true if this option is not provided 32 | * 33 | * @return bool 34 | */ 35 | public function isAbsent() 36 | { 37 | return empty($this->files); 38 | } 39 | 40 | /** 41 | * Normalize the provided values as an array 42 | * 43 | * - If it's either empty or absent, it returns an empty array 44 | * - If it's a single value separated by commas, it converts it to array 45 | * - Otherwise returns the value as is. 46 | * 47 | * @return array 48 | */ 49 | public function normalize() 50 | { 51 | if ($this->isAbsent() || $this->isEmpty()) { 52 | return []; 53 | } 54 | if (count($this->files) === 1 && strpos($this->files[0], ',') !== false) { 55 | return explode(',', $this->files[0]); 56 | } 57 | 58 | return $this->files; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/Style/SymfonyStyle.php: -------------------------------------------------------------------------------- 1 | input = $input; 36 | parent::__construct($input, $output); 37 | } 38 | 39 | /** 40 | * @param string $question 41 | * @param array $choices 42 | * @param mixed $default 43 | * @param bool $allowEmpty 44 | * 45 | * @return string 46 | */ 47 | public function choiceNoList($question, array $choices, $default = null, $allowEmpty = false) 48 | { 49 | if ($allowEmpty) { 50 | $default = ' '; 51 | } 52 | 53 | if (is_null($default)) { 54 | $default = current($choices); 55 | } 56 | 57 | if (!in_array($default, $choices)) { 58 | $choices[] = $default; 59 | } 60 | 61 | if (null !== $default) { 62 | $values = array_flip($choices); 63 | $default = $values[$default]; 64 | } 65 | 66 | return trim($this->askChoiceQuestion(new ChoiceQuestion($question, $choices, $default))); 67 | } 68 | 69 | /** 70 | * @param string $question 71 | * @param array $choices 72 | * @param null $default 73 | * @param bool $multiple 74 | * 75 | * @return string 76 | */ 77 | public function choice($question, array $choices, $default = null, $multiple = false) 78 | { 79 | if (null !== $default) { 80 | $values = array_flip($choices); 81 | $default = $values[$default]; 82 | } 83 | 84 | $choiceQuestion = new ChoiceQuestion($question, $choices, $default); 85 | $choiceQuestion->setMultiselect($multiple); 86 | 87 | return $this->askQuestion($choiceQuestion); 88 | } 89 | 90 | /** 91 | * @param ChoiceQuestion $question 92 | * 93 | * @return string 94 | */ 95 | public function askChoiceQuestion(ChoiceQuestion $question) 96 | { 97 | $questionHelper = new QuestionHelper(); 98 | $answer = $questionHelper->ask($this->input, $this, $question); 99 | 100 | return $answer; 101 | } 102 | 103 | /** 104 | * @param $question 105 | * 106 | * @return string 107 | */ 108 | public function askHiddenEmpty($question) 109 | { 110 | $question = new Question($question, ' '); 111 | $question->setHidden(true); 112 | 113 | return trim($this->askQuestion($question)); 114 | } 115 | 116 | /** 117 | * @param string $question 118 | * @param null|callable $validator 119 | * 120 | * @return string 121 | */ 122 | public function askEmpty($question, $validator = null) 123 | { 124 | $question = new Question($question, ' '); 125 | $question->setValidator($validator); 126 | 127 | return trim($this->askQuestion($question)); 128 | } 129 | 130 | /** 131 | * @param $message 132 | * @param bool $newLine 133 | */ 134 | public function info($message, $newLine = true) 135 | { 136 | $message = sprintf(' %s', $message); 137 | if ($newLine) { 138 | $this->writeln($message); 139 | } else { 140 | $this->write($message); 141 | } 142 | } 143 | 144 | /** 145 | * @param array|string $message 146 | * @param bool $newLine 147 | */ 148 | public function comment($message, $newLine = true) 149 | { 150 | $message = sprintf(' %s', $message); 151 | if ($newLine) { 152 | $this->writeln($message); 153 | } else { 154 | $this->write($message); 155 | } 156 | } 157 | 158 | /** 159 | * @param $message 160 | */ 161 | public function commentBlock($message) 162 | { 163 | $this->block( 164 | $message, null, 165 | 'bg=yellow;fg=black', 166 | ' ', 167 | true 168 | ); 169 | } 170 | 171 | /** 172 | * @param array $headers 173 | * @param array $rows 174 | * @param string $style 175 | */ 176 | public function table(array $headers, array $rows, $style = 'symfony-style-guide') 177 | { 178 | $headers = array_map( 179 | function ($value) { 180 | return sprintf('%s', $value); 181 | }, $headers 182 | ); 183 | 184 | if (!is_array(current($rows))) { 185 | $rows = array_map( 186 | function ($row) { 187 | return [$row]; 188 | }, 189 | $rows 190 | ); 191 | } 192 | 193 | $table = new Table($this); 194 | $table->setHeaders($headers); 195 | $table->setRows($rows); 196 | $table->setStyle($style); 197 | 198 | $table->render(); 199 | $this->newLine(); 200 | } 201 | 202 | /** 203 | * @param $message 204 | * @param bool $newLine 205 | */ 206 | public function simple($message, $newLine = true) 207 | { 208 | $message = sprintf(' %s', $message); 209 | if ($newLine) { 210 | $this->writeln($message); 211 | } else { 212 | $this->write($message); 213 | } 214 | } 215 | 216 | /** 217 | * @param array|string $message 218 | */ 219 | public function text($message) 220 | { 221 | $message = sprintf('// %s', $message); 222 | parent::text($message); 223 | } 224 | } 225 | -------------------------------------------------------------------------------- /src/Utils/Config.php: -------------------------------------------------------------------------------- 1 | custom = false; 27 | $this->config = []; 28 | $this->loadFile(__DIR__.'/../../'.'phpqa.yml'); 29 | if ($this->getApplicationConfigFile()) { 30 | $this->loadFile($this->getApplicationConfigFile()); 31 | $this->custom = true; 32 | } 33 | $this->loadFile($this->getBaseConfigDirectory().'messages.yml'); 34 | $this->loadFile($this->getUserHomeDirectory().'messages.yml'); 35 | } 36 | 37 | private function loadFile($file = null) 38 | { 39 | $config = null; 40 | 41 | if (file_exists($file)) { 42 | $parser = new Parser(); 43 | $config = $parser->parse(file_get_contents($file)); 44 | } 45 | 46 | if ($config) { 47 | $this->config = array_replace_recursive($this->config, $config); 48 | } 49 | } 50 | 51 | public function get($key, $default = '') 52 | { 53 | if (!$key) { 54 | return $default; 55 | } 56 | 57 | $config = $this->config; 58 | $items = explode('.', $key); 59 | 60 | if (!$items) { 61 | return $default; 62 | } 63 | foreach ($items as $item) { 64 | if (empty($config[$item])) { 65 | return $default; 66 | } 67 | $config = $config[$item]; 68 | } 69 | 70 | return $config; 71 | } 72 | 73 | public function getApplicationDirectory() 74 | { 75 | return getcwd() . '/'; 76 | } 77 | 78 | public function getBaseConfigDirectory() 79 | { 80 | return __DIR__.'/../../config/'; 81 | } 82 | 83 | public function getUserConfigDirectory() 84 | { 85 | return $this->getUserHomeDirectory().'/.phpqa/'; 86 | } 87 | 88 | public function getUserHomeDirectory() 89 | { 90 | return rtrim(getenv('HOME') ?: getenv('USERPROFILE'), '/\\'); 91 | } 92 | 93 | public function getApplicationConfigFile() 94 | { 95 | $configFile = $this->getApplicationDirectory() .'phpqa.yml'; 96 | if (file_exists($configFile)) { 97 | return $configFile; 98 | } 99 | 100 | $configFile = $this->getApplicationDirectory() .'phpqa.yml.dist'; 101 | if (file_exists($configFile)) { 102 | return $configFile; 103 | } 104 | 105 | return null; 106 | } 107 | 108 | public function loadProjectConfiguration($project) 109 | { 110 | if ($this->isCustom()) { 111 | return; 112 | } 113 | 114 | $configFile = $this->getUserConfigDirectory().$project.'/config.yml'; 115 | if (file_exists($configFile)) { 116 | $this->loadFile($configFile); 117 | 118 | return; 119 | } 120 | 121 | $configFile = $this->getBaseConfigDirectory().$project.'/config.yml'; 122 | if (file_exists($configFile)) { 123 | $this->loadFile($configFile); 124 | 125 | return; 126 | } 127 | } 128 | 129 | public function getProjectAnalyzerConfigFile($project, $analyzer) 130 | { 131 | $analyserConfig = $this->get('application.analyzer.'.$analyzer.'.file'); 132 | 133 | if (!is_array($analyserConfig)) { 134 | return; 135 | } 136 | 137 | $analyserConfigOption = key($analyserConfig); 138 | $analyserConfigFile = current($analyserConfig); 139 | 140 | $configFile = $this->getApplicationDirectory().$analyserConfigFile; 141 | if (file_exists($configFile)) { 142 | return '--'.$analyserConfigOption.'='.$configFile; 143 | } 144 | 145 | $configFile = __DIR__.'/../'.$analyserConfigFile; 146 | if (file_exists($configFile)) { 147 | return '--'.$analyserConfigOption.'='.$configFile; 148 | } 149 | 150 | $configFile = $this->getUserConfigDirectory().$project.'/'.$analyserConfigFile; 151 | if (file_exists($configFile)) { 152 | return '--'.$analyserConfigOption.'='.$configFile; 153 | } 154 | 155 | $configFile = $this->getUserConfigDirectory().$analyserConfigFile; 156 | if (file_exists($configFile)) { 157 | return '--'.$analyserConfigOption.'='.$configFile; 158 | } 159 | 160 | $configFile = $this->getBaseConfigDirectory().$analyserConfigFile; 161 | if (file_exists($configFile)) { 162 | return '--'.$analyserConfigOption.'='.$configFile; 163 | } 164 | 165 | return '--'.$analyserConfigOption.'='.$analyserConfigFile; 166 | } 167 | 168 | /** 169 | * @return boolean 170 | */ 171 | public function isCustom() 172 | { 173 | return $this->custom; 174 | } 175 | } 176 | -------------------------------------------------------------------------------- /tests/integration/Command/AnalyzeCommandTest.php: -------------------------------------------------------------------------------- 1 | setApplication($application); 21 | 22 | $tester = new CommandTester($command); 23 | 24 | $tester->execute([]); 25 | } 26 | 27 | /** 28 | * @test 29 | * @expectedException \Exception 30 | * @expectedExceptionMessage Options `files` and `git` cannot be used in combination. 31 | */ 32 | public function it_should_throw_exception_if_both_files_and_git_options_are_provided() 33 | { 34 | $application = new Application(); 35 | $command = new AnalyzeCommand(); 36 | $command->setApplication($application); 37 | 38 | $tester = new CommandTester($command); 39 | 40 | $tester->execute( 41 | [ 42 | '--files' => [null], 43 | '--git' => true 44 | ] 45 | ); 46 | } 47 | 48 | /** 49 | * @test 50 | * @expectedException \Exception 51 | * @expectedExceptionMessage Options `files` needs at least one file. 52 | */ 53 | public function it_should_throw_exception_if_files_is_provided_but_it_is_empty() 54 | { 55 | $application = new Application(); 56 | $command = new AnalyzeCommand(); 57 | $command->setApplication($application); 58 | 59 | $tester = new CommandTester($command); 60 | 61 | $tester->execute( 62 | [ 63 | '--files' => [null], 64 | ] 65 | ); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /tests/unit/Input/FilesOptionTest.php: -------------------------------------------------------------------------------- 1 | assertTrue($files->isAbsent()); 16 | } 17 | 18 | /** @test */ 19 | function it_should_recognize_if_option_is_provided_but_is_empty() 20 | { 21 | $emptyInput = [null]; 22 | $files = new FilesOption($emptyInput); 23 | 24 | $this->assertTrue($files->isEmpty()); 25 | } 26 | 27 | /** @test */ 28 | function it_should_recognize_if_option_is_provided_correctly() 29 | { 30 | $validInput = ['src/']; 31 | $files = new FilesOption($validInput); 32 | 33 | $this->assertFalse($files->isAbsent()); 34 | $this->assertFalse($files->isEmpty()); 35 | } 36 | 37 | /** @test */ 38 | function it_should_normalize_input_separated_by_commas() 39 | { 40 | // bin/phpqa analyze --files=src/,test/ 41 | $singleInputWithMultipleValues = ['src/,test/']; 42 | $files = new FilesOption($singleInputWithMultipleValues); 43 | 44 | $values = $files->normalize(); 45 | 46 | $this->assertCount(2, $values); 47 | $this->assertEquals('src/', $values[0]); 48 | $this->assertEquals('test/', $values[1]); 49 | } 50 | 51 | /** @test */ 52 | function it_should_return_multiple_files_input_as_is() 53 | { 54 | // bin/phpqa analyze --files=src/ --files=test/ 55 | $singleInputWithMultipleValues = ['src/','test/']; 56 | $files = new FilesOption($singleInputWithMultipleValues); 57 | 58 | $values = $files->normalize(); 59 | 60 | $this->assertCount(2, $values); 61 | $this->assertEquals('src/', $values[0]); 62 | $this->assertEquals('test/', $values[1]); 63 | } 64 | 65 | /** @test */ 66 | function it_should_return_empty_array_if_input_is_absent() 67 | { 68 | $absentInput = []; 69 | $files = new FilesOption($absentInput); 70 | 71 | $this->assertCount(0, $files->normalize()); 72 | } 73 | 74 | /** @test */ 75 | function it_should_return_empty_array_if_input_is_empty() 76 | { 77 | $emptyInput = [null]; 78 | $files = new FilesOption($emptyInput); 79 | 80 | $this->assertCount(0, $files->normalize()); 81 | } 82 | } 83 | --------------------------------------------------------------------------------