├── .gitignore ├── LICENSE.txt ├── Makefile ├── README.md ├── composer-lock-diff ├── composer.json ├── test-data ├── composer.from.json ├── composer.from.lock ├── composer.to.json └── composer.to.lock └── test-svn.sh /.gitignore: -------------------------------------------------------------------------------- 1 | [._]*.s[a-w][a-z] 2 | [._]s[a-w][a-z] 3 | Session.vim 4 | .netrwhist 5 | *~ 6 | tags 7 | tags.* 8 | .DS_Store 9 | .DS_Store? 10 | ._* 11 | .Spotlight-V100 12 | .Trashes 13 | ehthumbs.db 14 | Thumbs.db 15 | /test-project 16 | /test-data/vendor 17 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 David Jonas 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining 6 | a copy of this software and associated documentation files (the 7 | "Software"), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, 9 | distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so, subject to 11 | the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be 14 | included in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 20 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 22 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | OPTS ?= "" 2 | PHP = php 3 | 4 | all: test test-help test-help-vcs-error md no-links only-dev only-prod json json-pretty 5 | 6 | test: 7 | $(PHP) ./composer-lock-diff --from test-data/composer.from.lock --to test-data/composer.to.lock $(OPTS) 8 | 9 | test-help: 10 | $(PHP) ./composer-lock-diff --help 11 | 12 | test-help-vcs-error: 13 | $(PHP) ./composer-lock-diff --vcs UNKNOWN ; test $$? -eq 1 14 | 15 | md: 16 | $(MAKE) test OPTS=--md 17 | 18 | no-links: 19 | $(MAKE) test OPTS=--no-links 20 | 21 | only-dev: 22 | $(MAKE) test OPTS=--only-dev 23 | 24 | only-prod: 25 | $(MAKE) test OPTS=--only-prod 26 | 27 | json: 28 | $(MAKE) test OPTS=--json 29 | 30 | json-pretty: 31 | $(MAKE) test OPTS="--json --pretty" 32 | 33 | # Regenerate the lock files from the json. This is useful when adding new 34 | # entries to test. 35 | locks: 36 | rm -rf test-data/composer.from.lock test-data/vendor 37 | cd test-data && COMPOSER=composer.from.json composer install -v 38 | rm -rf test-data/composer.to.lock test-data/vendor 39 | cd test-data && COMPOSER=composer.to.json composer install -v 40 | rm -rf test-data/vendor 41 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | composer-lock-diff 2 | ================== 3 | 4 | See what packages have changed after you run `composer update` by comparing composer.lock to the the git HEAD. 5 | 6 | Requires: 7 | - php >= 5.3 8 | 9 | There are no other dependencies. 10 | 11 | Install 12 | ------- 13 | 14 | ```bash 15 | composer global require davidrjonas/composer-lock-diff:^1.0 16 | 17 | # With zsh, run `rehash` to make it known to the shell. 18 | 19 | # try it 20 | composer-lock-diff --help 21 | ``` 22 | 23 | If `composer-lock-diff` is not found, make sure `~/.composer/vendor/bin` is in 24 | your `$PATH` env variable. For more information on how to do that see [this question on Stack Overflow][SO]. 25 | 26 | [SO]: https://stackoverflow.com/questions/25373188/laravel-installation-how-to-place-the-composer-vendor-bin-directory-in-your 27 | 28 | Usage 29 | ===== 30 | 31 | ```bash 32 | composer update 33 | # don't commit yet! 34 | composer-lock-diff 35 | ``` 36 | 37 | Or from vim, to insert the output into the commit message, type `:r!composer-lock-diff`. 38 | 39 | ### Options 40 | 41 | - `-h, --help`: Print this message 42 | - `-p, --path`: Base to with which to prefix paths. Default "./" 43 | E.g. `-p app` would look for HEAD:app/composer.lock and app/composer.lock 44 | - `--from`: The file^, git ref, or git ref with filename to compare from (git: HEAD:composer.lock, svn: composer.lock@BASE) 45 | - `--to`: The file^, git ref, or git ref with filename to compare to (composer.lock) 46 | - `--json`: Format output as JSON 47 | - `--pretty`: Pretty print JSON output (PHP >= 5.4.0) 48 | - `--md`: Use markdown instead of plain text 49 | - `--no-links`: Don't include Compare links in plain text or any links in markdown 50 | - `--only-prod`: Only include changes from `packages` 51 | - `--only-dev`: Only include changes from `packages-dev` 52 | - `--vcs`: Force vcs (git, svn, ...). Default: attempt to auto-detect 53 | 54 | ^ File includes anything available as a [protocol stream wrapper](http://php.net/manual/en/wrappers.php) such as URLs. 55 | 56 | Example Plain Text Table Output 57 | =============================== 58 | 59 | ``` 60 | +--------------------+-------+--------+------------------------------------------------------------------+ 61 | | Production Changes | From | To | Compare | 62 | +--------------------+-------+--------+------------------------------------------------------------------+ 63 | | guzzlehttp/guzzle | 6.2.0 | 6.3.0 | https://github.com/guzzle/guzzle/compare/6.2.0...6.3.0 | 64 | | hashids/hashids | 2.0.0 | 2.0.4 | https://github.com/ivanakimov/hashids.php/compare/2.0.0...2.0.4 | 65 | | league/flysystem | 1.0.0 | 1.0.42 | https://github.com/thephpleague/flysystem/compare/1.0.0...1.0.42 | 66 | | monolog/monolog | NEW | 1.21.0 | | 67 | +--------------------+-------+--------+------------------------------------------------------------------+ 68 | 69 | +------------------+--------+---------+---------+ 70 | | Dev Changes | From | To | Compare | 71 | +------------------+--------+---------+---------+ 72 | | phpspec/php-diff | v1.0.2 | REMOVED | | 73 | +------------------+--------+---------+---------+ 74 | ``` 75 | 76 | Markdown Table 77 | ============== 78 | 79 | ### Raw 80 | 81 | ``` 82 | | Production Changes | From | To | Compare | 83 | |--------------------|-------|--------|-------------------------------------------------------------------------| 84 | | guzzlehttp/guzzle | 6.2.0 | 6.3.0 | [...](https://github.com/guzzle/guzzle/compare/6.2.0...6.3.0) | 85 | | hashids/hashids | 2.0.0 | 2.0.4 | [...](https://github.com/ivanakimov/hashids.php/compare/2.0.0...2.0.4) | 86 | | league/flysystem | 1.0.0 | 1.0.42 | [...](https://github.com/thephpleague/flysystem/compare/1.0.0...1.0.42) | 87 | | monolog/monolog | NEW | 1.21.0 | | 88 | 89 | | Dev Changes | From | To | Compare | 90 | |------------------|--------|---------|---------| 91 | | phpspec/php-diff | v1.0.2 | REMOVED | | 92 | ``` 93 | 94 | ### Rendered 95 | 96 | | Production Changes | From | To | Compare | 97 | |--------------------|-------|--------|-------------------------------------------------------------------------| 98 | | guzzlehttp/guzzle | 6.2.0 | 6.3.0 | [...](https://github.com/guzzle/guzzle/compare/6.2.0...6.3.0) | 99 | | hashids/hashids | 2.0.0 | 2.0.4 | [...](https://github.com/ivanakimov/hashids.php/compare/2.0.0...2.0.4) | 100 | | league/flysystem | 1.0.0 | 1.0.42 | [...](https://github.com/thephpleague/flysystem/compare/1.0.0...1.0.42) | 101 | | monolog/monolog | NEW | 1.21.0 | | 102 | 103 | | Dev Changes | From | To | Compare | 104 | |------------------|--------|---------|---------| 105 | | phpspec/php-diff | v1.0.2 | REMOVED | | 106 | 107 | Development 108 | =========== 109 | 110 | New features are always welcome! Follow these guidelines 111 | 112 | - Try to match the style of the code that already exists, even if it isn't _your_ style (sorry!). 113 | - Make sure there is a way to test the feature. 114 | - Test with PHP 5.3 (I'm serious!), >=5.4<7, 7.current. Docker is helpful, particularly for the older versions. Just run the ubuntu:12.04 image and install php for 5.3 and 14.04 for 5.6. I can help if you're having trouble. 115 | 116 | The [Makefile](Makefile) has some test cases. Run `make | less` and inspect the output. If you need specific versions or more information, continue reading. 117 | 118 | To run using the test data manually simply point the `--to` and `--from` args at the lock files, 119 | 120 | ```php 121 | php ./composer-lock-diff --from ./test-data/composer.from.lock --to ./test-data/composer.to.lock 122 | ``` 123 | 124 | Docker is very helpful for targeting a specific version of php and/or composer, 125 | 126 | ```php 127 | docker run --rm -it -v "$PWD":/src -w /src php:7.4.2 \ 128 | php ./composer-lock-diff --from ./test-data/composer.from.lock --to ./test-data/composer.to.lock 129 | ``` 130 | 131 | Sometimes you want to test the git related functions. To do that first I make a temporary repo. Then I copy into it `test-data/composer.from.lock` as `composer.lock` to set the previous state and `test-data/composer.to.json` as `composer.json` for the future state. I commit those then run `composer-lock-diff` with the options I want to test and visually inspect the results. 132 | 133 | ```bash 134 | mkdir tmp && cd tmp 135 | git init 136 | cp ../test-data/composer.to.json composer.json 137 | cp ../test-data/composer.from.lock composer.lock 138 | git add . 139 | git commit -m "initial" 140 | 141 | composer update 142 | # or 143 | docker run --rm -it -v "$PWD":/src -w /src composer:latest php composer update 144 | 145 | php ../composer-lock-diff 146 | 147 | # or, if you want to use docker, you'll need git 148 | cd .. 149 | docker run --rm -it -v "$PWD":/src -w /src php:7.4.2 bash 150 | apt-get update && apt-get install -y git 151 | # You may want composer as well, 152 | curl -OL https://getcomposer.org/download/1.9.3/composer.phar 153 | cd tmp 154 | php ../composer.phar update 155 | php ../composer-lock-diff 156 | ``` 157 | 158 | Add a test case to test-data/ 159 | ----------------------------- 160 | 161 | - Make a new, temporary git repo in `./tmp` 162 | - Copy `../test-data/composer.from.json` as `composer.json` and `../test-data/composer.from.lock` as `composer.lock`. 163 | - Commit them. 164 | - Run `composer install` 165 | - Add your _pre_ case to `composer.json`. Use an exact version. 166 | - Run `composer update`. 167 | - The generated `composer.lock` should look similar to `../test-data/composer.from.lock` but there will be differences due to transient dependencies. No real way around that. Use `composer-lock-diff` to make sure none of the named packages change versions and your new case is there. 168 | - Copy `composer.json` to `../test-data/composer.from.json` and `composer.lock` to `composer.from.lock`. 169 | - Copy `../test-data/composer.to.json` as `composer.json`. 170 | - Add your _post_ case to `composer.json`. Again, exact versions are best. 171 | - Generate a new lock file. 172 | - Use composer-lock-diff to test your feature. 173 | - When you're happy with it, copy `composer.json` to `../test-data/composer.to.json` and `composer.lock` to `../test-data/composer.to.lock`. 174 | 175 | Test Cases 176 | ---------- 177 | 178 | See [Makefile](Makefile). 179 | 180 | - `comopser-lock-diff` # no args 181 | - `composer-lock-diff --from ./test-data/composer.from.lock --to ./test-data/composer.to.lock` 182 | - `composer-lock-diff --path ./test-data/` 183 | - `composer-lock-diff --from ` # this gets tested with 'no args' 184 | - `composer-lock-diff --from ` 185 | - `composer-lock-diff --to ` 186 | - `composer-lock-diff --to ` 187 | - `composer-lock-diff --only-dev` 188 | - `composer-lock-diff --only-prod` 189 | - `composer-lock-diff --no-links` 190 | - `composer-lock-diff --json` 191 | - `composer-lock-diff --json --pretty` 192 | - `composer-lock-diff --md` 193 | - `composer-lock-diff --md --no-links` 194 | 195 | If anyone can help test with Windows that would be very much appreciated! 196 | 197 | Contributors 198 | ============ 199 | 200 | Thanks to everyone who has shared ideas and code! In particular, 201 | 202 | - https://github.com/delamart 203 | - https://github.com/prometheas 204 | - https://github.com/paxal 205 | - https://github.com/nclavaud 206 | - https://github.com/cafferata 207 | - https://github.com/ihor-sviziev 208 | - https://github.com/wiese 209 | - https://github.com/jibran 210 | - https://github.com/soleuu 211 | - https://github.com/stof 212 | 213 | -------------------------------------------------------------------------------- /composer-lock-diff: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | $opts['no-links'], 26 | ); 27 | 28 | if ($opts['md']) { 29 | $table_opts = array_merge($table_opts, array( 30 | 'capped' => false, 31 | 'joint' => '|', 32 | 'url_formatter' => 'urlFormatterMd', 33 | )); 34 | } 35 | 36 | $table_titles = array( 37 | 'changes' => 'Production Changes', 38 | 'changes-dev' => 'Dev Changes', 39 | ); 40 | 41 | foreach($changes as $k => $diff) { 42 | print tableize($table_titles[$k], $diff, $table_opts); 43 | } 44 | 45 | function diff($key, $data_from, $data_to) { 46 | 47 | $pkgs = array(); 48 | 49 | foreach($data_from->$key as $pkg) { 50 | $pkgs[$pkg->name] = array(version($pkg), 'REMOVED', ''); 51 | } 52 | 53 | foreach($data_to->$key as $pkg) { 54 | if (! array_key_exists($pkg->name, $pkgs)) { 55 | $pkgs[$pkg->name] = array('NEW', version($pkg), ''); 56 | continue; 57 | } 58 | 59 | if ($pkgs[$pkg->name][0] == version($pkg)) { 60 | unset($pkgs[$pkg->name]); 61 | } else { 62 | $pkgs[$pkg->name][1] = version($pkg); 63 | $pkgs[$pkg->name][2] = makeCompareUrl($pkg, $pkgs); 64 | } 65 | } 66 | 67 | return $pkgs; 68 | } 69 | 70 | function version($pkg) 71 | { 72 | if((substr($pkg->version,0,4) == 'dev-' || '-dev' === substr($pkg->version, -4)) && isset($pkg->source->reference)) { 73 | $version = substr($pkg->source->reference,0,7) ?: ''; 74 | } else { 75 | $version = (string) $pkg->version; 76 | } 77 | 78 | return $version; 79 | } 80 | 81 | function tableize($header, $data, $opts = array()) { 82 | if (empty($data)) return ''; 83 | 84 | $opts = array_merge(array('capped' => true, 'joint' => '+'), $opts); 85 | 86 | if ($opts['no-links']) { 87 | array_walk($data, function(&$values) { 88 | unset($values[2]); 89 | }); 90 | } else { 91 | if (array_key_exists('url_formatter', $opts)) { 92 | $formatter = $opts['url_formatter']; 93 | array_walk($data, function(&$values) use ($formatter) { 94 | $values[2] = call_user_func($formatter, $values[2], '...'); 95 | }); 96 | } 97 | } 98 | 99 | $titles = array($header, 'From', 'To'); 100 | if (! $opts['no-links']) array_push($titles, 'Compare'); 101 | 102 | $widths = array(maxLength(array_merge(array($header), array_keys($data)))); 103 | 104 | $count = count(reset($data)); 105 | for($i = 0; $i < $count; $i++) { 106 | $widths[] = max(strlen($titles[$i + 1]), maxLength(array_map(function($k) use ($data, $i) { return $data[$k][$i]; }, array_keys($data)))); 107 | } 108 | 109 | if ($opts['capped']) { 110 | $lines[] = separatorLine($widths, $opts['joint']); 111 | } 112 | 113 | $lines[] = tabelizeLine($titles, $widths); 114 | $lines[] = separatorLine($widths, $opts['joint']); 115 | 116 | foreach($data as $key => $v) { 117 | $lines[] = tabelizeLine(array_merge(array($key), $v), $widths); 118 | } 119 | 120 | if ($opts['capped']) { 121 | $lines[] = separatorLine($widths, $opts['joint']); 122 | } 123 | 124 | return implode(PHP_EOL, array_filter($lines)) . PHP_EOL . PHP_EOL; 125 | } 126 | 127 | function separatorLine($widths, $joint) { 128 | return $joint . implode($joint, array_map(function($n) { return str_repeat('-', $n + 2); }, $widths)) . $joint; 129 | } 130 | 131 | function maxLength(array $array) { 132 | return max(array_map('strlen', $array)); 133 | } 134 | 135 | function tabelizeLine($data, $widths) { 136 | $fields = array(); 137 | $count = max(array(count($data), count($widths))); 138 | for($i = 0; $i < $count; $i++) { 139 | $value = ($i >= count($data)) ? '' : $data[$i]; 140 | $width = ($i >= count($widths)) ? strlen($value) : $widths[$i]; 141 | $fields[] = sprintf("%-{$width}s", $value); 142 | } 143 | return '| ' . implode(' | ', $fields) . ' |'; 144 | } 145 | 146 | function urlFormatterMd($url, $text) { 147 | if (empty($url)) return ''; 148 | return sprintf('[%s](%s)', $text, $url); 149 | } 150 | 151 | // $fileish is what the user actually requested. 152 | // $default_fileish is what it should be if $fileish is empty 153 | function load($fileish, $base_path, $force_vcs, $default_fileish) { 154 | $loaders = ($force_vcs || (empty($fileish) && empty($default_fileish))) ? array() : array('loadFile'); 155 | 156 | $vcses = $force_vcs ? array($force_vcs) : getVcses(); 157 | $errors = array(); 158 | 159 | foreach($vcses as $vcs) { 160 | $detector = 'vcsDetect' . ucfirst($vcs); 161 | if($vcs != $force_vcs && function_exists($detector)) { 162 | list($available, $err) = call_user_func($detector, $fileish, $base_path, $default_fileish); 163 | if ($err) { 164 | $errors[] = $err; 165 | continue; 166 | } 167 | if (!$available) continue; 168 | } 169 | $loaders[] = 'vcsLoad' . ucfirst($vcs); 170 | } 171 | 172 | if (empty($loaders)) { 173 | error_log(implode("\n", $errors)); 174 | if ($force_vcs) { 175 | error_log("Requested vcs '$force_vcs' not installed or otherwise unavailable"); 176 | } else { 177 | error_log("No loaders were found; perhaps your vcs cli tools are not installed, not in PATH, or otherwise unavailable"); 178 | } 179 | exit(1); 180 | } 181 | 182 | $errors = array(); 183 | foreach($loaders as $loader) { 184 | list($result, $err) = call_user_func_array($loader, array($fileish, $base_path, $default_fileish)); 185 | if (empty($err)) { 186 | return $result; 187 | } 188 | $errors[] = "Failed to find '$fileish' with '$loader'; $err"; 189 | } 190 | 191 | foreach($errors as $e) { 192 | error_log($e); 193 | } 194 | 195 | exit(1); 196 | } 197 | 198 | function loadFile($fileish, $base_path, $default_fileish) { 199 | if (empty($fileish)) { 200 | $fileish = $default_fileish; 201 | if (!empty($base_path)) { 202 | $fileish = joinPath($base_path, $fileish); 203 | } 204 | } 205 | 206 | // Does it look like a url that we can handle with stream wrappers? 207 | if (isUrl($fileish) && in_array(parse_url($fileish, PHP_URL_SCHEME), stream_get_wrappers())) { 208 | return array(mustDecodeJson(file_get_contents($fileish), $fileish), false); 209 | } 210 | 211 | // Is it a file in the local filesystem? 212 | if (file_exists($fileish)) { 213 | return array(mustDecodeJson(file_get_contents($fileish), $fileish), false); 214 | } 215 | 216 | return array(false, "Candidate '$fileish' does not look loadable from the fs or php stream wrappers"); 217 | } 218 | 219 | function isUrl($string) { 220 | return filter_var($string, FILTER_VALIDATE_URL, FILTER_FLAG_PATH_REQUIRED); 221 | } 222 | 223 | function mustDecodeJson($json, $context) { 224 | $data = json_decode($json); 225 | 226 | if (empty($data)) { 227 | error_log("Error: contents from $context does not decode as json"); 228 | exit(1); 229 | } 230 | 231 | return $data; 232 | } 233 | 234 | function makeCompareUrl($pkg, $diff) { 235 | $func = 'formatCompare' . ucfirst(getSourceRepoType((string) @$pkg->source->url)); 236 | return call_user_func($func, @$pkg->source->url, $diff[$pkg->name][0], $diff[$pkg->name][1]); 237 | } 238 | 239 | function getSourceRepoType($url) { 240 | if (preg_match('/^git@bitbucket\..+:.+\.git$/', $url)) { 241 | return 'bitbucket'; 242 | } 243 | if (preg_match('/^git@github\..+:.+\.git$/', $url)) { 244 | return 'github'; 245 | } 246 | if (preg_match('/^git@gitlab\..+:.+\.git$/', $url)) { 247 | return 'gitlab'; 248 | } 249 | if (preg_match('/^git@git\.drupal\..+:.+\.git$/', $url)) { 250 | return 'drupal'; 251 | } 252 | 253 | if (! preg_match('/^http/i', $url)) { 254 | return 'unknown'; 255 | } 256 | 257 | $host = strtolower(parse_url($url, PHP_URL_HOST)); 258 | 259 | if (strpos($host, 'github') !== false) { 260 | return 'github'; 261 | } elseif (strpos($host, 'bitbucket') !== false) { 262 | return 'bitbucket'; 263 | } elseif (strpos($host, 'gitlab') !== false) { 264 | return 'gitlab'; 265 | } elseif (strpos($host, 'drupalcode') !== false) { 266 | return 'drupal'; 267 | } 268 | 269 | return 'unknown'; 270 | } 271 | 272 | function formatCompareUnknown($url, $from, $to) { 273 | return ''; 274 | } 275 | 276 | function formatCompareGithub($url, $from, $to) { 277 | if (strpos($url, 'http') === false) { 278 | $url = preg_replace('/^git@(github\.[^:]+):/', 'https://$1/', $url); 279 | } 280 | $url = preg_replace('/\.git$/', '', $url); 281 | return sprintf('%s/compare/%s...%s', $url, urlencode($from), urlencode($to)); 282 | } 283 | 284 | function formatCompareBitbucket($url, $from, $to) { 285 | if (strpos($url, 'http') === false) { 286 | $url = preg_replace('/^git@(bitbucket\.[^:]+):/', 'https://$1/', $url); 287 | } 288 | $url = preg_replace('/\.git$/', '', $url); 289 | return sprintf('%s/branches/compare/%s%%0D%s', $url, urlencode($to), urlencode($from)); 290 | } 291 | 292 | function formatCompareGitlab($url, $from, $to) { 293 | if (strpos($url, 'http') === false) { 294 | $url = preg_replace('/^git@(gitlab\.[^:]+):/', 'https://$1/', $url); 295 | } 296 | $url = preg_replace('/\.git$/', '', $url); 297 | return sprintf('%s/-/compare/%s...%s', $url, urlencode($from), urlencode($to)); 298 | } 299 | 300 | function formatCompareDrupal($url, $from, $to) { 301 | // Drupalcode uses self-hosted Gitlab now 302 | return formatCompareGitlab($url, $from, $to); 303 | } 304 | 305 | // 306 | // ## VCSes #################### 307 | // 308 | 309 | function getVcses() { 310 | return array('git', 'svn'); 311 | } 312 | 313 | function vcsDetectGit($_fileish) { 314 | // Is there a git executable? 315 | exec('sh -c "git --version" > /dev/null 2>&1', $_out, $exit); 316 | if ($exit !== 0) return array(false, "'git --version' exited with non-zero code '$exit'"); 317 | 318 | // Does this look like a git repo? 319 | $path = findUp('.', '.git'); 320 | return array(!! $path, ($path) ? false : "Could not find .git in current directory or parents"); 321 | } 322 | 323 | function vcsLoadGit($fileish, $base_path, $_default_fileish) { 324 | // We don't care about $default_fileish here - we are expected to load from 325 | // git and we must make a filename to do that. 326 | if (empty($fileish)) { 327 | $fileish = 'HEAD'; 328 | } 329 | 330 | if (strpos($fileish, ':') === false) { 331 | $fileish .= ':' . $base_path . 'composer.lock'; 332 | } 333 | 334 | $lines = array(); 335 | exec('git show ' . escapeshellarg($fileish), $lines, $exit); 336 | 337 | if ($exit !== 0) { 338 | return array('', "'git show $fileish' exited with non-zero code '$exit'"); 339 | } 340 | 341 | return array(mustDecodeJson(implode("\n", $lines), $fileish), false); 342 | } 343 | 344 | function vcsDetectSvn($fileish, $base_path, $default_fileish) { 345 | // Is there a git executable? 346 | exec('sh -c "svn --version" > /dev/null 2>&1', $_out, $exit); 347 | if ($exit !== 0) return array(false, "'svn --version' exited with non-zero code '$exit'"); 348 | 349 | if (strpos($fileish, 'svn://') === 0) { 350 | return array(true, false); 351 | } 352 | 353 | // Does this look like a svn repo? 354 | $path = findUp('.', '.svn'); 355 | return array(!! $path, ($path) ? false : "Could not find .svn in current directory or parents"); 356 | } 357 | 358 | function vcsLoadSvn($fileish, $base_path, $_default_fileish) { 359 | // We don't care about $default_fileish here - we are expected to load from 360 | // svn and we must make a filename to do that. 361 | if (empty($fileish)) { 362 | $fileish = 'BASE'; 363 | } 364 | 365 | // If $fileish starts with a url scheme that 'svn cat' can handle or ^, or 366 | // if it contains a @, assume it is already a proper svn identifier. 367 | // - file:// http:// https:// svn:// svn+ssh:// => absolute url of 368 | // repository (file/http/https may have been handled with stream wrappers 369 | // if '--vcs svn' wasn't specified) 370 | // - ^ => relative url from current workspace repository 371 | // - @ => repository url with revision 372 | if (preg_match('#^\^|^(file|http|https|svn|svn\+ssh)://|@#i', $fileish) === 0) { 373 | $fileish = $base_path . 'composer.lock@'.$fileish; 374 | } 375 | 376 | exec('svn cat ' . escapeshellarg($fileish), $lines, $exit); 377 | 378 | if ($exit !== 0) { 379 | return array('', "'svn cat $fileish' exited with non-zero code '$exit'"); 380 | } 381 | 382 | return array(mustDecodeJson(implode("\n", $lines), $fileish), false); 383 | } 384 | 385 | function findUp($path, $filename, $tries = 10) { 386 | if (empty($path)) { 387 | $path = '.'; 388 | } 389 | 390 | // > Trailing delimiters, such as \ and /, are also removed 391 | // > returns false on failure, e.g. if the file does not exist. 392 | $path = realpath($path); 393 | if ($path === false) return false; 394 | 395 | do { 396 | $candidate = joinPath($path, $filename); 397 | 398 | if (file_exists($candidate)) { 399 | return $candidate; 400 | } 401 | 402 | $path = dirnameSafe($path); 403 | } while ($path !== false && --$tries > 0); 404 | 405 | return false; 406 | } 407 | 408 | function dirnameSafe($path) { 409 | $parent = dirname($path); 410 | return ($parent != $path && !empty($parent)) ? $parent : false; 411 | } 412 | 413 | function joinPath(/* path parts */) { 414 | $args = func_get_args(); 415 | $head = $args[0]; 416 | $lead = ''; 417 | 418 | if ($head[0] == DIRECTORY_SEPARATOR) { 419 | $lead = DIRECTORY_SEPARATOR; 420 | } 421 | 422 | return $lead . implode(DIRECTORY_SEPARATOR, array_map(function($part) { 423 | return trim($part, DIRECTORY_SEPARATOR); 424 | }, $args)); 425 | } 426 | 427 | function ensureTrailingPathSep($path) { 428 | return trim($path, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR; 429 | } 430 | 431 | function parseOpts() { 432 | $given = getopt('hp:', array('path:', 'from:', 'to:', 'md', 'json', 'pretty', 'no-links', 'only-prod', 'only-dev', 'help', 'vcs:')); 433 | 434 | foreach(array('help' => 'h', 'path' => 'p') as $long => $short) { 435 | if (array_key_exists($short, $given)) { 436 | $given[$long] = $given[$short]; 437 | unset($given[$short]); 438 | } 439 | } 440 | 441 | if (array_key_exists('help', $given)) { 442 | usage(); 443 | } 444 | 445 | $vcs = array_key_exists('vcs', $given) ? $given['vcs'] : ''; 446 | if ($vcs && !function_exists('vcsLoad' . ucfirst($vcs))) { 447 | error_log(sprintf("Unsupported VCS '$vcs'; supported are: '%s'\n", implode("', '", getVcses()))); 448 | usage(1); 449 | } 450 | 451 | return array( 452 | 'path' => array_key_exists('path', $given) ? ensureTrailingPathSep($given['path']) : '', 453 | 'from' => array_key_exists('from', $given) ? $given['from'] : '', 454 | 'to' => array_key_exists('to', $given) ? $given['to'] : '', 455 | 'md' => array_key_exists('md', $given), 456 | 'json' => array_key_exists('json', $given), 457 | 'pretty' => version_compare(PHP_VERSION, '5.4.0', '>=') && array_key_exists('pretty', $given), 458 | 'no-links' => array_key_exists('no-links', $given), 459 | 'only-prod' => array_key_exists('only-prod', $given), 460 | 'only-dev' => array_key_exists('only-dev', $given), 461 | 'vcs' => $vcs, 462 | ); 463 | } 464 | 465 | function usage($status = 0) { 466 | $vcses = implode(', ', getVcses()); 467 | $help = <<= 5.4.0) 479 | --md Use markdown instead of plain text 480 | --no-links Don't include Compare links in plain text or any links in markdown 481 | --only-prod Only include changes from `packages` 482 | --only-dev Only include changes from `packages-dev` 483 | --vcs Force VCS ($vcses). Default: attempt to auto-detect 484 | EOF; 485 | 486 | if ($status) { 487 | error_log($help); 488 | } else { 489 | echo $help, "\n"; 490 | } 491 | 492 | exit($status); 493 | } 494 | # vim: ff=unix ts=4 ss=4 sr et 495 | 496 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "davidrjonas/composer-lock-diff", 3 | "description": "See what has changed after a composer update.", 4 | "authors": [{ 5 | "name": "David Jonas", 6 | "homepage": "https://github.com/davidrjonas" 7 | }], 8 | "type": "library", 9 | "license": "MIT", 10 | "require": {}, 11 | "bin": ["composer-lock-diff"], 12 | "extra": { "branch-alias": { "dev-master": "1.0.x-dev" }} 13 | } 14 | -------------------------------------------------------------------------------- /test-data/composer.from.json: -------------------------------------------------------------------------------- 1 | { 2 | "repositories": [ 3 | { 4 | "type": "vcs", 5 | "url": "git@gitlab.com:pmjones/fake.git" 6 | } 7 | ], 8 | "require": { 9 | "caseysoftware/marvel-helper": "=1.1.2", 10 | "doctrine/dbal": "=2.2.0", 11 | "ircmaxell/random-lib": "=1.1.0", 12 | "ircmaxell/security-lib": "=1.0.0", 13 | "monolog/monolog": "=1.10.0", 14 | "payintegrator/afterpay": "=1.5.0", 15 | "pmjones/fake": "=0.0.1" 16 | }, 17 | "require-dev": { 18 | "mockery/mockery": "=0.9.4", 19 | "phpunit/phpunit": "=5.0.0" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /test-data/composer.from.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#installing-dependencies", 5 | "This file is @generated automatically" 6 | ], 7 | "content-hash": "9a8b77e18efe273b0980d25d75f94f13", 8 | "packages": [ 9 | { 10 | "name": "caseysoftware/marvel-helper", 11 | "version": "1.1.2", 12 | "source": { 13 | "type": "git", 14 | "url": "git@gitlab.com:CaseySoftware/marvel-php.git", 15 | "reference": "4121ea4a825bbc0fba999014432ff2f928045a3e" 16 | }, 17 | "dist": { 18 | "type": "zip", 19 | "url": "https://gitlab.com/api/v3/projects/CaseySoftware%2Fmarvel-php/repository/archive.zip?sha=4121ea4a825bbc0fba999014432ff2f928045a3e", 20 | "reference": "4121ea4a825bbc0fba999014432ff2f928045a3e", 21 | "shasum": "" 22 | }, 23 | "require": { 24 | "guzzle/guzzle": "~3.7.0", 25 | "php": ">=5.3.0" 26 | }, 27 | "require-dev": { 28 | "mockery/mockery": ">=0.7.2", 29 | "phpunit/phpunit": "3.7.*" 30 | }, 31 | "type": "library", 32 | "autoload": { 33 | "psr-4": { 34 | "Marvel\\": "src/Marvel/" 35 | } 36 | }, 37 | "notification-url": "https://packagist.org/downloads/", 38 | "license": [ 39 | "MIT" 40 | ], 41 | "authors": [ 42 | { 43 | "name": "Keith Casey", 44 | "email": "contrib@caseysoftware.com" 45 | } 46 | ], 47 | "description": "A PHP wrapper for the Marvel Comics API", 48 | "homepage": "https://github.com/caseysoftware/marvel-php", 49 | "keywords": [ 50 | "api", 51 | "avengers", 52 | "comic", 53 | "marvel", 54 | "marvel comics", 55 | "x-men" 56 | ], 57 | "time": "2015-10-16T14:45:47+00:00" 58 | }, 59 | { 60 | "name": "doctrine/common", 61 | "version": "2.2.3", 62 | "source": { 63 | "type": "git", 64 | "url": "https://github.com/doctrine/common.git", 65 | "reference": "9e13facbacb001d324d71a0f6d25d8d7f12346b6" 66 | }, 67 | "dist": { 68 | "type": "zip", 69 | "url": "https://api.github.com/repos/doctrine/common/zipball/9e13facbacb001d324d71a0f6d25d8d7f12346b6", 70 | "reference": "9e13facbacb001d324d71a0f6d25d8d7f12346b6", 71 | "shasum": "" 72 | }, 73 | "require": { 74 | "php": ">=5.3.2" 75 | }, 76 | "type": "library", 77 | "autoload": { 78 | "psr-0": { 79 | "Doctrine\\Common": "lib/" 80 | } 81 | }, 82 | "notification-url": "https://packagist.org/downloads/", 83 | "license": [ 84 | "LGPL" 85 | ], 86 | "authors": [ 87 | { 88 | "name": "Jonathan Wage", 89 | "role": "Creator", 90 | "email": "jonwage@gmail.com", 91 | "homepage": "http://www.jwage.com/" 92 | }, 93 | { 94 | "name": "Guilherme Blanco", 95 | "email": "guilhermeblanco@gmail.com", 96 | "homepage": "http://www.instaclick.com" 97 | }, 98 | { 99 | "name": "Roman Borschel", 100 | "email": "roman@code-factory.org" 101 | }, 102 | { 103 | "name": "Benjamin Eberlei", 104 | "email": "kontakt@beberlei.de" 105 | }, 106 | { 107 | "name": "Johannes Schmitt", 108 | "role": "Developer of wrapped JMSSerializerBundle", 109 | "email": "schmittjoh@gmail.com", 110 | "homepage": "https://github.com/schmittjoh" 111 | } 112 | ], 113 | "description": "Common Library for Doctrine projects", 114 | "homepage": "http://www.doctrine-project.org", 115 | "keywords": [ 116 | "annotations", 117 | "collections", 118 | "eventmanager", 119 | "persistence", 120 | "spl" 121 | ], 122 | "time": "2012-08-29T08:04:14+00:00" 123 | }, 124 | { 125 | "name": "doctrine/dbal", 126 | "version": "2.2.0", 127 | "source": { 128 | "type": "git", 129 | "url": "https://github.com/doctrine/dbal.git", 130 | "reference": "32f5d4e1bbea493d8c5828f9d951e25420182e16" 131 | }, 132 | "dist": { 133 | "type": "zip", 134 | "url": "https://api.github.com/repos/doctrine/dbal/zipball/32f5d4e1bbea493d8c5828f9d951e25420182e16", 135 | "reference": "32f5d4e1bbea493d8c5828f9d951e25420182e16", 136 | "shasum": "" 137 | }, 138 | "require": { 139 | "doctrine/common": ">=2.2.0,<=2.2.99", 140 | "php": ">=5.3.2" 141 | }, 142 | "type": "library", 143 | "autoload": { 144 | "psr-0": { 145 | "Doctrine\\DBAL": "lib/" 146 | } 147 | }, 148 | "notification-url": "https://packagist.org/downloads/", 149 | "license": [ 150 | "LGPL" 151 | ], 152 | "authors": [ 153 | { 154 | "name": "Jonathan Wage", 155 | "role": "Creator", 156 | "email": "jonwage@gmail.com", 157 | "homepage": "http://www.jwage.com/" 158 | }, 159 | { 160 | "name": "Guilherme Blanco", 161 | "email": "guilhermeblanco@gmail.com", 162 | "homepage": "http://www.instaclick.com" 163 | }, 164 | { 165 | "name": "Roman Borschel", 166 | "email": "roman@code-factory.org" 167 | }, 168 | { 169 | "name": "Benjamin Eberlei", 170 | "email": "kontakt@beberlei.de" 171 | } 172 | ], 173 | "description": "Database Abstraction Layer", 174 | "homepage": "http://www.doctrine-project.org", 175 | "keywords": [ 176 | "database", 177 | "dbal", 178 | "persistence", 179 | "queryobject" 180 | ], 181 | "time": "2012-01-29T11:19:23+00:00" 182 | }, 183 | { 184 | "name": "guzzle/guzzle", 185 | "version": "v3.7.4", 186 | "source": { 187 | "type": "git", 188 | "url": "https://github.com/guzzle/guzzle.git", 189 | "reference": "b170b028c6bb5799640e46c8803015b0f9a45ed9" 190 | }, 191 | "dist": { 192 | "type": "zip", 193 | "url": "https://api.github.com/repos/guzzle/guzzle/zipball/b170b028c6bb5799640e46c8803015b0f9a45ed9", 194 | "reference": "b170b028c6bb5799640e46c8803015b0f9a45ed9", 195 | "shasum": "" 196 | }, 197 | "require": { 198 | "ext-curl": "*", 199 | "php": ">=5.3.3", 200 | "symfony/event-dispatcher": ">=2.1" 201 | }, 202 | "replace": { 203 | "guzzle/batch": "self.version", 204 | "guzzle/cache": "self.version", 205 | "guzzle/common": "self.version", 206 | "guzzle/http": "self.version", 207 | "guzzle/inflection": "self.version", 208 | "guzzle/iterator": "self.version", 209 | "guzzle/log": "self.version", 210 | "guzzle/parser": "self.version", 211 | "guzzle/plugin": "self.version", 212 | "guzzle/plugin-async": "self.version", 213 | "guzzle/plugin-backoff": "self.version", 214 | "guzzle/plugin-cache": "self.version", 215 | "guzzle/plugin-cookie": "self.version", 216 | "guzzle/plugin-curlauth": "self.version", 217 | "guzzle/plugin-error-response": "self.version", 218 | "guzzle/plugin-history": "self.version", 219 | "guzzle/plugin-log": "self.version", 220 | "guzzle/plugin-md5": "self.version", 221 | "guzzle/plugin-mock": "self.version", 222 | "guzzle/plugin-oauth": "self.version", 223 | "guzzle/service": "self.version", 224 | "guzzle/stream": "self.version" 225 | }, 226 | "require-dev": { 227 | "doctrine/cache": "*", 228 | "monolog/monolog": "1.*", 229 | "phpunit/phpunit": "3.7.*", 230 | "psr/log": "1.0.*", 231 | "symfony/class-loader": "*", 232 | "zendframework/zend-cache": "2.0.*", 233 | "zendframework/zend-log": "2.0.*" 234 | }, 235 | "type": "library", 236 | "extra": { 237 | "branch-alias": { 238 | "dev-master": "3.7-dev" 239 | } 240 | }, 241 | "autoload": { 242 | "psr-0": { 243 | "Guzzle\\Tests": "tests/", 244 | "Guzzle": "src/" 245 | } 246 | }, 247 | "notification-url": "https://packagist.org/downloads/", 248 | "license": [ 249 | "MIT" 250 | ], 251 | "authors": [ 252 | { 253 | "name": "Michael Dowling", 254 | "email": "mtdowling@gmail.com", 255 | "homepage": "https://github.com/mtdowling" 256 | }, 257 | { 258 | "name": "Guzzle Community", 259 | "homepage": "https://github.com/guzzle/guzzle/contributors" 260 | } 261 | ], 262 | "description": "Guzzle is a PHP HTTP client library and framework for building RESTful web service clients", 263 | "homepage": "http://guzzlephp.org/", 264 | "keywords": [ 265 | "client", 266 | "curl", 267 | "framework", 268 | "http", 269 | "http client", 270 | "rest", 271 | "web service" 272 | ], 273 | "abandoned": "guzzlehttp/guzzle", 274 | "time": "2013-10-02T20:47:00+00:00" 275 | }, 276 | { 277 | "name": "guzzlehttp/guzzle", 278 | "version": "6.2.3", 279 | "source": { 280 | "type": "git", 281 | "url": "https://github.com/guzzle/guzzle.git", 282 | "reference": "8d6c6cc55186db87b7dc5009827429ba4e9dc006" 283 | }, 284 | "dist": { 285 | "type": "zip", 286 | "url": "https://api.github.com/repos/guzzle/guzzle/zipball/8d6c6cc55186db87b7dc5009827429ba4e9dc006", 287 | "reference": "8d6c6cc55186db87b7dc5009827429ba4e9dc006", 288 | "shasum": "" 289 | }, 290 | "require": { 291 | "guzzlehttp/promises": "^1.0", 292 | "guzzlehttp/psr7": "^1.4", 293 | "php": ">=5.5" 294 | }, 295 | "require-dev": { 296 | "ext-curl": "*", 297 | "phpunit/phpunit": "^4.0", 298 | "psr/log": "^1.0" 299 | }, 300 | "type": "library", 301 | "extra": { 302 | "branch-alias": { 303 | "dev-master": "6.2-dev" 304 | } 305 | }, 306 | "autoload": { 307 | "files": [ 308 | "src/functions_include.php" 309 | ], 310 | "psr-4": { 311 | "GuzzleHttp\\": "src/" 312 | } 313 | }, 314 | "notification-url": "https://packagist.org/downloads/", 315 | "license": [ 316 | "MIT" 317 | ], 318 | "authors": [ 319 | { 320 | "name": "Michael Dowling", 321 | "email": "mtdowling@gmail.com", 322 | "homepage": "https://github.com/mtdowling" 323 | } 324 | ], 325 | "description": "Guzzle is a PHP HTTP client library", 326 | "homepage": "http://guzzlephp.org/", 327 | "keywords": [ 328 | "client", 329 | "curl", 330 | "framework", 331 | "http", 332 | "http client", 333 | "rest", 334 | "web service" 335 | ], 336 | "time": "2017-02-28T22:50:30+00:00" 337 | }, 338 | { 339 | "name": "guzzlehttp/promises", 340 | "version": "v1.3.1", 341 | "source": { 342 | "type": "git", 343 | "url": "https://github.com/guzzle/promises.git", 344 | "reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646" 345 | }, 346 | "dist": { 347 | "type": "zip", 348 | "url": "https://api.github.com/repos/guzzle/promises/zipball/a59da6cf61d80060647ff4d3eb2c03a2bc694646", 349 | "reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646", 350 | "shasum": "" 351 | }, 352 | "require": { 353 | "php": ">=5.5.0" 354 | }, 355 | "require-dev": { 356 | "phpunit/phpunit": "^4.0" 357 | }, 358 | "type": "library", 359 | "extra": { 360 | "branch-alias": { 361 | "dev-master": "1.4-dev" 362 | } 363 | }, 364 | "autoload": { 365 | "psr-4": { 366 | "GuzzleHttp\\Promise\\": "src/" 367 | }, 368 | "files": [ 369 | "src/functions_include.php" 370 | ] 371 | }, 372 | "notification-url": "https://packagist.org/downloads/", 373 | "license": [ 374 | "MIT" 375 | ], 376 | "authors": [ 377 | { 378 | "name": "Michael Dowling", 379 | "email": "mtdowling@gmail.com", 380 | "homepage": "https://github.com/mtdowling" 381 | } 382 | ], 383 | "description": "Guzzle promises library", 384 | "keywords": [ 385 | "promise" 386 | ], 387 | "time": "2016-12-20T10:07:11+00:00" 388 | }, 389 | { 390 | "name": "guzzlehttp/psr7", 391 | "version": "1.6.1", 392 | "source": { 393 | "type": "git", 394 | "url": "https://github.com/guzzle/psr7.git", 395 | "reference": "239400de7a173fe9901b9ac7c06497751f00727a" 396 | }, 397 | "dist": { 398 | "type": "zip", 399 | "url": "https://api.github.com/repos/guzzle/psr7/zipball/239400de7a173fe9901b9ac7c06497751f00727a", 400 | "reference": "239400de7a173fe9901b9ac7c06497751f00727a", 401 | "shasum": "" 402 | }, 403 | "require": { 404 | "php": ">=5.4.0", 405 | "psr/http-message": "~1.0", 406 | "ralouphie/getallheaders": "^2.0.5 || ^3.0.0" 407 | }, 408 | "provide": { 409 | "psr/http-message-implementation": "1.0" 410 | }, 411 | "require-dev": { 412 | "ext-zlib": "*", 413 | "phpunit/phpunit": "~4.8.36 || ^5.7.27 || ^6.5.8" 414 | }, 415 | "suggest": { 416 | "zendframework/zend-httphandlerrunner": "Emit PSR-7 responses" 417 | }, 418 | "type": "library", 419 | "extra": { 420 | "branch-alias": { 421 | "dev-master": "1.6-dev" 422 | } 423 | }, 424 | "autoload": { 425 | "psr-4": { 426 | "GuzzleHttp\\Psr7\\": "src/" 427 | }, 428 | "files": [ 429 | "src/functions_include.php" 430 | ] 431 | }, 432 | "notification-url": "https://packagist.org/downloads/", 433 | "license": [ 434 | "MIT" 435 | ], 436 | "authors": [ 437 | { 438 | "name": "Michael Dowling", 439 | "email": "mtdowling@gmail.com", 440 | "homepage": "https://github.com/mtdowling" 441 | }, 442 | { 443 | "name": "Tobias Schultze", 444 | "homepage": "https://github.com/Tobion" 445 | } 446 | ], 447 | "description": "PSR-7 message implementation that also provides common utility methods", 448 | "keywords": [ 449 | "http", 450 | "message", 451 | "psr-7", 452 | "request", 453 | "response", 454 | "stream", 455 | "uri", 456 | "url" 457 | ], 458 | "time": "2019-07-01T23:21:34+00:00" 459 | }, 460 | { 461 | "name": "ircmaxell/random-lib", 462 | "version": "v1.1.0", 463 | "source": { 464 | "type": "git", 465 | "url": "https://github.com/ircmaxell/RandomLib.git", 466 | "reference": "13efa4368bb2ac88bb3b1459b487d907de4dbf7c" 467 | }, 468 | "dist": { 469 | "type": "zip", 470 | "url": "https://api.github.com/repos/ircmaxell/RandomLib/zipball/13efa4368bb2ac88bb3b1459b487d907de4dbf7c", 471 | "reference": "13efa4368bb2ac88bb3b1459b487d907de4dbf7c", 472 | "shasum": "" 473 | }, 474 | "require": { 475 | "ircmaxell/security-lib": "1.0.*@dev", 476 | "php": ">=5.3.2" 477 | }, 478 | "require-dev": { 479 | "mikey179/vfsstream": "1.1.*", 480 | "phpunit/phpunit": "3.7.*" 481 | }, 482 | "type": "library", 483 | "extra": { 484 | "branch-alias": { 485 | "dev-master": "1.0.x-dev" 486 | } 487 | }, 488 | "autoload": { 489 | "psr-0": { 490 | "RandomLib": "lib" 491 | } 492 | }, 493 | "notification-url": "https://packagist.org/downloads/", 494 | "license": [ 495 | "MIT" 496 | ], 497 | "authors": [ 498 | { 499 | "name": "Anthony Ferrara", 500 | "email": "ircmaxell@ircmaxell.com", 501 | "homepage": "http://blog.ircmaxell.com" 502 | } 503 | ], 504 | "description": "A Library For Generating Secure Random Numbers", 505 | "homepage": "https://github.com/ircmaxell/RandomLib", 506 | "keywords": [ 507 | "cryptography", 508 | "random", 509 | "random-numbers", 510 | "random-strings" 511 | ], 512 | "time": "2015-01-15T16:31:45+00:00" 513 | }, 514 | { 515 | "name": "ircmaxell/security-lib", 516 | "version": "1.0.0", 517 | "source": { 518 | "type": "git", 519 | "url": "https://github.com/ircmaxell/SecurityLib.git", 520 | "reference": "80934de3c482dcafb46b5756e59ebece082b6dc7" 521 | }, 522 | "dist": { 523 | "type": "zip", 524 | "url": "https://api.github.com/repos/ircmaxell/SecurityLib/zipball/80934de3c482dcafb46b5756e59ebece082b6dc7", 525 | "reference": "80934de3c482dcafb46b5756e59ebece082b6dc7", 526 | "shasum": "" 527 | }, 528 | "require": { 529 | "php": ">=5.3.2" 530 | }, 531 | "require-dev": { 532 | "mikey179/vfsstream": "1.1.*" 533 | }, 534 | "type": "library", 535 | "autoload": { 536 | "psr-0": { 537 | "SecurityLib": "lib" 538 | } 539 | }, 540 | "notification-url": "https://packagist.org/downloads/", 541 | "license": [ 542 | "MIT" 543 | ], 544 | "authors": [ 545 | { 546 | "name": "Anthony Ferrara", 547 | "email": "ircmaxell@ircmaxell.com", 548 | "homepage": "http://blog.ircmaxell.com" 549 | } 550 | ], 551 | "description": "A Base Security Library", 552 | "homepage": "https://github.com/ircmaxell/PHP-SecurityLib", 553 | "time": "2013-04-30T18:00:34+00:00" 554 | }, 555 | { 556 | "name": "monolog/monolog", 557 | "version": "1.10.0", 558 | "source": { 559 | "type": "git", 560 | "url": "https://github.com/Seldaek/monolog.git", 561 | "reference": "25b16e801979098cb2f120e697bfce454b18bf23" 562 | }, 563 | "dist": { 564 | "type": "zip", 565 | "url": "https://api.github.com/repos/Seldaek/monolog/zipball/25b16e801979098cb2f120e697bfce454b18bf23", 566 | "reference": "25b16e801979098cb2f120e697bfce454b18bf23", 567 | "shasum": "" 568 | }, 569 | "require": { 570 | "php": ">=5.3.0", 571 | "psr/log": "~1.0" 572 | }, 573 | "require-dev": { 574 | "aws/aws-sdk-php": "~2.4, >2.4.8", 575 | "doctrine/couchdb": "~1.0@dev", 576 | "graylog2/gelf-php": "~1.0", 577 | "phpunit/phpunit": "~3.7.0", 578 | "raven/raven": "~0.5", 579 | "ruflin/elastica": "0.90.*" 580 | }, 581 | "suggest": { 582 | "aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB", 583 | "doctrine/couchdb": "Allow sending log messages to a CouchDB server", 584 | "ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)", 585 | "ext-mongo": "Allow sending log messages to a MongoDB server", 586 | "graylog2/gelf-php": "Allow sending log messages to a GrayLog2 server", 587 | "raven/raven": "Allow sending log messages to a Sentry server", 588 | "rollbar/rollbar": "Allow sending log messages to Rollbar", 589 | "ruflin/elastica": "Allow sending log messages to an Elastic Search server" 590 | }, 591 | "type": "library", 592 | "extra": { 593 | "branch-alias": { 594 | "dev-master": "1.10.x-dev" 595 | } 596 | }, 597 | "autoload": { 598 | "psr-4": { 599 | "Monolog\\": "src/Monolog" 600 | } 601 | }, 602 | "notification-url": "https://packagist.org/downloads/", 603 | "license": [ 604 | "MIT" 605 | ], 606 | "authors": [ 607 | { 608 | "name": "Jordi Boggiano", 609 | "role": "Developer", 610 | "email": "j.boggiano@seld.be", 611 | "homepage": "http://seld.be" 612 | } 613 | ], 614 | "description": "Sends your logs to files, sockets, inboxes, databases and various web services", 615 | "homepage": "http://github.com/Seldaek/monolog", 616 | "keywords": [ 617 | "log", 618 | "logging", 619 | "psr-3" 620 | ], 621 | "time": "2014-06-04T16:30:04+00:00" 622 | }, 623 | { 624 | "name": "payintegrator/afterpay", 625 | "version": "1.5.0", 626 | "source": { 627 | "type": "git", 628 | "url": "https://bitbucket.org/afterpay-plugins/afterpay-composer-package.git", 629 | "reference": "4dba617c3ccf29db4ab26e8077042d532859a6f0" 630 | }, 631 | "dist": { 632 | "type": "zip", 633 | "url": "https://bitbucket.org/afterpay-plugins/afterpay-composer-package/get/4dba617c3ccf29db4ab26e8077042d532859a6f0.zip", 634 | "reference": "4dba617c3ccf29db4ab26e8077042d532859a6f0", 635 | "shasum": "" 636 | }, 637 | "require": { 638 | "ext-soap": "*", 639 | "guzzlehttp/guzzle": "6.2.3", 640 | "php": ">=5.5" 641 | }, 642 | "type": "library", 643 | "autoload": { 644 | "psr-4": { 645 | "Afterpay\\": "src/" 646 | }, 647 | "files": [ 648 | "src/functions_include.php" 649 | ] 650 | }, 651 | "notification-url": "https://packagist.org/downloads/", 652 | "license": [ 653 | "MIT" 654 | ], 655 | "authors": [ 656 | { 657 | "name": "AfterPay", 658 | "role": "Developer", 659 | "email": "support@afterpay.nl", 660 | "homepage": "https://www.afterpay.io" 661 | } 662 | ], 663 | "description": "Library for connecting to AfterPay payment services", 664 | "homepage": "https://www.afterpay.nl", 665 | "keywords": [ 666 | "afterpay", 667 | "openinvoice", 668 | "payments" 669 | ], 670 | "time": "2018-01-22T16:23:50+00:00" 671 | }, 672 | { 673 | "name": "pmjones/fake", 674 | "version": "0.0.1", 675 | "source": { 676 | "type": "git", 677 | "url": "https://gitlab.com/pmjones/fake.git", 678 | "reference": "b632a641e603694e059994237910d94238125ee5" 679 | }, 680 | "dist": { 681 | "type": "zip", 682 | "url": "https://gitlab.com/api/v4/projects/pmjones%2Ffake/repository/archive.zip?sha=b632a641e603694e059994237910d94238125ee5", 683 | "reference": "b632a641e603694e059994237910d94238125ee5", 684 | "shasum": "" 685 | }, 686 | "type": "library", 687 | "license": [ 688 | "MIT" 689 | ], 690 | "authors": [ 691 | { 692 | "name": "Paul M. Jones", 693 | "email": "pmjones88@gmail.com" 694 | } 695 | ], 696 | "description": "A fake package for testing Gitlab.", 697 | "time": "2016-03-18T16:33:49+00:00" 698 | }, 699 | { 700 | "name": "psr/http-message", 701 | "version": "1.0.1", 702 | "source": { 703 | "type": "git", 704 | "url": "https://github.com/php-fig/http-message.git", 705 | "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363" 706 | }, 707 | "dist": { 708 | "type": "zip", 709 | "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363", 710 | "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363", 711 | "shasum": "" 712 | }, 713 | "require": { 714 | "php": ">=5.3.0" 715 | }, 716 | "type": "library", 717 | "extra": { 718 | "branch-alias": { 719 | "dev-master": "1.0.x-dev" 720 | } 721 | }, 722 | "autoload": { 723 | "psr-4": { 724 | "Psr\\Http\\Message\\": "src/" 725 | } 726 | }, 727 | "notification-url": "https://packagist.org/downloads/", 728 | "license": [ 729 | "MIT" 730 | ], 731 | "authors": [ 732 | { 733 | "name": "PHP-FIG", 734 | "homepage": "http://www.php-fig.org/" 735 | } 736 | ], 737 | "description": "Common interface for HTTP messages", 738 | "homepage": "https://github.com/php-fig/http-message", 739 | "keywords": [ 740 | "http", 741 | "http-message", 742 | "psr", 743 | "psr-7", 744 | "request", 745 | "response" 746 | ], 747 | "time": "2016-08-06T14:39:51+00:00" 748 | }, 749 | { 750 | "name": "psr/log", 751 | "version": "1.1.0", 752 | "source": { 753 | "type": "git", 754 | "url": "https://github.com/php-fig/log.git", 755 | "reference": "6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd" 756 | }, 757 | "dist": { 758 | "type": "zip", 759 | "url": "https://api.github.com/repos/php-fig/log/zipball/6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd", 760 | "reference": "6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd", 761 | "shasum": "" 762 | }, 763 | "require": { 764 | "php": ">=5.3.0" 765 | }, 766 | "type": "library", 767 | "extra": { 768 | "branch-alias": { 769 | "dev-master": "1.0.x-dev" 770 | } 771 | }, 772 | "autoload": { 773 | "psr-4": { 774 | "Psr\\Log\\": "Psr/Log/" 775 | } 776 | }, 777 | "notification-url": "https://packagist.org/downloads/", 778 | "license": [ 779 | "MIT" 780 | ], 781 | "authors": [ 782 | { 783 | "name": "PHP-FIG", 784 | "homepage": "http://www.php-fig.org/" 785 | } 786 | ], 787 | "description": "Common interface for logging libraries", 788 | "homepage": "https://github.com/php-fig/log", 789 | "keywords": [ 790 | "log", 791 | "psr", 792 | "psr-3" 793 | ], 794 | "time": "2018-11-20T15:27:04+00:00" 795 | }, 796 | { 797 | "name": "ralouphie/getallheaders", 798 | "version": "3.0.3", 799 | "source": { 800 | "type": "git", 801 | "url": "https://github.com/ralouphie/getallheaders.git", 802 | "reference": "120b605dfeb996808c31b6477290a714d356e822" 803 | }, 804 | "dist": { 805 | "type": "zip", 806 | "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822", 807 | "reference": "120b605dfeb996808c31b6477290a714d356e822", 808 | "shasum": "" 809 | }, 810 | "require": { 811 | "php": ">=5.6" 812 | }, 813 | "require-dev": { 814 | "php-coveralls/php-coveralls": "^2.1", 815 | "phpunit/phpunit": "^5 || ^6.5" 816 | }, 817 | "type": "library", 818 | "autoload": { 819 | "files": [ 820 | "src/getallheaders.php" 821 | ] 822 | }, 823 | "notification-url": "https://packagist.org/downloads/", 824 | "license": [ 825 | "MIT" 826 | ], 827 | "authors": [ 828 | { 829 | "name": "Ralph Khattar", 830 | "email": "ralph.khattar@gmail.com" 831 | } 832 | ], 833 | "description": "A polyfill for getallheaders.", 834 | "time": "2019-03-08T08:55:37+00:00" 835 | }, 836 | { 837 | "name": "symfony/event-dispatcher", 838 | "version": "v4.3.3", 839 | "source": { 840 | "type": "git", 841 | "url": "https://github.com/symfony/event-dispatcher.git", 842 | "reference": "212b020949331b6531250584531363844b34a94e" 843 | }, 844 | "dist": { 845 | "type": "zip", 846 | "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/212b020949331b6531250584531363844b34a94e", 847 | "reference": "212b020949331b6531250584531363844b34a94e", 848 | "shasum": "" 849 | }, 850 | "require": { 851 | "php": "^7.1.3", 852 | "symfony/event-dispatcher-contracts": "^1.1" 853 | }, 854 | "conflict": { 855 | "symfony/dependency-injection": "<3.4" 856 | }, 857 | "provide": { 858 | "psr/event-dispatcher-implementation": "1.0", 859 | "symfony/event-dispatcher-implementation": "1.1" 860 | }, 861 | "require-dev": { 862 | "psr/log": "~1.0", 863 | "symfony/config": "~3.4|~4.0", 864 | "symfony/dependency-injection": "~3.4|~4.0", 865 | "symfony/expression-language": "~3.4|~4.0", 866 | "symfony/http-foundation": "^3.4|^4.0", 867 | "symfony/service-contracts": "^1.1", 868 | "symfony/stopwatch": "~3.4|~4.0" 869 | }, 870 | "suggest": { 871 | "symfony/dependency-injection": "", 872 | "symfony/http-kernel": "" 873 | }, 874 | "type": "library", 875 | "extra": { 876 | "branch-alias": { 877 | "dev-master": "4.3-dev" 878 | } 879 | }, 880 | "autoload": { 881 | "psr-4": { 882 | "Symfony\\Component\\EventDispatcher\\": "" 883 | }, 884 | "exclude-from-classmap": [ 885 | "/Tests/" 886 | ] 887 | }, 888 | "notification-url": "https://packagist.org/downloads/", 889 | "license": [ 890 | "MIT" 891 | ], 892 | "authors": [ 893 | { 894 | "name": "Fabien Potencier", 895 | "email": "fabien@symfony.com" 896 | }, 897 | { 898 | "name": "Symfony Community", 899 | "homepage": "https://symfony.com/contributors" 900 | } 901 | ], 902 | "description": "Symfony EventDispatcher Component", 903 | "homepage": "https://symfony.com", 904 | "time": "2019-06-27T06:42:14+00:00" 905 | }, 906 | { 907 | "name": "symfony/event-dispatcher-contracts", 908 | "version": "v1.1.5", 909 | "source": { 910 | "type": "git", 911 | "url": "https://github.com/symfony/event-dispatcher-contracts.git", 912 | "reference": "c61766f4440ca687de1084a5c00b08e167a2575c" 913 | }, 914 | "dist": { 915 | "type": "zip", 916 | "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/c61766f4440ca687de1084a5c00b08e167a2575c", 917 | "reference": "c61766f4440ca687de1084a5c00b08e167a2575c", 918 | "shasum": "" 919 | }, 920 | "require": { 921 | "php": "^7.1.3" 922 | }, 923 | "suggest": { 924 | "psr/event-dispatcher": "", 925 | "symfony/event-dispatcher-implementation": "" 926 | }, 927 | "type": "library", 928 | "extra": { 929 | "branch-alias": { 930 | "dev-master": "1.1-dev" 931 | } 932 | }, 933 | "autoload": { 934 | "psr-4": { 935 | "Symfony\\Contracts\\EventDispatcher\\": "" 936 | } 937 | }, 938 | "notification-url": "https://packagist.org/downloads/", 939 | "license": [ 940 | "MIT" 941 | ], 942 | "authors": [ 943 | { 944 | "name": "Nicolas Grekas", 945 | "email": "p@tchwork.com" 946 | }, 947 | { 948 | "name": "Symfony Community", 949 | "homepage": "https://symfony.com/contributors" 950 | } 951 | ], 952 | "description": "Generic abstractions related to dispatching event", 953 | "homepage": "https://symfony.com", 954 | "keywords": [ 955 | "abstractions", 956 | "contracts", 957 | "decoupling", 958 | "interfaces", 959 | "interoperability", 960 | "standards" 961 | ], 962 | "time": "2019-06-20T06:46:26+00:00" 963 | } 964 | ], 965 | "packages-dev": [ 966 | { 967 | "name": "doctrine/instantiator", 968 | "version": "1.2.0", 969 | "source": { 970 | "type": "git", 971 | "url": "https://github.com/doctrine/instantiator.git", 972 | "reference": "a2c590166b2133a4633738648b6b064edae0814a" 973 | }, 974 | "dist": { 975 | "type": "zip", 976 | "url": "https://api.github.com/repos/doctrine/instantiator/zipball/a2c590166b2133a4633738648b6b064edae0814a", 977 | "reference": "a2c590166b2133a4633738648b6b064edae0814a", 978 | "shasum": "" 979 | }, 980 | "require": { 981 | "php": "^7.1" 982 | }, 983 | "require-dev": { 984 | "doctrine/coding-standard": "^6.0", 985 | "ext-pdo": "*", 986 | "ext-phar": "*", 987 | "phpbench/phpbench": "^0.13", 988 | "phpstan/phpstan-phpunit": "^0.11", 989 | "phpstan/phpstan-shim": "^0.11", 990 | "phpunit/phpunit": "^7.0" 991 | }, 992 | "type": "library", 993 | "extra": { 994 | "branch-alias": { 995 | "dev-master": "1.2.x-dev" 996 | } 997 | }, 998 | "autoload": { 999 | "psr-4": { 1000 | "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" 1001 | } 1002 | }, 1003 | "notification-url": "https://packagist.org/downloads/", 1004 | "license": [ 1005 | "MIT" 1006 | ], 1007 | "authors": [ 1008 | { 1009 | "name": "Marco Pivetta", 1010 | "email": "ocramius@gmail.com", 1011 | "homepage": "http://ocramius.github.com/" 1012 | } 1013 | ], 1014 | "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", 1015 | "homepage": "https://www.doctrine-project.org/projects/instantiator.html", 1016 | "keywords": [ 1017 | "constructor", 1018 | "instantiate" 1019 | ], 1020 | "time": "2019-03-17T17:37:11+00:00" 1021 | }, 1022 | { 1023 | "name": "hamcrest/hamcrest-php", 1024 | "version": "v1.2.2", 1025 | "source": { 1026 | "type": "git", 1027 | "url": "https://github.com/hamcrest/hamcrest-php.git", 1028 | "reference": "b37020aa976fa52d3de9aa904aa2522dc518f79c" 1029 | }, 1030 | "dist": { 1031 | "type": "zip", 1032 | "url": "https://api.github.com/repos/hamcrest/hamcrest-php/zipball/b37020aa976fa52d3de9aa904aa2522dc518f79c", 1033 | "reference": "b37020aa976fa52d3de9aa904aa2522dc518f79c", 1034 | "shasum": "" 1035 | }, 1036 | "require": { 1037 | "php": ">=5.3.2" 1038 | }, 1039 | "replace": { 1040 | "cordoval/hamcrest-php": "*", 1041 | "davedevelopment/hamcrest-php": "*", 1042 | "kodova/hamcrest-php": "*" 1043 | }, 1044 | "require-dev": { 1045 | "phpunit/php-file-iterator": "1.3.3", 1046 | "satooshi/php-coveralls": "dev-master" 1047 | }, 1048 | "type": "library", 1049 | "autoload": { 1050 | "classmap": [ 1051 | "hamcrest" 1052 | ], 1053 | "files": [ 1054 | "hamcrest/Hamcrest.php" 1055 | ] 1056 | }, 1057 | "notification-url": "https://packagist.org/downloads/", 1058 | "license": [ 1059 | "BSD" 1060 | ], 1061 | "description": "This is the PHP port of Hamcrest Matchers", 1062 | "keywords": [ 1063 | "test" 1064 | ], 1065 | "time": "2015-05-11T14:41:42+00:00" 1066 | }, 1067 | { 1068 | "name": "mockery/mockery", 1069 | "version": "0.9.4", 1070 | "source": { 1071 | "type": "git", 1072 | "url": "https://github.com/mockery/mockery.git", 1073 | "reference": "70bba85e4aabc9449626651f48b9018ede04f86b" 1074 | }, 1075 | "dist": { 1076 | "type": "zip", 1077 | "url": "https://api.github.com/repos/mockery/mockery/zipball/70bba85e4aabc9449626651f48b9018ede04f86b", 1078 | "reference": "70bba85e4aabc9449626651f48b9018ede04f86b", 1079 | "shasum": "" 1080 | }, 1081 | "require": { 1082 | "hamcrest/hamcrest-php": "~1.1", 1083 | "lib-pcre": ">=7.0", 1084 | "php": ">=5.3.2" 1085 | }, 1086 | "require-dev": { 1087 | "phpunit/phpunit": "~4.0" 1088 | }, 1089 | "type": "library", 1090 | "extra": { 1091 | "branch-alias": { 1092 | "dev-master": "0.9.x-dev" 1093 | } 1094 | }, 1095 | "autoload": { 1096 | "psr-0": { 1097 | "Mockery": "library/" 1098 | } 1099 | }, 1100 | "notification-url": "https://packagist.org/downloads/", 1101 | "license": [ 1102 | "BSD-3-Clause" 1103 | ], 1104 | "authors": [ 1105 | { 1106 | "name": "Pádraic Brady", 1107 | "email": "padraic.brady@gmail.com", 1108 | "homepage": "http://blog.astrumfutura.com" 1109 | }, 1110 | { 1111 | "name": "Dave Marshall", 1112 | "email": "dave.marshall@atstsolutions.co.uk", 1113 | "homepage": "http://davedevelopment.co.uk" 1114 | } 1115 | ], 1116 | "description": "Mockery is a simple yet flexible PHP mock object framework for use in unit testing with PHPUnit, PHPSpec or any other testing framework. Its core goal is to offer a test double framework with a succinct API capable of clearly defining all possible object operations and interactions using a human readable Domain Specific Language (DSL). Designed as a drop in alternative to PHPUnit's phpunit-mock-objects library, Mockery is easy to integrate with PHPUnit and can operate alongside phpunit-mock-objects without the World ending.", 1117 | "homepage": "http://github.com/padraic/mockery", 1118 | "keywords": [ 1119 | "BDD", 1120 | "TDD", 1121 | "library", 1122 | "mock", 1123 | "mock objects", 1124 | "mockery", 1125 | "stub", 1126 | "test", 1127 | "test double", 1128 | "testing" 1129 | ], 1130 | "time": "2015-04-02T19:54:00+00:00" 1131 | }, 1132 | { 1133 | "name": "myclabs/deep-copy", 1134 | "version": "1.9.1", 1135 | "source": { 1136 | "type": "git", 1137 | "url": "https://github.com/myclabs/DeepCopy.git", 1138 | "reference": "e6828efaba2c9b79f4499dae1d66ef8bfa7b2b72" 1139 | }, 1140 | "dist": { 1141 | "type": "zip", 1142 | "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/e6828efaba2c9b79f4499dae1d66ef8bfa7b2b72", 1143 | "reference": "e6828efaba2c9b79f4499dae1d66ef8bfa7b2b72", 1144 | "shasum": "" 1145 | }, 1146 | "require": { 1147 | "php": "^7.1" 1148 | }, 1149 | "replace": { 1150 | "myclabs/deep-copy": "self.version" 1151 | }, 1152 | "require-dev": { 1153 | "doctrine/collections": "^1.0", 1154 | "doctrine/common": "^2.6", 1155 | "phpunit/phpunit": "^7.1" 1156 | }, 1157 | "type": "library", 1158 | "autoload": { 1159 | "psr-4": { 1160 | "DeepCopy\\": "src/DeepCopy/" 1161 | }, 1162 | "files": [ 1163 | "src/DeepCopy/deep_copy.php" 1164 | ] 1165 | }, 1166 | "notification-url": "https://packagist.org/downloads/", 1167 | "license": [ 1168 | "MIT" 1169 | ], 1170 | "description": "Create deep copies (clones) of your objects", 1171 | "keywords": [ 1172 | "clone", 1173 | "copy", 1174 | "duplicate", 1175 | "object", 1176 | "object graph" 1177 | ], 1178 | "time": "2019-04-07T13:18:21+00:00" 1179 | }, 1180 | { 1181 | "name": "phpdocumentor/reflection-common", 1182 | "version": "1.0.1", 1183 | "source": { 1184 | "type": "git", 1185 | "url": "https://github.com/phpDocumentor/ReflectionCommon.git", 1186 | "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6" 1187 | }, 1188 | "dist": { 1189 | "type": "zip", 1190 | "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", 1191 | "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", 1192 | "shasum": "" 1193 | }, 1194 | "require": { 1195 | "php": ">=5.5" 1196 | }, 1197 | "require-dev": { 1198 | "phpunit/phpunit": "^4.6" 1199 | }, 1200 | "type": "library", 1201 | "extra": { 1202 | "branch-alias": { 1203 | "dev-master": "1.0.x-dev" 1204 | } 1205 | }, 1206 | "autoload": { 1207 | "psr-4": { 1208 | "phpDocumentor\\Reflection\\": [ 1209 | "src" 1210 | ] 1211 | } 1212 | }, 1213 | "notification-url": "https://packagist.org/downloads/", 1214 | "license": [ 1215 | "MIT" 1216 | ], 1217 | "authors": [ 1218 | { 1219 | "name": "Jaap van Otterdijk", 1220 | "email": "opensource@ijaap.nl" 1221 | } 1222 | ], 1223 | "description": "Common reflection classes used by phpdocumentor to reflect the code structure", 1224 | "homepage": "http://www.phpdoc.org", 1225 | "keywords": [ 1226 | "FQSEN", 1227 | "phpDocumentor", 1228 | "phpdoc", 1229 | "reflection", 1230 | "static analysis" 1231 | ], 1232 | "time": "2017-09-11T18:02:19+00:00" 1233 | }, 1234 | { 1235 | "name": "phpdocumentor/reflection-docblock", 1236 | "version": "4.3.1", 1237 | "source": { 1238 | "type": "git", 1239 | "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", 1240 | "reference": "bdd9f737ebc2a01c06ea7ff4308ec6697db9b53c" 1241 | }, 1242 | "dist": { 1243 | "type": "zip", 1244 | "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/bdd9f737ebc2a01c06ea7ff4308ec6697db9b53c", 1245 | "reference": "bdd9f737ebc2a01c06ea7ff4308ec6697db9b53c", 1246 | "shasum": "" 1247 | }, 1248 | "require": { 1249 | "php": "^7.0", 1250 | "phpdocumentor/reflection-common": "^1.0.0", 1251 | "phpdocumentor/type-resolver": "^0.4.0", 1252 | "webmozart/assert": "^1.0" 1253 | }, 1254 | "require-dev": { 1255 | "doctrine/instantiator": "~1.0.5", 1256 | "mockery/mockery": "^1.0", 1257 | "phpunit/phpunit": "^6.4" 1258 | }, 1259 | "type": "library", 1260 | "extra": { 1261 | "branch-alias": { 1262 | "dev-master": "4.x-dev" 1263 | } 1264 | }, 1265 | "autoload": { 1266 | "psr-4": { 1267 | "phpDocumentor\\Reflection\\": [ 1268 | "src/" 1269 | ] 1270 | } 1271 | }, 1272 | "notification-url": "https://packagist.org/downloads/", 1273 | "license": [ 1274 | "MIT" 1275 | ], 1276 | "authors": [ 1277 | { 1278 | "name": "Mike van Riel", 1279 | "email": "me@mikevanriel.com" 1280 | } 1281 | ], 1282 | "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", 1283 | "time": "2019-04-30T17:48:53+00:00" 1284 | }, 1285 | { 1286 | "name": "phpdocumentor/type-resolver", 1287 | "version": "0.4.0", 1288 | "source": { 1289 | "type": "git", 1290 | "url": "https://github.com/phpDocumentor/TypeResolver.git", 1291 | "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7" 1292 | }, 1293 | "dist": { 1294 | "type": "zip", 1295 | "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/9c977708995954784726e25d0cd1dddf4e65b0f7", 1296 | "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7", 1297 | "shasum": "" 1298 | }, 1299 | "require": { 1300 | "php": "^5.5 || ^7.0", 1301 | "phpdocumentor/reflection-common": "^1.0" 1302 | }, 1303 | "require-dev": { 1304 | "mockery/mockery": "^0.9.4", 1305 | "phpunit/phpunit": "^5.2||^4.8.24" 1306 | }, 1307 | "type": "library", 1308 | "extra": { 1309 | "branch-alias": { 1310 | "dev-master": "1.0.x-dev" 1311 | } 1312 | }, 1313 | "autoload": { 1314 | "psr-4": { 1315 | "phpDocumentor\\Reflection\\": [ 1316 | "src/" 1317 | ] 1318 | } 1319 | }, 1320 | "notification-url": "https://packagist.org/downloads/", 1321 | "license": [ 1322 | "MIT" 1323 | ], 1324 | "authors": [ 1325 | { 1326 | "name": "Mike van Riel", 1327 | "email": "me@mikevanriel.com" 1328 | } 1329 | ], 1330 | "time": "2017-07-14T14:27:02+00:00" 1331 | }, 1332 | { 1333 | "name": "phpspec/prophecy", 1334 | "version": "1.8.1", 1335 | "source": { 1336 | "type": "git", 1337 | "url": "https://github.com/phpspec/prophecy.git", 1338 | "reference": "1927e75f4ed19131ec9bcc3b002e07fb1173ee76" 1339 | }, 1340 | "dist": { 1341 | "type": "zip", 1342 | "url": "https://api.github.com/repos/phpspec/prophecy/zipball/1927e75f4ed19131ec9bcc3b002e07fb1173ee76", 1343 | "reference": "1927e75f4ed19131ec9bcc3b002e07fb1173ee76", 1344 | "shasum": "" 1345 | }, 1346 | "require": { 1347 | "doctrine/instantiator": "^1.0.2", 1348 | "php": "^5.3|^7.0", 1349 | "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0", 1350 | "sebastian/comparator": "^1.1|^2.0|^3.0", 1351 | "sebastian/recursion-context": "^1.0|^2.0|^3.0" 1352 | }, 1353 | "require-dev": { 1354 | "phpspec/phpspec": "^2.5|^3.2", 1355 | "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5 || ^7.1" 1356 | }, 1357 | "type": "library", 1358 | "extra": { 1359 | "branch-alias": { 1360 | "dev-master": "1.8.x-dev" 1361 | } 1362 | }, 1363 | "autoload": { 1364 | "psr-4": { 1365 | "Prophecy\\": "src/Prophecy" 1366 | } 1367 | }, 1368 | "notification-url": "https://packagist.org/downloads/", 1369 | "license": [ 1370 | "MIT" 1371 | ], 1372 | "authors": [ 1373 | { 1374 | "name": "Konstantin Kudryashov", 1375 | "email": "ever.zet@gmail.com", 1376 | "homepage": "http://everzet.com" 1377 | }, 1378 | { 1379 | "name": "Marcello Duarte", 1380 | "email": "marcello.duarte@gmail.com" 1381 | } 1382 | ], 1383 | "description": "Highly opinionated mocking framework for PHP 5.3+", 1384 | "homepage": "https://github.com/phpspec/prophecy", 1385 | "keywords": [ 1386 | "Double", 1387 | "Dummy", 1388 | "fake", 1389 | "mock", 1390 | "spy", 1391 | "stub" 1392 | ], 1393 | "time": "2019-06-13T12:50:23+00:00" 1394 | }, 1395 | { 1396 | "name": "phpunit/php-code-coverage", 1397 | "version": "3.3.3", 1398 | "source": { 1399 | "type": "git", 1400 | "url": "https://github.com/sebastianbergmann/php-code-coverage.git", 1401 | "reference": "44cd8e3930e431658d1a5de7d282d5cb37837fd5" 1402 | }, 1403 | "dist": { 1404 | "type": "zip", 1405 | "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/44cd8e3930e431658d1a5de7d282d5cb37837fd5", 1406 | "reference": "44cd8e3930e431658d1a5de7d282d5cb37837fd5", 1407 | "shasum": "" 1408 | }, 1409 | "require": { 1410 | "php": "^5.6 || ^7.0", 1411 | "phpunit/php-file-iterator": "~1.3", 1412 | "phpunit/php-text-template": "~1.2", 1413 | "phpunit/php-token-stream": "^1.4.2", 1414 | "sebastian/code-unit-reverse-lookup": "~1.0", 1415 | "sebastian/environment": "^1.3.2", 1416 | "sebastian/version": "~1.0|~2.0" 1417 | }, 1418 | "require-dev": { 1419 | "ext-xdebug": ">=2.1.4", 1420 | "phpunit/phpunit": "~5" 1421 | }, 1422 | "suggest": { 1423 | "ext-dom": "*", 1424 | "ext-xdebug": ">=2.4.0", 1425 | "ext-xmlwriter": "*" 1426 | }, 1427 | "type": "library", 1428 | "extra": { 1429 | "branch-alias": { 1430 | "dev-master": "3.3.x-dev" 1431 | } 1432 | }, 1433 | "autoload": { 1434 | "classmap": [ 1435 | "src/" 1436 | ] 1437 | }, 1438 | "notification-url": "https://packagist.org/downloads/", 1439 | "license": [ 1440 | "BSD-3-Clause" 1441 | ], 1442 | "authors": [ 1443 | { 1444 | "name": "Sebastian Bergmann", 1445 | "role": "lead", 1446 | "email": "sb@sebastian-bergmann.de" 1447 | } 1448 | ], 1449 | "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", 1450 | "homepage": "https://github.com/sebastianbergmann/php-code-coverage", 1451 | "keywords": [ 1452 | "coverage", 1453 | "testing", 1454 | "xunit" 1455 | ], 1456 | "time": "2016-05-27T16:24:29+00:00" 1457 | }, 1458 | { 1459 | "name": "phpunit/php-file-iterator", 1460 | "version": "1.4.5", 1461 | "source": { 1462 | "type": "git", 1463 | "url": "https://github.com/sebastianbergmann/php-file-iterator.git", 1464 | "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4" 1465 | }, 1466 | "dist": { 1467 | "type": "zip", 1468 | "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/730b01bc3e867237eaac355e06a36b85dd93a8b4", 1469 | "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4", 1470 | "shasum": "" 1471 | }, 1472 | "require": { 1473 | "php": ">=5.3.3" 1474 | }, 1475 | "type": "library", 1476 | "extra": { 1477 | "branch-alias": { 1478 | "dev-master": "1.4.x-dev" 1479 | } 1480 | }, 1481 | "autoload": { 1482 | "classmap": [ 1483 | "src/" 1484 | ] 1485 | }, 1486 | "notification-url": "https://packagist.org/downloads/", 1487 | "license": [ 1488 | "BSD-3-Clause" 1489 | ], 1490 | "authors": [ 1491 | { 1492 | "name": "Sebastian Bergmann", 1493 | "role": "lead", 1494 | "email": "sb@sebastian-bergmann.de" 1495 | } 1496 | ], 1497 | "description": "FilterIterator implementation that filters files based on a list of suffixes.", 1498 | "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", 1499 | "keywords": [ 1500 | "filesystem", 1501 | "iterator" 1502 | ], 1503 | "time": "2017-11-27T13:52:08+00:00" 1504 | }, 1505 | { 1506 | "name": "phpunit/php-text-template", 1507 | "version": "1.2.1", 1508 | "source": { 1509 | "type": "git", 1510 | "url": "https://github.com/sebastianbergmann/php-text-template.git", 1511 | "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686" 1512 | }, 1513 | "dist": { 1514 | "type": "zip", 1515 | "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686", 1516 | "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686", 1517 | "shasum": "" 1518 | }, 1519 | "require": { 1520 | "php": ">=5.3.3" 1521 | }, 1522 | "type": "library", 1523 | "autoload": { 1524 | "classmap": [ 1525 | "src/" 1526 | ] 1527 | }, 1528 | "notification-url": "https://packagist.org/downloads/", 1529 | "license": [ 1530 | "BSD-3-Clause" 1531 | ], 1532 | "authors": [ 1533 | { 1534 | "name": "Sebastian Bergmann", 1535 | "role": "lead", 1536 | "email": "sebastian@phpunit.de" 1537 | } 1538 | ], 1539 | "description": "Simple template engine.", 1540 | "homepage": "https://github.com/sebastianbergmann/php-text-template/", 1541 | "keywords": [ 1542 | "template" 1543 | ], 1544 | "time": "2015-06-21T13:50:34+00:00" 1545 | }, 1546 | { 1547 | "name": "phpunit/php-timer", 1548 | "version": "2.1.2", 1549 | "source": { 1550 | "type": "git", 1551 | "url": "https://github.com/sebastianbergmann/php-timer.git", 1552 | "reference": "1038454804406b0b5f5f520358e78c1c2f71501e" 1553 | }, 1554 | "dist": { 1555 | "type": "zip", 1556 | "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/1038454804406b0b5f5f520358e78c1c2f71501e", 1557 | "reference": "1038454804406b0b5f5f520358e78c1c2f71501e", 1558 | "shasum": "" 1559 | }, 1560 | "require": { 1561 | "php": "^7.1" 1562 | }, 1563 | "require-dev": { 1564 | "phpunit/phpunit": "^7.0" 1565 | }, 1566 | "type": "library", 1567 | "extra": { 1568 | "branch-alias": { 1569 | "dev-master": "2.1-dev" 1570 | } 1571 | }, 1572 | "autoload": { 1573 | "classmap": [ 1574 | "src/" 1575 | ] 1576 | }, 1577 | "notification-url": "https://packagist.org/downloads/", 1578 | "license": [ 1579 | "BSD-3-Clause" 1580 | ], 1581 | "authors": [ 1582 | { 1583 | "name": "Sebastian Bergmann", 1584 | "role": "lead", 1585 | "email": "sebastian@phpunit.de" 1586 | } 1587 | ], 1588 | "description": "Utility class for timing", 1589 | "homepage": "https://github.com/sebastianbergmann/php-timer/", 1590 | "keywords": [ 1591 | "timer" 1592 | ], 1593 | "time": "2019-06-07T04:22:29+00:00" 1594 | }, 1595 | { 1596 | "name": "phpunit/php-token-stream", 1597 | "version": "1.4.12", 1598 | "source": { 1599 | "type": "git", 1600 | "url": "https://github.com/sebastianbergmann/php-token-stream.git", 1601 | "reference": "1ce90ba27c42e4e44e6d8458241466380b51fa16" 1602 | }, 1603 | "dist": { 1604 | "type": "zip", 1605 | "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/1ce90ba27c42e4e44e6d8458241466380b51fa16", 1606 | "reference": "1ce90ba27c42e4e44e6d8458241466380b51fa16", 1607 | "shasum": "" 1608 | }, 1609 | "require": { 1610 | "ext-tokenizer": "*", 1611 | "php": ">=5.3.3" 1612 | }, 1613 | "require-dev": { 1614 | "phpunit/phpunit": "~4.2" 1615 | }, 1616 | "type": "library", 1617 | "extra": { 1618 | "branch-alias": { 1619 | "dev-master": "1.4-dev" 1620 | } 1621 | }, 1622 | "autoload": { 1623 | "classmap": [ 1624 | "src/" 1625 | ] 1626 | }, 1627 | "notification-url": "https://packagist.org/downloads/", 1628 | "license": [ 1629 | "BSD-3-Clause" 1630 | ], 1631 | "authors": [ 1632 | { 1633 | "name": "Sebastian Bergmann", 1634 | "email": "sebastian@phpunit.de" 1635 | } 1636 | ], 1637 | "description": "Wrapper around PHP's tokenizer extension.", 1638 | "homepage": "https://github.com/sebastianbergmann/php-token-stream/", 1639 | "keywords": [ 1640 | "tokenizer" 1641 | ], 1642 | "time": "2017-12-04T08:55:13+00:00" 1643 | }, 1644 | { 1645 | "name": "phpunit/phpunit", 1646 | "version": "5.0.0", 1647 | "source": { 1648 | "type": "git", 1649 | "url": "https://github.com/sebastianbergmann/phpunit.git", 1650 | "reference": "49f1c93ee37d10ffba6ce287d67110547b40b1d7" 1651 | }, 1652 | "dist": { 1653 | "type": "zip", 1654 | "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/49f1c93ee37d10ffba6ce287d67110547b40b1d7", 1655 | "reference": "49f1c93ee37d10ffba6ce287d67110547b40b1d7", 1656 | "shasum": "" 1657 | }, 1658 | "require": { 1659 | "ext-dom": "*", 1660 | "ext-json": "*", 1661 | "ext-pcre": "*", 1662 | "ext-reflection": "*", 1663 | "ext-spl": "*", 1664 | "myclabs/deep-copy": "~1.3", 1665 | "php": ">=5.6", 1666 | "phpspec/prophecy": "^1.3.1", 1667 | "phpunit/php-code-coverage": "~3.0", 1668 | "phpunit/php-file-iterator": "~1.4", 1669 | "phpunit/php-text-template": "~1.2", 1670 | "phpunit/php-timer": ">=1.0.6", 1671 | "phpunit/phpunit-mock-objects": ">=3.0", 1672 | "sebastian/comparator": "~1.1", 1673 | "sebastian/diff": "~1.2", 1674 | "sebastian/environment": "~1.3", 1675 | "sebastian/exporter": "~1.2", 1676 | "sebastian/global-state": "~1.0", 1677 | "sebastian/resource-operations": "~1.0", 1678 | "sebastian/version": "~1.0", 1679 | "symfony/yaml": "~2.1|~3.0" 1680 | }, 1681 | "suggest": { 1682 | "phpunit/php-invoker": "~1.1" 1683 | }, 1684 | "bin": [ 1685 | "phpunit" 1686 | ], 1687 | "type": "library", 1688 | "extra": { 1689 | "branch-alias": { 1690 | "dev-master": "5.0.x-dev" 1691 | } 1692 | }, 1693 | "autoload": { 1694 | "classmap": [ 1695 | "src/" 1696 | ] 1697 | }, 1698 | "notification-url": "https://packagist.org/downloads/", 1699 | "license": [ 1700 | "BSD-3-Clause" 1701 | ], 1702 | "authors": [ 1703 | { 1704 | "name": "Sebastian Bergmann", 1705 | "role": "lead", 1706 | "email": "sebastian@phpunit.de" 1707 | } 1708 | ], 1709 | "description": "The PHP Unit Testing framework.", 1710 | "homepage": "https://phpunit.de/", 1711 | "keywords": [ 1712 | "phpunit", 1713 | "testing", 1714 | "xunit" 1715 | ], 1716 | "time": "2015-10-02T03:16:10+00:00" 1717 | }, 1718 | { 1719 | "name": "phpunit/phpunit-mock-objects", 1720 | "version": "3.1.3", 1721 | "source": { 1722 | "type": "git", 1723 | "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", 1724 | "reference": "151c96874bff6fe61a25039df60e776613a61489" 1725 | }, 1726 | "dist": { 1727 | "type": "zip", 1728 | "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/151c96874bff6fe61a25039df60e776613a61489", 1729 | "reference": "151c96874bff6fe61a25039df60e776613a61489", 1730 | "shasum": "" 1731 | }, 1732 | "require": { 1733 | "doctrine/instantiator": "^1.0.2", 1734 | "php": ">=5.6", 1735 | "phpunit/php-text-template": "~1.2", 1736 | "sebastian/exporter": "~1.2" 1737 | }, 1738 | "require-dev": { 1739 | "phpunit/phpunit": "~5" 1740 | }, 1741 | "suggest": { 1742 | "ext-soap": "*" 1743 | }, 1744 | "type": "library", 1745 | "extra": { 1746 | "branch-alias": { 1747 | "dev-master": "3.1.x-dev" 1748 | } 1749 | }, 1750 | "autoload": { 1751 | "classmap": [ 1752 | "src/" 1753 | ] 1754 | }, 1755 | "notification-url": "https://packagist.org/downloads/", 1756 | "license": [ 1757 | "BSD-3-Clause" 1758 | ], 1759 | "authors": [ 1760 | { 1761 | "name": "Sebastian Bergmann", 1762 | "email": "sb@sebastian-bergmann.de", 1763 | "role": "lead" 1764 | } 1765 | ], 1766 | "description": "Mock Object library for PHPUnit", 1767 | "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/", 1768 | "keywords": [ 1769 | "mock", 1770 | "xunit" 1771 | ], 1772 | "abandoned": true, 1773 | "time": "2016-04-20T14:39:26+00:00" 1774 | }, 1775 | { 1776 | "name": "sebastian/code-unit-reverse-lookup", 1777 | "version": "1.0.1", 1778 | "source": { 1779 | "type": "git", 1780 | "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", 1781 | "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18" 1782 | }, 1783 | "dist": { 1784 | "type": "zip", 1785 | "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", 1786 | "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", 1787 | "shasum": "" 1788 | }, 1789 | "require": { 1790 | "php": "^5.6 || ^7.0" 1791 | }, 1792 | "require-dev": { 1793 | "phpunit/phpunit": "^5.7 || ^6.0" 1794 | }, 1795 | "type": "library", 1796 | "extra": { 1797 | "branch-alias": { 1798 | "dev-master": "1.0.x-dev" 1799 | } 1800 | }, 1801 | "autoload": { 1802 | "classmap": [ 1803 | "src/" 1804 | ] 1805 | }, 1806 | "notification-url": "https://packagist.org/downloads/", 1807 | "license": [ 1808 | "BSD-3-Clause" 1809 | ], 1810 | "authors": [ 1811 | { 1812 | "name": "Sebastian Bergmann", 1813 | "email": "sebastian@phpunit.de" 1814 | } 1815 | ], 1816 | "description": "Looks up which function or method a line of code belongs to", 1817 | "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", 1818 | "time": "2017-03-04T06:30:41+00:00" 1819 | }, 1820 | { 1821 | "name": "sebastian/comparator", 1822 | "version": "1.2.4", 1823 | "source": { 1824 | "type": "git", 1825 | "url": "https://github.com/sebastianbergmann/comparator.git", 1826 | "reference": "2b7424b55f5047b47ac6e5ccb20b2aea4011d9be" 1827 | }, 1828 | "dist": { 1829 | "type": "zip", 1830 | "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/2b7424b55f5047b47ac6e5ccb20b2aea4011d9be", 1831 | "reference": "2b7424b55f5047b47ac6e5ccb20b2aea4011d9be", 1832 | "shasum": "" 1833 | }, 1834 | "require": { 1835 | "php": ">=5.3.3", 1836 | "sebastian/diff": "~1.2", 1837 | "sebastian/exporter": "~1.2 || ~2.0" 1838 | }, 1839 | "require-dev": { 1840 | "phpunit/phpunit": "~4.4" 1841 | }, 1842 | "type": "library", 1843 | "extra": { 1844 | "branch-alias": { 1845 | "dev-master": "1.2.x-dev" 1846 | } 1847 | }, 1848 | "autoload": { 1849 | "classmap": [ 1850 | "src/" 1851 | ] 1852 | }, 1853 | "notification-url": "https://packagist.org/downloads/", 1854 | "license": [ 1855 | "BSD-3-Clause" 1856 | ], 1857 | "authors": [ 1858 | { 1859 | "name": "Jeff Welch", 1860 | "email": "whatthejeff@gmail.com" 1861 | }, 1862 | { 1863 | "name": "Volker Dusch", 1864 | "email": "github@wallbash.com" 1865 | }, 1866 | { 1867 | "name": "Bernhard Schussek", 1868 | "email": "bschussek@2bepublished.at" 1869 | }, 1870 | { 1871 | "name": "Sebastian Bergmann", 1872 | "email": "sebastian@phpunit.de" 1873 | } 1874 | ], 1875 | "description": "Provides the functionality to compare PHP values for equality", 1876 | "homepage": "http://www.github.com/sebastianbergmann/comparator", 1877 | "keywords": [ 1878 | "comparator", 1879 | "compare", 1880 | "equality" 1881 | ], 1882 | "time": "2017-01-29T09:50:25+00:00" 1883 | }, 1884 | { 1885 | "name": "sebastian/diff", 1886 | "version": "1.4.3", 1887 | "source": { 1888 | "type": "git", 1889 | "url": "https://github.com/sebastianbergmann/diff.git", 1890 | "reference": "7f066a26a962dbe58ddea9f72a4e82874a3975a4" 1891 | }, 1892 | "dist": { 1893 | "type": "zip", 1894 | "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/7f066a26a962dbe58ddea9f72a4e82874a3975a4", 1895 | "reference": "7f066a26a962dbe58ddea9f72a4e82874a3975a4", 1896 | "shasum": "" 1897 | }, 1898 | "require": { 1899 | "php": "^5.3.3 || ^7.0" 1900 | }, 1901 | "require-dev": { 1902 | "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0" 1903 | }, 1904 | "type": "library", 1905 | "extra": { 1906 | "branch-alias": { 1907 | "dev-master": "1.4-dev" 1908 | } 1909 | }, 1910 | "autoload": { 1911 | "classmap": [ 1912 | "src/" 1913 | ] 1914 | }, 1915 | "notification-url": "https://packagist.org/downloads/", 1916 | "license": [ 1917 | "BSD-3-Clause" 1918 | ], 1919 | "authors": [ 1920 | { 1921 | "name": "Kore Nordmann", 1922 | "email": "mail@kore-nordmann.de" 1923 | }, 1924 | { 1925 | "name": "Sebastian Bergmann", 1926 | "email": "sebastian@phpunit.de" 1927 | } 1928 | ], 1929 | "description": "Diff implementation", 1930 | "homepage": "https://github.com/sebastianbergmann/diff", 1931 | "keywords": [ 1932 | "diff" 1933 | ], 1934 | "time": "2017-05-22T07:24:03+00:00" 1935 | }, 1936 | { 1937 | "name": "sebastian/environment", 1938 | "version": "1.3.8", 1939 | "source": { 1940 | "type": "git", 1941 | "url": "https://github.com/sebastianbergmann/environment.git", 1942 | "reference": "be2c607e43ce4c89ecd60e75c6a85c126e754aea" 1943 | }, 1944 | "dist": { 1945 | "type": "zip", 1946 | "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/be2c607e43ce4c89ecd60e75c6a85c126e754aea", 1947 | "reference": "be2c607e43ce4c89ecd60e75c6a85c126e754aea", 1948 | "shasum": "" 1949 | }, 1950 | "require": { 1951 | "php": "^5.3.3 || ^7.0" 1952 | }, 1953 | "require-dev": { 1954 | "phpunit/phpunit": "^4.8 || ^5.0" 1955 | }, 1956 | "type": "library", 1957 | "extra": { 1958 | "branch-alias": { 1959 | "dev-master": "1.3.x-dev" 1960 | } 1961 | }, 1962 | "autoload": { 1963 | "classmap": [ 1964 | "src/" 1965 | ] 1966 | }, 1967 | "notification-url": "https://packagist.org/downloads/", 1968 | "license": [ 1969 | "BSD-3-Clause" 1970 | ], 1971 | "authors": [ 1972 | { 1973 | "name": "Sebastian Bergmann", 1974 | "email": "sebastian@phpunit.de" 1975 | } 1976 | ], 1977 | "description": "Provides functionality to handle HHVM/PHP environments", 1978 | "homepage": "http://www.github.com/sebastianbergmann/environment", 1979 | "keywords": [ 1980 | "Xdebug", 1981 | "environment", 1982 | "hhvm" 1983 | ], 1984 | "time": "2016-08-18T05:49:44+00:00" 1985 | }, 1986 | { 1987 | "name": "sebastian/exporter", 1988 | "version": "1.2.2", 1989 | "source": { 1990 | "type": "git", 1991 | "url": "https://github.com/sebastianbergmann/exporter.git", 1992 | "reference": "42c4c2eec485ee3e159ec9884f95b431287edde4" 1993 | }, 1994 | "dist": { 1995 | "type": "zip", 1996 | "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/42c4c2eec485ee3e159ec9884f95b431287edde4", 1997 | "reference": "42c4c2eec485ee3e159ec9884f95b431287edde4", 1998 | "shasum": "" 1999 | }, 2000 | "require": { 2001 | "php": ">=5.3.3", 2002 | "sebastian/recursion-context": "~1.0" 2003 | }, 2004 | "require-dev": { 2005 | "ext-mbstring": "*", 2006 | "phpunit/phpunit": "~4.4" 2007 | }, 2008 | "type": "library", 2009 | "extra": { 2010 | "branch-alias": { 2011 | "dev-master": "1.3.x-dev" 2012 | } 2013 | }, 2014 | "autoload": { 2015 | "classmap": [ 2016 | "src/" 2017 | ] 2018 | }, 2019 | "notification-url": "https://packagist.org/downloads/", 2020 | "license": [ 2021 | "BSD-3-Clause" 2022 | ], 2023 | "authors": [ 2024 | { 2025 | "name": "Jeff Welch", 2026 | "email": "whatthejeff@gmail.com" 2027 | }, 2028 | { 2029 | "name": "Volker Dusch", 2030 | "email": "github@wallbash.com" 2031 | }, 2032 | { 2033 | "name": "Bernhard Schussek", 2034 | "email": "bschussek@2bepublished.at" 2035 | }, 2036 | { 2037 | "name": "Sebastian Bergmann", 2038 | "email": "sebastian@phpunit.de" 2039 | }, 2040 | { 2041 | "name": "Adam Harvey", 2042 | "email": "aharvey@php.net" 2043 | } 2044 | ], 2045 | "description": "Provides the functionality to export PHP variables for visualization", 2046 | "homepage": "http://www.github.com/sebastianbergmann/exporter", 2047 | "keywords": [ 2048 | "export", 2049 | "exporter" 2050 | ], 2051 | "time": "2016-06-17T09:04:28+00:00" 2052 | }, 2053 | { 2054 | "name": "sebastian/global-state", 2055 | "version": "1.1.1", 2056 | "source": { 2057 | "type": "git", 2058 | "url": "https://github.com/sebastianbergmann/global-state.git", 2059 | "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4" 2060 | }, 2061 | "dist": { 2062 | "type": "zip", 2063 | "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bc37d50fea7d017d3d340f230811c9f1d7280af4", 2064 | "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4", 2065 | "shasum": "" 2066 | }, 2067 | "require": { 2068 | "php": ">=5.3.3" 2069 | }, 2070 | "require-dev": { 2071 | "phpunit/phpunit": "~4.2" 2072 | }, 2073 | "suggest": { 2074 | "ext-uopz": "*" 2075 | }, 2076 | "type": "library", 2077 | "extra": { 2078 | "branch-alias": { 2079 | "dev-master": "1.0-dev" 2080 | } 2081 | }, 2082 | "autoload": { 2083 | "classmap": [ 2084 | "src/" 2085 | ] 2086 | }, 2087 | "notification-url": "https://packagist.org/downloads/", 2088 | "license": [ 2089 | "BSD-3-Clause" 2090 | ], 2091 | "authors": [ 2092 | { 2093 | "name": "Sebastian Bergmann", 2094 | "email": "sebastian@phpunit.de" 2095 | } 2096 | ], 2097 | "description": "Snapshotting of global state", 2098 | "homepage": "http://www.github.com/sebastianbergmann/global-state", 2099 | "keywords": [ 2100 | "global state" 2101 | ], 2102 | "time": "2015-10-12T03:26:01+00:00" 2103 | }, 2104 | { 2105 | "name": "sebastian/recursion-context", 2106 | "version": "1.0.5", 2107 | "source": { 2108 | "type": "git", 2109 | "url": "https://github.com/sebastianbergmann/recursion-context.git", 2110 | "reference": "b19cc3298482a335a95f3016d2f8a6950f0fbcd7" 2111 | }, 2112 | "dist": { 2113 | "type": "zip", 2114 | "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/b19cc3298482a335a95f3016d2f8a6950f0fbcd7", 2115 | "reference": "b19cc3298482a335a95f3016d2f8a6950f0fbcd7", 2116 | "shasum": "" 2117 | }, 2118 | "require": { 2119 | "php": ">=5.3.3" 2120 | }, 2121 | "require-dev": { 2122 | "phpunit/phpunit": "~4.4" 2123 | }, 2124 | "type": "library", 2125 | "extra": { 2126 | "branch-alias": { 2127 | "dev-master": "1.0.x-dev" 2128 | } 2129 | }, 2130 | "autoload": { 2131 | "classmap": [ 2132 | "src/" 2133 | ] 2134 | }, 2135 | "notification-url": "https://packagist.org/downloads/", 2136 | "license": [ 2137 | "BSD-3-Clause" 2138 | ], 2139 | "authors": [ 2140 | { 2141 | "name": "Jeff Welch", 2142 | "email": "whatthejeff@gmail.com" 2143 | }, 2144 | { 2145 | "name": "Sebastian Bergmann", 2146 | "email": "sebastian@phpunit.de" 2147 | }, 2148 | { 2149 | "name": "Adam Harvey", 2150 | "email": "aharvey@php.net" 2151 | } 2152 | ], 2153 | "description": "Provides functionality to recursively process PHP variables", 2154 | "homepage": "http://www.github.com/sebastianbergmann/recursion-context", 2155 | "time": "2016-10-03T07:41:43+00:00" 2156 | }, 2157 | { 2158 | "name": "sebastian/resource-operations", 2159 | "version": "1.0.0", 2160 | "source": { 2161 | "type": "git", 2162 | "url": "https://github.com/sebastianbergmann/resource-operations.git", 2163 | "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52" 2164 | }, 2165 | "dist": { 2166 | "type": "zip", 2167 | "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", 2168 | "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", 2169 | "shasum": "" 2170 | }, 2171 | "require": { 2172 | "php": ">=5.6.0" 2173 | }, 2174 | "type": "library", 2175 | "extra": { 2176 | "branch-alias": { 2177 | "dev-master": "1.0.x-dev" 2178 | } 2179 | }, 2180 | "autoload": { 2181 | "classmap": [ 2182 | "src/" 2183 | ] 2184 | }, 2185 | "notification-url": "https://packagist.org/downloads/", 2186 | "license": [ 2187 | "BSD-3-Clause" 2188 | ], 2189 | "authors": [ 2190 | { 2191 | "name": "Sebastian Bergmann", 2192 | "email": "sebastian@phpunit.de" 2193 | } 2194 | ], 2195 | "description": "Provides a list of PHP built-in functions that operate on resources", 2196 | "homepage": "https://www.github.com/sebastianbergmann/resource-operations", 2197 | "time": "2015-07-28T20:34:47+00:00" 2198 | }, 2199 | { 2200 | "name": "sebastian/version", 2201 | "version": "1.0.6", 2202 | "source": { 2203 | "type": "git", 2204 | "url": "https://github.com/sebastianbergmann/version.git", 2205 | "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6" 2206 | }, 2207 | "dist": { 2208 | "type": "zip", 2209 | "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/58b3a85e7999757d6ad81c787a1fbf5ff6c628c6", 2210 | "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6", 2211 | "shasum": "" 2212 | }, 2213 | "type": "library", 2214 | "autoload": { 2215 | "classmap": [ 2216 | "src/" 2217 | ] 2218 | }, 2219 | "notification-url": "https://packagist.org/downloads/", 2220 | "license": [ 2221 | "BSD-3-Clause" 2222 | ], 2223 | "authors": [ 2224 | { 2225 | "name": "Sebastian Bergmann", 2226 | "role": "lead", 2227 | "email": "sebastian@phpunit.de" 2228 | } 2229 | ], 2230 | "description": "Library that helps with managing the version number of Git-hosted PHP projects", 2231 | "homepage": "https://github.com/sebastianbergmann/version", 2232 | "time": "2015-06-21T13:59:46+00:00" 2233 | }, 2234 | { 2235 | "name": "symfony/polyfill-ctype", 2236 | "version": "v1.12.0", 2237 | "source": { 2238 | "type": "git", 2239 | "url": "https://github.com/symfony/polyfill-ctype.git", 2240 | "reference": "550ebaac289296ce228a706d0867afc34687e3f4" 2241 | }, 2242 | "dist": { 2243 | "type": "zip", 2244 | "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/550ebaac289296ce228a706d0867afc34687e3f4", 2245 | "reference": "550ebaac289296ce228a706d0867afc34687e3f4", 2246 | "shasum": "" 2247 | }, 2248 | "require": { 2249 | "php": ">=5.3.3" 2250 | }, 2251 | "suggest": { 2252 | "ext-ctype": "For best performance" 2253 | }, 2254 | "type": "library", 2255 | "extra": { 2256 | "branch-alias": { 2257 | "dev-master": "1.12-dev" 2258 | } 2259 | }, 2260 | "autoload": { 2261 | "psr-4": { 2262 | "Symfony\\Polyfill\\Ctype\\": "" 2263 | }, 2264 | "files": [ 2265 | "bootstrap.php" 2266 | ] 2267 | }, 2268 | "notification-url": "https://packagist.org/downloads/", 2269 | "license": [ 2270 | "MIT" 2271 | ], 2272 | "authors": [ 2273 | { 2274 | "name": "Gert de Pagter", 2275 | "email": "BackEndTea@gmail.com" 2276 | }, 2277 | { 2278 | "name": "Symfony Community", 2279 | "homepage": "https://symfony.com/contributors" 2280 | } 2281 | ], 2282 | "description": "Symfony polyfill for ctype functions", 2283 | "homepage": "https://symfony.com", 2284 | "keywords": [ 2285 | "compatibility", 2286 | "ctype", 2287 | "polyfill", 2288 | "portable" 2289 | ], 2290 | "time": "2019-08-06T08:03:45+00:00" 2291 | }, 2292 | { 2293 | "name": "symfony/yaml", 2294 | "version": "v3.4.30", 2295 | "source": { 2296 | "type": "git", 2297 | "url": "https://github.com/symfony/yaml.git", 2298 | "reference": "051d045c684148060ebfc9affb7e3f5e0899d40b" 2299 | }, 2300 | "dist": { 2301 | "type": "zip", 2302 | "url": "https://api.github.com/repos/symfony/yaml/zipball/051d045c684148060ebfc9affb7e3f5e0899d40b", 2303 | "reference": "051d045c684148060ebfc9affb7e3f5e0899d40b", 2304 | "shasum": "" 2305 | }, 2306 | "require": { 2307 | "php": "^5.5.9|>=7.0.8", 2308 | "symfony/polyfill-ctype": "~1.8" 2309 | }, 2310 | "conflict": { 2311 | "symfony/console": "<3.4" 2312 | }, 2313 | "require-dev": { 2314 | "symfony/console": "~3.4|~4.0" 2315 | }, 2316 | "suggest": { 2317 | "symfony/console": "For validating YAML files using the lint command" 2318 | }, 2319 | "type": "library", 2320 | "extra": { 2321 | "branch-alias": { 2322 | "dev-master": "3.4-dev" 2323 | } 2324 | }, 2325 | "autoload": { 2326 | "psr-4": { 2327 | "Symfony\\Component\\Yaml\\": "" 2328 | }, 2329 | "exclude-from-classmap": [ 2330 | "/Tests/" 2331 | ] 2332 | }, 2333 | "notification-url": "https://packagist.org/downloads/", 2334 | "license": [ 2335 | "MIT" 2336 | ], 2337 | "authors": [ 2338 | { 2339 | "name": "Fabien Potencier", 2340 | "email": "fabien@symfony.com" 2341 | }, 2342 | { 2343 | "name": "Symfony Community", 2344 | "homepage": "https://symfony.com/contributors" 2345 | } 2346 | ], 2347 | "description": "Symfony Yaml Component", 2348 | "homepage": "https://symfony.com", 2349 | "time": "2019-07-24T13:01:31+00:00" 2350 | }, 2351 | { 2352 | "name": "webmozart/assert", 2353 | "version": "1.4.0", 2354 | "source": { 2355 | "type": "git", 2356 | "url": "https://github.com/webmozart/assert.git", 2357 | "reference": "83e253c8e0be5b0257b881e1827274667c5c17a9" 2358 | }, 2359 | "dist": { 2360 | "type": "zip", 2361 | "url": "https://api.github.com/repos/webmozart/assert/zipball/83e253c8e0be5b0257b881e1827274667c5c17a9", 2362 | "reference": "83e253c8e0be5b0257b881e1827274667c5c17a9", 2363 | "shasum": "" 2364 | }, 2365 | "require": { 2366 | "php": "^5.3.3 || ^7.0", 2367 | "symfony/polyfill-ctype": "^1.8" 2368 | }, 2369 | "require-dev": { 2370 | "phpunit/phpunit": "^4.6", 2371 | "sebastian/version": "^1.0.1" 2372 | }, 2373 | "type": "library", 2374 | "extra": { 2375 | "branch-alias": { 2376 | "dev-master": "1.3-dev" 2377 | } 2378 | }, 2379 | "autoload": { 2380 | "psr-4": { 2381 | "Webmozart\\Assert\\": "src/" 2382 | } 2383 | }, 2384 | "notification-url": "https://packagist.org/downloads/", 2385 | "license": [ 2386 | "MIT" 2387 | ], 2388 | "authors": [ 2389 | { 2390 | "name": "Bernhard Schussek", 2391 | "email": "bschussek@gmail.com" 2392 | } 2393 | ], 2394 | "description": "Assertions to validate method input/output with nice error messages.", 2395 | "keywords": [ 2396 | "assert", 2397 | "check", 2398 | "validate" 2399 | ], 2400 | "time": "2018-12-25T11:19:39+00:00" 2401 | } 2402 | ], 2403 | "aliases": [], 2404 | "minimum-stability": "stable", 2405 | "stability-flags": [], 2406 | "prefer-stable": false, 2407 | "prefer-lowest": false, 2408 | "platform": [], 2409 | "platform-dev": [] 2410 | } 2411 | -------------------------------------------------------------------------------- /test-data/composer.to.json: -------------------------------------------------------------------------------- 1 | { 2 | "repositories": [ 3 | { 4 | "type": "vcs", 5 | "url": "git@gitlab.com:pmjones/fake.git" 6 | } 7 | ], 8 | "require": { 9 | "caseysoftware/marvel-helper": "=2.0.0", 10 | "doctrine/dbal": "=2.9.2", 11 | "ircmaxell/random-lib": "=1.2.0", 12 | "ircmaxell/security-lib": "=1.1.0", 13 | "monolog/monolog": "1.x-dev", 14 | "payintegrator/afterpay": "=2.0.0", 15 | "pmjones/fake": "=0.2.0" 16 | }, 17 | "require-dev": { 18 | "mockery/mockery": "=0.9.11", 19 | "phpunit/phpunit": "=5.7.27" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /test-svn.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | DIR="$( CDPATH='' cd -- "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" 4 | [ "$DIR" ] || exit 5 | 6 | svn --help > /dev/null || { echo "Fail: could not find 'svn' executable"; exit 1; } 7 | svnadmin --help > /dev/null || { echo "Fail: could not find 'svnadmin' executable"; exit 1; } 8 | 9 | trap cleanup INT ERR 10 | 11 | function cleanup() { 12 | cd "$DIR/test-data" || exit 13 | rm -rf proj proj-working svnrepo 14 | } 15 | 16 | set -eEx 17 | 18 | cd test-data 19 | 20 | mkdir -p proj/trunk 21 | 22 | cp composer.from.json proj/trunk/composer.json 23 | cp composer.from.lock proj/trunk/composer.lock 24 | 25 | svnadmin create svnrepo 26 | svn import ./proj file://$PWD/svnrepo -m "Initial commit" 27 | 28 | svn checkout file://$PWD/svnrepo proj-working 29 | cp composer.to.json proj-working/trunk/composer.json 30 | cp composer.to.lock proj-working/trunk/composer.lock 31 | 32 | cd proj-working/trunk 33 | ../../../composer-lock-diff 34 | 35 | cd .. 36 | ../../composer-lock-diff -p trunk 37 | 38 | cd .. 39 | rm -rf proj proj-working svnrepo 40 | 41 | --------------------------------------------------------------------------------