├── src ├── ErrorException.php ├── Tissue.php └── GithubIssue.php ├── config └── config.yaml.dist ├── .gitignore ├── tests ├── UncaughtExceptionTest.php └── TissueTest.php ├── composer.json ├── LICENSE ├── README.md └── composer.lock /src/ErrorException.php: -------------------------------------------------------------------------------- 1 | 25 | -------------------------------------------------------------------------------- /tests/TissueTest.php: -------------------------------------------------------------------------------- 1 | getMessage(), $e->getCode(), $e->getSeverity(), $e->getFile()); 28 | } 29 | } 30 | 31 | /** 32 | * Tests what an issue created with partial information looks like (2/3) 33 | * @throws \ErrorException 34 | */ 35 | public function testPartialIssueTwo() 36 | { 37 | try { 38 | 39 | throw new \ErrorException('2/3 A partial error.'); 40 | 41 | } catch (\ErrorException $e) { 42 | 43 | Tissue::setConfigPath(TEST_CONFIG_PATH); 44 | Tissue::create($e->getMessage(), null, null, null, $e->getLine(), $e->getTraceAsString()); 45 | } 46 | } 47 | 48 | /** 49 | * Tests what an issue created with partial information looks like (3/3) 50 | * @throws \ErrorException 51 | */ 52 | public function testPartialIssueThree() 53 | { 54 | try { 55 | 56 | throw new \ErrorException('3/3 A partial error.'); 57 | 58 | } catch (\ErrorException $e) { 59 | 60 | Tissue::setConfigPath(TEST_CONFIG_PATH); 61 | Tissue::create(null, null, null, $e->getFile(), null, $e->getTraceAsString()); 62 | } 63 | } 64 | 65 | /** 66 | * Tests a valid full request 67 | * @throws \ErrorException 68 | */ 69 | public function testValidRequest() 70 | { 71 | try { 72 | 73 | throw new \ErrorException('This is your issue title and message.'); 74 | 75 | } catch (\ErrorException $e) { 76 | 77 | Tissue::setConfigPath(TEST_CONFIG_PATH); 78 | $result = Tissue::createFromException($e); 79 | 80 | static::assertNotNull($result, 'null result received'); 81 | static::assertTrue(array_key_exists('duplicate', $result), 'duplicate parameter missing'); 82 | if (!$result['duplicate']) { 83 | static::assertTrue(array_key_exists('number', $result), 'id parameter missing'); 84 | static::assertTrue(array_key_exists('url', $result), 'url parameter missing'); 85 | static::assertTrue(is_int($result['number']), 'id must be an int'); 86 | static::assertTrue(is_string($result['url']), 'url must be a string'); 87 | static::assertNotFalse(filter_var($result['url'], FILTER_VALIDATE_URL), 'url must be a url (duh)'); 88 | static::assertEquals(false, $result['duplicate']); 89 | } else { 90 | static::assertTrue(is_bool($result['duplicate'])); 91 | static::assertEquals(true, $result['duplicate']); 92 | } 93 | } 94 | } 95 | 96 | /** 97 | * Tries to create an issue from an Exception 98 | * @throws \ErrorException 99 | */ 100 | public function testFromException() 101 | { 102 | try { 103 | 104 | throw new \ErrorException('This issue was created from an exception.'); 105 | 106 | } catch (\ErrorException $e) { 107 | 108 | Tissue::setConfigPath(TEST_CONFIG_PATH); 109 | Tissue::createFromException($e); 110 | } 111 | } 112 | } 113 | 114 | -------------------------------------------------------------------------------- /src/Tissue.php: -------------------------------------------------------------------------------- 1 | getSeverity(); 60 | } 61 | return static::create( 62 | $e->getMessage(), 63 | $e->getCode(), 64 | $severity, 65 | $e->getFile(), 66 | $e->getLine(), 67 | $e->getTraceAsString() 68 | ); 69 | } 70 | 71 | /** 72 | * Create an issue from the sent request 73 | * @param null $message 74 | * @param null $code 75 | * @param null $severity 76 | * @param null $path 77 | * @param null $lineno 78 | * @param null $trace 79 | * @return array 80 | * @throws ErrorException 81 | * @throws InvalidArgumentException 82 | * @throws MissingArgumentException 83 | * @throws ParseException 84 | */ 85 | public static function create($message = null, $code = null, $severity = null, $path = null, $lineno = null, $trace = null) 86 | { 87 | static::loadConfig(); 88 | 89 | if (null === array_unique([$message, $code, $severity, $path, $lineno, $trace])) { 90 | throw new ErrorException('At least one parameter must be set.'); 91 | } 92 | 93 | $issue = new GithubIssue($message, $code, $severity, $path, $lineno, $trace); 94 | 95 | return $issue->commit( 96 | static::$config['you']['username'], 97 | static::$config['you']['password'], 98 | static::$config['repo']['author'], 99 | static::$config['repo']['name'] 100 | ); 101 | } 102 | 103 | /** 104 | * Loads configuration 105 | * @throws ErrorException 106 | * @throws ParseException 107 | */ 108 | static private function loadConfig() 109 | { 110 | // Only load once 111 | if (null !== static::$config) { 112 | return; 113 | } 114 | if (!file_exists(static::$configPath) || !is_readable(static::$configPath)) { 115 | throw new ErrorException('Config file not found or unreadable.'); 116 | } 117 | $config = Yaml::parse(file_get_contents(static::$configPath))['tissue']; 118 | 119 | if (['you', 'repo'] !== array_keys($config) || 120 | ['username', 'password'] !== array_keys($config['you']) || 121 | ['author', 'name'] !== array_keys($config['repo']) 122 | ) { 123 | throw new ErrorException('Invalid config file.'); 124 | } 125 | static::$config = $config; 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # tissue 2 | 3 | [![Latest Version on Packagist][ico-version]][link-packagist] 4 | [![License][ico-license]](LICENSE) 5 | [![SensioLabsInsight](https://insight.sensiolabs.com/projects/fdc3c186-f787-4427-9c81-a3f82f3db720/mini.png)](https://insight.sensiolabs.com/projects/fdc3c186-f787-4427-9c81-a3f82f3db720) 6 | 7 | Create Github issues from your ``catch {}`` blocks. I was heavily inspired by [ohCrash](https://ohcrash.com/). 8 | 9 | When you call ``Tissue::create``, a Github issue is created in the repo of your choice and a "bug" label is automatically applied. Duplicates are detected, to a certain extent. 10 | 11 | The name comes from "Throw ISSUE" — genius, I know. 12 | 13 | ## Install 14 | 15 | ``` bash 16 | $ composer require bouiboui/tissue 17 | ``` 18 | 19 | Create a local ``config/config.yaml`` file from the template in [``config/config.yaml.dist``](https://github.com/bouiboui/tissue/blob/master/config/config.yaml.dist) 20 | 21 | ## Usage 22 | 23 | **The easy way: `bindUncaughtExceptionHandler`** 24 | ``` php 25 | // Not shown: include composer's autoload.php 26 | use bouiboui\Tissue\Tissue; 27 | 28 | // All uncaught exceptions will trigger the creation of a Github issue 29 | Tissue::bindUncaughtExceptionHandler(); 30 | ``` 31 | **The catch-block-specific way: `createFromException`** 32 | ``` php 33 | // Not shown: include composer's autoload.php 34 | use bouiboui\Tissue\Tissue; 35 | 36 | try { 37 | 38 | throw new ErrorException('This is your issue title and message.'); 39 | 40 | } catch (\ErrorException $e) { 41 | 42 | // Only exceptions caught by this block will create Github issues 43 | $result = Tissue::createFromException($e); 44 | 45 | } 46 | ``` 47 | 48 | **The "customized output" way: `create`** 49 | ``` php 50 | // Not shown: include composer's autoload.php 51 | use bouiboui\Tissue\Tissue; 52 | 53 | try { 54 | 55 | throw new ErrorException('This is your issue title and message.'); 56 | 57 | } catch (\ErrorException $e) { 58 | 59 | // Set any parameter to null if you don't want to display it in the issue 60 | $result = Tissue::create( 61 | $e->getMessage(), 62 | $e->getCode(), 63 | $e->getSeverity(), 64 | $e->getFile(), 65 | $e->getLine(), 66 | $e->getTraceAsString() 67 | ); 68 | 69 | var_dump($result); 70 | 71 | } 72 | ``` 73 | Creates the following issue: 74 | 75 | ![Something like this](http://i.imgur.com/N5r8Ljh.png) 76 | ![Something like this](http://i.imgur.com/a96l7hR.png) 77 | 78 | And outputs the following: 79 | 80 | ``` php 81 | array(3) { 82 | ["duplicate"]=> 83 | bool(false) 84 | ["number"]=> 85 | int(35) 86 | ["url"]=> 87 | string(50) "https://api.github.com/repos/author/name/issues/35" 88 | } 89 | ``` 90 | 91 | For security purposes, if your Github repository is public you should at the *very* least disable the `trace` parameter, unless you want strangers on the Internet to know the full path to the files on your server. [You may also want to read this](https://www.owasp.org/index.php/Improper_Error_Handling#Description). 92 | 93 | ## Credits 94 | 95 | - bouiboui — [Github](https://github.com/bouiboui) [Twitter](https://twitter.com/j_____________n) [Website](http://cod3.net) 96 | - [All contributors](https://github.com/bouiboui/tissue/graphs/contributors) 97 | 98 | ## License 99 | 100 | Unlicense. Public domain, basically. Please treat it kindly. See [License File](LICENSE) for more information. 101 | 102 | This project uses the following open source projects 103 | - [knplabs/github-api](https://github.com/KnpLabs/php-github-api) by [KnpLabs](https://github.com/KnpLabs) — [License](https://github.com/KnpLabs/php-github-api/blob/master/LICENSE). 104 | - [symfony/yaml](https://github.com/symfony/yaml) by [Fabien Potencier](https://github.com/fabpot) — [License](https://github.com/symfony/yaml/blob/master/LICENSE). 105 | - [phpunit/phpunit](https://github.com/sebastianbergmann/phpunit) by [Sebastian Bergmann](https://github.com/sebastianbergmann) — [License](https://github.com/sebastianbergmann/phpunit/blob/master/LICENSE). 106 | 107 | [ico-version]: https://img.shields.io/packagist/v/bouiboui/tissue.svg?style=flat-square 108 | [ico-license]: https://img.shields.io/badge/license-Unlicense-brightgreen.svg?style=flat-square 109 | 110 | [link-packagist]: https://packagist.org/packages/bouiboui/tissue 111 | -------------------------------------------------------------------------------- /src/GithubIssue.php: -------------------------------------------------------------------------------- 1 | title = GithubIssue::formatTitle($path, $lineno, $message); 45 | 46 | // Only display a two-parent-directories-deep path, for readability 47 | $shortPath = GithubIssue::formatPath($path); 48 | 49 | $bodyContents = []; 50 | 51 | // Head table (Code and Severity) 52 | if (null !== $code || null !== $severity) { 53 | $bodyContents[] = GithubIssue::formatTable($code, $severity); 54 | } 55 | 56 | // $path:$line 57 | if (null !== $path) { 58 | $pathText = '**Path**' . PHP_EOL . $shortPath; 59 | if (null !== $lineno) { 60 | $pathText .= ':**' . $lineno . '**'; 61 | } 62 | $bodyContents[] = $pathText; 63 | } 64 | if (null !== $message) { 65 | $bodyContents[] = '**Message**' . PHP_EOL . $message; 66 | } 67 | if (null !== $trace) { 68 | $bodyContents[] = '**Stack trace**' . PHP_EOL . '```' . PHP_EOL . $trace . PHP_EOL . '```'; 69 | } 70 | 71 | // Format the body 72 | $this->body = GithubIssue::formatBody($bodyContents); 73 | } 74 | 75 | /** 76 | * Formats the issue's title 77 | * @param $path 78 | * @param $lineno 79 | * @param $message 80 | * @return string 81 | */ 82 | private static function formatTitle($path, $lineno, $message) 83 | { 84 | $title = ''; 85 | // [basename($path):$line] $shortMessage 86 | if (null !== $path) { 87 | $title .= '[' . basename($path); 88 | if (null !== $lineno) { 89 | $title .= ':' . $lineno; 90 | } 91 | $title .= '] '; 92 | } 93 | $shortMessage = $message; 94 | if (mb_strlen($message) >= GithubIssue::READABLE_TITLE_LENGTH) { 95 | $shortMessage = mb_substr($message, 0, GithubIssue::READABLE_TITLE_LENGTH - 1) . '…'; 96 | } 97 | $title .= $shortMessage; 98 | return $title; 99 | } 100 | 101 | /** 102 | * Formats the issue's path 103 | * @param $path 104 | * @return string 105 | */ 106 | private static function formatPath($path) 107 | { 108 | $dirs = explode(DIRECTORY_SEPARATOR, $path); 109 | return '..' . DIRECTORY_SEPARATOR . implode(DIRECTORY_SEPARATOR, array_slice($dirs, count($dirs) - 3)); 110 | } 111 | 112 | /** 113 | * Formats the issue's table 114 | * @param $code 115 | * @param $severity 116 | * @return string 117 | */ 118 | private static function formatTable($code, $severity) 119 | { 120 | $displayCode = null !== $code; 121 | $displaySeverity = null !== $severity; 122 | $tableTitle = ''; 123 | $tableContents = ''; 124 | $tableDivider = '---'; 125 | if ($displayCode && $displaySeverity) { 126 | $tableTitle = 'Code | Severity'; 127 | $tableDivider = '--- | ---'; 128 | $tableContents = $code . ' | ' . $severity; 129 | } else if ($displayCode) { 130 | $tableTitle = 'Code'; 131 | $tableContents = $code; 132 | } else if ($displaySeverity) { 133 | $tableTitle = 'Severity'; 134 | $tableContents = $severity; 135 | } 136 | return '| ' . $tableTitle . ' |' . PHP_EOL . '| ' . $tableDivider . ' |' . PHP_EOL . '| ' . $tableContents . ' |'; 137 | } 138 | 139 | /** 140 | * Formats the issue's body 141 | * @param array $bodyContents 142 | * @return string 143 | */ 144 | private static function formatBody(array $bodyContents) 145 | { 146 | return implode(PHP_EOL . PHP_EOL, $bodyContents); 147 | } 148 | 149 | /** 150 | * Actually creates the issue on Github, returns an array with the issue's number and URL. 151 | * @param $yourUsername 152 | * @param $yourPassword 153 | * @param $targetRepoAuthor 154 | * @param $targetRepoName 155 | * @return array 156 | * @throws InvalidArgumentException 157 | * @throws MissingArgumentException 158 | * @throws ErrorException 159 | */ 160 | public function commit($yourUsername, $yourPassword, $targetRepoAuthor, $targetRepoName) 161 | { 162 | $client = new GithubClient(); 163 | $client->authenticate($yourUsername, $yourPassword, GithubClient::AUTH_HTTP_PASSWORD); 164 | 165 | /** @var Search $searchApi */ 166 | $searchApi = $client->api('search'); 167 | /** @var Issue $issueApi */ 168 | $issueApi = $client->api('issue'); 169 | 170 | // Check existing issues to avoid duplicates 171 | $duplicates = $searchApi->issues($this->title . ' in:title state:open label:bug repo:' . $targetRepoAuthor . '/' . $targetRepoName); 172 | 173 | if ((int)$duplicates['total_count'] > 0) { 174 | return ['duplicate' => true]; 175 | } 176 | 177 | // Create the issue and fetch the issue's info 178 | $issueInfo = $issueApi->create( 179 | $targetRepoAuthor, 180 | $targetRepoName, [ 181 | 'title' => $this->title, 182 | 'body' => $this->body 183 | ] 184 | ); 185 | 186 | if (!array_key_exists('number', $issueInfo) || !array_key_exists('url', $issueInfo)) { 187 | throw new ErrorException('Missing Github issue info parameter'); 188 | } 189 | 190 | // Apply the "Bug" label 191 | $issueApi->labels()->add($targetRepoAuthor, $targetRepoName, $issueInfo['number'], 'bug'); 192 | 193 | $this->number = $issueInfo['number']; 194 | $this->url = $issueInfo['url']; 195 | 196 | return ['duplicate' => false, 'number' => $this->number, 'url' => $this->url]; 197 | 198 | } 199 | 200 | } 201 | -------------------------------------------------------------------------------- /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 | "hash": "e938a6ea04425773ef04d1afb70508a2", 8 | "content-hash": "9e1071f6bce85fedc142de29bcc8ada1", 9 | "packages": [ 10 | { 11 | "name": "guzzle/guzzle", 12 | "version": "v3.9.3", 13 | "source": { 14 | "type": "git", 15 | "url": "https://github.com/guzzle/guzzle3.git", 16 | "reference": "0645b70d953bc1c067bbc8d5bc53194706b628d9" 17 | }, 18 | "dist": { 19 | "type": "zip", 20 | "url": "https://api.github.com/repos/guzzle/guzzle3/zipball/0645b70d953bc1c067bbc8d5bc53194706b628d9", 21 | "reference": "0645b70d953bc1c067bbc8d5bc53194706b628d9", 22 | "shasum": "" 23 | }, 24 | "require": { 25 | "ext-curl": "*", 26 | "php": ">=5.3.3", 27 | "symfony/event-dispatcher": "~2.1" 28 | }, 29 | "replace": { 30 | "guzzle/batch": "self.version", 31 | "guzzle/cache": "self.version", 32 | "guzzle/common": "self.version", 33 | "guzzle/http": "self.version", 34 | "guzzle/inflection": "self.version", 35 | "guzzle/iterator": "self.version", 36 | "guzzle/log": "self.version", 37 | "guzzle/parser": "self.version", 38 | "guzzle/plugin": "self.version", 39 | "guzzle/plugin-async": "self.version", 40 | "guzzle/plugin-backoff": "self.version", 41 | "guzzle/plugin-cache": "self.version", 42 | "guzzle/plugin-cookie": "self.version", 43 | "guzzle/plugin-curlauth": "self.version", 44 | "guzzle/plugin-error-response": "self.version", 45 | "guzzle/plugin-history": "self.version", 46 | "guzzle/plugin-log": "self.version", 47 | "guzzle/plugin-md5": "self.version", 48 | "guzzle/plugin-mock": "self.version", 49 | "guzzle/plugin-oauth": "self.version", 50 | "guzzle/service": "self.version", 51 | "guzzle/stream": "self.version" 52 | }, 53 | "require-dev": { 54 | "doctrine/cache": "~1.3", 55 | "monolog/monolog": "~1.0", 56 | "phpunit/phpunit": "3.7.*", 57 | "psr/log": "~1.0", 58 | "symfony/class-loader": "~2.1", 59 | "zendframework/zend-cache": "2.*,<2.3", 60 | "zendframework/zend-log": "2.*,<2.3" 61 | }, 62 | "suggest": { 63 | "guzzlehttp/guzzle": "Guzzle 5 has moved to a new package name. The package you have installed, Guzzle 3, is deprecated." 64 | }, 65 | "type": "library", 66 | "extra": { 67 | "branch-alias": { 68 | "dev-master": "3.9-dev" 69 | } 70 | }, 71 | "autoload": { 72 | "psr-0": { 73 | "Guzzle": "src/", 74 | "Guzzle\\Tests": "tests/" 75 | } 76 | }, 77 | "notification-url": "https://packagist.org/downloads/", 78 | "license": [ 79 | "MIT" 80 | ], 81 | "authors": [ 82 | { 83 | "name": "Michael Dowling", 84 | "email": "mtdowling@gmail.com", 85 | "homepage": "https://github.com/mtdowling" 86 | }, 87 | { 88 | "name": "Guzzle Community", 89 | "homepage": "https://github.com/guzzle/guzzle/contributors" 90 | } 91 | ], 92 | "description": "PHP HTTP client. This library is deprecated in favor of https://packagist.org/packages/guzzlehttp/guzzle", 93 | "homepage": "http://guzzlephp.org/", 94 | "keywords": [ 95 | "client", 96 | "curl", 97 | "framework", 98 | "http", 99 | "http client", 100 | "rest", 101 | "web service" 102 | ], 103 | "time": "2015-03-18 18:23:50" 104 | }, 105 | { 106 | "name": "knplabs/github-api", 107 | "version": "1.5.1", 108 | "source": { 109 | "type": "git", 110 | "url": "https://github.com/KnpLabs/php-github-api.git", 111 | "reference": "832b7be695ed2733741cd5c79166b4a88fb50786" 112 | }, 113 | "dist": { 114 | "type": "zip", 115 | "url": "https://api.github.com/repos/KnpLabs/php-github-api/zipball/832b7be695ed2733741cd5c79166b4a88fb50786", 116 | "reference": "832b7be695ed2733741cd5c79166b4a88fb50786", 117 | "shasum": "" 118 | }, 119 | "require": { 120 | "ext-curl": "*", 121 | "guzzle/guzzle": "~3.7", 122 | "php": ">=5.3.2" 123 | }, 124 | "require-dev": { 125 | "phpunit/phpunit": "~4.0" 126 | }, 127 | "suggest": { 128 | "knplabs/gaufrette": "Needed for optional Gaufrette cache" 129 | }, 130 | "type": "library", 131 | "extra": { 132 | "branch-alias": { 133 | "dev-master": "1.4.x-dev" 134 | } 135 | }, 136 | "autoload": { 137 | "psr-4": { 138 | "Github\\": "lib/Github/" 139 | } 140 | }, 141 | "notification-url": "https://packagist.org/downloads/", 142 | "license": [ 143 | "MIT" 144 | ], 145 | "authors": [ 146 | { 147 | "name": "Thibault Duplessis", 148 | "email": "thibault.duplessis@gmail.com", 149 | "homepage": "http://ornicar.github.com" 150 | }, 151 | { 152 | "name": "KnpLabs Team", 153 | "homepage": "http://knplabs.com" 154 | } 155 | ], 156 | "description": "GitHub API v3 client", 157 | "homepage": "https://github.com/KnpLabs/php-github-api", 158 | "keywords": [ 159 | "api", 160 | "gh", 161 | "gist", 162 | "github" 163 | ], 164 | "time": "2015-10-11 02:38:28" 165 | }, 166 | { 167 | "name": "symfony/event-dispatcher", 168 | "version": "v2.8.2", 169 | "source": { 170 | "type": "git", 171 | "url": "https://github.com/symfony/event-dispatcher.git", 172 | "reference": "ee278f7c851533e58ca307f66305ccb9188aceda" 173 | }, 174 | "dist": { 175 | "type": "zip", 176 | "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/ee278f7c851533e58ca307f66305ccb9188aceda", 177 | "reference": "ee278f7c851533e58ca307f66305ccb9188aceda", 178 | "shasum": "" 179 | }, 180 | "require": { 181 | "php": ">=5.3.9" 182 | }, 183 | "require-dev": { 184 | "psr/log": "~1.0", 185 | "symfony/config": "~2.0,>=2.0.5|~3.0.0", 186 | "symfony/dependency-injection": "~2.6|~3.0.0", 187 | "symfony/expression-language": "~2.6|~3.0.0", 188 | "symfony/stopwatch": "~2.3|~3.0.0" 189 | }, 190 | "suggest": { 191 | "symfony/dependency-injection": "", 192 | "symfony/http-kernel": "" 193 | }, 194 | "type": "library", 195 | "extra": { 196 | "branch-alias": { 197 | "dev-master": "2.8-dev" 198 | } 199 | }, 200 | "autoload": { 201 | "psr-4": { 202 | "Symfony\\Component\\EventDispatcher\\": "" 203 | }, 204 | "exclude-from-classmap": [ 205 | "/Tests/" 206 | ] 207 | }, 208 | "notification-url": "https://packagist.org/downloads/", 209 | "license": [ 210 | "MIT" 211 | ], 212 | "authors": [ 213 | { 214 | "name": "Fabien Potencier", 215 | "email": "fabien@symfony.com" 216 | }, 217 | { 218 | "name": "Symfony Community", 219 | "homepage": "https://symfony.com/contributors" 220 | } 221 | ], 222 | "description": "Symfony EventDispatcher Component", 223 | "homepage": "https://symfony.com", 224 | "time": "2016-01-13 10:28:07" 225 | }, 226 | { 227 | "name": "symfony/yaml", 228 | "version": "v3.0.2", 229 | "source": { 230 | "type": "git", 231 | "url": "https://github.com/symfony/yaml.git", 232 | "reference": "3cf0709d7fe936e97bee9e954382e449003f1d9a" 233 | }, 234 | "dist": { 235 | "type": "zip", 236 | "url": "https://api.github.com/repos/symfony/yaml/zipball/3cf0709d7fe936e97bee9e954382e449003f1d9a", 237 | "reference": "3cf0709d7fe936e97bee9e954382e449003f1d9a", 238 | "shasum": "" 239 | }, 240 | "require": { 241 | "php": ">=5.5.9" 242 | }, 243 | "type": "library", 244 | "extra": { 245 | "branch-alias": { 246 | "dev-master": "3.0-dev" 247 | } 248 | }, 249 | "autoload": { 250 | "psr-4": { 251 | "Symfony\\Component\\Yaml\\": "" 252 | }, 253 | "exclude-from-classmap": [ 254 | "/Tests/" 255 | ] 256 | }, 257 | "notification-url": "https://packagist.org/downloads/", 258 | "license": [ 259 | "MIT" 260 | ], 261 | "authors": [ 262 | { 263 | "name": "Fabien Potencier", 264 | "email": "fabien@symfony.com" 265 | }, 266 | { 267 | "name": "Symfony Community", 268 | "homepage": "https://symfony.com/contributors" 269 | } 270 | ], 271 | "description": "Symfony Yaml Component", 272 | "homepage": "https://symfony.com", 273 | "time": "2016-02-02 13:44:19" 274 | } 275 | ], 276 | "packages-dev": [ 277 | { 278 | "name": "doctrine/instantiator", 279 | "version": "1.0.5", 280 | "source": { 281 | "type": "git", 282 | "url": "https://github.com/doctrine/instantiator.git", 283 | "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d" 284 | }, 285 | "dist": { 286 | "type": "zip", 287 | "url": "https://api.github.com/repos/doctrine/instantiator/zipball/8e884e78f9f0eb1329e445619e04456e64d8051d", 288 | "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d", 289 | "shasum": "" 290 | }, 291 | "require": { 292 | "php": ">=5.3,<8.0-DEV" 293 | }, 294 | "require-dev": { 295 | "athletic/athletic": "~0.1.8", 296 | "ext-pdo": "*", 297 | "ext-phar": "*", 298 | "phpunit/phpunit": "~4.0", 299 | "squizlabs/php_codesniffer": "~2.0" 300 | }, 301 | "type": "library", 302 | "extra": { 303 | "branch-alias": { 304 | "dev-master": "1.0.x-dev" 305 | } 306 | }, 307 | "autoload": { 308 | "psr-4": { 309 | "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" 310 | } 311 | }, 312 | "notification-url": "https://packagist.org/downloads/", 313 | "license": [ 314 | "MIT" 315 | ], 316 | "authors": [ 317 | { 318 | "name": "Marco Pivetta", 319 | "email": "ocramius@gmail.com", 320 | "homepage": "http://ocramius.github.com/" 321 | } 322 | ], 323 | "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", 324 | "homepage": "https://github.com/doctrine/instantiator", 325 | "keywords": [ 326 | "constructor", 327 | "instantiate" 328 | ], 329 | "time": "2015-06-14 21:17:01" 330 | }, 331 | { 332 | "name": "myclabs/deep-copy", 333 | "version": "1.5.0", 334 | "source": { 335 | "type": "git", 336 | "url": "https://github.com/myclabs/DeepCopy.git", 337 | "reference": "e3abefcd7f106677fd352cd7c187d6c969aa9ddc" 338 | }, 339 | "dist": { 340 | "type": "zip", 341 | "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/e3abefcd7f106677fd352cd7c187d6c969aa9ddc", 342 | "reference": "e3abefcd7f106677fd352cd7c187d6c969aa9ddc", 343 | "shasum": "" 344 | }, 345 | "require": { 346 | "php": ">=5.4.0" 347 | }, 348 | "require-dev": { 349 | "doctrine/collections": "1.*", 350 | "phpunit/phpunit": "~4.1" 351 | }, 352 | "type": "library", 353 | "autoload": { 354 | "psr-4": { 355 | "DeepCopy\\": "src/DeepCopy/" 356 | } 357 | }, 358 | "notification-url": "https://packagist.org/downloads/", 359 | "license": [ 360 | "MIT" 361 | ], 362 | "description": "Create deep copies (clones) of your objects", 363 | "homepage": "https://github.com/myclabs/DeepCopy", 364 | "keywords": [ 365 | "clone", 366 | "copy", 367 | "duplicate", 368 | "object", 369 | "object graph" 370 | ], 371 | "time": "2015-11-07 22:20:37" 372 | }, 373 | { 374 | "name": "phpdocumentor/reflection-docblock", 375 | "version": "2.0.4", 376 | "source": { 377 | "type": "git", 378 | "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", 379 | "reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8" 380 | }, 381 | "dist": { 382 | "type": "zip", 383 | "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/d68dbdc53dc358a816f00b300704702b2eaff7b8", 384 | "reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8", 385 | "shasum": "" 386 | }, 387 | "require": { 388 | "php": ">=5.3.3" 389 | }, 390 | "require-dev": { 391 | "phpunit/phpunit": "~4.0" 392 | }, 393 | "suggest": { 394 | "dflydev/markdown": "~1.0", 395 | "erusev/parsedown": "~1.0" 396 | }, 397 | "type": "library", 398 | "extra": { 399 | "branch-alias": { 400 | "dev-master": "2.0.x-dev" 401 | } 402 | }, 403 | "autoload": { 404 | "psr-0": { 405 | "phpDocumentor": [ 406 | "src/" 407 | ] 408 | } 409 | }, 410 | "notification-url": "https://packagist.org/downloads/", 411 | "license": [ 412 | "MIT" 413 | ], 414 | "authors": [ 415 | { 416 | "name": "Mike van Riel", 417 | "email": "mike.vanriel@naenius.com" 418 | } 419 | ], 420 | "time": "2015-02-03 12:10:50" 421 | }, 422 | { 423 | "name": "phpspec/prophecy", 424 | "version": "v1.6.0", 425 | "source": { 426 | "type": "git", 427 | "url": "https://github.com/phpspec/prophecy.git", 428 | "reference": "3c91bdf81797d725b14cb62906f9a4ce44235972" 429 | }, 430 | "dist": { 431 | "type": "zip", 432 | "url": "https://api.github.com/repos/phpspec/prophecy/zipball/3c91bdf81797d725b14cb62906f9a4ce44235972", 433 | "reference": "3c91bdf81797d725b14cb62906f9a4ce44235972", 434 | "shasum": "" 435 | }, 436 | "require": { 437 | "doctrine/instantiator": "^1.0.2", 438 | "php": "^5.3|^7.0", 439 | "phpdocumentor/reflection-docblock": "~2.0", 440 | "sebastian/comparator": "~1.1", 441 | "sebastian/recursion-context": "~1.0" 442 | }, 443 | "require-dev": { 444 | "phpspec/phpspec": "~2.0" 445 | }, 446 | "type": "library", 447 | "extra": { 448 | "branch-alias": { 449 | "dev-master": "1.5.x-dev" 450 | } 451 | }, 452 | "autoload": { 453 | "psr-0": { 454 | "Prophecy\\": "src/" 455 | } 456 | }, 457 | "notification-url": "https://packagist.org/downloads/", 458 | "license": [ 459 | "MIT" 460 | ], 461 | "authors": [ 462 | { 463 | "name": "Konstantin Kudryashov", 464 | "email": "ever.zet@gmail.com", 465 | "homepage": "http://everzet.com" 466 | }, 467 | { 468 | "name": "Marcello Duarte", 469 | "email": "marcello.duarte@gmail.com" 470 | } 471 | ], 472 | "description": "Highly opinionated mocking framework for PHP 5.3+", 473 | "homepage": "https://github.com/phpspec/prophecy", 474 | "keywords": [ 475 | "Double", 476 | "Dummy", 477 | "fake", 478 | "mock", 479 | "spy", 480 | "stub" 481 | ], 482 | "time": "2016-02-15 07:46:21" 483 | }, 484 | { 485 | "name": "phpunit/php-code-coverage", 486 | "version": "3.2.1", 487 | "source": { 488 | "type": "git", 489 | "url": "https://github.com/sebastianbergmann/php-code-coverage.git", 490 | "reference": "a58f95ae76fe201b571fad3e8370a50c4368678c" 491 | }, 492 | "dist": { 493 | "type": "zip", 494 | "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/a58f95ae76fe201b571fad3e8370a50c4368678c", 495 | "reference": "a58f95ae76fe201b571fad3e8370a50c4368678c", 496 | "shasum": "" 497 | }, 498 | "require": { 499 | "php": "^5.6 || ^7.0", 500 | "phpunit/php-file-iterator": "~1.3", 501 | "phpunit/php-text-template": "~1.2", 502 | "phpunit/php-token-stream": "^1.4.2", 503 | "sebastian/code-unit-reverse-lookup": "~1.0", 504 | "sebastian/environment": "^1.3.2", 505 | "sebastian/version": "~1.0|~2.0" 506 | }, 507 | "require-dev": { 508 | "ext-xdebug": ">=2.1.4", 509 | "phpunit/phpunit": "~5" 510 | }, 511 | "suggest": { 512 | "ext-dom": "*", 513 | "ext-xdebug": ">=2.2.1", 514 | "ext-xmlwriter": "*" 515 | }, 516 | "type": "library", 517 | "extra": { 518 | "branch-alias": { 519 | "dev-master": "3.2.x-dev" 520 | } 521 | }, 522 | "autoload": { 523 | "classmap": [ 524 | "src/" 525 | ] 526 | }, 527 | "notification-url": "https://packagist.org/downloads/", 528 | "license": [ 529 | "BSD-3-Clause" 530 | ], 531 | "authors": [ 532 | { 533 | "name": "Sebastian Bergmann", 534 | "email": "sb@sebastian-bergmann.de", 535 | "role": "lead" 536 | } 537 | ], 538 | "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", 539 | "homepage": "https://github.com/sebastianbergmann/php-code-coverage", 540 | "keywords": [ 541 | "coverage", 542 | "testing", 543 | "xunit" 544 | ], 545 | "time": "2016-02-18 07:31:12" 546 | }, 547 | { 548 | "name": "phpunit/php-file-iterator", 549 | "version": "1.4.1", 550 | "source": { 551 | "type": "git", 552 | "url": "https://github.com/sebastianbergmann/php-file-iterator.git", 553 | "reference": "6150bf2c35d3fc379e50c7602b75caceaa39dbf0" 554 | }, 555 | "dist": { 556 | "type": "zip", 557 | "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/6150bf2c35d3fc379e50c7602b75caceaa39dbf0", 558 | "reference": "6150bf2c35d3fc379e50c7602b75caceaa39dbf0", 559 | "shasum": "" 560 | }, 561 | "require": { 562 | "php": ">=5.3.3" 563 | }, 564 | "type": "library", 565 | "extra": { 566 | "branch-alias": { 567 | "dev-master": "1.4.x-dev" 568 | } 569 | }, 570 | "autoload": { 571 | "classmap": [ 572 | "src/" 573 | ] 574 | }, 575 | "notification-url": "https://packagist.org/downloads/", 576 | "license": [ 577 | "BSD-3-Clause" 578 | ], 579 | "authors": [ 580 | { 581 | "name": "Sebastian Bergmann", 582 | "email": "sb@sebastian-bergmann.de", 583 | "role": "lead" 584 | } 585 | ], 586 | "description": "FilterIterator implementation that filters files based on a list of suffixes.", 587 | "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", 588 | "keywords": [ 589 | "filesystem", 590 | "iterator" 591 | ], 592 | "time": "2015-06-21 13:08:43" 593 | }, 594 | { 595 | "name": "phpunit/php-text-template", 596 | "version": "1.2.1", 597 | "source": { 598 | "type": "git", 599 | "url": "https://github.com/sebastianbergmann/php-text-template.git", 600 | "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686" 601 | }, 602 | "dist": { 603 | "type": "zip", 604 | "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686", 605 | "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686", 606 | "shasum": "" 607 | }, 608 | "require": { 609 | "php": ">=5.3.3" 610 | }, 611 | "type": "library", 612 | "autoload": { 613 | "classmap": [ 614 | "src/" 615 | ] 616 | }, 617 | "notification-url": "https://packagist.org/downloads/", 618 | "license": [ 619 | "BSD-3-Clause" 620 | ], 621 | "authors": [ 622 | { 623 | "name": "Sebastian Bergmann", 624 | "email": "sebastian@phpunit.de", 625 | "role": "lead" 626 | } 627 | ], 628 | "description": "Simple template engine.", 629 | "homepage": "https://github.com/sebastianbergmann/php-text-template/", 630 | "keywords": [ 631 | "template" 632 | ], 633 | "time": "2015-06-21 13:50:34" 634 | }, 635 | { 636 | "name": "phpunit/php-timer", 637 | "version": "1.0.7", 638 | "source": { 639 | "type": "git", 640 | "url": "https://github.com/sebastianbergmann/php-timer.git", 641 | "reference": "3e82f4e9fc92665fafd9157568e4dcb01d014e5b" 642 | }, 643 | "dist": { 644 | "type": "zip", 645 | "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3e82f4e9fc92665fafd9157568e4dcb01d014e5b", 646 | "reference": "3e82f4e9fc92665fafd9157568e4dcb01d014e5b", 647 | "shasum": "" 648 | }, 649 | "require": { 650 | "php": ">=5.3.3" 651 | }, 652 | "type": "library", 653 | "autoload": { 654 | "classmap": [ 655 | "src/" 656 | ] 657 | }, 658 | "notification-url": "https://packagist.org/downloads/", 659 | "license": [ 660 | "BSD-3-Clause" 661 | ], 662 | "authors": [ 663 | { 664 | "name": "Sebastian Bergmann", 665 | "email": "sb@sebastian-bergmann.de", 666 | "role": "lead" 667 | } 668 | ], 669 | "description": "Utility class for timing", 670 | "homepage": "https://github.com/sebastianbergmann/php-timer/", 671 | "keywords": [ 672 | "timer" 673 | ], 674 | "time": "2015-06-21 08:01:12" 675 | }, 676 | { 677 | "name": "phpunit/php-token-stream", 678 | "version": "1.4.8", 679 | "source": { 680 | "type": "git", 681 | "url": "https://github.com/sebastianbergmann/php-token-stream.git", 682 | "reference": "3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da" 683 | }, 684 | "dist": { 685 | "type": "zip", 686 | "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da", 687 | "reference": "3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da", 688 | "shasum": "" 689 | }, 690 | "require": { 691 | "ext-tokenizer": "*", 692 | "php": ">=5.3.3" 693 | }, 694 | "require-dev": { 695 | "phpunit/phpunit": "~4.2" 696 | }, 697 | "type": "library", 698 | "extra": { 699 | "branch-alias": { 700 | "dev-master": "1.4-dev" 701 | } 702 | }, 703 | "autoload": { 704 | "classmap": [ 705 | "src/" 706 | ] 707 | }, 708 | "notification-url": "https://packagist.org/downloads/", 709 | "license": [ 710 | "BSD-3-Clause" 711 | ], 712 | "authors": [ 713 | { 714 | "name": "Sebastian Bergmann", 715 | "email": "sebastian@phpunit.de" 716 | } 717 | ], 718 | "description": "Wrapper around PHP's tokenizer extension.", 719 | "homepage": "https://github.com/sebastianbergmann/php-token-stream/", 720 | "keywords": [ 721 | "tokenizer" 722 | ], 723 | "time": "2015-09-15 10:49:45" 724 | }, 725 | { 726 | "name": "phpunit/phpunit", 727 | "version": "5.2.9", 728 | "source": { 729 | "type": "git", 730 | "url": "https://github.com/sebastianbergmann/phpunit.git", 731 | "reference": "b12b9c37e382c096b93c3f26e7395775f59a5eea" 732 | }, 733 | "dist": { 734 | "type": "zip", 735 | "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/b12b9c37e382c096b93c3f26e7395775f59a5eea", 736 | "reference": "b12b9c37e382c096b93c3f26e7395775f59a5eea", 737 | "shasum": "" 738 | }, 739 | "require": { 740 | "ext-dom": "*", 741 | "ext-json": "*", 742 | "ext-pcre": "*", 743 | "ext-reflection": "*", 744 | "ext-spl": "*", 745 | "myclabs/deep-copy": "~1.3", 746 | "php": "^5.6 || ^7.0", 747 | "phpspec/prophecy": "^1.3.1", 748 | "phpunit/php-code-coverage": "^3.2.1", 749 | "phpunit/php-file-iterator": "~1.4", 750 | "phpunit/php-text-template": "~1.2", 751 | "phpunit/php-timer": ">=1.0.6", 752 | "phpunit/phpunit-mock-objects": ">=3.0.5", 753 | "sebastian/comparator": "~1.1", 754 | "sebastian/diff": "~1.2", 755 | "sebastian/environment": "~1.3", 756 | "sebastian/exporter": "~1.2", 757 | "sebastian/global-state": "~1.0", 758 | "sebastian/resource-operations": "~1.0", 759 | "sebastian/version": "~1.0|~2.0", 760 | "symfony/yaml": "~2.1|~3.0" 761 | }, 762 | "suggest": { 763 | "phpunit/php-invoker": "~1.1" 764 | }, 765 | "bin": [ 766 | "phpunit" 767 | ], 768 | "type": "library", 769 | "extra": { 770 | "branch-alias": { 771 | "dev-master": "5.2.x-dev" 772 | } 773 | }, 774 | "autoload": { 775 | "classmap": [ 776 | "src/" 777 | ] 778 | }, 779 | "notification-url": "https://packagist.org/downloads/", 780 | "license": [ 781 | "BSD-3-Clause" 782 | ], 783 | "authors": [ 784 | { 785 | "name": "Sebastian Bergmann", 786 | "email": "sebastian@phpunit.de", 787 | "role": "lead" 788 | } 789 | ], 790 | "description": "The PHP Unit Testing framework.", 791 | "homepage": "https://phpunit.de/", 792 | "keywords": [ 793 | "phpunit", 794 | "testing", 795 | "xunit" 796 | ], 797 | "time": "2016-02-19 11:43:07" 798 | }, 799 | { 800 | "name": "phpunit/phpunit-mock-objects", 801 | "version": "3.0.6", 802 | "source": { 803 | "type": "git", 804 | "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", 805 | "reference": "49bc700750196c04dd6bc2c4c99cb632b893836b" 806 | }, 807 | "dist": { 808 | "type": "zip", 809 | "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/49bc700750196c04dd6bc2c4c99cb632b893836b", 810 | "reference": "49bc700750196c04dd6bc2c4c99cb632b893836b", 811 | "shasum": "" 812 | }, 813 | "require": { 814 | "doctrine/instantiator": "^1.0.2", 815 | "php": ">=5.6", 816 | "phpunit/php-text-template": "~1.2", 817 | "sebastian/exporter": "~1.2" 818 | }, 819 | "require-dev": { 820 | "phpunit/phpunit": "~5" 821 | }, 822 | "suggest": { 823 | "ext-soap": "*" 824 | }, 825 | "type": "library", 826 | "extra": { 827 | "branch-alias": { 828 | "dev-master": "3.0.x-dev" 829 | } 830 | }, 831 | "autoload": { 832 | "classmap": [ 833 | "src/" 834 | ] 835 | }, 836 | "notification-url": "https://packagist.org/downloads/", 837 | "license": [ 838 | "BSD-3-Clause" 839 | ], 840 | "authors": [ 841 | { 842 | "name": "Sebastian Bergmann", 843 | "email": "sb@sebastian-bergmann.de", 844 | "role": "lead" 845 | } 846 | ], 847 | "description": "Mock Object library for PHPUnit", 848 | "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/", 849 | "keywords": [ 850 | "mock", 851 | "xunit" 852 | ], 853 | "time": "2015-12-08 08:47:06" 854 | }, 855 | { 856 | "name": "sebastian/code-unit-reverse-lookup", 857 | "version": "1.0.0", 858 | "source": { 859 | "type": "git", 860 | "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", 861 | "reference": "c36f5e7cfce482fde5bf8d10d41a53591e0198fe" 862 | }, 863 | "dist": { 864 | "type": "zip", 865 | "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/c36f5e7cfce482fde5bf8d10d41a53591e0198fe", 866 | "reference": "c36f5e7cfce482fde5bf8d10d41a53591e0198fe", 867 | "shasum": "" 868 | }, 869 | "require": { 870 | "php": ">=5.6" 871 | }, 872 | "require-dev": { 873 | "phpunit/phpunit": "~5" 874 | }, 875 | "type": "library", 876 | "extra": { 877 | "branch-alias": { 878 | "dev-master": "1.0.x-dev" 879 | } 880 | }, 881 | "autoload": { 882 | "classmap": [ 883 | "src/" 884 | ] 885 | }, 886 | "notification-url": "https://packagist.org/downloads/", 887 | "license": [ 888 | "BSD-3-Clause" 889 | ], 890 | "authors": [ 891 | { 892 | "name": "Sebastian Bergmann", 893 | "email": "sebastian@phpunit.de" 894 | } 895 | ], 896 | "description": "Looks up which function or method a line of code belongs to", 897 | "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", 898 | "time": "2016-02-13 06:45:14" 899 | }, 900 | { 901 | "name": "sebastian/comparator", 902 | "version": "1.2.0", 903 | "source": { 904 | "type": "git", 905 | "url": "https://github.com/sebastianbergmann/comparator.git", 906 | "reference": "937efb279bd37a375bcadf584dec0726f84dbf22" 907 | }, 908 | "dist": { 909 | "type": "zip", 910 | "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/937efb279bd37a375bcadf584dec0726f84dbf22", 911 | "reference": "937efb279bd37a375bcadf584dec0726f84dbf22", 912 | "shasum": "" 913 | }, 914 | "require": { 915 | "php": ">=5.3.3", 916 | "sebastian/diff": "~1.2", 917 | "sebastian/exporter": "~1.2" 918 | }, 919 | "require-dev": { 920 | "phpunit/phpunit": "~4.4" 921 | }, 922 | "type": "library", 923 | "extra": { 924 | "branch-alias": { 925 | "dev-master": "1.2.x-dev" 926 | } 927 | }, 928 | "autoload": { 929 | "classmap": [ 930 | "src/" 931 | ] 932 | }, 933 | "notification-url": "https://packagist.org/downloads/", 934 | "license": [ 935 | "BSD-3-Clause" 936 | ], 937 | "authors": [ 938 | { 939 | "name": "Jeff Welch", 940 | "email": "whatthejeff@gmail.com" 941 | }, 942 | { 943 | "name": "Volker Dusch", 944 | "email": "github@wallbash.com" 945 | }, 946 | { 947 | "name": "Bernhard Schussek", 948 | "email": "bschussek@2bepublished.at" 949 | }, 950 | { 951 | "name": "Sebastian Bergmann", 952 | "email": "sebastian@phpunit.de" 953 | } 954 | ], 955 | "description": "Provides the functionality to compare PHP values for equality", 956 | "homepage": "http://www.github.com/sebastianbergmann/comparator", 957 | "keywords": [ 958 | "comparator", 959 | "compare", 960 | "equality" 961 | ], 962 | "time": "2015-07-26 15:48:44" 963 | }, 964 | { 965 | "name": "sebastian/diff", 966 | "version": "1.4.1", 967 | "source": { 968 | "type": "git", 969 | "url": "https://github.com/sebastianbergmann/diff.git", 970 | "reference": "13edfd8706462032c2f52b4b862974dd46b71c9e" 971 | }, 972 | "dist": { 973 | "type": "zip", 974 | "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/13edfd8706462032c2f52b4b862974dd46b71c9e", 975 | "reference": "13edfd8706462032c2f52b4b862974dd46b71c9e", 976 | "shasum": "" 977 | }, 978 | "require": { 979 | "php": ">=5.3.3" 980 | }, 981 | "require-dev": { 982 | "phpunit/phpunit": "~4.8" 983 | }, 984 | "type": "library", 985 | "extra": { 986 | "branch-alias": { 987 | "dev-master": "1.4-dev" 988 | } 989 | }, 990 | "autoload": { 991 | "classmap": [ 992 | "src/" 993 | ] 994 | }, 995 | "notification-url": "https://packagist.org/downloads/", 996 | "license": [ 997 | "BSD-3-Clause" 998 | ], 999 | "authors": [ 1000 | { 1001 | "name": "Kore Nordmann", 1002 | "email": "mail@kore-nordmann.de" 1003 | }, 1004 | { 1005 | "name": "Sebastian Bergmann", 1006 | "email": "sebastian@phpunit.de" 1007 | } 1008 | ], 1009 | "description": "Diff implementation", 1010 | "homepage": "https://github.com/sebastianbergmann/diff", 1011 | "keywords": [ 1012 | "diff" 1013 | ], 1014 | "time": "2015-12-08 07:14:41" 1015 | }, 1016 | { 1017 | "name": "sebastian/environment", 1018 | "version": "1.3.3", 1019 | "source": { 1020 | "type": "git", 1021 | "url": "https://github.com/sebastianbergmann/environment.git", 1022 | "reference": "6e7133793a8e5a5714a551a8324337374be209df" 1023 | }, 1024 | "dist": { 1025 | "type": "zip", 1026 | "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/6e7133793a8e5a5714a551a8324337374be209df", 1027 | "reference": "6e7133793a8e5a5714a551a8324337374be209df", 1028 | "shasum": "" 1029 | }, 1030 | "require": { 1031 | "php": ">=5.3.3" 1032 | }, 1033 | "require-dev": { 1034 | "phpunit/phpunit": "~4.4" 1035 | }, 1036 | "type": "library", 1037 | "extra": { 1038 | "branch-alias": { 1039 | "dev-master": "1.3.x-dev" 1040 | } 1041 | }, 1042 | "autoload": { 1043 | "classmap": [ 1044 | "src/" 1045 | ] 1046 | }, 1047 | "notification-url": "https://packagist.org/downloads/", 1048 | "license": [ 1049 | "BSD-3-Clause" 1050 | ], 1051 | "authors": [ 1052 | { 1053 | "name": "Sebastian Bergmann", 1054 | "email": "sebastian@phpunit.de" 1055 | } 1056 | ], 1057 | "description": "Provides functionality to handle HHVM/PHP environments", 1058 | "homepage": "http://www.github.com/sebastianbergmann/environment", 1059 | "keywords": [ 1060 | "Xdebug", 1061 | "environment", 1062 | "hhvm" 1063 | ], 1064 | "time": "2015-12-02 08:37:27" 1065 | }, 1066 | { 1067 | "name": "sebastian/exporter", 1068 | "version": "1.2.1", 1069 | "source": { 1070 | "type": "git", 1071 | "url": "https://github.com/sebastianbergmann/exporter.git", 1072 | "reference": "7ae5513327cb536431847bcc0c10edba2701064e" 1073 | }, 1074 | "dist": { 1075 | "type": "zip", 1076 | "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/7ae5513327cb536431847bcc0c10edba2701064e", 1077 | "reference": "7ae5513327cb536431847bcc0c10edba2701064e", 1078 | "shasum": "" 1079 | }, 1080 | "require": { 1081 | "php": ">=5.3.3", 1082 | "sebastian/recursion-context": "~1.0" 1083 | }, 1084 | "require-dev": { 1085 | "phpunit/phpunit": "~4.4" 1086 | }, 1087 | "type": "library", 1088 | "extra": { 1089 | "branch-alias": { 1090 | "dev-master": "1.2.x-dev" 1091 | } 1092 | }, 1093 | "autoload": { 1094 | "classmap": [ 1095 | "src/" 1096 | ] 1097 | }, 1098 | "notification-url": "https://packagist.org/downloads/", 1099 | "license": [ 1100 | "BSD-3-Clause" 1101 | ], 1102 | "authors": [ 1103 | { 1104 | "name": "Jeff Welch", 1105 | "email": "whatthejeff@gmail.com" 1106 | }, 1107 | { 1108 | "name": "Volker Dusch", 1109 | "email": "github@wallbash.com" 1110 | }, 1111 | { 1112 | "name": "Bernhard Schussek", 1113 | "email": "bschussek@2bepublished.at" 1114 | }, 1115 | { 1116 | "name": "Sebastian Bergmann", 1117 | "email": "sebastian@phpunit.de" 1118 | }, 1119 | { 1120 | "name": "Adam Harvey", 1121 | "email": "aharvey@php.net" 1122 | } 1123 | ], 1124 | "description": "Provides the functionality to export PHP variables for visualization", 1125 | "homepage": "http://www.github.com/sebastianbergmann/exporter", 1126 | "keywords": [ 1127 | "export", 1128 | "exporter" 1129 | ], 1130 | "time": "2015-06-21 07:55:53" 1131 | }, 1132 | { 1133 | "name": "sebastian/global-state", 1134 | "version": "1.1.1", 1135 | "source": { 1136 | "type": "git", 1137 | "url": "https://github.com/sebastianbergmann/global-state.git", 1138 | "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4" 1139 | }, 1140 | "dist": { 1141 | "type": "zip", 1142 | "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bc37d50fea7d017d3d340f230811c9f1d7280af4", 1143 | "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4", 1144 | "shasum": "" 1145 | }, 1146 | "require": { 1147 | "php": ">=5.3.3" 1148 | }, 1149 | "require-dev": { 1150 | "phpunit/phpunit": "~4.2" 1151 | }, 1152 | "suggest": { 1153 | "ext-uopz": "*" 1154 | }, 1155 | "type": "library", 1156 | "extra": { 1157 | "branch-alias": { 1158 | "dev-master": "1.0-dev" 1159 | } 1160 | }, 1161 | "autoload": { 1162 | "classmap": [ 1163 | "src/" 1164 | ] 1165 | }, 1166 | "notification-url": "https://packagist.org/downloads/", 1167 | "license": [ 1168 | "BSD-3-Clause" 1169 | ], 1170 | "authors": [ 1171 | { 1172 | "name": "Sebastian Bergmann", 1173 | "email": "sebastian@phpunit.de" 1174 | } 1175 | ], 1176 | "description": "Snapshotting of global state", 1177 | "homepage": "http://www.github.com/sebastianbergmann/global-state", 1178 | "keywords": [ 1179 | "global state" 1180 | ], 1181 | "time": "2015-10-12 03:26:01" 1182 | }, 1183 | { 1184 | "name": "sebastian/recursion-context", 1185 | "version": "1.0.2", 1186 | "source": { 1187 | "type": "git", 1188 | "url": "https://github.com/sebastianbergmann/recursion-context.git", 1189 | "reference": "913401df809e99e4f47b27cdd781f4a258d58791" 1190 | }, 1191 | "dist": { 1192 | "type": "zip", 1193 | "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/913401df809e99e4f47b27cdd781f4a258d58791", 1194 | "reference": "913401df809e99e4f47b27cdd781f4a258d58791", 1195 | "shasum": "" 1196 | }, 1197 | "require": { 1198 | "php": ">=5.3.3" 1199 | }, 1200 | "require-dev": { 1201 | "phpunit/phpunit": "~4.4" 1202 | }, 1203 | "type": "library", 1204 | "extra": { 1205 | "branch-alias": { 1206 | "dev-master": "1.0.x-dev" 1207 | } 1208 | }, 1209 | "autoload": { 1210 | "classmap": [ 1211 | "src/" 1212 | ] 1213 | }, 1214 | "notification-url": "https://packagist.org/downloads/", 1215 | "license": [ 1216 | "BSD-3-Clause" 1217 | ], 1218 | "authors": [ 1219 | { 1220 | "name": "Jeff Welch", 1221 | "email": "whatthejeff@gmail.com" 1222 | }, 1223 | { 1224 | "name": "Sebastian Bergmann", 1225 | "email": "sebastian@phpunit.de" 1226 | }, 1227 | { 1228 | "name": "Adam Harvey", 1229 | "email": "aharvey@php.net" 1230 | } 1231 | ], 1232 | "description": "Provides functionality to recursively process PHP variables", 1233 | "homepage": "http://www.github.com/sebastianbergmann/recursion-context", 1234 | "time": "2015-11-11 19:50:13" 1235 | }, 1236 | { 1237 | "name": "sebastian/resource-operations", 1238 | "version": "1.0.0", 1239 | "source": { 1240 | "type": "git", 1241 | "url": "https://github.com/sebastianbergmann/resource-operations.git", 1242 | "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52" 1243 | }, 1244 | "dist": { 1245 | "type": "zip", 1246 | "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", 1247 | "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", 1248 | "shasum": "" 1249 | }, 1250 | "require": { 1251 | "php": ">=5.6.0" 1252 | }, 1253 | "type": "library", 1254 | "extra": { 1255 | "branch-alias": { 1256 | "dev-master": "1.0.x-dev" 1257 | } 1258 | }, 1259 | "autoload": { 1260 | "classmap": [ 1261 | "src/" 1262 | ] 1263 | }, 1264 | "notification-url": "https://packagist.org/downloads/", 1265 | "license": [ 1266 | "BSD-3-Clause" 1267 | ], 1268 | "authors": [ 1269 | { 1270 | "name": "Sebastian Bergmann", 1271 | "email": "sebastian@phpunit.de" 1272 | } 1273 | ], 1274 | "description": "Provides a list of PHP built-in functions that operate on resources", 1275 | "homepage": "https://www.github.com/sebastianbergmann/resource-operations", 1276 | "time": "2015-07-28 20:34:47" 1277 | }, 1278 | { 1279 | "name": "sebastian/version", 1280 | "version": "2.0.0", 1281 | "source": { 1282 | "type": "git", 1283 | "url": "https://github.com/sebastianbergmann/version.git", 1284 | "reference": "c829badbd8fdf16a0bad8aa7fa7971c029f1b9c5" 1285 | }, 1286 | "dist": { 1287 | "type": "zip", 1288 | "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c829badbd8fdf16a0bad8aa7fa7971c029f1b9c5", 1289 | "reference": "c829badbd8fdf16a0bad8aa7fa7971c029f1b9c5", 1290 | "shasum": "" 1291 | }, 1292 | "require": { 1293 | "php": ">=5.6" 1294 | }, 1295 | "type": "library", 1296 | "extra": { 1297 | "branch-alias": { 1298 | "dev-master": "2.0.x-dev" 1299 | } 1300 | }, 1301 | "autoload": { 1302 | "classmap": [ 1303 | "src/" 1304 | ] 1305 | }, 1306 | "notification-url": "https://packagist.org/downloads/", 1307 | "license": [ 1308 | "BSD-3-Clause" 1309 | ], 1310 | "authors": [ 1311 | { 1312 | "name": "Sebastian Bergmann", 1313 | "email": "sebastian@phpunit.de", 1314 | "role": "lead" 1315 | } 1316 | ], 1317 | "description": "Library that helps with managing the version number of Git-hosted PHP projects", 1318 | "homepage": "https://github.com/sebastianbergmann/version", 1319 | "time": "2016-02-04 12:56:52" 1320 | } 1321 | ], 1322 | "aliases": [], 1323 | "minimum-stability": "stable", 1324 | "stability-flags": [], 1325 | "prefer-stable": false, 1326 | "prefer-lowest": false, 1327 | "platform": [], 1328 | "platform-dev": [] 1329 | } 1330 | --------------------------------------------------------------------------------