├── .editorconfig ├── .gitignore ├── .scenarios.lock ├── install └── phpunit4 │ ├── .gitignore │ ├── composer.json │ ├── composer.lock │ ├── src │ └── tests ├── .travis.yml ├── README.md ├── composer.json ├── composer.lock ├── phpunit.xml.dist ├── src ├── CommandProvider.php ├── DrupalScaffoldCommand.php ├── FileFetcher.php ├── Handler.php ├── Plugin.php └── PrestissimoFileFetcher.php └── tests ├── FetcherTest.php └── PluginTest.php /.editorconfig: -------------------------------------------------------------------------------- 1 | # Drupal editor configuration normalization 2 | # @see http://editorconfig.org/ 3 | 4 | # This is the top-most .editorconfig file; do not search in parent directories. 5 | root = true 6 | 7 | # All files. 8 | [*] 9 | end_of_line = LF 10 | indent_style = space 11 | indent_size = 2 12 | charset = utf-8 13 | trim_trailing_whitespace = true 14 | insert_final_newline = true 15 | 16 | [{composer.json,composer.lock}] 17 | indent_size = 4 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | vendor 2 | -------------------------------------------------------------------------------- /.scenarios.lock/install: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | SCENARIO=$1 4 | DEPENDENCIES=${2-install} 5 | 6 | # Convert the aliases 'highest', 'lowest' and 'lock' to 7 | # the corresponding composer command to run. 8 | case $DEPENDENCIES in 9 | highest) 10 | DEPENDENCIES=update 11 | ;; 12 | lowest) 13 | DEPENDENCIES='update --prefer-lowest' 14 | ;; 15 | lock|default|"") 16 | DEPENDENCIES=install 17 | ;; 18 | esac 19 | 20 | original_name=scenarios 21 | recommended_name=".scenarios.lock" 22 | 23 | base="$original_name" 24 | if [ -d "$recommended_name" ] ; then 25 | base="$recommended_name" 26 | fi 27 | 28 | # If scenario is not specified, install the lockfile at 29 | # the root of the project. 30 | dir="$base/${SCENARIO}" 31 | if [ -z "$SCENARIO" ] || [ "$SCENARIO" == "default" ] ; then 32 | SCENARIO=default 33 | dir=. 34 | fi 35 | 36 | # Test to make sure that the selected scenario exists. 37 | if [ ! -d "$dir" ] ; then 38 | echo "Requested scenario '${SCENARIO}' does not exist." 39 | exit 1 40 | fi 41 | 42 | echo 43 | echo "::" 44 | echo ":: Switch to ${SCENARIO} scenario" 45 | echo "::" 46 | echo 47 | 48 | set -ex 49 | 50 | composer -n validate --working-dir=$dir --no-check-all --ansi 51 | composer -n --working-dir=$dir ${DEPENDENCIES} --prefer-dist --no-scripts 52 | composer -n --working-dir=$dir info 53 | -------------------------------------------------------------------------------- /.scenarios.lock/phpunit4/.gitignore: -------------------------------------------------------------------------------- 1 | vendor 2 | -------------------------------------------------------------------------------- /.scenarios.lock/phpunit4/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "drupal-composer/drupal-scaffold", 3 | "description": "Composer Plugin for updating the Drupal scaffold files when using drupal/core", 4 | "type": "composer-plugin", 5 | "license": "GPL-2.0-or-later", 6 | "require": { 7 | "php": "^5.5.9|>=7.0.8", 8 | "composer-plugin-api": "^1.0.0", 9 | "composer/semver": "^1.4" 10 | }, 11 | "autoload": { 12 | "psr-4": { 13 | "DrupalComposer\\DrupalScaffold\\": "src/" 14 | } 15 | }, 16 | "extra": { 17 | "class": "DrupalComposer\\DrupalScaffold\\Plugin", 18 | "branch-alias": { 19 | "dev-master": "2.0.x-dev" 20 | } 21 | }, 22 | "scripts": { 23 | "cs": "phpcs --standard=PSR2 -n src", 24 | "cbf": "phpcbf --standard=PSR2 -n src", 25 | "unit": "phpunit --colors=always", 26 | "lint": [ 27 | "find src -name '*.php' -print0 | xargs -0 -n1 php -l" 28 | ], 29 | "test": [ 30 | "@lint", 31 | "@unit" 32 | ], 33 | "scenario": ".scenarios.lock/install", 34 | "post-update-cmd": [ 35 | "create-scenario phpunit4 'phpunit/phpunit:^4.8.36' --platform-php '5.5.27'" 36 | ] 37 | }, 38 | "config": { 39 | "optimize-autoloader": true, 40 | "sort-packages": true, 41 | "platform": { 42 | "php": "5.5.27" 43 | }, 44 | "vendor-dir": "../../vendor" 45 | }, 46 | "require-dev": { 47 | "composer/composer": "dev-master", 48 | "g1a/composer-test-scenarios": "^2.1.0", 49 | "phpunit/phpunit": "^4.8.36", 50 | "squizlabs/php_codesniffer": "^2.8" 51 | }, 52 | "minimum-stability": "stable" 53 | } 54 | -------------------------------------------------------------------------------- /.scenarios.lock/phpunit4/composer.lock: -------------------------------------------------------------------------------- 1 | { 2 | "_readme": [ 3 | "This file locks the dependencies of your project to a known state", 4 | "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", 5 | "This file is @generated automatically" 6 | ], 7 | "content-hash": "421671c61c80e5b56a0317e25a7c457b", 8 | "packages": [ 9 | { 10 | "name": "composer/semver", 11 | "version": "1.4.2", 12 | "source": { 13 | "type": "git", 14 | "url": "https://github.com/composer/semver.git", 15 | "reference": "c7cb9a2095a074d131b65a8a0cd294479d785573" 16 | }, 17 | "dist": { 18 | "type": "zip", 19 | "url": "https://api.github.com/repos/composer/semver/zipball/c7cb9a2095a074d131b65a8a0cd294479d785573", 20 | "reference": "c7cb9a2095a074d131b65a8a0cd294479d785573", 21 | "shasum": "" 22 | }, 23 | "require": { 24 | "php": "^5.3.2 || ^7.0" 25 | }, 26 | "require-dev": { 27 | "phpunit/phpunit": "^4.5 || ^5.0.5", 28 | "phpunit/phpunit-mock-objects": "2.3.0 || ^3.0" 29 | }, 30 | "type": "library", 31 | "extra": { 32 | "branch-alias": { 33 | "dev-master": "1.x-dev" 34 | } 35 | }, 36 | "autoload": { 37 | "psr-4": { 38 | "Composer\\Semver\\": "src" 39 | } 40 | }, 41 | "notification-url": "https://packagist.org/downloads/", 42 | "license": [ 43 | "MIT" 44 | ], 45 | "authors": [ 46 | { 47 | "name": "Nils Adermann", 48 | "email": "naderman@naderman.de", 49 | "homepage": "http://www.naderman.de" 50 | }, 51 | { 52 | "name": "Jordi Boggiano", 53 | "email": "j.boggiano@seld.be", 54 | "homepage": "http://seld.be" 55 | }, 56 | { 57 | "name": "Rob Bast", 58 | "email": "rob.bast@gmail.com", 59 | "homepage": "http://robbast.nl" 60 | } 61 | ], 62 | "description": "Semver library that offers utilities, version constraint parsing and validation.", 63 | "keywords": [ 64 | "semantic", 65 | "semver", 66 | "validation", 67 | "versioning" 68 | ], 69 | "time": "2016-08-30T16:08:34+00:00" 70 | } 71 | ], 72 | "packages-dev": [ 73 | { 74 | "name": "composer/ca-bundle", 75 | "version": "1.1.3", 76 | "source": { 77 | "type": "git", 78 | "url": "https://github.com/composer/ca-bundle.git", 79 | "reference": "8afa52cd417f4ec417b4bfe86b68106538a87660" 80 | }, 81 | "dist": { 82 | "type": "zip", 83 | "url": "https://api.github.com/repos/composer/ca-bundle/zipball/8afa52cd417f4ec417b4bfe86b68106538a87660", 84 | "reference": "8afa52cd417f4ec417b4bfe86b68106538a87660", 85 | "shasum": "" 86 | }, 87 | "require": { 88 | "ext-openssl": "*", 89 | "ext-pcre": "*", 90 | "php": "^5.3.2 || ^7.0" 91 | }, 92 | "require-dev": { 93 | "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5", 94 | "psr/log": "^1.0", 95 | "symfony/process": "^2.5 || ^3.0 || ^4.0" 96 | }, 97 | "type": "library", 98 | "extra": { 99 | "branch-alias": { 100 | "dev-master": "1.x-dev" 101 | } 102 | }, 103 | "autoload": { 104 | "psr-4": { 105 | "Composer\\CaBundle\\": "src" 106 | } 107 | }, 108 | "notification-url": "https://packagist.org/downloads/", 109 | "license": [ 110 | "MIT" 111 | ], 112 | "authors": [ 113 | { 114 | "name": "Jordi Boggiano", 115 | "email": "j.boggiano@seld.be", 116 | "homepage": "http://seld.be" 117 | } 118 | ], 119 | "description": "Lets you find a path to the system CA bundle, and includes a fallback to the Mozilla CA bundle.", 120 | "keywords": [ 121 | "cabundle", 122 | "cacert", 123 | "certificate", 124 | "ssl", 125 | "tls" 126 | ], 127 | "time": "2018-10-18T06:09:13+00:00" 128 | }, 129 | { 130 | "name": "composer/composer", 131 | "version": "dev-master", 132 | "source": { 133 | "type": "git", 134 | "url": "https://github.com/composer/composer.git", 135 | "reference": "154ae6fae28c210cd6cf5d76aace04aefef1ca65" 136 | }, 137 | "dist": { 138 | "type": "zip", 139 | "url": "https://api.github.com/repos/composer/composer/zipball/154ae6fae28c210cd6cf5d76aace04aefef1ca65", 140 | "reference": "154ae6fae28c210cd6cf5d76aace04aefef1ca65", 141 | "shasum": "" 142 | }, 143 | "require": { 144 | "composer/ca-bundle": "^1.0", 145 | "composer/semver": "^1.0", 146 | "composer/spdx-licenses": "^1.2", 147 | "composer/xdebug-handler": "^1.1", 148 | "justinrainbow/json-schema": "^3.0 || ^4.0 || ^5.0", 149 | "php": "^5.3.2 || ^7.0", 150 | "psr/log": "^1.0", 151 | "seld/jsonlint": "^1.4", 152 | "seld/phar-utils": "^1.0", 153 | "symfony/console": "^2.7 || ^3.0 || ^4.0", 154 | "symfony/filesystem": "^2.7 || ^3.0 || ^4.0", 155 | "symfony/finder": "^2.7 || ^3.0 || ^4.0", 156 | "symfony/process": "^2.7 || ^3.0 || ^4.0" 157 | }, 158 | "conflict": { 159 | "symfony/console": "2.8.38" 160 | }, 161 | "require-dev": { 162 | "phpunit/phpunit": "^4.8.35 || ^5.7", 163 | "phpunit/phpunit-mock-objects": "^2.3 || ^3.0" 164 | }, 165 | "suggest": { 166 | "ext-openssl": "Enabling the openssl extension allows you to access https URLs for repositories and packages", 167 | "ext-zip": "Enabling the zip extension allows you to unzip archives", 168 | "ext-zlib": "Allow gzip compression of HTTP requests" 169 | }, 170 | "bin": [ 171 | "bin/composer" 172 | ], 173 | "type": "library", 174 | "extra": { 175 | "branch-alias": { 176 | "dev-master": "1.9-dev" 177 | } 178 | }, 179 | "autoload": { 180 | "psr-4": { 181 | "Composer\\": "src/Composer" 182 | } 183 | }, 184 | "notification-url": "https://packagist.org/downloads/", 185 | "license": [ 186 | "MIT" 187 | ], 188 | "authors": [ 189 | { 190 | "name": "Nils Adermann", 191 | "email": "naderman@naderman.de", 192 | "homepage": "http://www.naderman.de" 193 | }, 194 | { 195 | "name": "Jordi Boggiano", 196 | "email": "j.boggiano@seld.be", 197 | "homepage": "http://seld.be" 198 | } 199 | ], 200 | "description": "Composer helps you declare, manage and install dependencies of PHP projects, ensuring you have the right stack everywhere.", 201 | "homepage": "https://getcomposer.org/", 202 | "keywords": [ 203 | "autoload", 204 | "dependency", 205 | "package" 206 | ], 207 | "time": "2019-01-03T09:53:00+00:00" 208 | }, 209 | { 210 | "name": "composer/spdx-licenses", 211 | "version": "1.5.0", 212 | "source": { 213 | "type": "git", 214 | "url": "https://github.com/composer/spdx-licenses.git", 215 | "reference": "7a9556b22bd9d4df7cad89876b00af58ef20d3a2" 216 | }, 217 | "dist": { 218 | "type": "zip", 219 | "url": "https://api.github.com/repos/composer/spdx-licenses/zipball/7a9556b22bd9d4df7cad89876b00af58ef20d3a2", 220 | "reference": "7a9556b22bd9d4df7cad89876b00af58ef20d3a2", 221 | "shasum": "" 222 | }, 223 | "require": { 224 | "php": "^5.3.2 || ^7.0" 225 | }, 226 | "require-dev": { 227 | "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5", 228 | "phpunit/phpunit-mock-objects": "2.3.0 || ^3.0" 229 | }, 230 | "type": "library", 231 | "extra": { 232 | "branch-alias": { 233 | "dev-master": "1.x-dev" 234 | } 235 | }, 236 | "autoload": { 237 | "psr-4": { 238 | "Composer\\Spdx\\": "src" 239 | } 240 | }, 241 | "notification-url": "https://packagist.org/downloads/", 242 | "license": [ 243 | "MIT" 244 | ], 245 | "authors": [ 246 | { 247 | "name": "Nils Adermann", 248 | "email": "naderman@naderman.de", 249 | "homepage": "http://www.naderman.de" 250 | }, 251 | { 252 | "name": "Jordi Boggiano", 253 | "email": "j.boggiano@seld.be", 254 | "homepage": "http://seld.be" 255 | }, 256 | { 257 | "name": "Rob Bast", 258 | "email": "rob.bast@gmail.com", 259 | "homepage": "http://robbast.nl" 260 | } 261 | ], 262 | "description": "SPDX licenses list and validation library.", 263 | "keywords": [ 264 | "license", 265 | "spdx", 266 | "validator" 267 | ], 268 | "time": "2018-11-01T09:45:54+00:00" 269 | }, 270 | { 271 | "name": "composer/xdebug-handler", 272 | "version": "1.3.1", 273 | "source": { 274 | "type": "git", 275 | "url": "https://github.com/composer/xdebug-handler.git", 276 | "reference": "dc523135366eb68f22268d069ea7749486458562" 277 | }, 278 | "dist": { 279 | "type": "zip", 280 | "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/dc523135366eb68f22268d069ea7749486458562", 281 | "reference": "dc523135366eb68f22268d069ea7749486458562", 282 | "shasum": "" 283 | }, 284 | "require": { 285 | "php": "^5.3.2 || ^7.0", 286 | "psr/log": "^1.0" 287 | }, 288 | "require-dev": { 289 | "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5" 290 | }, 291 | "type": "library", 292 | "autoload": { 293 | "psr-4": { 294 | "Composer\\XdebugHandler\\": "src" 295 | } 296 | }, 297 | "notification-url": "https://packagist.org/downloads/", 298 | "license": [ 299 | "MIT" 300 | ], 301 | "authors": [ 302 | { 303 | "name": "John Stevenson", 304 | "email": "john-stevenson@blueyonder.co.uk" 305 | } 306 | ], 307 | "description": "Restarts a process without xdebug.", 308 | "keywords": [ 309 | "Xdebug", 310 | "performance" 311 | ], 312 | "time": "2018-11-29T10:59:02+00:00" 313 | }, 314 | { 315 | "name": "doctrine/instantiator", 316 | "version": "1.0.5", 317 | "source": { 318 | "type": "git", 319 | "url": "https://github.com/doctrine/instantiator.git", 320 | "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d" 321 | }, 322 | "dist": { 323 | "type": "zip", 324 | "url": "https://api.github.com/repos/doctrine/instantiator/zipball/8e884e78f9f0eb1329e445619e04456e64d8051d", 325 | "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d", 326 | "shasum": "" 327 | }, 328 | "require": { 329 | "php": ">=5.3,<8.0-DEV" 330 | }, 331 | "require-dev": { 332 | "athletic/athletic": "~0.1.8", 333 | "ext-pdo": "*", 334 | "ext-phar": "*", 335 | "phpunit/phpunit": "~4.0", 336 | "squizlabs/php_codesniffer": "~2.0" 337 | }, 338 | "type": "library", 339 | "extra": { 340 | "branch-alias": { 341 | "dev-master": "1.0.x-dev" 342 | } 343 | }, 344 | "autoload": { 345 | "psr-4": { 346 | "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" 347 | } 348 | }, 349 | "notification-url": "https://packagist.org/downloads/", 350 | "license": [ 351 | "MIT" 352 | ], 353 | "authors": [ 354 | { 355 | "name": "Marco Pivetta", 356 | "email": "ocramius@gmail.com", 357 | "homepage": "http://ocramius.github.com/" 358 | } 359 | ], 360 | "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", 361 | "homepage": "https://github.com/doctrine/instantiator", 362 | "keywords": [ 363 | "constructor", 364 | "instantiate" 365 | ], 366 | "time": "2015-06-14T21:17:01+00:00" 367 | }, 368 | { 369 | "name": "g1a/composer-test-scenarios", 370 | "version": "2.2.0", 371 | "source": { 372 | "type": "git", 373 | "url": "https://github.com/g1a/composer-test-scenarios.git", 374 | "reference": "a166fd15191aceab89f30c097e694b7cf3db4880" 375 | }, 376 | "dist": { 377 | "type": "zip", 378 | "url": "https://api.github.com/repos/g1a/composer-test-scenarios/zipball/a166fd15191aceab89f30c097e694b7cf3db4880", 379 | "reference": "a166fd15191aceab89f30c097e694b7cf3db4880", 380 | "shasum": "" 381 | }, 382 | "bin": [ 383 | "scripts/create-scenario", 384 | "scripts/dependency-licenses", 385 | "scripts/install-scenario" 386 | ], 387 | "type": "library", 388 | "notification-url": "https://packagist.org/downloads/", 389 | "license": [ 390 | "MIT" 391 | ], 392 | "authors": [ 393 | { 394 | "name": "Greg Anderson", 395 | "email": "greg.1.anderson@greenknowe.org" 396 | } 397 | ], 398 | "description": "Useful scripts for testing multiple sets of Composer dependencies.", 399 | "time": "2018-08-08T23:37:23+00:00" 400 | }, 401 | { 402 | "name": "justinrainbow/json-schema", 403 | "version": "5.2.7", 404 | "source": { 405 | "type": "git", 406 | "url": "https://github.com/justinrainbow/json-schema.git", 407 | "reference": "8560d4314577199ba51bf2032f02cd1315587c23" 408 | }, 409 | "dist": { 410 | "type": "zip", 411 | "url": "https://api.github.com/repos/justinrainbow/json-schema/zipball/8560d4314577199ba51bf2032f02cd1315587c23", 412 | "reference": "8560d4314577199ba51bf2032f02cd1315587c23", 413 | "shasum": "" 414 | }, 415 | "require": { 416 | "php": ">=5.3.3" 417 | }, 418 | "require-dev": { 419 | "friendsofphp/php-cs-fixer": "^2.1", 420 | "json-schema/json-schema-test-suite": "1.2.0", 421 | "phpunit/phpunit": "^4.8.35" 422 | }, 423 | "bin": [ 424 | "bin/validate-json" 425 | ], 426 | "type": "library", 427 | "extra": { 428 | "branch-alias": { 429 | "dev-master": "5.0.x-dev" 430 | } 431 | }, 432 | "autoload": { 433 | "psr-4": { 434 | "JsonSchema\\": "src/JsonSchema/" 435 | } 436 | }, 437 | "notification-url": "https://packagist.org/downloads/", 438 | "license": [ 439 | "MIT" 440 | ], 441 | "authors": [ 442 | { 443 | "name": "Bruno Prieto Reis", 444 | "email": "bruno.p.reis@gmail.com" 445 | }, 446 | { 447 | "name": "Justin Rainbow", 448 | "email": "justin.rainbow@gmail.com" 449 | }, 450 | { 451 | "name": "Igor Wiedler", 452 | "email": "igor@wiedler.ch" 453 | }, 454 | { 455 | "name": "Robert Schönthal", 456 | "email": "seroscho@googlemail.com" 457 | } 458 | ], 459 | "description": "A library to validate a json schema.", 460 | "homepage": "https://github.com/justinrainbow/json-schema", 461 | "keywords": [ 462 | "json", 463 | "schema" 464 | ], 465 | "time": "2018-02-14T22:26:30+00:00" 466 | }, 467 | { 468 | "name": "phpdocumentor/reflection-common", 469 | "version": "1.0.1", 470 | "source": { 471 | "type": "git", 472 | "url": "https://github.com/phpDocumentor/ReflectionCommon.git", 473 | "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6" 474 | }, 475 | "dist": { 476 | "type": "zip", 477 | "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", 478 | "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", 479 | "shasum": "" 480 | }, 481 | "require": { 482 | "php": ">=5.5" 483 | }, 484 | "require-dev": { 485 | "phpunit/phpunit": "^4.6" 486 | }, 487 | "type": "library", 488 | "extra": { 489 | "branch-alias": { 490 | "dev-master": "1.0.x-dev" 491 | } 492 | }, 493 | "autoload": { 494 | "psr-4": { 495 | "phpDocumentor\\Reflection\\": [ 496 | "src" 497 | ] 498 | } 499 | }, 500 | "notification-url": "https://packagist.org/downloads/", 501 | "license": [ 502 | "MIT" 503 | ], 504 | "authors": [ 505 | { 506 | "name": "Jaap van Otterdijk", 507 | "email": "opensource@ijaap.nl" 508 | } 509 | ], 510 | "description": "Common reflection classes used by phpdocumentor to reflect the code structure", 511 | "homepage": "http://www.phpdoc.org", 512 | "keywords": [ 513 | "FQSEN", 514 | "phpDocumentor", 515 | "phpdoc", 516 | "reflection", 517 | "static analysis" 518 | ], 519 | "time": "2017-09-11T18:02:19+00:00" 520 | }, 521 | { 522 | "name": "phpdocumentor/reflection-docblock", 523 | "version": "3.2.2", 524 | "source": { 525 | "type": "git", 526 | "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", 527 | "reference": "4aada1f93c72c35e22fb1383b47fee43b8f1d157" 528 | }, 529 | "dist": { 530 | "type": "zip", 531 | "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/4aada1f93c72c35e22fb1383b47fee43b8f1d157", 532 | "reference": "4aada1f93c72c35e22fb1383b47fee43b8f1d157", 533 | "shasum": "" 534 | }, 535 | "require": { 536 | "php": ">=5.5", 537 | "phpdocumentor/reflection-common": "^1.0@dev", 538 | "phpdocumentor/type-resolver": "^0.3.0", 539 | "webmozart/assert": "^1.0" 540 | }, 541 | "require-dev": { 542 | "mockery/mockery": "^0.9.4", 543 | "phpunit/phpunit": "^4.4" 544 | }, 545 | "type": "library", 546 | "autoload": { 547 | "psr-4": { 548 | "phpDocumentor\\Reflection\\": [ 549 | "src/" 550 | ] 551 | } 552 | }, 553 | "notification-url": "https://packagist.org/downloads/", 554 | "license": [ 555 | "MIT" 556 | ], 557 | "authors": [ 558 | { 559 | "name": "Mike van Riel", 560 | "email": "me@mikevanriel.com" 561 | } 562 | ], 563 | "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", 564 | "time": "2017-08-08T06:39:58+00:00" 565 | }, 566 | { 567 | "name": "phpdocumentor/type-resolver", 568 | "version": "0.3.0", 569 | "source": { 570 | "type": "git", 571 | "url": "https://github.com/phpDocumentor/TypeResolver.git", 572 | "reference": "fb3933512008d8162b3cdf9e18dba9309b7c3773" 573 | }, 574 | "dist": { 575 | "type": "zip", 576 | "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/fb3933512008d8162b3cdf9e18dba9309b7c3773", 577 | "reference": "fb3933512008d8162b3cdf9e18dba9309b7c3773", 578 | "shasum": "" 579 | }, 580 | "require": { 581 | "php": "^5.5 || ^7.0", 582 | "phpdocumentor/reflection-common": "^1.0" 583 | }, 584 | "require-dev": { 585 | "mockery/mockery": "^0.9.4", 586 | "phpunit/phpunit": "^5.2||^4.8.24" 587 | }, 588 | "type": "library", 589 | "extra": { 590 | "branch-alias": { 591 | "dev-master": "1.0.x-dev" 592 | } 593 | }, 594 | "autoload": { 595 | "psr-4": { 596 | "phpDocumentor\\Reflection\\": [ 597 | "src/" 598 | ] 599 | } 600 | }, 601 | "notification-url": "https://packagist.org/downloads/", 602 | "license": [ 603 | "MIT" 604 | ], 605 | "authors": [ 606 | { 607 | "name": "Mike van Riel", 608 | "email": "me@mikevanriel.com" 609 | } 610 | ], 611 | "time": "2017-06-03T08:32:36+00:00" 612 | }, 613 | { 614 | "name": "phpspec/prophecy", 615 | "version": "1.8.0", 616 | "source": { 617 | "type": "git", 618 | "url": "https://github.com/phpspec/prophecy.git", 619 | "reference": "4ba436b55987b4bf311cb7c6ba82aa528aac0a06" 620 | }, 621 | "dist": { 622 | "type": "zip", 623 | "url": "https://api.github.com/repos/phpspec/prophecy/zipball/4ba436b55987b4bf311cb7c6ba82aa528aac0a06", 624 | "reference": "4ba436b55987b4bf311cb7c6ba82aa528aac0a06", 625 | "shasum": "" 626 | }, 627 | "require": { 628 | "doctrine/instantiator": "^1.0.2", 629 | "php": "^5.3|^7.0", 630 | "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0", 631 | "sebastian/comparator": "^1.1|^2.0|^3.0", 632 | "sebastian/recursion-context": "^1.0|^2.0|^3.0" 633 | }, 634 | "require-dev": { 635 | "phpspec/phpspec": "^2.5|^3.2", 636 | "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5 || ^7.1" 637 | }, 638 | "type": "library", 639 | "extra": { 640 | "branch-alias": { 641 | "dev-master": "1.8.x-dev" 642 | } 643 | }, 644 | "autoload": { 645 | "psr-0": { 646 | "Prophecy\\": "src/" 647 | } 648 | }, 649 | "notification-url": "https://packagist.org/downloads/", 650 | "license": [ 651 | "MIT" 652 | ], 653 | "authors": [ 654 | { 655 | "name": "Konstantin Kudryashov", 656 | "email": "ever.zet@gmail.com", 657 | "homepage": "http://everzet.com" 658 | }, 659 | { 660 | "name": "Marcello Duarte", 661 | "email": "marcello.duarte@gmail.com" 662 | } 663 | ], 664 | "description": "Highly opinionated mocking framework for PHP 5.3+", 665 | "homepage": "https://github.com/phpspec/prophecy", 666 | "keywords": [ 667 | "Double", 668 | "Dummy", 669 | "fake", 670 | "mock", 671 | "spy", 672 | "stub" 673 | ], 674 | "time": "2018-08-05T17:53:17+00:00" 675 | }, 676 | { 677 | "name": "phpunit/php-code-coverage", 678 | "version": "2.2.4", 679 | "source": { 680 | "type": "git", 681 | "url": "https://github.com/sebastianbergmann/php-code-coverage.git", 682 | "reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979" 683 | }, 684 | "dist": { 685 | "type": "zip", 686 | "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/eabf68b476ac7d0f73793aada060f1c1a9bf8979", 687 | "reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979", 688 | "shasum": "" 689 | }, 690 | "require": { 691 | "php": ">=5.3.3", 692 | "phpunit/php-file-iterator": "~1.3", 693 | "phpunit/php-text-template": "~1.2", 694 | "phpunit/php-token-stream": "~1.3", 695 | "sebastian/environment": "^1.3.2", 696 | "sebastian/version": "~1.0" 697 | }, 698 | "require-dev": { 699 | "ext-xdebug": ">=2.1.4", 700 | "phpunit/phpunit": "~4" 701 | }, 702 | "suggest": { 703 | "ext-dom": "*", 704 | "ext-xdebug": ">=2.2.1", 705 | "ext-xmlwriter": "*" 706 | }, 707 | "type": "library", 708 | "extra": { 709 | "branch-alias": { 710 | "dev-master": "2.2.x-dev" 711 | } 712 | }, 713 | "autoload": { 714 | "classmap": [ 715 | "src/" 716 | ] 717 | }, 718 | "notification-url": "https://packagist.org/downloads/", 719 | "license": [ 720 | "BSD-3-Clause" 721 | ], 722 | "authors": [ 723 | { 724 | "name": "Sebastian Bergmann", 725 | "email": "sb@sebastian-bergmann.de", 726 | "role": "lead" 727 | } 728 | ], 729 | "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", 730 | "homepage": "https://github.com/sebastianbergmann/php-code-coverage", 731 | "keywords": [ 732 | "coverage", 733 | "testing", 734 | "xunit" 735 | ], 736 | "time": "2015-10-06T15:47:00+00:00" 737 | }, 738 | { 739 | "name": "phpunit/php-file-iterator", 740 | "version": "1.4.5", 741 | "source": { 742 | "type": "git", 743 | "url": "https://github.com/sebastianbergmann/php-file-iterator.git", 744 | "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4" 745 | }, 746 | "dist": { 747 | "type": "zip", 748 | "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/730b01bc3e867237eaac355e06a36b85dd93a8b4", 749 | "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4", 750 | "shasum": "" 751 | }, 752 | "require": { 753 | "php": ">=5.3.3" 754 | }, 755 | "type": "library", 756 | "extra": { 757 | "branch-alias": { 758 | "dev-master": "1.4.x-dev" 759 | } 760 | }, 761 | "autoload": { 762 | "classmap": [ 763 | "src/" 764 | ] 765 | }, 766 | "notification-url": "https://packagist.org/downloads/", 767 | "license": [ 768 | "BSD-3-Clause" 769 | ], 770 | "authors": [ 771 | { 772 | "name": "Sebastian Bergmann", 773 | "email": "sb@sebastian-bergmann.de", 774 | "role": "lead" 775 | } 776 | ], 777 | "description": "FilterIterator implementation that filters files based on a list of suffixes.", 778 | "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", 779 | "keywords": [ 780 | "filesystem", 781 | "iterator" 782 | ], 783 | "time": "2017-11-27T13:52:08+00:00" 784 | }, 785 | { 786 | "name": "phpunit/php-text-template", 787 | "version": "1.2.1", 788 | "source": { 789 | "type": "git", 790 | "url": "https://github.com/sebastianbergmann/php-text-template.git", 791 | "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686" 792 | }, 793 | "dist": { 794 | "type": "zip", 795 | "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686", 796 | "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686", 797 | "shasum": "" 798 | }, 799 | "require": { 800 | "php": ">=5.3.3" 801 | }, 802 | "type": "library", 803 | "autoload": { 804 | "classmap": [ 805 | "src/" 806 | ] 807 | }, 808 | "notification-url": "https://packagist.org/downloads/", 809 | "license": [ 810 | "BSD-3-Clause" 811 | ], 812 | "authors": [ 813 | { 814 | "name": "Sebastian Bergmann", 815 | "email": "sebastian@phpunit.de", 816 | "role": "lead" 817 | } 818 | ], 819 | "description": "Simple template engine.", 820 | "homepage": "https://github.com/sebastianbergmann/php-text-template/", 821 | "keywords": [ 822 | "template" 823 | ], 824 | "time": "2015-06-21T13:50:34+00:00" 825 | }, 826 | { 827 | "name": "phpunit/php-timer", 828 | "version": "1.0.9", 829 | "source": { 830 | "type": "git", 831 | "url": "https://github.com/sebastianbergmann/php-timer.git", 832 | "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f" 833 | }, 834 | "dist": { 835 | "type": "zip", 836 | "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", 837 | "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", 838 | "shasum": "" 839 | }, 840 | "require": { 841 | "php": "^5.3.3 || ^7.0" 842 | }, 843 | "require-dev": { 844 | "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0" 845 | }, 846 | "type": "library", 847 | "extra": { 848 | "branch-alias": { 849 | "dev-master": "1.0-dev" 850 | } 851 | }, 852 | "autoload": { 853 | "classmap": [ 854 | "src/" 855 | ] 856 | }, 857 | "notification-url": "https://packagist.org/downloads/", 858 | "license": [ 859 | "BSD-3-Clause" 860 | ], 861 | "authors": [ 862 | { 863 | "name": "Sebastian Bergmann", 864 | "email": "sb@sebastian-bergmann.de", 865 | "role": "lead" 866 | } 867 | ], 868 | "description": "Utility class for timing", 869 | "homepage": "https://github.com/sebastianbergmann/php-timer/", 870 | "keywords": [ 871 | "timer" 872 | ], 873 | "time": "2017-02-26T11:10:40+00:00" 874 | }, 875 | { 876 | "name": "phpunit/php-token-stream", 877 | "version": "1.4.12", 878 | "source": { 879 | "type": "git", 880 | "url": "https://github.com/sebastianbergmann/php-token-stream.git", 881 | "reference": "1ce90ba27c42e4e44e6d8458241466380b51fa16" 882 | }, 883 | "dist": { 884 | "type": "zip", 885 | "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/1ce90ba27c42e4e44e6d8458241466380b51fa16", 886 | "reference": "1ce90ba27c42e4e44e6d8458241466380b51fa16", 887 | "shasum": "" 888 | }, 889 | "require": { 890 | "ext-tokenizer": "*", 891 | "php": ">=5.3.3" 892 | }, 893 | "require-dev": { 894 | "phpunit/phpunit": "~4.2" 895 | }, 896 | "type": "library", 897 | "extra": { 898 | "branch-alias": { 899 | "dev-master": "1.4-dev" 900 | } 901 | }, 902 | "autoload": { 903 | "classmap": [ 904 | "src/" 905 | ] 906 | }, 907 | "notification-url": "https://packagist.org/downloads/", 908 | "license": [ 909 | "BSD-3-Clause" 910 | ], 911 | "authors": [ 912 | { 913 | "name": "Sebastian Bergmann", 914 | "email": "sebastian@phpunit.de" 915 | } 916 | ], 917 | "description": "Wrapper around PHP's tokenizer extension.", 918 | "homepage": "https://github.com/sebastianbergmann/php-token-stream/", 919 | "keywords": [ 920 | "tokenizer" 921 | ], 922 | "time": "2017-12-04T08:55:13+00:00" 923 | }, 924 | { 925 | "name": "phpunit/phpunit", 926 | "version": "4.8.36", 927 | "source": { 928 | "type": "git", 929 | "url": "https://github.com/sebastianbergmann/phpunit.git", 930 | "reference": "46023de9a91eec7dfb06cc56cb4e260017298517" 931 | }, 932 | "dist": { 933 | "type": "zip", 934 | "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/46023de9a91eec7dfb06cc56cb4e260017298517", 935 | "reference": "46023de9a91eec7dfb06cc56cb4e260017298517", 936 | "shasum": "" 937 | }, 938 | "require": { 939 | "ext-dom": "*", 940 | "ext-json": "*", 941 | "ext-pcre": "*", 942 | "ext-reflection": "*", 943 | "ext-spl": "*", 944 | "php": ">=5.3.3", 945 | "phpspec/prophecy": "^1.3.1", 946 | "phpunit/php-code-coverage": "~2.1", 947 | "phpunit/php-file-iterator": "~1.4", 948 | "phpunit/php-text-template": "~1.2", 949 | "phpunit/php-timer": "^1.0.6", 950 | "phpunit/phpunit-mock-objects": "~2.3", 951 | "sebastian/comparator": "~1.2.2", 952 | "sebastian/diff": "~1.2", 953 | "sebastian/environment": "~1.3", 954 | "sebastian/exporter": "~1.2", 955 | "sebastian/global-state": "~1.0", 956 | "sebastian/version": "~1.0", 957 | "symfony/yaml": "~2.1|~3.0" 958 | }, 959 | "suggest": { 960 | "phpunit/php-invoker": "~1.1" 961 | }, 962 | "bin": [ 963 | "phpunit" 964 | ], 965 | "type": "library", 966 | "extra": { 967 | "branch-alias": { 968 | "dev-master": "4.8.x-dev" 969 | } 970 | }, 971 | "autoload": { 972 | "classmap": [ 973 | "src/" 974 | ] 975 | }, 976 | "notification-url": "https://packagist.org/downloads/", 977 | "license": [ 978 | "BSD-3-Clause" 979 | ], 980 | "authors": [ 981 | { 982 | "name": "Sebastian Bergmann", 983 | "email": "sebastian@phpunit.de", 984 | "role": "lead" 985 | } 986 | ], 987 | "description": "The PHP Unit Testing framework.", 988 | "homepage": "https://phpunit.de/", 989 | "keywords": [ 990 | "phpunit", 991 | "testing", 992 | "xunit" 993 | ], 994 | "time": "2017-06-21T08:07:12+00:00" 995 | }, 996 | { 997 | "name": "phpunit/phpunit-mock-objects", 998 | "version": "2.3.8", 999 | "source": { 1000 | "type": "git", 1001 | "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", 1002 | "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983" 1003 | }, 1004 | "dist": { 1005 | "type": "zip", 1006 | "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/ac8e7a3db35738d56ee9a76e78a4e03d97628983", 1007 | "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983", 1008 | "shasum": "" 1009 | }, 1010 | "require": { 1011 | "doctrine/instantiator": "^1.0.2", 1012 | "php": ">=5.3.3", 1013 | "phpunit/php-text-template": "~1.2", 1014 | "sebastian/exporter": "~1.2" 1015 | }, 1016 | "require-dev": { 1017 | "phpunit/phpunit": "~4.4" 1018 | }, 1019 | "suggest": { 1020 | "ext-soap": "*" 1021 | }, 1022 | "type": "library", 1023 | "extra": { 1024 | "branch-alias": { 1025 | "dev-master": "2.3.x-dev" 1026 | } 1027 | }, 1028 | "autoload": { 1029 | "classmap": [ 1030 | "src/" 1031 | ] 1032 | }, 1033 | "notification-url": "https://packagist.org/downloads/", 1034 | "license": [ 1035 | "BSD-3-Clause" 1036 | ], 1037 | "authors": [ 1038 | { 1039 | "name": "Sebastian Bergmann", 1040 | "email": "sb@sebastian-bergmann.de", 1041 | "role": "lead" 1042 | } 1043 | ], 1044 | "description": "Mock Object library for PHPUnit", 1045 | "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/", 1046 | "keywords": [ 1047 | "mock", 1048 | "xunit" 1049 | ], 1050 | "time": "2015-10-02T06:51:40+00:00" 1051 | }, 1052 | { 1053 | "name": "psr/log", 1054 | "version": "1.1.0", 1055 | "source": { 1056 | "type": "git", 1057 | "url": "https://github.com/php-fig/log.git", 1058 | "reference": "6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd" 1059 | }, 1060 | "dist": { 1061 | "type": "zip", 1062 | "url": "https://api.github.com/repos/php-fig/log/zipball/6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd", 1063 | "reference": "6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd", 1064 | "shasum": "" 1065 | }, 1066 | "require": { 1067 | "php": ">=5.3.0" 1068 | }, 1069 | "type": "library", 1070 | "extra": { 1071 | "branch-alias": { 1072 | "dev-master": "1.0.x-dev" 1073 | } 1074 | }, 1075 | "autoload": { 1076 | "psr-4": { 1077 | "Psr\\Log\\": "Psr/Log/" 1078 | } 1079 | }, 1080 | "notification-url": "https://packagist.org/downloads/", 1081 | "license": [ 1082 | "MIT" 1083 | ], 1084 | "authors": [ 1085 | { 1086 | "name": "PHP-FIG", 1087 | "homepage": "http://www.php-fig.org/" 1088 | } 1089 | ], 1090 | "description": "Common interface for logging libraries", 1091 | "homepage": "https://github.com/php-fig/log", 1092 | "keywords": [ 1093 | "log", 1094 | "psr", 1095 | "psr-3" 1096 | ], 1097 | "time": "2018-11-20T15:27:04+00:00" 1098 | }, 1099 | { 1100 | "name": "sebastian/comparator", 1101 | "version": "1.2.4", 1102 | "source": { 1103 | "type": "git", 1104 | "url": "https://github.com/sebastianbergmann/comparator.git", 1105 | "reference": "2b7424b55f5047b47ac6e5ccb20b2aea4011d9be" 1106 | }, 1107 | "dist": { 1108 | "type": "zip", 1109 | "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/2b7424b55f5047b47ac6e5ccb20b2aea4011d9be", 1110 | "reference": "2b7424b55f5047b47ac6e5ccb20b2aea4011d9be", 1111 | "shasum": "" 1112 | }, 1113 | "require": { 1114 | "php": ">=5.3.3", 1115 | "sebastian/diff": "~1.2", 1116 | "sebastian/exporter": "~1.2 || ~2.0" 1117 | }, 1118 | "require-dev": { 1119 | "phpunit/phpunit": "~4.4" 1120 | }, 1121 | "type": "library", 1122 | "extra": { 1123 | "branch-alias": { 1124 | "dev-master": "1.2.x-dev" 1125 | } 1126 | }, 1127 | "autoload": { 1128 | "classmap": [ 1129 | "src/" 1130 | ] 1131 | }, 1132 | "notification-url": "https://packagist.org/downloads/", 1133 | "license": [ 1134 | "BSD-3-Clause" 1135 | ], 1136 | "authors": [ 1137 | { 1138 | "name": "Jeff Welch", 1139 | "email": "whatthejeff@gmail.com" 1140 | }, 1141 | { 1142 | "name": "Volker Dusch", 1143 | "email": "github@wallbash.com" 1144 | }, 1145 | { 1146 | "name": "Bernhard Schussek", 1147 | "email": "bschussek@2bepublished.at" 1148 | }, 1149 | { 1150 | "name": "Sebastian Bergmann", 1151 | "email": "sebastian@phpunit.de" 1152 | } 1153 | ], 1154 | "description": "Provides the functionality to compare PHP values for equality", 1155 | "homepage": "http://www.github.com/sebastianbergmann/comparator", 1156 | "keywords": [ 1157 | "comparator", 1158 | "compare", 1159 | "equality" 1160 | ], 1161 | "time": "2017-01-29T09:50:25+00:00" 1162 | }, 1163 | { 1164 | "name": "sebastian/diff", 1165 | "version": "1.4.3", 1166 | "source": { 1167 | "type": "git", 1168 | "url": "https://github.com/sebastianbergmann/diff.git", 1169 | "reference": "7f066a26a962dbe58ddea9f72a4e82874a3975a4" 1170 | }, 1171 | "dist": { 1172 | "type": "zip", 1173 | "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/7f066a26a962dbe58ddea9f72a4e82874a3975a4", 1174 | "reference": "7f066a26a962dbe58ddea9f72a4e82874a3975a4", 1175 | "shasum": "" 1176 | }, 1177 | "require": { 1178 | "php": "^5.3.3 || ^7.0" 1179 | }, 1180 | "require-dev": { 1181 | "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0" 1182 | }, 1183 | "type": "library", 1184 | "extra": { 1185 | "branch-alias": { 1186 | "dev-master": "1.4-dev" 1187 | } 1188 | }, 1189 | "autoload": { 1190 | "classmap": [ 1191 | "src/" 1192 | ] 1193 | }, 1194 | "notification-url": "https://packagist.org/downloads/", 1195 | "license": [ 1196 | "BSD-3-Clause" 1197 | ], 1198 | "authors": [ 1199 | { 1200 | "name": "Kore Nordmann", 1201 | "email": "mail@kore-nordmann.de" 1202 | }, 1203 | { 1204 | "name": "Sebastian Bergmann", 1205 | "email": "sebastian@phpunit.de" 1206 | } 1207 | ], 1208 | "description": "Diff implementation", 1209 | "homepage": "https://github.com/sebastianbergmann/diff", 1210 | "keywords": [ 1211 | "diff" 1212 | ], 1213 | "time": "2017-05-22T07:24:03+00:00" 1214 | }, 1215 | { 1216 | "name": "sebastian/environment", 1217 | "version": "1.3.8", 1218 | "source": { 1219 | "type": "git", 1220 | "url": "https://github.com/sebastianbergmann/environment.git", 1221 | "reference": "be2c607e43ce4c89ecd60e75c6a85c126e754aea" 1222 | }, 1223 | "dist": { 1224 | "type": "zip", 1225 | "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/be2c607e43ce4c89ecd60e75c6a85c126e754aea", 1226 | "reference": "be2c607e43ce4c89ecd60e75c6a85c126e754aea", 1227 | "shasum": "" 1228 | }, 1229 | "require": { 1230 | "php": "^5.3.3 || ^7.0" 1231 | }, 1232 | "require-dev": { 1233 | "phpunit/phpunit": "^4.8 || ^5.0" 1234 | }, 1235 | "type": "library", 1236 | "extra": { 1237 | "branch-alias": { 1238 | "dev-master": "1.3.x-dev" 1239 | } 1240 | }, 1241 | "autoload": { 1242 | "classmap": [ 1243 | "src/" 1244 | ] 1245 | }, 1246 | "notification-url": "https://packagist.org/downloads/", 1247 | "license": [ 1248 | "BSD-3-Clause" 1249 | ], 1250 | "authors": [ 1251 | { 1252 | "name": "Sebastian Bergmann", 1253 | "email": "sebastian@phpunit.de" 1254 | } 1255 | ], 1256 | "description": "Provides functionality to handle HHVM/PHP environments", 1257 | "homepage": "http://www.github.com/sebastianbergmann/environment", 1258 | "keywords": [ 1259 | "Xdebug", 1260 | "environment", 1261 | "hhvm" 1262 | ], 1263 | "time": "2016-08-18T05:49:44+00:00" 1264 | }, 1265 | { 1266 | "name": "sebastian/exporter", 1267 | "version": "1.2.2", 1268 | "source": { 1269 | "type": "git", 1270 | "url": "https://github.com/sebastianbergmann/exporter.git", 1271 | "reference": "42c4c2eec485ee3e159ec9884f95b431287edde4" 1272 | }, 1273 | "dist": { 1274 | "type": "zip", 1275 | "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/42c4c2eec485ee3e159ec9884f95b431287edde4", 1276 | "reference": "42c4c2eec485ee3e159ec9884f95b431287edde4", 1277 | "shasum": "" 1278 | }, 1279 | "require": { 1280 | "php": ">=5.3.3", 1281 | "sebastian/recursion-context": "~1.0" 1282 | }, 1283 | "require-dev": { 1284 | "ext-mbstring": "*", 1285 | "phpunit/phpunit": "~4.4" 1286 | }, 1287 | "type": "library", 1288 | "extra": { 1289 | "branch-alias": { 1290 | "dev-master": "1.3.x-dev" 1291 | } 1292 | }, 1293 | "autoload": { 1294 | "classmap": [ 1295 | "src/" 1296 | ] 1297 | }, 1298 | "notification-url": "https://packagist.org/downloads/", 1299 | "license": [ 1300 | "BSD-3-Clause" 1301 | ], 1302 | "authors": [ 1303 | { 1304 | "name": "Jeff Welch", 1305 | "email": "whatthejeff@gmail.com" 1306 | }, 1307 | { 1308 | "name": "Volker Dusch", 1309 | "email": "github@wallbash.com" 1310 | }, 1311 | { 1312 | "name": "Bernhard Schussek", 1313 | "email": "bschussek@2bepublished.at" 1314 | }, 1315 | { 1316 | "name": "Sebastian Bergmann", 1317 | "email": "sebastian@phpunit.de" 1318 | }, 1319 | { 1320 | "name": "Adam Harvey", 1321 | "email": "aharvey@php.net" 1322 | } 1323 | ], 1324 | "description": "Provides the functionality to export PHP variables for visualization", 1325 | "homepage": "http://www.github.com/sebastianbergmann/exporter", 1326 | "keywords": [ 1327 | "export", 1328 | "exporter" 1329 | ], 1330 | "time": "2016-06-17T09:04:28+00:00" 1331 | }, 1332 | { 1333 | "name": "sebastian/global-state", 1334 | "version": "1.1.1", 1335 | "source": { 1336 | "type": "git", 1337 | "url": "https://github.com/sebastianbergmann/global-state.git", 1338 | "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4" 1339 | }, 1340 | "dist": { 1341 | "type": "zip", 1342 | "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bc37d50fea7d017d3d340f230811c9f1d7280af4", 1343 | "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4", 1344 | "shasum": "" 1345 | }, 1346 | "require": { 1347 | "php": ">=5.3.3" 1348 | }, 1349 | "require-dev": { 1350 | "phpunit/phpunit": "~4.2" 1351 | }, 1352 | "suggest": { 1353 | "ext-uopz": "*" 1354 | }, 1355 | "type": "library", 1356 | "extra": { 1357 | "branch-alias": { 1358 | "dev-master": "1.0-dev" 1359 | } 1360 | }, 1361 | "autoload": { 1362 | "classmap": [ 1363 | "src/" 1364 | ] 1365 | }, 1366 | "notification-url": "https://packagist.org/downloads/", 1367 | "license": [ 1368 | "BSD-3-Clause" 1369 | ], 1370 | "authors": [ 1371 | { 1372 | "name": "Sebastian Bergmann", 1373 | "email": "sebastian@phpunit.de" 1374 | } 1375 | ], 1376 | "description": "Snapshotting of global state", 1377 | "homepage": "http://www.github.com/sebastianbergmann/global-state", 1378 | "keywords": [ 1379 | "global state" 1380 | ], 1381 | "time": "2015-10-12T03:26:01+00:00" 1382 | }, 1383 | { 1384 | "name": "sebastian/recursion-context", 1385 | "version": "1.0.5", 1386 | "source": { 1387 | "type": "git", 1388 | "url": "https://github.com/sebastianbergmann/recursion-context.git", 1389 | "reference": "b19cc3298482a335a95f3016d2f8a6950f0fbcd7" 1390 | }, 1391 | "dist": { 1392 | "type": "zip", 1393 | "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/b19cc3298482a335a95f3016d2f8a6950f0fbcd7", 1394 | "reference": "b19cc3298482a335a95f3016d2f8a6950f0fbcd7", 1395 | "shasum": "" 1396 | }, 1397 | "require": { 1398 | "php": ">=5.3.3" 1399 | }, 1400 | "require-dev": { 1401 | "phpunit/phpunit": "~4.4" 1402 | }, 1403 | "type": "library", 1404 | "extra": { 1405 | "branch-alias": { 1406 | "dev-master": "1.0.x-dev" 1407 | } 1408 | }, 1409 | "autoload": { 1410 | "classmap": [ 1411 | "src/" 1412 | ] 1413 | }, 1414 | "notification-url": "https://packagist.org/downloads/", 1415 | "license": [ 1416 | "BSD-3-Clause" 1417 | ], 1418 | "authors": [ 1419 | { 1420 | "name": "Jeff Welch", 1421 | "email": "whatthejeff@gmail.com" 1422 | }, 1423 | { 1424 | "name": "Sebastian Bergmann", 1425 | "email": "sebastian@phpunit.de" 1426 | }, 1427 | { 1428 | "name": "Adam Harvey", 1429 | "email": "aharvey@php.net" 1430 | } 1431 | ], 1432 | "description": "Provides functionality to recursively process PHP variables", 1433 | "homepage": "http://www.github.com/sebastianbergmann/recursion-context", 1434 | "time": "2016-10-03T07:41:43+00:00" 1435 | }, 1436 | { 1437 | "name": "sebastian/version", 1438 | "version": "1.0.6", 1439 | "source": { 1440 | "type": "git", 1441 | "url": "https://github.com/sebastianbergmann/version.git", 1442 | "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6" 1443 | }, 1444 | "dist": { 1445 | "type": "zip", 1446 | "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/58b3a85e7999757d6ad81c787a1fbf5ff6c628c6", 1447 | "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6", 1448 | "shasum": "" 1449 | }, 1450 | "type": "library", 1451 | "autoload": { 1452 | "classmap": [ 1453 | "src/" 1454 | ] 1455 | }, 1456 | "notification-url": "https://packagist.org/downloads/", 1457 | "license": [ 1458 | "BSD-3-Clause" 1459 | ], 1460 | "authors": [ 1461 | { 1462 | "name": "Sebastian Bergmann", 1463 | "email": "sebastian@phpunit.de", 1464 | "role": "lead" 1465 | } 1466 | ], 1467 | "description": "Library that helps with managing the version number of Git-hosted PHP projects", 1468 | "homepage": "https://github.com/sebastianbergmann/version", 1469 | "time": "2015-06-21T13:59:46+00:00" 1470 | }, 1471 | { 1472 | "name": "seld/jsonlint", 1473 | "version": "1.7.1", 1474 | "source": { 1475 | "type": "git", 1476 | "url": "https://github.com/Seldaek/jsonlint.git", 1477 | "reference": "d15f59a67ff805a44c50ea0516d2341740f81a38" 1478 | }, 1479 | "dist": { 1480 | "type": "zip", 1481 | "url": "https://api.github.com/repos/Seldaek/jsonlint/zipball/d15f59a67ff805a44c50ea0516d2341740f81a38", 1482 | "reference": "d15f59a67ff805a44c50ea0516d2341740f81a38", 1483 | "shasum": "" 1484 | }, 1485 | "require": { 1486 | "php": "^5.3 || ^7.0" 1487 | }, 1488 | "require-dev": { 1489 | "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0" 1490 | }, 1491 | "bin": [ 1492 | "bin/jsonlint" 1493 | ], 1494 | "type": "library", 1495 | "autoload": { 1496 | "psr-4": { 1497 | "Seld\\JsonLint\\": "src/Seld/JsonLint/" 1498 | } 1499 | }, 1500 | "notification-url": "https://packagist.org/downloads/", 1501 | "license": [ 1502 | "MIT" 1503 | ], 1504 | "authors": [ 1505 | { 1506 | "name": "Jordi Boggiano", 1507 | "email": "j.boggiano@seld.be", 1508 | "homepage": "http://seld.be" 1509 | } 1510 | ], 1511 | "description": "JSON Linter", 1512 | "keywords": [ 1513 | "json", 1514 | "linter", 1515 | "parser", 1516 | "validator" 1517 | ], 1518 | "time": "2018-01-24T12:46:19+00:00" 1519 | }, 1520 | { 1521 | "name": "seld/phar-utils", 1522 | "version": "1.0.1", 1523 | "source": { 1524 | "type": "git", 1525 | "url": "https://github.com/Seldaek/phar-utils.git", 1526 | "reference": "7009b5139491975ef6486545a39f3e6dad5ac30a" 1527 | }, 1528 | "dist": { 1529 | "type": "zip", 1530 | "url": "https://api.github.com/repos/Seldaek/phar-utils/zipball/7009b5139491975ef6486545a39f3e6dad5ac30a", 1531 | "reference": "7009b5139491975ef6486545a39f3e6dad5ac30a", 1532 | "shasum": "" 1533 | }, 1534 | "require": { 1535 | "php": ">=5.3" 1536 | }, 1537 | "type": "library", 1538 | "extra": { 1539 | "branch-alias": { 1540 | "dev-master": "1.x-dev" 1541 | } 1542 | }, 1543 | "autoload": { 1544 | "psr-4": { 1545 | "Seld\\PharUtils\\": "src/" 1546 | } 1547 | }, 1548 | "notification-url": "https://packagist.org/downloads/", 1549 | "license": [ 1550 | "MIT" 1551 | ], 1552 | "authors": [ 1553 | { 1554 | "name": "Jordi Boggiano", 1555 | "email": "j.boggiano@seld.be" 1556 | } 1557 | ], 1558 | "description": "PHAR file format utilities, for when PHP phars you up", 1559 | "keywords": [ 1560 | "phra" 1561 | ], 1562 | "time": "2015-10-13T18:44:15+00:00" 1563 | }, 1564 | { 1565 | "name": "squizlabs/php_codesniffer", 1566 | "version": "2.9.2", 1567 | "source": { 1568 | "type": "git", 1569 | "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", 1570 | "reference": "2acf168de78487db620ab4bc524135a13cfe6745" 1571 | }, 1572 | "dist": { 1573 | "type": "zip", 1574 | "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/2acf168de78487db620ab4bc524135a13cfe6745", 1575 | "reference": "2acf168de78487db620ab4bc524135a13cfe6745", 1576 | "shasum": "" 1577 | }, 1578 | "require": { 1579 | "ext-simplexml": "*", 1580 | "ext-tokenizer": "*", 1581 | "ext-xmlwriter": "*", 1582 | "php": ">=5.1.2" 1583 | }, 1584 | "require-dev": { 1585 | "phpunit/phpunit": "~4.0" 1586 | }, 1587 | "bin": [ 1588 | "scripts/phpcs", 1589 | "scripts/phpcbf" 1590 | ], 1591 | "type": "library", 1592 | "extra": { 1593 | "branch-alias": { 1594 | "dev-master": "2.x-dev" 1595 | } 1596 | }, 1597 | "autoload": { 1598 | "classmap": [ 1599 | "CodeSniffer.php", 1600 | "CodeSniffer/CLI.php", 1601 | "CodeSniffer/Exception.php", 1602 | "CodeSniffer/File.php", 1603 | "CodeSniffer/Fixer.php", 1604 | "CodeSniffer/Report.php", 1605 | "CodeSniffer/Reporting.php", 1606 | "CodeSniffer/Sniff.php", 1607 | "CodeSniffer/Tokens.php", 1608 | "CodeSniffer/Reports/", 1609 | "CodeSniffer/Tokenizers/", 1610 | "CodeSniffer/DocGenerators/", 1611 | "CodeSniffer/Standards/AbstractPatternSniff.php", 1612 | "CodeSniffer/Standards/AbstractScopeSniff.php", 1613 | "CodeSniffer/Standards/AbstractVariableSniff.php", 1614 | "CodeSniffer/Standards/IncorrectPatternException.php", 1615 | "CodeSniffer/Standards/Generic/Sniffs/", 1616 | "CodeSniffer/Standards/MySource/Sniffs/", 1617 | "CodeSniffer/Standards/PEAR/Sniffs/", 1618 | "CodeSniffer/Standards/PSR1/Sniffs/", 1619 | "CodeSniffer/Standards/PSR2/Sniffs/", 1620 | "CodeSniffer/Standards/Squiz/Sniffs/", 1621 | "CodeSniffer/Standards/Zend/Sniffs/" 1622 | ] 1623 | }, 1624 | "notification-url": "https://packagist.org/downloads/", 1625 | "license": [ 1626 | "BSD-3-Clause" 1627 | ], 1628 | "authors": [ 1629 | { 1630 | "name": "Greg Sherwood", 1631 | "role": "lead" 1632 | } 1633 | ], 1634 | "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.", 1635 | "homepage": "http://www.squizlabs.com/php-codesniffer", 1636 | "keywords": [ 1637 | "phpcs", 1638 | "standards" 1639 | ], 1640 | "time": "2018-11-07T22:31:41+00:00" 1641 | }, 1642 | { 1643 | "name": "symfony/console", 1644 | "version": "v3.4.21", 1645 | "source": { 1646 | "type": "git", 1647 | "url": "https://github.com/symfony/console.git", 1648 | "reference": "a700b874d3692bc8342199adfb6d3b99f62cc61a" 1649 | }, 1650 | "dist": { 1651 | "type": "zip", 1652 | "url": "https://api.github.com/repos/symfony/console/zipball/a700b874d3692bc8342199adfb6d3b99f62cc61a", 1653 | "reference": "a700b874d3692bc8342199adfb6d3b99f62cc61a", 1654 | "shasum": "" 1655 | }, 1656 | "require": { 1657 | "php": "^5.5.9|>=7.0.8", 1658 | "symfony/debug": "~2.8|~3.0|~4.0", 1659 | "symfony/polyfill-mbstring": "~1.0" 1660 | }, 1661 | "conflict": { 1662 | "symfony/dependency-injection": "<3.4", 1663 | "symfony/process": "<3.3" 1664 | }, 1665 | "require-dev": { 1666 | "psr/log": "~1.0", 1667 | "symfony/config": "~3.3|~4.0", 1668 | "symfony/dependency-injection": "~3.4|~4.0", 1669 | "symfony/event-dispatcher": "~2.8|~3.0|~4.0", 1670 | "symfony/lock": "~3.4|~4.0", 1671 | "symfony/process": "~3.3|~4.0" 1672 | }, 1673 | "suggest": { 1674 | "psr/log-implementation": "For using the console logger", 1675 | "symfony/event-dispatcher": "", 1676 | "symfony/lock": "", 1677 | "symfony/process": "" 1678 | }, 1679 | "type": "library", 1680 | "extra": { 1681 | "branch-alias": { 1682 | "dev-master": "3.4-dev" 1683 | } 1684 | }, 1685 | "autoload": { 1686 | "psr-4": { 1687 | "Symfony\\Component\\Console\\": "" 1688 | }, 1689 | "exclude-from-classmap": [ 1690 | "/Tests/" 1691 | ] 1692 | }, 1693 | "notification-url": "https://packagist.org/downloads/", 1694 | "license": [ 1695 | "MIT" 1696 | ], 1697 | "authors": [ 1698 | { 1699 | "name": "Fabien Potencier", 1700 | "email": "fabien@symfony.com" 1701 | }, 1702 | { 1703 | "name": "Symfony Community", 1704 | "homepage": "https://symfony.com/contributors" 1705 | } 1706 | ], 1707 | "description": "Symfony Console Component", 1708 | "homepage": "https://symfony.com", 1709 | "time": "2019-01-04T04:42:43+00:00" 1710 | }, 1711 | { 1712 | "name": "symfony/debug", 1713 | "version": "v3.4.21", 1714 | "source": { 1715 | "type": "git", 1716 | "url": "https://github.com/symfony/debug.git", 1717 | "reference": "26d7f23b9bd0b93bee5583e4d6ca5cb1ab31b186" 1718 | }, 1719 | "dist": { 1720 | "type": "zip", 1721 | "url": "https://api.github.com/repos/symfony/debug/zipball/26d7f23b9bd0b93bee5583e4d6ca5cb1ab31b186", 1722 | "reference": "26d7f23b9bd0b93bee5583e4d6ca5cb1ab31b186", 1723 | "shasum": "" 1724 | }, 1725 | "require": { 1726 | "php": "^5.5.9|>=7.0.8", 1727 | "psr/log": "~1.0" 1728 | }, 1729 | "conflict": { 1730 | "symfony/http-kernel": ">=2.3,<2.3.24|~2.4.0|>=2.5,<2.5.9|>=2.6,<2.6.2" 1731 | }, 1732 | "require-dev": { 1733 | "symfony/http-kernel": "~2.8|~3.0|~4.0" 1734 | }, 1735 | "type": "library", 1736 | "extra": { 1737 | "branch-alias": { 1738 | "dev-master": "3.4-dev" 1739 | } 1740 | }, 1741 | "autoload": { 1742 | "psr-4": { 1743 | "Symfony\\Component\\Debug\\": "" 1744 | }, 1745 | "exclude-from-classmap": [ 1746 | "/Tests/" 1747 | ] 1748 | }, 1749 | "notification-url": "https://packagist.org/downloads/", 1750 | "license": [ 1751 | "MIT" 1752 | ], 1753 | "authors": [ 1754 | { 1755 | "name": "Fabien Potencier", 1756 | "email": "fabien@symfony.com" 1757 | }, 1758 | { 1759 | "name": "Symfony Community", 1760 | "homepage": "https://symfony.com/contributors" 1761 | } 1762 | ], 1763 | "description": "Symfony Debug Component", 1764 | "homepage": "https://symfony.com", 1765 | "time": "2019-01-01T13:45:19+00:00" 1766 | }, 1767 | { 1768 | "name": "symfony/filesystem", 1769 | "version": "v3.4.21", 1770 | "source": { 1771 | "type": "git", 1772 | "url": "https://github.com/symfony/filesystem.git", 1773 | "reference": "c24ce3d18ccc9bb9d7e1d6ce9330fcc6061cafde" 1774 | }, 1775 | "dist": { 1776 | "type": "zip", 1777 | "url": "https://api.github.com/repos/symfony/filesystem/zipball/c24ce3d18ccc9bb9d7e1d6ce9330fcc6061cafde", 1778 | "reference": "c24ce3d18ccc9bb9d7e1d6ce9330fcc6061cafde", 1779 | "shasum": "" 1780 | }, 1781 | "require": { 1782 | "php": "^5.5.9|>=7.0.8", 1783 | "symfony/polyfill-ctype": "~1.8" 1784 | }, 1785 | "type": "library", 1786 | "extra": { 1787 | "branch-alias": { 1788 | "dev-master": "3.4-dev" 1789 | } 1790 | }, 1791 | "autoload": { 1792 | "psr-4": { 1793 | "Symfony\\Component\\Filesystem\\": "" 1794 | }, 1795 | "exclude-from-classmap": [ 1796 | "/Tests/" 1797 | ] 1798 | }, 1799 | "notification-url": "https://packagist.org/downloads/", 1800 | "license": [ 1801 | "MIT" 1802 | ], 1803 | "authors": [ 1804 | { 1805 | "name": "Fabien Potencier", 1806 | "email": "fabien@symfony.com" 1807 | }, 1808 | { 1809 | "name": "Symfony Community", 1810 | "homepage": "https://symfony.com/contributors" 1811 | } 1812 | ], 1813 | "description": "Symfony Filesystem Component", 1814 | "homepage": "https://symfony.com", 1815 | "time": "2019-01-01T13:45:19+00:00" 1816 | }, 1817 | { 1818 | "name": "symfony/finder", 1819 | "version": "v3.4.21", 1820 | "source": { 1821 | "type": "git", 1822 | "url": "https://github.com/symfony/finder.git", 1823 | "reference": "3f2a2ab6315dd7682d4c16dcae1e7b95c8b8555e" 1824 | }, 1825 | "dist": { 1826 | "type": "zip", 1827 | "url": "https://api.github.com/repos/symfony/finder/zipball/3f2a2ab6315dd7682d4c16dcae1e7b95c8b8555e", 1828 | "reference": "3f2a2ab6315dd7682d4c16dcae1e7b95c8b8555e", 1829 | "shasum": "" 1830 | }, 1831 | "require": { 1832 | "php": "^5.5.9|>=7.0.8" 1833 | }, 1834 | "type": "library", 1835 | "extra": { 1836 | "branch-alias": { 1837 | "dev-master": "3.4-dev" 1838 | } 1839 | }, 1840 | "autoload": { 1841 | "psr-4": { 1842 | "Symfony\\Component\\Finder\\": "" 1843 | }, 1844 | "exclude-from-classmap": [ 1845 | "/Tests/" 1846 | ] 1847 | }, 1848 | "notification-url": "https://packagist.org/downloads/", 1849 | "license": [ 1850 | "MIT" 1851 | ], 1852 | "authors": [ 1853 | { 1854 | "name": "Fabien Potencier", 1855 | "email": "fabien@symfony.com" 1856 | }, 1857 | { 1858 | "name": "Symfony Community", 1859 | "homepage": "https://symfony.com/contributors" 1860 | } 1861 | ], 1862 | "description": "Symfony Finder Component", 1863 | "homepage": "https://symfony.com", 1864 | "time": "2019-01-01T13:45:19+00:00" 1865 | }, 1866 | { 1867 | "name": "symfony/polyfill-ctype", 1868 | "version": "v1.10.0", 1869 | "source": { 1870 | "type": "git", 1871 | "url": "https://github.com/symfony/polyfill-ctype.git", 1872 | "reference": "e3d826245268269cd66f8326bd8bc066687b4a19" 1873 | }, 1874 | "dist": { 1875 | "type": "zip", 1876 | "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/e3d826245268269cd66f8326bd8bc066687b4a19", 1877 | "reference": "e3d826245268269cd66f8326bd8bc066687b4a19", 1878 | "shasum": "" 1879 | }, 1880 | "require": { 1881 | "php": ">=5.3.3" 1882 | }, 1883 | "suggest": { 1884 | "ext-ctype": "For best performance" 1885 | }, 1886 | "type": "library", 1887 | "extra": { 1888 | "branch-alias": { 1889 | "dev-master": "1.9-dev" 1890 | } 1891 | }, 1892 | "autoload": { 1893 | "psr-4": { 1894 | "Symfony\\Polyfill\\Ctype\\": "" 1895 | }, 1896 | "files": [ 1897 | "bootstrap.php" 1898 | ] 1899 | }, 1900 | "notification-url": "https://packagist.org/downloads/", 1901 | "license": [ 1902 | "MIT" 1903 | ], 1904 | "authors": [ 1905 | { 1906 | "name": "Symfony Community", 1907 | "homepage": "https://symfony.com/contributors" 1908 | }, 1909 | { 1910 | "name": "Gert de Pagter", 1911 | "email": "BackEndTea@gmail.com" 1912 | } 1913 | ], 1914 | "description": "Symfony polyfill for ctype functions", 1915 | "homepage": "https://symfony.com", 1916 | "keywords": [ 1917 | "compatibility", 1918 | "ctype", 1919 | "polyfill", 1920 | "portable" 1921 | ], 1922 | "time": "2018-08-06T14:22:27+00:00" 1923 | }, 1924 | { 1925 | "name": "symfony/polyfill-mbstring", 1926 | "version": "v1.10.0", 1927 | "source": { 1928 | "type": "git", 1929 | "url": "https://github.com/symfony/polyfill-mbstring.git", 1930 | "reference": "c79c051f5b3a46be09205c73b80b346e4153e494" 1931 | }, 1932 | "dist": { 1933 | "type": "zip", 1934 | "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/c79c051f5b3a46be09205c73b80b346e4153e494", 1935 | "reference": "c79c051f5b3a46be09205c73b80b346e4153e494", 1936 | "shasum": "" 1937 | }, 1938 | "require": { 1939 | "php": ">=5.3.3" 1940 | }, 1941 | "suggest": { 1942 | "ext-mbstring": "For best performance" 1943 | }, 1944 | "type": "library", 1945 | "extra": { 1946 | "branch-alias": { 1947 | "dev-master": "1.9-dev" 1948 | } 1949 | }, 1950 | "autoload": { 1951 | "psr-4": { 1952 | "Symfony\\Polyfill\\Mbstring\\": "" 1953 | }, 1954 | "files": [ 1955 | "bootstrap.php" 1956 | ] 1957 | }, 1958 | "notification-url": "https://packagist.org/downloads/", 1959 | "license": [ 1960 | "MIT" 1961 | ], 1962 | "authors": [ 1963 | { 1964 | "name": "Nicolas Grekas", 1965 | "email": "p@tchwork.com" 1966 | }, 1967 | { 1968 | "name": "Symfony Community", 1969 | "homepage": "https://symfony.com/contributors" 1970 | } 1971 | ], 1972 | "description": "Symfony polyfill for the Mbstring extension", 1973 | "homepage": "https://symfony.com", 1974 | "keywords": [ 1975 | "compatibility", 1976 | "mbstring", 1977 | "polyfill", 1978 | "portable", 1979 | "shim" 1980 | ], 1981 | "time": "2018-09-21T13:07:52+00:00" 1982 | }, 1983 | { 1984 | "name": "symfony/process", 1985 | "version": "v3.4.21", 1986 | "source": { 1987 | "type": "git", 1988 | "url": "https://github.com/symfony/process.git", 1989 | "reference": "0d41dd7d95ed179aed6a13393b0f4f97bfa2d25c" 1990 | }, 1991 | "dist": { 1992 | "type": "zip", 1993 | "url": "https://api.github.com/repos/symfony/process/zipball/0d41dd7d95ed179aed6a13393b0f4f97bfa2d25c", 1994 | "reference": "0d41dd7d95ed179aed6a13393b0f4f97bfa2d25c", 1995 | "shasum": "" 1996 | }, 1997 | "require": { 1998 | "php": "^5.5.9|>=7.0.8" 1999 | }, 2000 | "type": "library", 2001 | "extra": { 2002 | "branch-alias": { 2003 | "dev-master": "3.4-dev" 2004 | } 2005 | }, 2006 | "autoload": { 2007 | "psr-4": { 2008 | "Symfony\\Component\\Process\\": "" 2009 | }, 2010 | "exclude-from-classmap": [ 2011 | "/Tests/" 2012 | ] 2013 | }, 2014 | "notification-url": "https://packagist.org/downloads/", 2015 | "license": [ 2016 | "MIT" 2017 | ], 2018 | "authors": [ 2019 | { 2020 | "name": "Fabien Potencier", 2021 | "email": "fabien@symfony.com" 2022 | }, 2023 | { 2024 | "name": "Symfony Community", 2025 | "homepage": "https://symfony.com/contributors" 2026 | } 2027 | ], 2028 | "description": "Symfony Process Component", 2029 | "homepage": "https://symfony.com", 2030 | "time": "2019-01-02T21:24:08+00:00" 2031 | }, 2032 | { 2033 | "name": "symfony/yaml", 2034 | "version": "v3.4.21", 2035 | "source": { 2036 | "type": "git", 2037 | "url": "https://github.com/symfony/yaml.git", 2038 | "reference": "554a59a1ccbaac238a89b19c8e551a556fd0e2ea" 2039 | }, 2040 | "dist": { 2041 | "type": "zip", 2042 | "url": "https://api.github.com/repos/symfony/yaml/zipball/554a59a1ccbaac238a89b19c8e551a556fd0e2ea", 2043 | "reference": "554a59a1ccbaac238a89b19c8e551a556fd0e2ea", 2044 | "shasum": "" 2045 | }, 2046 | "require": { 2047 | "php": "^5.5.9|>=7.0.8", 2048 | "symfony/polyfill-ctype": "~1.8" 2049 | }, 2050 | "conflict": { 2051 | "symfony/console": "<3.4" 2052 | }, 2053 | "require-dev": { 2054 | "symfony/console": "~3.4|~4.0" 2055 | }, 2056 | "suggest": { 2057 | "symfony/console": "For validating YAML files using the lint command" 2058 | }, 2059 | "type": "library", 2060 | "extra": { 2061 | "branch-alias": { 2062 | "dev-master": "3.4-dev" 2063 | } 2064 | }, 2065 | "autoload": { 2066 | "psr-4": { 2067 | "Symfony\\Component\\Yaml\\": "" 2068 | }, 2069 | "exclude-from-classmap": [ 2070 | "/Tests/" 2071 | ] 2072 | }, 2073 | "notification-url": "https://packagist.org/downloads/", 2074 | "license": [ 2075 | "MIT" 2076 | ], 2077 | "authors": [ 2078 | { 2079 | "name": "Fabien Potencier", 2080 | "email": "fabien@symfony.com" 2081 | }, 2082 | { 2083 | "name": "Symfony Community", 2084 | "homepage": "https://symfony.com/contributors" 2085 | } 2086 | ], 2087 | "description": "Symfony Yaml Component", 2088 | "homepage": "https://symfony.com", 2089 | "time": "2019-01-01T13:45:19+00:00" 2090 | }, 2091 | { 2092 | "name": "webmozart/assert", 2093 | "version": "1.4.0", 2094 | "source": { 2095 | "type": "git", 2096 | "url": "https://github.com/webmozart/assert.git", 2097 | "reference": "83e253c8e0be5b0257b881e1827274667c5c17a9" 2098 | }, 2099 | "dist": { 2100 | "type": "zip", 2101 | "url": "https://api.github.com/repos/webmozart/assert/zipball/83e253c8e0be5b0257b881e1827274667c5c17a9", 2102 | "reference": "83e253c8e0be5b0257b881e1827274667c5c17a9", 2103 | "shasum": "" 2104 | }, 2105 | "require": { 2106 | "php": "^5.3.3 || ^7.0", 2107 | "symfony/polyfill-ctype": "^1.8" 2108 | }, 2109 | "require-dev": { 2110 | "phpunit/phpunit": "^4.6", 2111 | "sebastian/version": "^1.0.1" 2112 | }, 2113 | "type": "library", 2114 | "extra": { 2115 | "branch-alias": { 2116 | "dev-master": "1.3-dev" 2117 | } 2118 | }, 2119 | "autoload": { 2120 | "psr-4": { 2121 | "Webmozart\\Assert\\": "src/" 2122 | } 2123 | }, 2124 | "notification-url": "https://packagist.org/downloads/", 2125 | "license": [ 2126 | "MIT" 2127 | ], 2128 | "authors": [ 2129 | { 2130 | "name": "Bernhard Schussek", 2131 | "email": "bschussek@gmail.com" 2132 | } 2133 | ], 2134 | "description": "Assertions to validate method input/output with nice error messages.", 2135 | "keywords": [ 2136 | "assert", 2137 | "check", 2138 | "validate" 2139 | ], 2140 | "time": "2018-12-25T11:19:39+00:00" 2141 | } 2142 | ], 2143 | "aliases": [], 2144 | "minimum-stability": "stable", 2145 | "stability-flags": { 2146 | "composer/composer": 20 2147 | }, 2148 | "prefer-stable": false, 2149 | "prefer-lowest": false, 2150 | "platform": { 2151 | "php": "^5.5.9|>=7.0.8" 2152 | }, 2153 | "platform-dev": [], 2154 | "platform-overrides": { 2155 | "php": "5.5.27" 2156 | } 2157 | } 2158 | -------------------------------------------------------------------------------- /.scenarios.lock/phpunit4/src: -------------------------------------------------------------------------------- 1 | ../../src -------------------------------------------------------------------------------- /.scenarios.lock/phpunit4/tests: -------------------------------------------------------------------------------- 1 | ../../tests -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: php 2 | 3 | branches: 4 | # Only test the master branch and SemVer tags. 5 | only: 6 | - master 7 | - /^[[:digit:]]+\.[[:digit:]]+\.[[:digit:]]+.*$/ 8 | 9 | matrix: 10 | fast_finish: true 11 | include: 12 | - php: 7.2 13 | env: 'DEPENCENCIES=highest' 14 | - php: 7.2 15 | - php: 7.1 16 | - php: 7.0.11 17 | - php: 5.6 18 | env: 'SCENARIO=phpunit4' 19 | - php: 5.5 20 | env: 'SCENARIO=phpunit4' 21 | - php: 5.5 22 | env: 'SCENARIO=phpunit4 DEPENDENCIES=lowest' 23 | 24 | sudo: false 25 | 26 | git: 27 | depth: 10000 28 | 29 | before_install: 30 | - phpenv config-rm xdebug.ini 31 | - composer --verbose self-update 32 | - composer --version 33 | 34 | install: 35 | - 'composer scenario "${SCENARIO}" "${DEPENDENCIES}"' 36 | 37 | before_script: 38 | - git config --global user.email "travisci@example.com" 39 | - git config --global user.name "Travis CI Test" 40 | - export COMPOSER_PROCESS_TIMEOUT=600 41 | 42 | script: 43 | - composer test 44 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # drupal-scaffold 2 | 3 | [![Build Status](https://travis-ci.org/drupal-composer/drupal-scaffold.svg?branch=master)](https://travis-ci.org/drupal-composer/drupal-scaffold) 4 | 5 | # DEPRECATED - DO NOT USE 6 | 7 | This project is deprecated. Please use [drupal/core-composer-scaffold](https://github.com/drupal/core-composer-scaffold). 8 | 9 | If you are still using this plugin because you are on Drupal 8.7.x or earlier, please note that it **is** possible to use core-composer-scaffold with older versions of Drupal 8. Start with the template project [drupal/recommended-project](https://github.com/drupal/recommended-project), and then pin to an earlier version of drupal/core-recommended after the initial create-project is done. Note that it's generally easier to remove composer.lock and vendor first when moving back to older versions of Drupal core. 10 | 11 | # OLD README FOLLOWS 12 | 13 | Composer plugin for automatically downloading Drupal scaffold files (like 14 | `index.php`, `update.php`, …) when using `drupal/core` via Composer. 15 | 16 | It is recommended that the vendor directory be placed in its standard location 17 | at the project root, outside of the Drupal root; however, the location of the 18 | vendor directory and the name of the Drupal root may be placed in whatever 19 | location suits the project. Drupal-scaffold will generate the autoload.php 20 | file at the Drupal root to require the Composer-generated autoload file in the 21 | vendor directory. 22 | 23 | ## Usage 24 | 25 | Run `composer require drupal-composer/drupal-scaffold:dev-master` in your composer 26 | project before installing or updating `drupal/core`. 27 | 28 | Once drupal-scaffold is required by your project, it will automatically update 29 | your scaffold files whenever `composer update` changes the version of 30 | `drupal/core` installed. 31 | 32 | ## Configuration 33 | 34 | You can configure the plugin with providing some settings in the `extra` section 35 | of your root `composer.json`. 36 | 37 | ```json 38 | { 39 | "extra": { 40 | "drupal-scaffold": { 41 | "source": "https://git.drupalcode.org/project/drupal/raw/{version}/{path}", 42 | "excludes": [ 43 | "google123.html", 44 | "robots.txt" 45 | ], 46 | "includes": [ 47 | "sites/default/example.settings.my.php" 48 | ], 49 | "initial": { 50 | "sites/default/default.services.yml": "sites/default/services.yml", 51 | "sites/default/default.settings.php": "sites/default/settings.php" 52 | }, 53 | "omit-defaults": false 54 | } 55 | } 56 | } 57 | ``` 58 | The `source` option may be used to specify the URL to download the 59 | scaffold files from; the default source is drupal.org. The literal string 60 | `{version}` in the `source` option is replaced with the current version of 61 | Drupal core being updated prior to download. 62 | You can also define `source` as an array to have fallbacks in case of 63 | any HTTP issues. 64 | 65 | ```json 66 | { 67 | "extra": { 68 | "drupal-scaffold": { 69 | "source": [ 70 | "https://git.drupalcode.org/project/drupal/raw/{version}/{path}", 71 | "https://raw.githubusercontent.com/drupal/drupal/{version}/{path}" 72 | ] 73 | } 74 | } 75 | } 76 | ``` 77 | 78 | With the `drupal-scaffold` option `excludes`, you can provide additional paths 79 | that should not be copied or overwritten. The plugin provides no excludes by 80 | default. 81 | 82 | Default includes are provided by the plugin: 83 | ``` 84 | .csslintrc 85 | .editorconfig 86 | .eslintignore 87 | .eslintrc (Drupal <= 8.2.x) 88 | .eslintrc.json (Drupal >= 8.3.x) 89 | .gitattributes 90 | .ht.router.php (Drupal >= 8.5.x) 91 | .htaccess 92 | index.php 93 | robots.txt 94 | sites/default/default.settings.php 95 | sites/default/default.services.yml 96 | sites/development.services.yml 97 | sites/example.settings.local.php 98 | sites/example.sites.php 99 | update.php 100 | web.config 101 | ``` 102 | 103 | When setting `omit-defaults` to `true`, neither the default excludes nor the 104 | default includes will be provided; in this instance, only those files explicitly 105 | listed in the `excludes` and `includes` options will be considered. If 106 | `omit-defaults` is `false` (the default), then any items listed in `excludes` 107 | or `includes` will be in addition to the usual defaults. 108 | 109 | The `initial` hash lists files that should be copied over only if they do not 110 | exist in the destination. The key specifies the path to the source file, and 111 | the value indicates the path to the destination file. 112 | 113 | ## Limitation 114 | 115 | When using Composer to install or update the Drupal development branch, the 116 | scaffold files are always taken from the HEAD of the branch (or, more 117 | specifically, from the most recent development .tar.gz archive). This might 118 | not be what you want when using an old development version (e.g. when the 119 | version is fixed via composer.lock). To avoid problems, always commit your 120 | scaffold files to the repository any time that composer.lock is committed. 121 | Note that the correct scaffold files are retrieved when using a tagged release 122 | of `drupal/core` (recommended). 123 | 124 | ## Custom command 125 | 126 | The plugin by default is only downloading the scaffold files when installing or 127 | updating `drupal/core`. If you want to call it manually, you have to add the 128 | command callback to the `scripts`-section of your root `composer.json`, like this: 129 | 130 | ```json 131 | { 132 | "scripts": { 133 | "drupal-scaffold": "DrupalComposer\\DrupalScaffold\\Plugin::scaffold" 134 | } 135 | } 136 | ``` 137 | 138 | After that you can manually download the scaffold files according to your 139 | configuration by using `composer drupal:scaffold`. 140 | 141 | It is assumed that the scaffold files will be committed to the repository, to 142 | ensure that the correct files are used on the CI server (see **Limitation**, 143 | above). After running `composer install` for the first time commit the scaffold 144 | files to your repository. 145 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "drupal-composer/drupal-scaffold", 3 | "description": "Composer Plugin for updating the Drupal scaffold files when using drupal/core", 4 | "type": "composer-plugin", 5 | "license": "GPL-2.0-or-later", 6 | "require": { 7 | "php": "^5.5.9|>=7.0.8", 8 | "composer-plugin-api": "^1.0.0", 9 | "composer/semver": "^1.4" 10 | }, 11 | "autoload": { 12 | "psr-4": { 13 | "DrupalComposer\\DrupalScaffold\\": "src/" 14 | } 15 | }, 16 | "extra": { 17 | "class": "DrupalComposer\\DrupalScaffold\\Plugin", 18 | "branch-alias": { 19 | "dev-master": "2.0.x-dev" 20 | } 21 | }, 22 | "scripts": { 23 | "cs": "phpcs --standard=PSR2 -n src", 24 | "cbf": "phpcbf --standard=PSR2 -n src", 25 | "unit": "phpunit --colors=always", 26 | "lint": [ 27 | "find src -name '*.php' -print0 | xargs -0 -n1 php -l" 28 | ], 29 | "test": [ 30 | "@lint", 31 | "@unit" 32 | ], 33 | "scenario": ".scenarios.lock/install", 34 | "post-update-cmd": [ 35 | "create-scenario phpunit4 'phpunit/phpunit:^4.8.36' --platform-php '5.5.27'" 36 | ] 37 | }, 38 | "config": { 39 | "optimize-autoloader": true, 40 | "sort-packages": true, 41 | "platform": { 42 | "php": "7.0.8" 43 | } 44 | }, 45 | "require-dev": { 46 | "composer/composer": "dev-master", 47 | "g1a/composer-test-scenarios": "^2.1.0", 48 | "phpunit/phpunit": "^6", 49 | "squizlabs/php_codesniffer": "^2.8" 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /phpunit.xml.dist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 10 | 11 | 12 | ./tests/ 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/CommandProvider.php: -------------------------------------------------------------------------------- 1 | setName('drupal:scaffold') 23 | ->setDescription('Update the Drupal scaffold files.'); 24 | } 25 | 26 | /** 27 | * {@inheritdoc} 28 | */ 29 | protected function execute(InputInterface $input, OutputInterface $output) { 30 | $handler = new Handler($this->getComposer(), $this->getIO()); 31 | $handler->downloadScaffold(); 32 | // Generate the autoload.php file after generating the scaffold files. 33 | $handler->generateAutoload(); 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/FileFetcher.php: -------------------------------------------------------------------------------- 1 | remoteFilesystem = $remoteFilesystem; 64 | $this->io = $io; 65 | $this->fs = new Filesystem(); 66 | $this->progress = $progress; 67 | } 68 | 69 | /** 70 | * Downloads all required files and writes it to the file system. 71 | */ 72 | public function fetch($version, $destination, $override) { 73 | $errors = []; 74 | 75 | foreach ($this->filenames as $sourceFilename => $filename) { 76 | $target = "$destination/$filename"; 77 | if ($override || !file_exists($target)) { 78 | $url = $this->getUri($sourceFilename, $version); 79 | $this->fs->ensureDirectoryExists($destination . '/' . dirname($filename)); 80 | 81 | if ($this->progress) { 82 | $this->io->writeError(" - $filename ($url): ", FALSE); 83 | try { 84 | $this->remoteFilesystem->copy($url, $url, $target, $this->progress); 85 | } catch(\Exception $e) { 86 | $errors[] = $url; 87 | } 88 | // New line because the remoteFilesystem does not put one. 89 | $this->io->writeError(''); 90 | } 91 | else { 92 | try { 93 | $this->remoteFilesystem->copy($url, $url, $target, $this->progress); 94 | } catch(\Exception $e) { 95 | $errors[] = $url; 96 | } 97 | } 98 | } 99 | } 100 | 101 | if ($errors) { 102 | $this->addError('Failed to download: ' . "\r\n" . implode("\r\n", $errors)); 103 | return FALSE; 104 | } 105 | return TRUE; 106 | } 107 | 108 | /** 109 | * Set filenames. 110 | */ 111 | public function setFilenames(array $filenames) { 112 | $this->filenames = $filenames; 113 | } 114 | 115 | /** 116 | * Set source. 117 | */ 118 | public function setSource($source) { 119 | $this->source = $source; 120 | } 121 | 122 | /** 123 | * Set error. 124 | */ 125 | public function addError($error) { 126 | $this->errors[] = $error; 127 | } 128 | 129 | /** 130 | * Get errors. 131 | */ 132 | public function getErrors() { 133 | return $this->errors; 134 | } 135 | 136 | /** 137 | * Replace filename and version in the source pattern with their values. 138 | */ 139 | protected function getUri($filename, $version) { 140 | $map = [ 141 | '{path}' => $filename, 142 | '{version}' => $version, 143 | ]; 144 | return str_replace(array_keys($map), array_values($map), $this->source); 145 | } 146 | 147 | } 148 | -------------------------------------------------------------------------------- /src/Handler.php: -------------------------------------------------------------------------------- 1 | composer = $composer; 57 | $this->io = $io; 58 | $this->progress = TRUE; 59 | 60 | // Pre-load all of our sources so that we do not run up 61 | // against problems in `composer update` operations. 62 | $this->manualLoad(); 63 | } 64 | 65 | protected function manualLoad() { 66 | $src_dir = __DIR__; 67 | 68 | $classes = [ 69 | 'CommandProvider', 70 | 'DrupalScaffoldCommand', 71 | 'FileFetcher', 72 | 'PrestissimoFileFetcher', 73 | ]; 74 | 75 | foreach ($classes as $src) { 76 | if (!class_exists('\\DrupalComposer\\DrupalScaffold\\' . $src)) { 77 | include "{$src_dir}/{$src}.php"; 78 | } 79 | } 80 | } 81 | 82 | /** 83 | * @param $operation 84 | * @return mixed 85 | */ 86 | protected function getCorePackage($operation) { 87 | if ($operation instanceof InstallOperation) { 88 | $package = $operation->getPackage(); 89 | } 90 | elseif ($operation instanceof UpdateOperation) { 91 | $package = $operation->getTargetPackage(); 92 | } 93 | if (isset($package) && $package instanceof PackageInterface && $package->getName() == 'drupal/core') { 94 | return $package; 95 | } 96 | return NULL; 97 | } 98 | 99 | /** 100 | * Get the command options. 101 | * 102 | * @param \Composer\Plugin\CommandEvent $event 103 | */ 104 | public function onCmdBeginsEvent(CommandEvent $event) { 105 | if ($event->getInput()->hasOption('no-progress')) { 106 | $this->progress = !($event->getInput()->getOption('no-progress')); 107 | } 108 | else { 109 | $this->progress = TRUE; 110 | } 111 | } 112 | 113 | /** 114 | * Marks scaffolding to be processed after an install or update command. 115 | * 116 | * @param \Composer\Installer\PackageEvent $event 117 | */ 118 | public function onPostPackageEvent(PackageEvent $event) { 119 | $package = $this->getCorePackage($event->getOperation()); 120 | if ($package) { 121 | // By explicitly setting the core package, the onPostCmdEvent() will 122 | // process the scaffolding automatically. 123 | $this->drupalCorePackage = $package; 124 | } 125 | } 126 | 127 | /** 128 | * Post install command event to execute the scaffolding. 129 | * 130 | * @param \Composer\Script\Event $event 131 | */ 132 | public function onPostCmdEvent(Event $event) { 133 | // Only install the scaffolding if drupal/core was installed, 134 | // AND there are no scaffolding files present. 135 | if (isset($this->drupalCorePackage)) { 136 | $this->downloadScaffold(); 137 | // Generate the autoload.php file after generating the scaffold files. 138 | $this->generateAutoload(); 139 | } 140 | } 141 | 142 | /** 143 | * Downloads drupal scaffold files for the current process. 144 | */ 145 | public function downloadScaffold() { 146 | $drupalCorePackage = $this->getDrupalCorePackage(); 147 | $webroot = realpath($this->getWebRoot()); 148 | 149 | // Collect options, excludes and settings files. 150 | $options = $this->getOptions(); 151 | $files = array_diff($this->getIncludes(), $this->getExcludes()); 152 | $files = array_combine($files, $files); 153 | 154 | // Call any pre-scaffold scripts that may be defined. 155 | $dispatcher = new EventDispatcher($this->composer, $this->io); 156 | $dispatcher->dispatch(self::PRE_DRUPAL_SCAFFOLD_CMD); 157 | 158 | $version = $this->getDrupalCoreVersion($drupalCorePackage); 159 | 160 | $remoteFs = new RemoteFilesystem($this->io); 161 | 162 | $fetcher = new PrestissimoFileFetcher($remoteFs, $this->io, $this->progress, $this->composer->getConfig()); 163 | $sources = (array) $options['source']; 164 | $all_succeeded = FALSE; 165 | 166 | do { 167 | $source = current($sources); 168 | 169 | $fetcher->setSource($source); 170 | 171 | $fetcher->setFilenames($files); 172 | if ($fetcher->fetch($version, $webroot, TRUE)) { 173 | $fetcher->setFilenames($this->getInitial()); 174 | if ($fetcher->fetch($version, $webroot, FALSE)) { 175 | $all_succeeded = TRUE; 176 | break; 177 | } 178 | } 179 | 180 | // If here, it means that the fetch for this source has failed. 181 | $next_source = next($sources); 182 | 183 | $this->io->writeError(''); 184 | $this->io->writeError(" - Has failed with the " . (!$next_source ? 'last ' : '') . "source: $source", TRUE); 185 | if ($next_source) { 186 | $this->io->writeError(" - Now trying with the source: $next_source", TRUE); 187 | } 188 | $this->io->writeError(''); 189 | 190 | } while($next_source); 191 | 192 | if (!$all_succeeded) { 193 | throw new \Exception(implode("\r\n\r\n", $fetcher->getErrors())); 194 | } 195 | 196 | // Call post-scaffold scripts. 197 | $dispatcher->dispatch(self::POST_DRUPAL_SCAFFOLD_CMD); 198 | } 199 | 200 | /** 201 | * Generate the autoload file at the project root. Include the 202 | * autoload file that Composer generated. 203 | */ 204 | public function generateAutoload() { 205 | $vendorPath = $this->getVendorPath(); 206 | $webroot = $this->getWebRoot(); 207 | 208 | // Calculate the relative path from the webroot (location of the 209 | // project autoload.php) to the vendor directory. 210 | $fs = new SymfonyFilesystem(); 211 | $relativeVendorPath = $fs->makePathRelative($vendorPath, realpath($webroot)); 212 | 213 | $fs->dumpFile($webroot . "/autoload.php", $this->autoLoadContents($relativeVendorPath)); 214 | } 215 | 216 | /** 217 | * Build the contents of the autoload file. 218 | * 219 | * @return string 220 | */ 221 | protected function autoLoadContents($relativeVendorPath) { 222 | $relativeVendorPath = rtrim($relativeVendorPath, '/'); 223 | 224 | $autoloadContents = <<composer->getConfig(); 254 | $filesystem = new Filesystem(); 255 | $filesystem->ensureDirectoryExists($config->get('vendor-dir')); 256 | $vendorPath = $filesystem->normalizePath(realpath($config->get('vendor-dir'))); 257 | 258 | return $vendorPath; 259 | } 260 | 261 | /** 262 | * Look up the Drupal core package object, or return it from where we cached 263 | * it in the $drupalCorePackage field. 264 | * 265 | * @return \Composer\Package\PackageInterface 266 | */ 267 | public function getDrupalCorePackage() { 268 | if (!isset($this->drupalCorePackage)) { 269 | $this->drupalCorePackage = $this->getPackage('drupal/core'); 270 | } 271 | return $this->drupalCorePackage; 272 | } 273 | 274 | /** 275 | * Returns the Drupal core version for the given package. 276 | * 277 | * @param \Composer\Package\PackageInterface $drupalCorePackage 278 | * 279 | * @return string 280 | */ 281 | protected function getDrupalCoreVersion(PackageInterface $drupalCorePackage) { 282 | $version = $drupalCorePackage->getPrettyVersion(); 283 | if ($drupalCorePackage->getStability() == 'dev' && substr($version, -4) == '-dev') { 284 | $version = substr($version, 0, -4); 285 | return $version; 286 | } 287 | return $version; 288 | } 289 | 290 | /** 291 | * Retrieve the path to the web root. 292 | * 293 | * @return string 294 | */ 295 | public function getWebRoot() { 296 | $drupalCorePackage = $this->getDrupalCorePackage(); 297 | $installationManager = $this->composer->getInstallationManager(); 298 | $corePath = $installationManager->getInstallPath($drupalCorePackage); 299 | // Webroot is the parent path of the drupal core installation path. 300 | $webroot = dirname($corePath); 301 | 302 | return $webroot; 303 | } 304 | 305 | /** 306 | * Retrieve a package from the current composer process. 307 | * 308 | * @param string $name 309 | * Name of the package to get from the current composer installation. 310 | * 311 | * @return \Composer\Package\PackageInterface 312 | */ 313 | protected function getPackage($name) { 314 | return $this->composer->getRepositoryManager()->getLocalRepository()->findPackage($name, '*'); 315 | } 316 | 317 | /** 318 | * Retrieve excludes from optional "extra" configuration. 319 | * 320 | * @return array 321 | */ 322 | protected function getExcludes() { 323 | return $this->getNamedOptionList('excludes', 'getExcludesDefault'); 324 | } 325 | 326 | /** 327 | * Retrieve list of additional settings files from optional "extra" configuration. 328 | * 329 | * @return array 330 | */ 331 | protected function getIncludes() { 332 | return $this->getNamedOptionList('includes', 'getIncludesDefault'); 333 | } 334 | 335 | /** 336 | * Retrieve list of initial files from optional "extra" configuration. 337 | * 338 | * @return array 339 | */ 340 | protected function getInitial() { 341 | return $this->getNamedOptionList('initial', 'getInitialDefault'); 342 | } 343 | 344 | /** 345 | * Retrieve a named list of options from optional "extra" configuration. 346 | * Respects 'omit-defaults', and either includes or does not include the 347 | * default values, as requested. 348 | * 349 | * @return array 350 | */ 351 | protected function getNamedOptionList($optionName, $defaultFn) { 352 | $options = $this->getOptions($this->composer); 353 | $result = []; 354 | if (empty($options['omit-defaults'])) { 355 | $result = $this->$defaultFn(); 356 | } 357 | $result = array_merge($result, (array) $options[$optionName]); 358 | 359 | return $result; 360 | } 361 | 362 | /** 363 | * Retrieve excludes from optional "extra" configuration. 364 | * 365 | * @return array 366 | */ 367 | protected function getOptions() { 368 | $extra = $this->composer->getPackage()->getExtra() + ['drupal-scaffold' => []]; 369 | $options = $extra['drupal-scaffold'] + [ 370 | 'omit-defaults' => FALSE, 371 | 'excludes' => [], 372 | 'includes' => [], 373 | 'initial' => [], 374 | 'source' => [ 375 | 'https://git.drupalcode.org/project/drupal/raw/{version}/{path}', 376 | 'https://raw.githubusercontent.com/drupal/drupal/{version}/{path}' 377 | ], 378 | ]; 379 | return $options; 380 | } 381 | 382 | /** 383 | * Holds default excludes. 384 | */ 385 | protected function getExcludesDefault() { 386 | return []; 387 | } 388 | 389 | /** 390 | * Holds default settings files list. 391 | */ 392 | protected function getIncludesDefault() { 393 | $version = $this->getDrupalCoreVersion($this->getDrupalCorePackage()); 394 | list($major, $minor) = explode('.', $version, 3); 395 | $version = "$major.$minor"; 396 | 397 | /** 398 | * Files from 8.3.x 399 | * 400 | * @see https://git.drupalcode.org/project/drupal/tree/8.3.x 401 | */ 402 | $common = [ 403 | '.csslintrc', 404 | '.editorconfig', 405 | '.eslintignore', 406 | '.gitattributes', 407 | '.htaccess', 408 | 'index.php', 409 | 'robots.txt', 410 | 'sites/default/default.settings.php', 411 | 'sites/default/default.services.yml', 412 | 'sites/development.services.yml', 413 | 'sites/example.settings.local.php', 414 | 'sites/example.sites.php', 415 | 'update.php', 416 | 'web.config', 417 | ]; 418 | 419 | // Version specific variations. 420 | if (Semver::satisfies($version, '<8.3')) { 421 | $common[] = '.eslintrc'; 422 | } 423 | if (Semver::satisfies($version, '>=8.3')) { 424 | $common[] = '.eslintrc.json'; 425 | } 426 | if (Semver::satisfies($version, '>=8.5')) { 427 | $common[] = '.ht.router.php'; 428 | } 429 | 430 | sort($common); 431 | return $common; 432 | } 433 | 434 | /** 435 | * Holds default initial files. 436 | */ 437 | protected function getInitialDefault() { 438 | return []; 439 | } 440 | 441 | } 442 | -------------------------------------------------------------------------------- /src/Plugin.php: -------------------------------------------------------------------------------- 1 | handler = new Handler($composer, $io); 36 | } 37 | 38 | /** 39 | * {@inheritdoc} 40 | */ 41 | public function getCapabilities() { 42 | return [ 43 | 'Composer\Plugin\Capability\CommandProvider' => 'DrupalComposer\DrupalScaffold\CommandProvider', 44 | ]; 45 | } 46 | 47 | /** 48 | * {@inheritdoc} 49 | */ 50 | public static function getSubscribedEvents() { 51 | return [ 52 | PackageEvents::POST_PACKAGE_INSTALL => 'postPackage', 53 | PackageEvents::POST_PACKAGE_UPDATE => 'postPackage', 54 | ScriptEvents::POST_UPDATE_CMD => 'postCmd', 55 | PluginEvents::COMMAND => 'cmdBegins', 56 | ]; 57 | } 58 | 59 | /** 60 | * Command begins event callback. 61 | * 62 | * @param \Composer\Plugin\CommandEvent $event 63 | */ 64 | public function cmdBegins(CommandEvent $event) { 65 | $this->handler->onCmdBeginsEvent($event); 66 | } 67 | 68 | /** 69 | * Post package event behaviour. 70 | * 71 | * @param \Composer\Installer\PackageEvent $event 72 | */ 73 | public function postPackage(PackageEvent $event) { 74 | $this->handler->onPostPackageEvent($event); 75 | } 76 | 77 | /** 78 | * Post command event callback. 79 | * 80 | * @param \Composer\Script\Event $event 81 | */ 82 | public function postCmd(Event $event) { 83 | $this->handler->onPostCmdEvent($event); 84 | } 85 | 86 | /** 87 | * Script callback for putting in composer scripts to download the 88 | * scaffold files. 89 | * 90 | * @param \Composer\Script\Event $event 91 | * 92 | * @deprecated since version 2.5.0, to be removed in 3.0. Use the command 93 | * "composer drupal:scaffold" instead. 94 | */ 95 | public static function scaffold(Event $event) { 96 | @trigger_error('\DrupalComposer\DrupalScaffold\Plugin::scaffold is deprecated since version 2.5.0 and will be removed in 3.0. Use "composer drupal:scaffold" instead.', E_USER_DEPRECATED); 97 | $handler = new Handler($event->getComposer(), $event->getIO()); 98 | $handler->downloadScaffold(); 99 | // Generate the autoload.php file after generating the scaffold files. 100 | $handler->generateAutoload(); 101 | } 102 | 103 | } 104 | -------------------------------------------------------------------------------- /src/PrestissimoFileFetcher.php: -------------------------------------------------------------------------------- 1 | config = $config; 28 | } 29 | 30 | /** 31 | * {@inheritdoc} 32 | */ 33 | public function fetch($version, $destination, $override) { 34 | if (class_exists(CurlMulti::class)) { 35 | return $this->fetchWithPrestissimo($version, $destination, $override); 36 | } 37 | return parent::fetch($version, $destination, $override); 38 | } 39 | 40 | /** 41 | * Fetch files in parallel. 42 | */ 43 | protected function fetchWithPrestissimo($version, $destination, $override) { 44 | $requests = []; 45 | 46 | foreach ($this->filenames as $sourceFilename => $filename) { 47 | $target = "$destination/$filename"; 48 | if ($override || !file_exists($target)) { 49 | $url = $this->getUri($sourceFilename, $version); 50 | $this->fs->ensureDirectoryExists($destination . '/' . dirname($filename)); 51 | $requests[] = new CopyRequest($url, $target, FALSE, $this->io, $this->config); 52 | } 53 | } 54 | 55 | $successCnt = $failureCnt = 0; 56 | $errors = []; 57 | $totalCnt = count($requests); 58 | if ($totalCnt == 0) { 59 | return TRUE; 60 | } 61 | 62 | $multi = new CurlMulti(); 63 | $multi->setRequests($requests); 64 | do { 65 | $multi->setupEventLoop(); 66 | $multi->wait(); 67 | $result = $multi->getFinishedResults(); 68 | $successCnt += $result['successCnt']; 69 | $failureCnt += $result['failureCnt']; 70 | if (isset($result['errors'])) { 71 | $errors += $result['errors']; 72 | foreach ($result['errors'] as $url => $error) { 73 | $this->io->writeError(" - Downloading $successCnt/$totalCnt: $url (failed)", TRUE); 74 | } 75 | } 76 | if ($this->progress) { 77 | foreach ($result['urls'] as $url) { 78 | $this->io->writeError(" - Downloading $successCnt/$totalCnt: $url", TRUE); 79 | } 80 | } 81 | } while ($multi->remain()); 82 | 83 | if ($errors) { 84 | $this->addError('Failed to download: ' . "\r\n" . implode("\r\n", array_keys($errors))); 85 | $errors_extra = []; 86 | foreach($errors as $error) { 87 | if ($error !== "0: " && !isset($errors_extra[$error])) { 88 | $errors_extra[$error] = $error; 89 | } 90 | } 91 | if ($errors_extra) { 92 | $this->addError(implode("\r\n", $errors_extra)); 93 | } 94 | return FALSE; 95 | } 96 | return TRUE; 97 | } 98 | 99 | } 100 | -------------------------------------------------------------------------------- /tests/FetcherTest.php: -------------------------------------------------------------------------------- 1 | rootDir = realpath(realpath(__DIR__ . '/..')); 38 | 39 | // Prepare temp directory. 40 | $this->fs = new Filesystem(); 41 | $this->tmpDir = realpath(sys_get_temp_dir()) . DIRECTORY_SEPARATOR . 'drupal-scaffold'; 42 | $this->ensureDirectoryExistsAndClear($this->tmpDir); 43 | 44 | chdir($this->tmpDir); 45 | } 46 | 47 | /** 48 | * Makes sure the given directory exists and has no content. 49 | * 50 | * @param string $directory 51 | */ 52 | protected function ensureDirectoryExistsAndClear($directory) { 53 | if (is_dir($directory)) { 54 | $this->fs->removeDirectory($directory); 55 | } 56 | mkdir($directory, 0777, TRUE); 57 | } 58 | 59 | public function testFetch() { 60 | $fetcher = new FileFetcher(new RemoteFilesystem(new NullIO()), new NullIO()); 61 | $fetcher->setSource('https://git.drupalcode.org/project/drupal/raw/{version}/{path}'); 62 | $fetcher->setFilenames([ 63 | '.htaccess' => '.htaccess', 64 | 'sites/default/default.settings.php' => 'sites/default/default.settings.php', 65 | ]); 66 | $fetcher->fetch('8.1.1', $this->tmpDir, TRUE); 67 | $this->assertFileExists($this->tmpDir . '/.htaccess'); 68 | $this->assertFileExists($this->tmpDir . '/sites/default/default.settings.php'); 69 | } 70 | 71 | public function testInitialFetch() { 72 | $fetcher = new FileFetcher(new RemoteFilesystem(new NullIO()), new NullIO()); 73 | $fetcher->setSource('https://git.drupalcode.org/project/drupal/raw/{version}/{path}'); 74 | $fetcher->setFilenames([ 75 | 'sites/default/default.settings.php' => 'sites/default/settings.php', 76 | ]); 77 | $fetcher->fetch('8.1.1', $this->tmpDir, FALSE); 78 | $this->assertFileExists($this->tmpDir . '/sites/default/settings.php'); 79 | } 80 | 81 | } 82 | -------------------------------------------------------------------------------- /tests/PluginTest.php: -------------------------------------------------------------------------------- 1 | rootDir = realpath(realpath(__DIR__ . '/..')); 38 | 39 | // Prepare temp directory. 40 | $this->fs = new Filesystem(); 41 | $this->tmpDir = realpath(sys_get_temp_dir()) . DIRECTORY_SEPARATOR . 'drupal-scaffold'; 42 | $this->ensureDirectoryExistsAndClear($this->tmpDir); 43 | 44 | $this->writeTestReleaseTag(); 45 | $this->writeComposerJSON(); 46 | 47 | chdir($this->tmpDir); 48 | } 49 | 50 | /** 51 | * TearDown. 52 | * 53 | * @return void 54 | */ 55 | public function tearDown() { 56 | $this->fs->removeDirectory($this->tmpDir); 57 | $this->git(sprintf('tag -d "%s"', $this->tmpReleaseTag)); 58 | } 59 | 60 | /** 61 | * Tests a simple composer install without core, but adding core later. 62 | */ 63 | public function testComposerInstallAndUpdate() { 64 | $exampleScaffoldFile = $this->tmpDir . DIRECTORY_SEPARATOR . 'index.php'; 65 | $this->assertFileNotExists($exampleScaffoldFile, 'Scaffold file should not be exist.'); 66 | $this->composer('install --no-dev --prefer-dist'); 67 | $this->assertFileExists($this->tmpDir . DIRECTORY_SEPARATOR . 'core', 'Drupal core is installed.'); 68 | $this->assertFileExists($exampleScaffoldFile, 'Scaffold file should be automatically installed.'); 69 | $this->fs->remove($exampleScaffoldFile); 70 | $this->assertFileNotExists($exampleScaffoldFile, 'Scaffold file should not be exist.'); 71 | $this->composer('drupal:scaffold'); 72 | $this->assertFileExists($exampleScaffoldFile, 'Scaffold file should be installed by "drupal:scaffold" command.'); 73 | 74 | foreach (['8.0.1', '8.1.x-dev', '8.3.0', '8.5.x-dev'] as $version) { 75 | // We touch a scaffold file, so we can check the file was modified after 76 | // the scaffold update. 77 | touch($exampleScaffoldFile); 78 | $mtime_touched = filemtime($exampleScaffoldFile); 79 | // Requiring a newer version triggers "composer update". 80 | $this->composer('require --update-with-dependencies --prefer-dist --update-no-dev drupal/core:"' . $version . '"'); 81 | clearstatcache(); 82 | $mtime_after = filemtime($exampleScaffoldFile); 83 | $this->assertNotEquals($mtime_after, $mtime_touched, 'Scaffold file was modified by composer update. (' . $version . ')'); 84 | switch ($version) { 85 | case '8.0.1': 86 | case '8.1.x-dev': 87 | $this->assertFileExists($this->tmpDir . DIRECTORY_SEPARATOR . '.eslintrc'); 88 | $this->assertFileNotExists($this->tmpDir . DIRECTORY_SEPARATOR . '.eslintrc.json'); 89 | $this->assertFileNotExists($this->tmpDir . DIRECTORY_SEPARATOR . '.ht.router.php'); 90 | break; 91 | 92 | case '8.3.0': 93 | // Note we don't clean up .eslintrc file. 94 | $this->assertFileExists($this->tmpDir . DIRECTORY_SEPARATOR . '.eslintrc'); 95 | $this->assertFileExists($this->tmpDir . DIRECTORY_SEPARATOR . '.eslintrc.json'); 96 | $this->assertFileNotExists($this->tmpDir . DIRECTORY_SEPARATOR . '.ht.router.php'); 97 | break; 98 | 99 | case '8.5.x-dev': 100 | $this->assertFileExists($this->tmpDir . DIRECTORY_SEPARATOR . '.eslintrc'); 101 | $this->assertFileExists($this->tmpDir . DIRECTORY_SEPARATOR . '.eslintrc.json'); 102 | $this->assertFileExists($this->tmpDir . DIRECTORY_SEPARATOR . '.ht.router.php'); 103 | break; 104 | } 105 | } 106 | 107 | // We touch a scaffold file, so we can check the file was modified by the 108 | // custom command. 109 | file_put_contents($exampleScaffoldFile, 1); 110 | $this->composer('drupal:scaffold'); 111 | $this->assertNotEquals(file_get_contents($exampleScaffoldFile), 1, 'Scaffold file was modified by custom command.'); 112 | } 113 | 114 | /** 115 | * Writes the default composer json to the temp direcoty. 116 | */ 117 | protected function writeComposerJSON() { 118 | $json = json_encode($this->composerJSONDefaults(), JSON_PRETTY_PRINT); 119 | // Write composer.json. 120 | file_put_contents($this->tmpDir . '/composer.json', $json); 121 | } 122 | 123 | /** 124 | * Writes a tag for the current commit, so we can reference it directly in the 125 | * composer.json. 126 | */ 127 | protected function writeTestReleaseTag() { 128 | // Tag the current state. 129 | $this->tmpReleaseTag = '999.0.' . time(); 130 | $this->git(sprintf('tag -a "%s" -m "%s"', $this->tmpReleaseTag, 'Tag for testing this exact commit')); 131 | } 132 | 133 | /** 134 | * Provides the default composer.json data. 135 | * 136 | * @return array 137 | */ 138 | protected function composerJSONDefaults() { 139 | return [ 140 | 'repositories' => [ 141 | [ 142 | 'type' => 'vcs', 143 | 'url' => $this->rootDir, 144 | ], 145 | ], 146 | 'require' => [ 147 | 'drupal-composer/drupal-scaffold' => $this->tmpReleaseTag, 148 | 'composer/installers' => '^1.0.20', 149 | 'drupal/core' => '8.0.0', 150 | ], 151 | 'minimum-stability' => 'dev', 152 | ]; 153 | } 154 | 155 | /** 156 | * Wrapper for the composer command. 157 | * 158 | * @param string $command 159 | * Composer command name, arguments and/or options. 160 | */ 161 | protected function composer($command) { 162 | chdir($this->tmpDir); 163 | passthru(escapeshellcmd($this->rootDir . '/vendor/bin/composer ' . $command), $exit_code); 164 | if ($exit_code !== 0) { 165 | throw new \Exception('Composer returned a non-zero exit code'); 166 | } 167 | } 168 | 169 | /** 170 | * Wrapper for git command in the root directory. 171 | * 172 | * @param $command 173 | * Git command name, arguments and/or options. 174 | */ 175 | protected function git($command) { 176 | chdir($this->rootDir); 177 | passthru(escapeshellcmd('git ' . $command), $exit_code); 178 | if ($exit_code !== 0) { 179 | throw new \Exception('Git returned a non-zero exit code'); 180 | } 181 | } 182 | 183 | /** 184 | * Makes sure the given directory exists and has no content. 185 | * 186 | * @param string $directory 187 | */ 188 | protected function ensureDirectoryExistsAndClear($directory) { 189 | if (is_dir($directory)) { 190 | $this->fs->removeDirectory($directory); 191 | } 192 | mkdir($directory, 0777, TRUE); 193 | } 194 | 195 | } 196 | --------------------------------------------------------------------------------