diff --git a/.gitignore b/.gitignore index 3740b59c..8c818d2f 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,7 @@ /fixtures/set004/scoper.inc.php /fixtures/*/.box_dump/ /fixtures/*/vendor/ +/fixtures/set028-symfony/expected-output .phpunit* /vendor/ /vendor-bin/*/vendor/ diff --git a/Makefile b/Makefile index 22ada04b..bded3f60 100644 --- a/Makefile +++ b/Makefile @@ -62,7 +62,7 @@ tm: bin/phpunit .PHONY: e2e e2e: ## Run end-to-end tests -e2e: e2e_004 e2e_005 e2e_011 e2e_013 e2e_014 e2e_015 e2e_016 e2e_017 e2e_018 e2e_019 e2e_020 e2e_021 e2e_022 e2e_023 e2e_024 e2e_025 e2e_026 e2e_027 +e2e: e2e_004 e2e_005 e2e_011 e2e_013 e2e_014 e2e_015 e2e_016 e2e_017 e2e_018 e2e_019 e2e_020 e2e_021 e2e_022 e2e_023 e2e_024 e2e_025 e2e_026 e2e_027 e2e_028 PHPSCOPER=bin/php-scoper.phar @@ -282,7 +282,6 @@ e2e_026: bin/php-scoper.phar fixtures/set026/vendor php build/set026/main.php > build/set026/output diff fixtures/set026/expected-output build/set026/output - .PHONY: e2e_027 e2e_027: ## Run end-to-end tests for the fixture set 027 — Laravel e2e_027: bin/php-scoper.phar fixtures/set027-laravel/vendor @@ -298,6 +297,24 @@ e2e_027: bin/php-scoper.phar fixtures/set027-laravel/vendor php build/set027-laravel/artisan -V > build/set027-laravel/output diff fixtures/set027-laravel/expected-output build/set027-laravel/output +.PHONY: e2e_028 +e2e_028: ## Run end-to-end tests for the fixture set 028 — Symfony +e2e_028: bin/php-scoper.phar fixtures/set028-symfony/vendor + php $(PHPSCOPER) add-prefix \ + --working-dir=fixtures/set028-symfony \ + --output-dir=../../build/set028-symfony \ + --no-config \ + --force \ + --no-interaction \ + --stop-on-failure + + APP_ENV=dev composer --working-dir=fixtures/set028-symfony dump-autoload --no-dev + APP_ENV=dev php fixtures/set028-symfony/bin/console -V > fixtures/set028-symfony/expected-output + + APP_ENV=dev composer --working-dir=build/set028-symfony dump-autoload --no-dev + APP_ENV=dev php build/set028-symfony/bin/console -V > build/set028-symfony/output + + diff fixtures/set028-symfony/expected-output build/set028-symfony/output .PHONY: tb BLACKFIRE=blackfire @@ -396,6 +413,10 @@ fixtures/set027-laravel/vendor: fixtures/set027-laravel/composer.lock composer --working-dir=fixtures/set027-laravel install --no-dev touch $@ +fixtures/set028-symfony/vendor: fixtures/set028-symfony/composer.lock + composer --working-dir=fixtures/set028-symfony install --no-dev --no-scripts + touch $@ + composer.lock: composer.json @echo composer.lock is not up to date. @@ -444,6 +465,9 @@ fixtures/set025/composer.lock: fixtures/set025/composer.json fixtures/set027-laravel/composer.lock: fixtures/set027-laravel/composer.json @echo fixtures/set027-laravel/composer.lock is not up to date. +fixtures/set028-symfony/composer.lock: fixtures/set028-symfony/composer.json + @echo fixtures/set028-symfony/composer.lock is not up to date. + bin/php-scoper.phar: bin/php-scoper src vendor scoper.inc.php box.json.dist $(BOX) compile touch $@ diff --git a/composer.lock b/composer.lock index 3cb26bf2..0f6e854a 100644 --- a/composer.lock +++ b/composer.lock @@ -876,16 +876,16 @@ }, { "name": "amphp/byte-stream", - "version": "v1.4.0", + "version": "v1.5.0", "source": { "type": "git", "url": "https://github.com/amphp/byte-stream.git", - "reference": "17fae3bcecf9b4e7854c4ee41e8d6f58dac5d98d" + "reference": "37b9ab16bb8f69c825c3c4e553fe00da73dd6926" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/amphp/byte-stream/zipball/17fae3bcecf9b4e7854c4ee41e8d6f58dac5d98d", - "reference": "17fae3bcecf9b4e7854c4ee41e8d6f58dac5d98d", + "url": "https://api.github.com/repos/amphp/byte-stream/zipball/37b9ab16bb8f69c825c3c4e553fe00da73dd6926", + "reference": "37b9ab16bb8f69c825c3c4e553fe00da73dd6926", "shasum": "" }, "require": { @@ -931,7 +931,7 @@ "non-blocking", "stream" ], - "time": "2018-10-03T15:37:23+00:00" + "time": "2018-10-22T19:37:37+00:00" }, { "name": "amphp/parallel", @@ -1246,26 +1246,25 @@ }, { "name": "beberlei/assert", - "version": "v3.0.0", + "version": "v3.0.1", "source": { "type": "git", "url": "https://github.com/beberlei/assert.git", - "reference": "891103759a35926323be6296ebd3f1579a52d82a" + "reference": "12322a8ea8eb0561ccb91a7a6b28fd2f6a9fefec" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/beberlei/assert/zipball/891103759a35926323be6296ebd3f1579a52d82a", - "reference": "891103759a35926323be6296ebd3f1579a52d82a", + "url": "https://api.github.com/repos/beberlei/assert/zipball/12322a8ea8eb0561ccb91a7a6b28fd2f6a9fefec", + "reference": "12322a8ea8eb0561ccb91a7a6b28fd2f6a9fefec", "shasum": "" }, "require": { - "ext-mbstring": "*", "php": "^7" }, "require-dev": { - "friendsofphp/php-cs-fixer": "^2.1.1", - "phpstan/phpstan": "^0.9.2", - "phpunit/phpunit": "^5.7" + "friendsofphp/php-cs-fixer": "*", + "phpstan/phpstan-shim": "*", + "phpunit/phpunit": "*" }, "type": "library", "autoload": { @@ -1298,20 +1297,20 @@ "assertion", "validation" ], - "time": "2018-07-04T11:02:54+00:00" + "time": "2018-10-11T22:24:24+00:00" }, { "name": "composer/ca-bundle", - "version": "1.1.2", + "version": "1.1.3", "source": { "type": "git", "url": "https://github.com/composer/ca-bundle.git", - "reference": "46afded9720f40b9dc63542af4e3e43a1177acb0" + "reference": "8afa52cd417f4ec417b4bfe86b68106538a87660" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/ca-bundle/zipball/46afded9720f40b9dc63542af4e3e43a1177acb0", - "reference": "46afded9720f40b9dc63542af4e3e43a1177acb0", + "url": "https://api.github.com/repos/composer/ca-bundle/zipball/8afa52cd417f4ec417b4bfe86b68106538a87660", + "reference": "8afa52cd417f4ec417b4bfe86b68106538a87660", "shasum": "" }, "require": { @@ -1354,7 +1353,7 @@ "ssl", "tls" ], - "time": "2018-08-08T08:57:40+00:00" + "time": "2018-10-18T06:09:13+00:00" }, { "name": "composer/composer", @@ -1835,16 +1834,16 @@ }, { "name": "humbug/box", - "version": "3.1.1", + "version": "3.1.2", "source": { "type": "git", "url": "https://github.com/humbug/box.git", - "reference": "6dc36fdd2240b81dc65c6e33b1a82d2a63c2eb86" + "reference": "f5403bdafaa8d5713841d44edf5b62799265a602" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/humbug/box/zipball/6dc36fdd2240b81dc65c6e33b1a82d2a63c2eb86", - "reference": "6dc36fdd2240b81dc65c6e33b1a82d2a63c2eb86", + "url": "https://api.github.com/repos/humbug/box/zipball/f5403bdafaa8d5713841d44edf5b62799265a602", + "reference": "f5403bdafaa8d5713841d44edf5b62799265a602", "shasum": "" }, "require": { @@ -1922,7 +1921,7 @@ "keywords": [ "phar" ], - "time": "2018-10-09T21:20:46+00:00" + "time": "2018-10-16T10:19:45+00:00" }, { "name": "justinrainbow/json-schema", @@ -2646,16 +2645,16 @@ }, { "name": "phpunit/php-code-coverage", - "version": "6.0.8", + "version": "6.1.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "848f78b3309780fef7ec8c4666b7ab4e6b09b22f" + "reference": "4d3ae9b21a7d7e440bd0cf65565533117976859f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/848f78b3309780fef7ec8c4666b7ab4e6b09b22f", - "reference": "848f78b3309780fef7ec8c4666b7ab4e6b09b22f", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/4d3ae9b21a7d7e440bd0cf65565533117976859f", + "reference": "4d3ae9b21a7d7e440bd0cf65565533117976859f", "shasum": "" }, "require": { @@ -2666,7 +2665,7 @@ "phpunit/php-text-template": "^1.2.1", "phpunit/php-token-stream": "^3.0", "sebastian/code-unit-reverse-lookup": "^1.0.1", - "sebastian/environment": "^3.1", + "sebastian/environment": "^3.1 || ^4.0", "sebastian/version": "^2.0.1", "theseer/tokenizer": "^1.1" }, @@ -2679,7 +2678,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "6.0-dev" + "dev-master": "6.1-dev" } }, "autoload": { @@ -2705,7 +2704,7 @@ "testing", "xunit" ], - "time": "2018-10-04T03:41:23+00:00" + "time": "2018-10-23T05:59:32+00:00" }, { "name": "phpunit/php-file-iterator", @@ -2898,16 +2897,16 @@ }, { "name": "phpunit/phpunit", - "version": "7.4.0", + "version": "7.4.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "f3837fa1e07758057ae06e8ddec6d06ba183f126" + "reference": "c151651fb6ed264038d486ea262e243af72e5e64" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/f3837fa1e07758057ae06e8ddec6d06ba183f126", - "reference": "f3837fa1e07758057ae06e8ddec6d06ba183f126", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/c151651fb6ed264038d486ea262e243af72e5e64", + "reference": "c151651fb6ed264038d486ea262e243af72e5e64", "shasum": "" }, "require": { @@ -2928,7 +2927,7 @@ "phpunit/php-timer": "^2.0", "sebastian/comparator": "^3.0", "sebastian/diff": "^3.0", - "sebastian/environment": "^3.1", + "sebastian/environment": "^3.1 || ^4.0", "sebastian/exporter": "^3.1", "sebastian/global-state": "^2.0", "sebastian/object-enumerator": "^3.0.3", @@ -2978,7 +2977,7 @@ "testing", "xunit" ], - "time": "2018-10-05T04:05:24+00:00" + "time": "2018-10-23T05:57:41+00:00" }, { "name": "sebastian/code-unit-reverse-lookup", diff --git a/fixtures/set028-symfony/.env.dist b/fixtures/set028-symfony/.env.dist new file mode 100644 index 00000000..fb56320b --- /dev/null +++ b/fixtures/set028-symfony/.env.dist @@ -0,0 +1,10 @@ +# This file is a "template" of which env vars need to be defined for your application +# Copy this file to .env file for development, create environment variables when deploying to production +# https://symfony.com/doc/current/best_practices/configuration.html#infrastructure-related-configuration + +###> symfony/framework-bundle ### +APP_ENV=dev +APP_SECRET=7379902cbd219672e341bc2d985138b1 +#TRUSTED_PROXIES=127.0.0.1,127.0.0.2 +#TRUSTED_HOSTS=localhost,example.com +###< symfony/framework-bundle ### diff --git a/fixtures/set028-symfony/.gitignore b/fixtures/set028-symfony/.gitignore new file mode 100644 index 00000000..1c80869d --- /dev/null +++ b/fixtures/set028-symfony/.gitignore @@ -0,0 +1,7 @@ + +###> symfony/framework-bundle ### +/.env +/public/bundles/ +/var/ +/vendor/ +###< symfony/framework-bundle ### diff --git a/fixtures/set028-symfony/bin/console b/fixtures/set028-symfony/bin/console new file mode 100755 index 00000000..5187d027 --- /dev/null +++ b/fixtures/set028-symfony/bin/console @@ -0,0 +1,39 @@ +#!/usr/bin/env php +load(__DIR__.'/../.env'); +} + +$input = new ArgvInput(); +$env = $input->getParameterOption(['--env', '-e'], $_SERVER['APP_ENV'] ?? 'dev', true); +$debug = (bool) ($_SERVER['APP_DEBUG'] ?? ('prod' !== $env)) && !$input->hasParameterOption('--no-debug', true); + +if ($debug) { + umask(0000); + + if (class_exists(Debug::class)) { + Debug::enable(); + } +} + +$kernel = new Kernel($env, $debug); +$application = new Application($kernel); +$application->run($input); diff --git a/fixtures/set028-symfony/composer.json b/fixtures/set028-symfony/composer.json new file mode 100644 index 00000000..9563f23e --- /dev/null +++ b/fixtures/set028-symfony/composer.json @@ -0,0 +1,61 @@ +{ + "type": "project", + "license": "proprietary", + "require": { + "php": "^7.1.3", + "ext-ctype": "*", + "ext-iconv": "*", + "symfony/console": "*", + "symfony/flex": "^1.1", + "symfony/framework-bundle": "*", + "symfony/yaml": "*" + }, + "require-dev": { + "symfony/dotenv": "*" + }, + "config": { + "preferred-install": { + "*": "dist" + }, + "sort-packages": true + }, + "autoload": { + "psr-4": { + "App\\": "src/" + } + }, + "autoload-dev": { + "psr-4": { + "App\\Tests\\": "tests/" + } + }, + "replace": { + "paragonie/random_compat": "2.*", + "symfony/polyfill-ctype": "*", + "symfony/polyfill-iconv": "*", + "symfony/polyfill-php71": "*", + "symfony/polyfill-php70": "*", + "symfony/polyfill-php56": "*" + }, + "scripts": { + "auto-scripts": { + "cache:clear": "symfony-cmd", + "assets:install %PUBLIC_DIR%": "symfony-cmd" + }, + "post-install-cmd": [ + "@auto-scripts" + ], + "post-update-cmd": [ + "@auto-scripts" + ] + }, + "conflict": { + "symfony/symfony": "*" + }, + "extra": { + "symfony": { + "allow-contrib": false, + "require": "4.1.*" + } + } +} diff --git a/fixtures/set028-symfony/composer.lock b/fixtures/set028-symfony/composer.lock new file mode 100644 index 00000000..1001666d --- /dev/null +++ b/fixtures/set028-symfony/composer.lock @@ -0,0 +1,1259 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "This file is @generated automatically" + ], + "content-hash": "626c5bd436f867ed8c4a4bd50351ae2e", + "packages": [ + { + "name": "psr/cache", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/cache.git", + "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/cache/zipball/d11b50ad223250cf17b86e38383413f5a6764bf8", + "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Cache\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for caching libraries", + "keywords": [ + "cache", + "psr", + "psr-6" + ], + "time": "2016-08-06T20:24:11+00:00" + }, + { + "name": "psr/container", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/container.git", + "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/container/zipball/b7ce3b176482dbbc1245ebf52b181af44c2cf55f", + "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Container\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common Container Interface (PHP FIG PSR-11)", + "homepage": "https://github.com/php-fig/container", + "keywords": [ + "PSR-11", + "container", + "container-interface", + "container-interop", + "psr" + ], + "time": "2017-02-14T16:28:37+00:00" + }, + { + "name": "psr/log", + "version": "1.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/4ebe3a8bf773a19edfe0a84b6585ba3d401b724d", + "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Log\\": "Psr/Log/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "time": "2016-10-10T12:19:37+00:00" + }, + { + "name": "psr/simple-cache", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/simple-cache.git", + "reference": "408d5eafb83c57f6365a3ca330ff23aa4a5fa39b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/simple-cache/zipball/408d5eafb83c57f6365a3ca330ff23aa4a5fa39b", + "reference": "408d5eafb83c57f6365a3ca330ff23aa4a5fa39b", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\SimpleCache\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interfaces for simple caching", + "keywords": [ + "cache", + "caching", + "psr", + "psr-16", + "simple-cache" + ], + "time": "2017-10-23T01:57:42+00:00" + }, + { + "name": "symfony/cache", + "version": "v4.1.6", + "source": { + "type": "git", + "url": "https://github.com/symfony/cache.git", + "reference": "05ce0ddc8bc1ffe592105398fc2c725cb3080a38" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/cache/zipball/05ce0ddc8bc1ffe592105398fc2c725cb3080a38", + "reference": "05ce0ddc8bc1ffe592105398fc2c725cb3080a38", + "shasum": "" + }, + "require": { + "php": "^7.1.3", + "psr/cache": "~1.0", + "psr/log": "~1.0", + "psr/simple-cache": "^1.0" + }, + "conflict": { + "symfony/var-dumper": "<3.4" + }, + "provide": { + "psr/cache-implementation": "1.0", + "psr/simple-cache-implementation": "1.0" + }, + "require-dev": { + "cache/integration-tests": "dev-master", + "doctrine/cache": "~1.6", + "doctrine/dbal": "~2.4", + "predis/predis": "~1.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.1-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Cache\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Cache component with PSR-6, PSR-16, and tags", + "homepage": "https://symfony.com", + "keywords": [ + "caching", + "psr6" + ], + "time": "2018-09-30T03:38:13+00:00" + }, + { + "name": "symfony/config", + "version": "v4.1.6", + "source": { + "type": "git", + "url": "https://github.com/symfony/config.git", + "reference": "b3d4d7b567d7a49e6dfafb6d4760abc921177c96" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/config/zipball/b3d4d7b567d7a49e6dfafb6d4760abc921177c96", + "reference": "b3d4d7b567d7a49e6dfafb6d4760abc921177c96", + "shasum": "" + }, + "require": { + "php": "^7.1.3", + "symfony/filesystem": "~3.4|~4.0", + "symfony/polyfill-ctype": "~1.8" + }, + "conflict": { + "symfony/finder": "<3.4" + }, + "require-dev": { + "symfony/dependency-injection": "~3.4|~4.0", + "symfony/event-dispatcher": "~3.4|~4.0", + "symfony/finder": "~3.4|~4.0", + "symfony/yaml": "~3.4|~4.0" + }, + "suggest": { + "symfony/yaml": "To use the yaml reference dumper" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.1-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Config\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Config Component", + "homepage": "https://symfony.com", + "time": "2018-09-08T13:24:10+00:00" + }, + { + "name": "symfony/console", + "version": "v4.1.6", + "source": { + "type": "git", + "url": "https://github.com/symfony/console.git", + "reference": "dc7122fe5f6113cfaba3b3de575d31112c9aa60b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/console/zipball/dc7122fe5f6113cfaba3b3de575d31112c9aa60b", + "reference": "dc7122fe5f6113cfaba3b3de575d31112c9aa60b", + "shasum": "" + }, + "require": { + "php": "^7.1.3", + "symfony/polyfill-mbstring": "~1.0" + }, + "conflict": { + "symfony/dependency-injection": "<3.4", + "symfony/process": "<3.3" + }, + "require-dev": { + "psr/log": "~1.0", + "symfony/config": "~3.4|~4.0", + "symfony/dependency-injection": "~3.4|~4.0", + "symfony/event-dispatcher": "~3.4|~4.0", + "symfony/lock": "~3.4|~4.0", + "symfony/process": "~3.4|~4.0" + }, + "suggest": { + "psr/log-implementation": "For using the console logger", + "symfony/event-dispatcher": "", + "symfony/lock": "", + "symfony/process": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.1-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Console\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Console Component", + "homepage": "https://symfony.com", + "time": "2018-10-03T08:15:46+00:00" + }, + { + "name": "symfony/debug", + "version": "v4.1.6", + "source": { + "type": "git", + "url": "https://github.com/symfony/debug.git", + "reference": "e3f76ce6198f81994e019bb2b4e533e9de1b9b90" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/debug/zipball/e3f76ce6198f81994e019bb2b4e533e9de1b9b90", + "reference": "e3f76ce6198f81994e019bb2b4e533e9de1b9b90", + "shasum": "" + }, + "require": { + "php": "^7.1.3", + "psr/log": "~1.0" + }, + "conflict": { + "symfony/http-kernel": "<3.4" + }, + "require-dev": { + "symfony/http-kernel": "~3.4|~4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.1-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Debug\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Debug Component", + "homepage": "https://symfony.com", + "time": "2018-10-02T16:36:10+00:00" + }, + { + "name": "symfony/dependency-injection", + "version": "v4.1.6", + "source": { + "type": "git", + "url": "https://github.com/symfony/dependency-injection.git", + "reference": "f6b9d893ad28aefd8942dc0469c8397e2216fe30" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/f6b9d893ad28aefd8942dc0469c8397e2216fe30", + "reference": "f6b9d893ad28aefd8942dc0469c8397e2216fe30", + "shasum": "" + }, + "require": { + "php": "^7.1.3", + "psr/container": "^1.0" + }, + "conflict": { + "symfony/config": "<4.1.1", + "symfony/finder": "<3.4", + "symfony/proxy-manager-bridge": "<3.4", + "symfony/yaml": "<3.4" + }, + "provide": { + "psr/container-implementation": "1.0" + }, + "require-dev": { + "symfony/config": "~4.1", + "symfony/expression-language": "~3.4|~4.0", + "symfony/yaml": "~3.4|~4.0" + }, + "suggest": { + "symfony/config": "", + "symfony/expression-language": "For using expressions in service container configuration", + "symfony/finder": "For using double-star glob patterns or when GLOB_BRACE portability is required", + "symfony/proxy-manager-bridge": "Generate service proxies to lazy load them", + "symfony/yaml": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.1-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\DependencyInjection\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony DependencyInjection Component", + "homepage": "https://symfony.com", + "time": "2018-10-02T12:40:59+00:00" + }, + { + "name": "symfony/event-dispatcher", + "version": "v4.1.6", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher.git", + "reference": "bfb30c2ad377615a463ebbc875eba64a99f6aa3e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/bfb30c2ad377615a463ebbc875eba64a99f6aa3e", + "reference": "bfb30c2ad377615a463ebbc875eba64a99f6aa3e", + "shasum": "" + }, + "require": { + "php": "^7.1.3" + }, + "conflict": { + "symfony/dependency-injection": "<3.4" + }, + "require-dev": { + "psr/log": "~1.0", + "symfony/config": "~3.4|~4.0", + "symfony/dependency-injection": "~3.4|~4.0", + "symfony/expression-language": "~3.4|~4.0", + "symfony/stopwatch": "~3.4|~4.0" + }, + "suggest": { + "symfony/dependency-injection": "", + "symfony/http-kernel": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.1-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\EventDispatcher\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony EventDispatcher Component", + "homepage": "https://symfony.com", + "time": "2018-07-26T09:10:45+00:00" + }, + { + "name": "symfony/filesystem", + "version": "v4.1.6", + "source": { + "type": "git", + "url": "https://github.com/symfony/filesystem.git", + "reference": "596d12b40624055c300c8b619755b748ca5cf0b5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/596d12b40624055c300c8b619755b748ca5cf0b5", + "reference": "596d12b40624055c300c8b619755b748ca5cf0b5", + "shasum": "" + }, + "require": { + "php": "^7.1.3", + "symfony/polyfill-ctype": "~1.8" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.1-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Filesystem\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Filesystem Component", + "homepage": "https://symfony.com", + "time": "2018-10-02T12:40:59+00:00" + }, + { + "name": "symfony/finder", + "version": "v4.1.6", + "source": { + "type": "git", + "url": "https://github.com/symfony/finder.git", + "reference": "1f17195b44543017a9c9b2d437c670627e96ad06" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/finder/zipball/1f17195b44543017a9c9b2d437c670627e96ad06", + "reference": "1f17195b44543017a9c9b2d437c670627e96ad06", + "shasum": "" + }, + "require": { + "php": "^7.1.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.1-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Finder\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Finder Component", + "homepage": "https://symfony.com", + "time": "2018-10-03T08:47:56+00:00" + }, + { + "name": "symfony/flex", + "version": "v1.1.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/flex.git", + "reference": "9fb60f232af0764d58002e7872acb43a74506d25" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/flex/zipball/9fb60f232af0764d58002e7872acb43a74506d25", + "reference": "9fb60f232af0764d58002e7872acb43a74506d25", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^1.0", + "php": "^7.0" + }, + "require-dev": { + "composer/composer": "^1.0.2", + "symfony/phpunit-bridge": "^3.2.8" + }, + "type": "composer-plugin", + "extra": { + "branch-alias": { + "dev-master": "1.1-dev" + }, + "class": "Symfony\\Flex\\Flex" + }, + "autoload": { + "psr-4": { + "Symfony\\Flex\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien.potencier@gmail.com" + } + ], + "description": "Composer plugin for Symfony", + "time": "2018-09-03T08:17:12+00:00" + }, + { + "name": "symfony/framework-bundle", + "version": "v4.1.6", + "source": { + "type": "git", + "url": "https://github.com/symfony/framework-bundle.git", + "reference": "3a0f2ec035c6ecc0f751fda1a76b02310bc9bbfe" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/framework-bundle/zipball/3a0f2ec035c6ecc0f751fda1a76b02310bc9bbfe", + "reference": "3a0f2ec035c6ecc0f751fda1a76b02310bc9bbfe", + "shasum": "" + }, + "require": { + "ext-xml": "*", + "php": "^7.1.3", + "symfony/cache": "~3.4|~4.0", + "symfony/config": "~3.4|~4.0", + "symfony/dependency-injection": "^4.1.1", + "symfony/event-dispatcher": "^4.1", + "symfony/filesystem": "~3.4|~4.0", + "symfony/finder": "~3.4|~4.0", + "symfony/http-foundation": "^4.1", + "symfony/http-kernel": "^4.1", + "symfony/polyfill-mbstring": "~1.0", + "symfony/routing": "^4.1" + }, + "conflict": { + "phpdocumentor/reflection-docblock": "<3.0", + "phpdocumentor/type-resolver": "<0.2.1", + "phpunit/phpunit": "<4.8.35|<5.4.3,>=5.0", + "symfony/asset": "<3.4", + "symfony/console": "<3.4", + "symfony/form": "<4.1", + "symfony/messenger": ">=4.2", + "symfony/property-info": "<3.4", + "symfony/serializer": "<4.1", + "symfony/stopwatch": "<3.4", + "symfony/translation": "<3.4", + "symfony/twig-bridge": "<4.1.1", + "symfony/validator": "<4.1", + "symfony/workflow": "<4.1" + }, + "require-dev": { + "doctrine/annotations": "~1.0", + "doctrine/cache": "~1.0", + "fig/link-util": "^1.0", + "phpdocumentor/reflection-docblock": "^3.0|^4.0", + "symfony/asset": "~3.4|~4.0", + "symfony/browser-kit": "~3.4|~4.0", + "symfony/console": "~3.4|~4.0", + "symfony/css-selector": "~3.4|~4.0", + "symfony/dom-crawler": "~3.4|~4.0", + "symfony/expression-language": "~3.4|~4.0", + "symfony/form": "^4.1", + "symfony/lock": "~3.4|~4.0", + "symfony/messenger": "^4.1", + "symfony/polyfill-intl-icu": "~1.0", + "symfony/process": "~3.4|~4.0", + "symfony/property-info": "~3.4|~4.0", + "symfony/security": "~3.4|~4.0", + "symfony/security-core": "~3.4|~4.0", + "symfony/security-csrf": "~3.4|~4.0", + "symfony/serializer": "^4.1", + "symfony/stopwatch": "~3.4|~4.0", + "symfony/templating": "~3.4|~4.0", + "symfony/translation": "~3.4|~4.0", + "symfony/validator": "^4.1", + "symfony/var-dumper": "~3.4|~4.0", + "symfony/web-link": "~3.4|~4.0", + "symfony/workflow": "^4.1", + "symfony/yaml": "~3.4|~4.0", + "twig/twig": "~1.34|~2.4" + }, + "suggest": { + "ext-apcu": "For best performance of the system caches", + "symfony/console": "For using the console commands", + "symfony/form": "For using forms", + "symfony/property-info": "For using the property_info service", + "symfony/serializer": "For using the serializer service", + "symfony/validator": "For using validation", + "symfony/web-link": "For using web links, features such as preloading, prefetching or prerendering", + "symfony/yaml": "For using the debug:config and lint:yaml commands" + }, + "type": "symfony-bundle", + "extra": { + "branch-alias": { + "dev-master": "4.1-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Bundle\\FrameworkBundle\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony FrameworkBundle", + "homepage": "https://symfony.com", + "time": "2018-10-03T08:47:56+00:00" + }, + { + "name": "symfony/http-foundation", + "version": "v4.1.6", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-foundation.git", + "reference": "d528136617ff24f530e70df9605acc1b788b08d4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/d528136617ff24f530e70df9605acc1b788b08d4", + "reference": "d528136617ff24f530e70df9605acc1b788b08d4", + "shasum": "" + }, + "require": { + "php": "^7.1.3", + "symfony/polyfill-mbstring": "~1.1" + }, + "require-dev": { + "predis/predis": "~1.0", + "symfony/expression-language": "~3.4|~4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.1-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\HttpFoundation\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony HttpFoundation Component", + "homepage": "https://symfony.com", + "time": "2018-10-03T08:48:45+00:00" + }, + { + "name": "symfony/http-kernel", + "version": "v4.1.6", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-kernel.git", + "reference": "f5e7c15a5d010be0e16ce798594c5960451d4220" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/f5e7c15a5d010be0e16ce798594c5960451d4220", + "reference": "f5e7c15a5d010be0e16ce798594c5960451d4220", + "shasum": "" + }, + "require": { + "php": "^7.1.3", + "psr/log": "~1.0", + "symfony/debug": "~3.4|~4.0", + "symfony/event-dispatcher": "~4.1", + "symfony/http-foundation": "^4.1.1", + "symfony/polyfill-ctype": "~1.8" + }, + "conflict": { + "symfony/config": "<3.4", + "symfony/dependency-injection": "<4.1", + "symfony/var-dumper": "<4.1.1", + "twig/twig": "<1.34|<2.4,>=2" + }, + "provide": { + "psr/log-implementation": "1.0" + }, + "require-dev": { + "psr/cache": "~1.0", + "symfony/browser-kit": "~3.4|~4.0", + "symfony/config": "~3.4|~4.0", + "symfony/console": "~3.4|~4.0", + "symfony/css-selector": "~3.4|~4.0", + "symfony/dependency-injection": "^4.1", + "symfony/dom-crawler": "~3.4|~4.0", + "symfony/expression-language": "~3.4|~4.0", + "symfony/finder": "~3.4|~4.0", + "symfony/process": "~3.4|~4.0", + "symfony/routing": "~3.4|~4.0", + "symfony/stopwatch": "~3.4|~4.0", + "symfony/templating": "~3.4|~4.0", + "symfony/translation": "~3.4|~4.0", + "symfony/var-dumper": "^4.1.1" + }, + "suggest": { + "symfony/browser-kit": "", + "symfony/config": "", + "symfony/console": "", + "symfony/dependency-injection": "", + "symfony/var-dumper": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.1-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\HttpKernel\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony HttpKernel Component", + "homepage": "https://symfony.com", + "time": "2018-10-03T12:53:38+00:00" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.9.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "d0cd638f4634c16d8df4508e847f14e9e43168b8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/d0cd638f4634c16d8df4508e847f14e9e43168b8", + "reference": "d0cd638f4634c16d8df4508e847f14e9e43168b8", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.9-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for the Mbstring extension", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "mbstring", + "polyfill", + "portable", + "shim" + ], + "time": "2018-08-06T14:22:27+00:00" + }, + { + "name": "symfony/routing", + "version": "v4.1.6", + "source": { + "type": "git", + "url": "https://github.com/symfony/routing.git", + "reference": "537803f0bdfede36b9acef052d2e4d447d9fa0e9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/routing/zipball/537803f0bdfede36b9acef052d2e4d447d9fa0e9", + "reference": "537803f0bdfede36b9acef052d2e4d447d9fa0e9", + "shasum": "" + }, + "require": { + "php": "^7.1.3" + }, + "conflict": { + "symfony/config": "<3.4", + "symfony/dependency-injection": "<3.4", + "symfony/yaml": "<3.4" + }, + "require-dev": { + "doctrine/annotations": "~1.0", + "psr/log": "~1.0", + "symfony/config": "~3.4|~4.0", + "symfony/dependency-injection": "~3.4|~4.0", + "symfony/expression-language": "~3.4|~4.0", + "symfony/http-foundation": "~3.4|~4.0", + "symfony/yaml": "~3.4|~4.0" + }, + "suggest": { + "doctrine/annotations": "For using the annotation loader", + "symfony/config": "For using the all-in-one router or any loader", + "symfony/dependency-injection": "For loading routes from a service", + "symfony/expression-language": "For using expression matching", + "symfony/http-foundation": "For using a Symfony Request object", + "symfony/yaml": "For using the YAML loader" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.1-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Routing\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Routing Component", + "homepage": "https://symfony.com", + "keywords": [ + "router", + "routing", + "uri", + "url" + ], + "time": "2018-10-02T12:40:59+00:00" + }, + { + "name": "symfony/yaml", + "version": "v4.1.6", + "source": { + "type": "git", + "url": "https://github.com/symfony/yaml.git", + "reference": "367e689b2fdc19965be435337b50bc8adf2746c9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/yaml/zipball/367e689b2fdc19965be435337b50bc8adf2746c9", + "reference": "367e689b2fdc19965be435337b50bc8adf2746c9", + "shasum": "" + }, + "require": { + "php": "^7.1.3", + "symfony/polyfill-ctype": "~1.8" + }, + "conflict": { + "symfony/console": "<3.4" + }, + "require-dev": { + "symfony/console": "~3.4|~4.0" + }, + "suggest": { + "symfony/console": "For validating YAML files using the lint command" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.1-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Yaml\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Yaml Component", + "homepage": "https://symfony.com", + "time": "2018-10-02T16:36:10+00:00" + } + ], + "packages-dev": [ + { + "name": "symfony/dotenv", + "version": "v4.1.6", + "source": { + "type": "git", + "url": "https://github.com/symfony/dotenv.git", + "reference": "22ca63c46e252b8a8f37b8f9e6da66bff5b3d3e7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/dotenv/zipball/22ca63c46e252b8a8f37b8f9e6da66bff5b3d3e7", + "reference": "22ca63c46e252b8a8f37b8f9e6da66bff5b3d3e7", + "shasum": "" + }, + "require": { + "php": "^7.1.3" + }, + "require-dev": { + "symfony/process": "~3.4|~4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.1-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Dotenv\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Registers environment variables from a .env file", + "homepage": "https://symfony.com", + "keywords": [ + "dotenv", + "env", + "environment" + ], + "time": "2018-07-26T11:24:31+00:00" + } + ], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [], + "prefer-stable": false, + "prefer-lowest": false, + "platform": { + "php": "^7.1.3", + "ext-ctype": "*", + "ext-iconv": "*" + }, + "platform-dev": [] +} diff --git a/fixtures/set028-symfony/config/bundles.php b/fixtures/set028-symfony/config/bundles.php new file mode 100644 index 00000000..49d3fb6f --- /dev/null +++ b/fixtures/set028-symfony/config/bundles.php @@ -0,0 +1,5 @@ + ['all' => true], +]; diff --git a/fixtures/set028-symfony/config/packages/dev/routing.yaml b/fixtures/set028-symfony/config/packages/dev/routing.yaml new file mode 100644 index 00000000..4116679a --- /dev/null +++ b/fixtures/set028-symfony/config/packages/dev/routing.yaml @@ -0,0 +1,3 @@ +framework: + router: + strict_requirements: true diff --git a/fixtures/set028-symfony/config/packages/framework.yaml b/fixtures/set028-symfony/config/packages/framework.yaml new file mode 100644 index 00000000..8b244184 --- /dev/null +++ b/fixtures/set028-symfony/config/packages/framework.yaml @@ -0,0 +1,30 @@ +framework: + secret: '%env(APP_SECRET)%' + #default_locale: en + #csrf_protection: true + #http_method_override: true + + # Enables session support. Note that the session will ONLY be started if you read or write from it. + # Remove or comment this section to explicitly disable session support. + session: + handler_id: ~ + + #esi: true + #fragments: true + php_errors: + log: true + + cache: + # Put the unique name of your app here: the prefix seed + # is used to compute stable namespaces for cache keys. + #prefix_seed: your_vendor_name/app_name + + # The app cache caches to the filesystem by default. + # Other options include: + + # Redis + #app: cache.adapter.redis + #default_redis_provider: redis://localhost + + # APCu (not recommended with heavy random-write workloads as memory fragmentation can cause perf issues) + #app: cache.adapter.apcu diff --git a/fixtures/set028-symfony/config/packages/routing.yaml b/fixtures/set028-symfony/config/packages/routing.yaml new file mode 100644 index 00000000..368bc7f4 --- /dev/null +++ b/fixtures/set028-symfony/config/packages/routing.yaml @@ -0,0 +1,3 @@ +framework: + router: + strict_requirements: ~ diff --git a/fixtures/set028-symfony/config/packages/test/framework.yaml b/fixtures/set028-symfony/config/packages/test/framework.yaml new file mode 100644 index 00000000..d051c840 --- /dev/null +++ b/fixtures/set028-symfony/config/packages/test/framework.yaml @@ -0,0 +1,4 @@ +framework: + test: true + session: + storage_id: session.storage.mock_file diff --git a/fixtures/set028-symfony/config/packages/test/routing.yaml b/fixtures/set028-symfony/config/packages/test/routing.yaml new file mode 100644 index 00000000..4116679a --- /dev/null +++ b/fixtures/set028-symfony/config/packages/test/routing.yaml @@ -0,0 +1,3 @@ +framework: + router: + strict_requirements: true diff --git a/fixtures/set028-symfony/config/routes.yaml b/fixtures/set028-symfony/config/routes.yaml new file mode 100644 index 00000000..c3283aa2 --- /dev/null +++ b/fixtures/set028-symfony/config/routes.yaml @@ -0,0 +1,3 @@ +#index: +# path: / +# controller: App\Controller\DefaultController::index diff --git a/fixtures/set028-symfony/config/services.yaml b/fixtures/set028-symfony/config/services.yaml new file mode 100644 index 00000000..da151db0 --- /dev/null +++ b/fixtures/set028-symfony/config/services.yaml @@ -0,0 +1,30 @@ +# This file is the entry point to configure your own services. +# Files in the packages/ subdirectory configure your dependencies. + +# Put parameters here that don't need to change on each machine where the app is deployed +# https://symfony.com/doc/current/best_practices/configuration.html#application-related-configuration +parameters: + +services: + # default configuration for services in *this* file + _defaults: + autowire: true # Automatically injects dependencies in your services. + autoconfigure: true # Automatically registers your services as commands, event subscribers, etc. + public: false # Allows optimizing the container by removing unused services; this also means + # fetching services directly from the container via $container->get() won't work. + # The best practice is to be explicit about your dependencies anyway. + + # makes classes in src/ available to be used as services + # this creates a service per class whose id is the fully-qualified class name + App\: + resource: '../src/*' + exclude: '../src/{DependencyInjection,Entity,Migrations,Tests,Kernel.php}' + + # controllers are imported separately to make sure services can be injected + # as action arguments even if you don't extend any base controller class + # App\Controller\: + # resource: '../src/Controller' + # tags: ['controller.service_arguments'] + + # add more service definitions when explicit configuration is needed + # please note that last definitions always *replace* previous ones diff --git a/fixtures/set028-symfony/expected-output b/fixtures/set028-symfony/expected-output new file mode 100644 index 00000000..27030a5f --- /dev/null +++ b/fixtures/set028-symfony/expected-output @@ -0,0 +1 @@ +Symfony 4.1.6 (kernel: src, env: dev, debug: true) diff --git a/fixtures/set028-symfony/public/index.php b/fixtures/set028-symfony/public/index.php new file mode 100644 index 00000000..5283b7ce --- /dev/null +++ b/fixtures/set028-symfony/public/index.php @@ -0,0 +1,39 @@ +load(__DIR__.'/../.env'); +} + +$env = $_SERVER['APP_ENV'] ?? $_ENV['APP_ENV'] ?? 'dev'; +$debug = (bool) ($_SERVER['APP_DEBUG'] ?? $_ENV['APP_DEBUG'] ?? ('prod' !== $env)); + +if ($debug) { + umask(0000); + + Debug::enable(); +} + +if ($trustedProxies = $_SERVER['TRUSTED_PROXIES'] ?? $_ENV['TRUSTED_PROXIES'] ?? false) { + Request::setTrustedProxies(explode(',', $trustedProxies), Request::HEADER_X_FORWARDED_ALL ^ Request::HEADER_X_FORWARDED_HOST); +} + +if ($trustedHosts = $_SERVER['TRUSTED_HOSTS'] ?? $_ENV['TRUSTED_HOSTS'] ?? false) { + Request::setTrustedHosts(explode(',', $trustedHosts)); +} + +$kernel = new Kernel($env, $debug); +$request = Request::createFromGlobals(); +$response = $kernel->handle($request); +$response->send(); +$kernel->terminate($request, $response); diff --git a/fixtures/set028-symfony/src/Kernel.php b/fixtures/set028-symfony/src/Kernel.php new file mode 100644 index 00000000..dc2f242c --- /dev/null +++ b/fixtures/set028-symfony/src/Kernel.php @@ -0,0 +1,61 @@ +getProjectDir().'/var/cache/'.$this->environment; + } + + public function getLogDir() + { + return $this->getProjectDir().'/var/log'; + } + + public function registerBundles() + { + $contents = require $this->getProjectDir().'/config/bundles.php'; + foreach ($contents as $class => $envs) { + if (isset($envs['all']) || isset($envs[$this->environment])) { + yield new $class(); + } + } + } + + protected function configureContainer(ContainerBuilder $container, LoaderInterface $loader) + { + $container->addResource(new FileResource($this->getProjectDir().'/config/bundles.php')); + // Feel free to remove the "container.autowiring.strict_mode" parameter + // if you are using symfony/dependency-injection 4.0+ as it's the default behavior + $container->setParameter('container.autowiring.strict_mode', true); + $container->setParameter('container.dumper.inline_class_loader', true); + $confDir = $this->getProjectDir().'/config'; + + $loader->load($confDir.'/{packages}/*'.self::CONFIG_EXTS, 'glob'); + $loader->load($confDir.'/{packages}/'.$this->environment.'/**/*'.self::CONFIG_EXTS, 'glob'); + $loader->load($confDir.'/{services}'.self::CONFIG_EXTS, 'glob'); + $loader->load($confDir.'/{services}_'.$this->environment.self::CONFIG_EXTS, 'glob'); + } + + protected function configureRoutes(RouteCollectionBuilder $routes) + { + $confDir = $this->getProjectDir().'/config'; + + $routes->import($confDir.'/{routes}/*'.self::CONFIG_EXTS, '/', 'glob'); + $routes->import($confDir.'/{routes}/'.$this->environment.'/**/*'.self::CONFIG_EXTS, '/', 'glob'); + $routes->import($confDir.'/{routes}'.self::CONFIG_EXTS, '/', 'glob'); + } +} diff --git a/fixtures/set028-symfony/symfony.lock b/fixtures/set028-symfony/symfony.lock new file mode 100644 index 00000000..2c227a8a --- /dev/null +++ b/fixtures/set028-symfony/symfony.lock @@ -0,0 +1,86 @@ +{ + "psr/cache": { + "version": "1.0.1" + }, + "psr/container": { + "version": "1.0.0" + }, + "psr/log": { + "version": "1.0.2" + }, + "psr/simple-cache": { + "version": "1.0.1" + }, + "symfony/cache": { + "version": "v4.1.6" + }, + "symfony/config": { + "version": "v4.1.6" + }, + "symfony/console": { + "version": "3.3", + "recipe": { + "repo": "github.com/symfony/recipes", + "branch": "master", + "version": "3.3", + "ref": "e3868d2f4a5104f19f844fe551099a00c6562527" + } + }, + "symfony/debug": { + "version": "v4.1.6" + }, + "symfony/dependency-injection": { + "version": "v4.1.6" + }, + "symfony/dotenv": { + "version": "v4.1.6" + }, + "symfony/event-dispatcher": { + "version": "v4.1.6" + }, + "symfony/filesystem": { + "version": "v4.1.6" + }, + "symfony/finder": { + "version": "v4.1.6" + }, + "symfony/flex": { + "version": "1.0", + "recipe": { + "repo": "github.com/symfony/recipes", + "branch": "master", + "version": "1.0", + "ref": "e921bdbfe20cdefa3b82f379d1cd36df1bc8d115" + } + }, + "symfony/framework-bundle": { + "version": "3.3", + "recipe": { + "repo": "github.com/symfony/recipes", + "branch": "master", + "version": "3.3", + "ref": "1717e67afa995e4f01a25ba9ae7aca5b2327bcaa" + } + }, + "symfony/http-foundation": { + "version": "v4.1.6" + }, + "symfony/http-kernel": { + "version": "v4.1.6" + }, + "symfony/polyfill-mbstring": { + "version": "v1.9.0" + }, + "symfony/routing": { + "version": "4.0", + "recipe": { + "repo": "github.com/symfony/recipes", + "branch": "master", + "version": "4.0", + "ref": "5f514d9d3b8a8aac3d62ae6a86b18b90ed0c7826" + } + }, + "symfony/yaml": { + "version": "v4.1.6" + } +} diff --git a/src/Configuration.php b/src/Configuration.php index 4f0bdcd1..7622fe3e 100644 --- a/src/Configuration.php +++ b/src/Configuration.php @@ -14,6 +14,7 @@ namespace Humbug\PhpScoper; +use Humbug\PhpScoper\Patcher\SymfonyPatcher; use InvalidArgumentException; use Iterator; use RuntimeException; @@ -22,6 +23,7 @@ use Symfony\Component\Finder\Finder; use const DIRECTORY_SEPARATOR; use function array_key_exists; +use function array_unshift; use function dirname; use function file_exists; use function gettype; @@ -128,6 +130,9 @@ public static function load(string $path = null, array $paths = []): self $whitelistedFiles = null === $path ? [] : self::retrieveWhitelistedFiles(dirname($path), $config); $patchers = self::retrievePatchers($config); + + array_unshift($patchers, new SymfonyPatcher()); + $whitelist = self::retrieveWhitelist($config); $finders = self::retrieveFinders($config); diff --git a/src/Console/ApplicationFactory.php b/src/Console/ApplicationFactory.php index 665a2a78..ebacfef5 100644 --- a/src/Console/ApplicationFactory.php +++ b/src/Console/ApplicationFactory.php @@ -24,6 +24,7 @@ use Humbug\PhpScoper\Scoper\NullScoper; use Humbug\PhpScoper\Scoper\PatchScoper; use Humbug\PhpScoper\Scoper\PhpScoper; +use Humbug\PhpScoper\Scoper\SymfonyScoper; use PackageVersions\Versions; use PhpParser\Parser; use PhpParser\ParserFactory; @@ -71,7 +72,9 @@ protected static function createScoper(): Scoper static::createParser(), new JsonFileScoper( new InstalledPackagesScoper( - new NullScoper() + new SymfonyScoper( + new NullScoper() + ) ) ), new TraverserFactory(static::createReflector()) diff --git a/src/Patcher/SymfonyPatcher.php b/src/Patcher/SymfonyPatcher.php new file mode 100644 index 00000000..4d1f8cbd --- /dev/null +++ b/src/Patcher/SymfonyPatcher.php @@ -0,0 +1,53 @@ +, + * Pádraic Brady + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Humbug\PhpScoper\Patcher; + +use function preg_replace; +use function strpos; + +final class SymfonyPatcher +{ + private const PATHS = [ + 'src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php', + 'symfony/dependency-injection/Dumper/PhpDumper.php', + ]; + + public function __invoke(string $filePath, string $prefix, string $contents): string + { + if (false === $this->isValidPath($filePath)) { + return $contents; + } + + return preg_replace( + '/use (Symfony(\\\\(?:\\\\)?)Component\\\\.+?;)/', + sprintf( + 'use %s$2$1', + $prefix + ), + $contents + ); + } + + private function isValidPath(string $filePath): bool + { + foreach (self::PATHS as $path) { + if (false !== strpos($filePath, $path)) { + return true; + } + } + + return false; + } +} diff --git a/src/Scoper/ConfigurableScoper.php b/src/Scoper/ConfigurableScoper.php index ceb097c4..7d268c86 100644 --- a/src/Scoper/ConfigurableScoper.php +++ b/src/Scoper/ConfigurableScoper.php @@ -16,6 +16,7 @@ use Humbug\PhpScoper\Scoper; use Humbug\PhpScoper\Whitelist; +use function func_get_args; final class ConfigurableScoper implements Scoper { @@ -46,6 +47,6 @@ public function withWhitelistedFiles(string ...$whitelistedFiles): self */ public function scope(string $filePath, string $contents, string $prefix, array $patchers, Whitelist $whitelist): string { - return $this->decoratedScoper->scope($filePath, $contents, $prefix, $patchers, $whitelist); + return $this->decoratedScoper->scope(...func_get_args()); } } diff --git a/src/Scoper/FileWhitelistScoper.php b/src/Scoper/FileWhitelistScoper.php index fe92350d..e6d81618 100644 --- a/src/Scoper/FileWhitelistScoper.php +++ b/src/Scoper/FileWhitelistScoper.php @@ -18,6 +18,7 @@ use Humbug\PhpScoper\Whitelist; use function array_flip; use function array_key_exists; +use function func_get_args; final class FileWhitelistScoper implements Scoper { @@ -39,6 +40,6 @@ public function scope(string $filePath, string $contents, string $prefix, array return $contents; } - return $this->decoratedScoper->scope($filePath, $contents, $prefix, $patchers, $whitelist); + return $this->decoratedScoper->scope(...func_get_args()); } } diff --git a/src/Scoper/PatchScoper.php b/src/Scoper/PatchScoper.php index 6dc3ce09..f2897d07 100644 --- a/src/Scoper/PatchScoper.php +++ b/src/Scoper/PatchScoper.php @@ -16,6 +16,7 @@ use Humbug\PhpScoper\Scoper; use Humbug\PhpScoper\Whitelist; +use function func_get_args; final class PatchScoper implements Scoper { @@ -31,7 +32,7 @@ public function __construct(Scoper $decoratedScoper) */ public function scope(string $filePath, string $contents, string $prefix, array $patchers, Whitelist $whitelist): string { - $contents = $this->decoratedScoper->scope($filePath, $contents, $prefix, $patchers, $whitelist); + $contents = $this->decoratedScoper->scope(...func_get_args()); return array_reduce( $patchers, diff --git a/src/Scoper/PhpScoper.php b/src/Scoper/PhpScoper.php index 104e2e61..07563bb2 100644 --- a/src/Scoper/PhpScoper.php +++ b/src/Scoper/PhpScoper.php @@ -20,6 +20,7 @@ use PhpParser\Error as PhpParserError; use PhpParser\Parser; use PhpParser\PrettyPrinter\Standard; +use function func_get_args; final class PhpScoper implements Scoper { @@ -49,7 +50,7 @@ public function __construct(Parser $parser, Scoper $decoratedScoper, TraverserFa public function scope(string $filePath, string $contents, string $prefix, array $patchers, Whitelist $whitelist): string { if (false === $this->isPhpFile($filePath, $contents)) { - return $this->decoratedScoper->scope($filePath, $contents, $prefix, $patchers, $whitelist); + return $this->decoratedScoper->scope(...func_get_args()); } return $this->scopePhp($contents, $prefix, $whitelist); diff --git a/src/Scoper/Symfony/XmlScoper.php b/src/Scoper/Symfony/XmlScoper.php new file mode 100644 index 00000000..0894a9a5 --- /dev/null +++ b/src/Scoper/Symfony/XmlScoper.php @@ -0,0 +1,138 @@ +, + * Pádraic Brady + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Humbug\PhpScoper\Scoper\Symfony; + +use Humbug\PhpScoper\Scoper; +use Humbug\PhpScoper\Whitelist; +use PhpParser\Node\Name\FullyQualified; +use function func_get_args; +use function preg_match_all; +use function str_replace; +use function strlen; +use function strpos; +use function substr; + +/** + * Scopes the Symfony XML configuration files. + */ +final class XmlScoper implements Scoper +{ + private const FILE_PATH_PATTERN = '/.*\.xml$/i'; + + private $decoratedScoper; + + public function __construct(Scoper $decoratedScoper) + { + $this->decoratedScoper = $decoratedScoper; + } + + /** + * {@inheritdoc} + */ + public function scope(string $filePath, string $contents, string $prefix, array $patchers, Whitelist $whitelist): string + { + if (1 !== preg_match(self::FILE_PATH_PATTERN, $filePath)) { + return $this->decoratedScoper->scope(...func_get_args()); + } + + $contents = $this->scopeClasses($contents, $prefix, $whitelist); + $contents = $this->scopeNamespaces($contents, $prefix, $whitelist); + + return $contents; + } + + private function scopeClasses(string $contents, string $prefix, Whitelist $whitelist): string + { + if (1 > preg_match_all('/(?:(?(?:[\p{L}_\d]+(?\\\\(?:\\\\)?){1})):)|(?(?:[\p{L}_\d]+(?\\\\(?:\\\\)?)+)+[\p{L}_\d]+)/u', $contents, $matches)) { + return $contents; + } + + $contents = $this->replaceClasses( + array_filter($matches['singleClass']), + array_filter($matches['singleSeparator']), + $prefix, + $contents, + $whitelist + ); + + $contents = $this->replaceClasses( + array_filter($matches['class']), + array_filter($matches['separator']), + $prefix, + $contents, + $whitelist + ); + + return $contents; + } + + private function scopeNamespaces(string $contents, string $prefix, Whitelist $whitelist): string + { + if (1 > preg_match_all('/\(?:[^\\\\]+(?\\\\(?:\\\\)?){1})))"/', $contents, $matches)) { + return $contents; + } + + return $this->replaceClasses( + array_filter($matches['namespace']), + array_filter($matches['separator']), + $prefix, + $contents, + $whitelist + ); + } + + /** + * @param string[] $classes + * @param string[] $separators + */ + private function replaceClasses( + array $classes, + array $separators, + string $prefix, + string $contents, + Whitelist $whitelist + ): string { + if ([] === $classes) { + return $contents; + } + + $scopedContents = ''; + + foreach ($classes as $index => $class) { + $offset = strpos($contents, $class) + strlen($class); + + $stringToScope = substr($contents, 0, $offset); + $contents = substr($contents, $offset); + + $prefixedClass = $prefix.$separators[$index].$class; + + $scopedContents .= $whitelist->belongsToWhitelistedNamespace($class) + ? $stringToScope + : str_replace($class, $prefixedClass, $stringToScope) + ; + + if ($whitelist->isSymbolWhitelisted($class) || $whitelist->isGlobalWhitelistedClass($class)) { + $whitelist->recordWhitelistedClass( + new FullyQualified($class), + new FullyQualified($prefixedClass) + ); + } + } + + $scopedContents .= $contents; + + return $scopedContents; + } +} diff --git a/src/Scoper/Symfony/YamlScoper.php b/src/Scoper/Symfony/YamlScoper.php new file mode 100644 index 00000000..eae348c1 --- /dev/null +++ b/src/Scoper/Symfony/YamlScoper.php @@ -0,0 +1,116 @@ +, + * Pádraic Brady + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Humbug\PhpScoper\Scoper\Symfony; + +use Humbug\PhpScoper\Scoper; +use Humbug\PhpScoper\Whitelist; +use PhpParser\Node\Name\FullyQualified; +use function array_filter; +use function func_get_args; +use function preg_match_all; +use function str_replace; +use function strlen; +use function strpos; +use function substr; + +/** + * Scopes the Symfony YAML configuration files. + */ +final class YamlScoper implements Scoper +{ + private const FILE_PATH_PATTERN = '/.*\.ya?ml$/i'; + + private $decoratedScoper; + + public function __construct(Scoper $decoratedScoper) + { + $this->decoratedScoper = $decoratedScoper; + } + + /** + * {@inheritdoc} + */ + public function scope(string $filePath, string $contents, string $prefix, array $patchers, Whitelist $whitelist): string + { + if (1 !== preg_match(self::FILE_PATH_PATTERN, $filePath)) { + return $this->decoratedScoper->scope(...func_get_args()); + } + + if (1 > preg_match_all('/(?:(?(?:[\p{L}_\d]+(?\\\\(?:\\\\)?){1})):)|(?(?:[\p{L}_\d]+(?\\\\(?:\\\\)?)+)+[\p{L}_\d]+)/u', $contents, $matches)) { + return $contents; + } + + $contents = $this->replaceClasses( + array_filter($matches['singleClass']), + array_filter($matches['singleSeparator']), + $prefix, + $contents, + $whitelist + ); + + $contents = $this->replaceClasses( + array_filter($matches['class']), + array_filter($matches['separator']), + $prefix, + $contents, + $whitelist + ); + + return $contents; + } + + /** + * @param string[] $classes + * @param string[] $separators + */ + private function replaceClasses( + array $classes, + array $separators, + string $prefix, + string $contents, + Whitelist $whitelist + ): string { + if ([] === $classes) { + return $contents; + } + + $scopedContents = ''; + + foreach ($classes as $index => $class) { + $offset = strpos($contents, $class) + strlen($class); + + $stringToScope = substr($contents, 0, $offset); + $contents = substr($contents, $offset); + + $prefixedClass = $prefix.$separators[$index].$class; + + $scopedContents .= $whitelist->belongsToWhitelistedNamespace($class) + ? $stringToScope + : str_replace($class, $prefixedClass, $stringToScope) + ; + + if ($whitelist->isSymbolWhitelisted($class) || $whitelist->isGlobalWhitelistedClass($class)) { + $whitelist->recordWhitelistedClass( + new FullyQualified($class), + new FullyQualified($prefixedClass) + ); + } + } + + $scopedContents .= $contents; + + return $scopedContents; + } +} diff --git a/src/Scoper/SymfonyScoper.php b/src/Scoper/SymfonyScoper.php new file mode 100644 index 00000000..9f8d3c68 --- /dev/null +++ b/src/Scoper/SymfonyScoper.php @@ -0,0 +1,49 @@ +, + * Pádraic Brady + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Humbug\PhpScoper\Scoper; + +use Humbug\PhpScoper\Scoper; +use Humbug\PhpScoper\Scoper\Symfony\XmlScoper as SymfonyXmlScoper; +use Humbug\PhpScoper\Scoper\Symfony\YamlScoper as SymfonyYamlScoper; +use Humbug\PhpScoper\Whitelist; +use PhpParser\Error as PhpParserError; +use function func_get_args; + +/** + * Scopes the Symfony configuration related files. + */ +final class SymfonyScoper implements Scoper +{ + private $decoratedScoper; + + public function __construct(Scoper $decoratedScoper) + { + $this->decoratedScoper = new SymfonyXmlScoper( + new SymfonyYamlScoper($decoratedScoper) + ); + } + + /** + * Scopes PHP files. + * + * {@inheritdoc} + * + * @throws PhpParserError + */ + public function scope(string $filePath, string $contents, string $prefix, array $patchers, Whitelist $whitelist): string + { + return $this->decoratedScoper->scope(...func_get_args()); + } +} diff --git a/tests/ConfigurationTest.php b/tests/ConfigurationTest.php index f51bfe6c..81a28491 100644 --- a/tests/ConfigurationTest.php +++ b/tests/ConfigurationTest.php @@ -14,6 +14,7 @@ namespace Humbug\PhpScoper; +use Humbug\PhpScoper\Patcher\SymfonyPatcher; use InvalidArgumentException; use function KevinGH\Box\FileSystem\dump_file; @@ -34,7 +35,7 @@ public function test_it_can_be_created_without_a_file(): void $this->assertNull($configuration->getPath()); $this->assertNull($configuration->getPrefix()); $this->assertSame([], $configuration->getFilesWithContents()); - $this->assertSame([], $configuration->getPatchers()); + $this->assertEquals([new SymfonyPatcher()], $configuration->getPatchers()); } public function test_it_cannot_create_a_configuration_with_an_invalid_key(): void @@ -91,6 +92,6 @@ public function test_it_can_create_a_complete_configuration(): void $this->assertSame($this->tmp.'/scoper.inc.php', $configuration->getPath()); $this->assertSame('MyPrefix', $configuration->getPrefix()); $this->assertSame([], $configuration->getFilesWithContents()); - $this->assertSame([], $configuration->getPatchers()); + $this->assertEquals([new SymfonyPatcher()], $configuration->getPatchers()); } } diff --git a/tests/Console/Command/AddPrefixCommandTest.php b/tests/Console/Command/AddPrefixCommandTest.php index c19f0b72..d6e4588e 100644 --- a/tests/Console/Command/AddPrefixCommandTest.php +++ b/tests/Console/Command/AddPrefixCommandTest.php @@ -16,6 +16,7 @@ use Humbug\PhpScoper\Console\Application; use Humbug\PhpScoper\FileSystemTestCase; +use Humbug\PhpScoper\Patcher\SymfonyPatcher; use Humbug\PhpScoper\Scoper; use Humbug\PhpScoper\Whitelist; use InvalidArgumentException; @@ -176,7 +177,7 @@ public function test_scope_the_given_paths(): void $inputPath, $inputContents, 'MyPrefix', - [], + Argument::any(), Whitelist::create(true, true, true) ) ->willReturn($prefixedContents) @@ -239,7 +240,7 @@ public function test_let_the_file_unchanged_when_cannot_scope_a_file(): void $inputPath, $inputContents, 'MyPrefix', - [], + Argument::any(), Whitelist::create(true, true, true) ) ->willReturn($prefixedContents) @@ -252,7 +253,7 @@ public function test_let_the_file_unchanged_when_cannot_scope_a_file(): void $inputPath, $inputContents, 'MyPrefix', - [], + Argument::any(), Whitelist::create(true, true, true) ) ->willThrow(new RootRuntimeException('Scoping of the file failed')) @@ -312,7 +313,7 @@ public function test_do_not_scope_duplicated_given_paths(): void $inputPath, $inputContents, 'MyPrefix', - [], + Argument::any(), Whitelist::create(true, true, true) ) ->willReturn($prefixedContents) @@ -373,7 +374,7 @@ public function test_scope_the_given_paths_and_the_ones_found_by_the_finder(): v $inputPath, $inputContents, 'MyPrefix', - [], + Argument::any(), Whitelist::create(true, true, true) ) ->willReturn($prefixedFileContents) @@ -427,7 +428,7 @@ function (string $prefix): bool { return true; } ), - [], + Argument::any(), Whitelist::create(true, true, true) ) ->willReturn('') @@ -485,7 +486,7 @@ public function test_scope_the_current_working_directory_if_no_path_given(): voi $inputPath, $inputContents, 'MyPrefix', - [], + Argument::any(), Whitelist::create(true, true, true) ) ->willReturn($prefixedContents) @@ -531,7 +532,7 @@ public function test_prefix_can_end_by_a_backslash(): void Argument::any(), Argument::any(), 'MyPrefix', - [], + Argument::any(), Whitelist::create(true, true, true) ) ->willReturn('') @@ -574,7 +575,7 @@ public function test_prefix_can_end_by_multiple_backslashes(): void Argument::any(), Argument::any(), 'MyPrefix', - [], + Argument::any(), Whitelist::create(true, true, true) ) ->willReturn('') @@ -632,7 +633,7 @@ public function test_an_output_directory_can_be_given(): void $inputPath, $inputContents, 'MyPrefix', - [], + Argument::any(), Whitelist::create(true, true, true) ) ->willReturn($prefixedContents) @@ -694,7 +695,7 @@ public function test_relative_output_directory_are_made_absolute(): void $inputPath, $inputContents, 'MyPrefix', - [], + Argument::any(), Whitelist::create(true, true, true) ) ->willReturn($prefixedContents) @@ -798,8 +799,9 @@ public function test_attempts_to_use_patch_file_in_current_directory(): void $this->assertSame(0, $this->appTester->getStatusCode()); - $this->assertCount(1, $patchersFound); - $this->assertEquals('Hello world!', $patchersFound[0]()); + $this->assertCount(2, $patchersFound); + $this->assertEquals(new SymfonyPatcher(), $patchersFound[0]); + $this->assertEquals('Hello world!', $patchersFound[1]()); $this->fileSystemProphecy->isAbsolutePath(Argument::cetera())->shouldHaveBeenCalledTimes(2); @@ -870,7 +872,7 @@ public function test_can_scope_projects_with_invalid_files(): void $inputPath, $fileContents, 'MyPrefix', - [], + Argument::any(), Whitelist::create(true, true, true) ) ->willThrow($scopingException = new RuntimeException('Could not scope file')) diff --git a/tests/Patcher/SymfonyPatcherTest.php b/tests/Patcher/SymfonyPatcherTest.php new file mode 100644 index 00000000..ea7a3844 --- /dev/null +++ b/tests/Patcher/SymfonyPatcherTest.php @@ -0,0 +1,297 @@ +, + * Pádraic Brady + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Humbug\PhpScoper\Patcher; + +use Generator; +use PHPUnit\Framework\TestCase; + +/** + * @covers \Humbug\PhpScoper\Patcher\SymfonyPatcher + */ +class SymfonyPatcherTest extends TestCase +{ + /** + * @dataProvider provideFiles + */ + public function test_patch_the_Symfony_DependencyInjectionContainer_PhpDumper(string $filePath, string $contents, string $expected): void + { + $actual = (new SymfonyPatcher())->__invoke($filePath, 'Humbug', $contents); + + $this->assertSame($expected, $actual); + } + + public function provideFiles(): Generator + { + $validPaths = [ + 'src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php', + 'symfony/dependency-injection/Dumper/PhpDumper.php', + 'vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php', + 'vendor/symfony/dependency-injection/Dumper/PhpDumper.php', + ]; + + $invalidPaths = [ + 'DependencyInjection/Dumper/PhpDumper.php', + 'dependency-injection/Dumper/PhpDumper.php', + 'Dumper/PhpDumper.php', + ]; + + foreach ($this->provideCodeSamples() as [$input, $scopedOutput]) { + foreach ($validPaths as $path) { + yield [$path, $input, $scopedOutput]; + } + + foreach ($invalidPaths as $path) { + yield [$path, $input, $input]; + } + } + } + + private function provideCodeSamples(): Generator + { + yield [ + <<<'PHP' + private function startClass(string $class, string $baseClass, string $baseClassWithNamespace): string + { + $namespaceLine = !$this->asFiles && $this->namespace ? "\nnamespace {$this->namespace};\n" : ''; + + $code = <<docStar} + * This class has been auto-generated + * by the Symfony Dependency Injection Component. + * + * @final since Symfony 3.3 + */ +class $class extends $baseClass +{ + private \$parameters; + private \$targetDirs = array(); + + /*{$this->docStar} + * @internal but protected for BC on cache:clear + */ + protected \$privates = array(); + + public function __construct() + { + +EOF; +PHP + , + <<<'PHP' + private function startClass(string $class, string $baseClass, string $baseClassWithNamespace): string + { + $namespaceLine = !$this->asFiles && $this->namespace ? "\nnamespace {$this->namespace};\n" : ''; + + $code = <<docStar} + * This class has been auto-generated + * by the Symfony Dependency Injection Component. + * + * @final since Symfony 3.3 + */ +class $class extends $baseClass +{ + private \$parameters; + private \$targetDirs = array(); + + /*{$this->docStar} + * @internal but protected for BC on cache:clear + */ + protected \$privates = array(); + + public function __construct() + { + +EOF; +PHP + ]; + + yield [ + <<<'PHP' + private function startClass(string $class, string $baseClass, string $baseClassWithNamespace): string + { + $namespaceLine = !$this->asFiles && $this->namespace ? "\nnamespace {$this->namespace};\n" : ''; + + $code = <<docStar} + * This class has been auto-generated + * by the Symfony Dependency Injection Component. + * + * @final since Symfony 3.3 + */ +class $class extends $baseClass +{ + private \$parameters; + private \$targetDirs = array(); + + /*{$this->docStar} + * @internal but protected for BC on cache:clear + */ + protected \$privates = array(); + + public function __construct() + { + +EOF; +PHP + , + <<<'PHP' + private function startClass(string $class, string $baseClass, string $baseClassWithNamespace): string + { + $namespaceLine = !$this->asFiles && $this->namespace ? "\nnamespace {$this->namespace};\n" : ''; + + $code = <<docStar} + * This class has been auto-generated + * by the Symfony Dependency Injection Component. + * + * @final since Symfony 3.3 + */ +class $class extends $baseClass +{ + private \$parameters; + private \$targetDirs = array(); + + /*{$this->docStar} + * @internal but protected for BC on cache:clear + */ + protected \$privates = array(); + + public function __construct() + { + +EOF; +PHP + ]; + + yield [ + <<<'PHP' + private function startClass(string $class, string $baseClass, string $baseClassWithNamespace): string + { + $namespaceLine = !$this->asFiles && $this->namespace ? "\nnamespace {$this->namespace};\n" : ''; + + $code = <<docStar} + * This class has been auto-generated + * by the Symfony Dependency Injection Component. + * + * @final since Symfony 3.3 + */ +class $class extends $baseClass +{ + private \$parameters; + private \$targetDirs = array(); + + /*{$this->docStar} + * @internal but protected for BC on cache:clear + */ + protected \$privates = array(); + + public function __construct() + { + +EOF; +PHP + , + <<<'PHP' + private function startClass(string $class, string $baseClass, string $baseClassWithNamespace): string + { + $namespaceLine = !$this->asFiles && $this->namespace ? "\nnamespace {$this->namespace};\n" : ''; + + $code = <<docStar} + * This class has been auto-generated + * by the Symfony Dependency Injection Component. + * + * @final since Symfony 3.3 + */ +class $class extends $baseClass +{ + private \$parameters; + private \$targetDirs = array(); + + /*{$this->docStar} + * @internal but protected for BC on cache:clear + */ + protected \$privates = array(); + + public function __construct() + { + +EOF; +PHP + ]; + } +} diff --git a/tests/Scoper/Symfony/XmlScoperTest.php b/tests/Scoper/Symfony/XmlScoperTest.php new file mode 100644 index 00000000..2647d1d1 --- /dev/null +++ b/tests/Scoper/Symfony/XmlScoperTest.php @@ -0,0 +1,527 @@ +, + * Pádraic Brady + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Humbug\PhpScoper\Scoper\Symfony; + +use Generator; +use Humbug\PhpScoper\Scoper; +use Humbug\PhpScoper\Whitelist; +use PHPUnit\Framework\TestCase; +use Prophecy\Argument; +use Prophecy\Prophecy\ObjectProphecy; +use function Humbug\PhpScoper\create_fake_patcher; + +/** + * @covers \Humbug\PhpScoper\Scoper\Symfony\XmlScoper + */ +class XmlScoperTest extends TestCase +{ + /** + * @var Scoper + */ + private $scoper; + + /** + * @var Scoper|ObjectProphecy + */ + private $decoratedScoperProphecy; + + /** + * @var Scoper + */ + private $decoratedScoper; + + /** + * @inheritdoc + */ + public function setUp(): void + { + $this->decoratedScoperProphecy = $this->prophesize(Scoper::class); + $this->decoratedScoper = $this->decoratedScoperProphecy->reveal(); + + $this->scoper = new XmlScoper($this->decoratedScoper); + } + + public function test_it_is_a_Scoper(): void + { + $this->assertTrue(is_a(XmlScoper::class, Scoper::class, true)); + } + + /** + * @dataProvider provideXmlFilesExtensions + */ + public function test_it_can_scope_XML_files(string $file, bool $scoped): void + { + $prefix = 'Humbug'; + $patchers = [create_fake_patcher()]; + $whitelist = Whitelist::create(true, true, true, 'Foo'); + + $contents = ''; + + if (false === $scoped) { + $this->decoratedScoperProphecy->scope(Argument::cetera())->willReturn($expected = 'scoped by decorated scoper'); + $scopedCount = 1; + } else { + $expected = $contents; + $scopedCount = 0; + } + + $actual = $this->scoper->scope($file, $contents, $prefix, $patchers, $whitelist); + + $this->assertSame($expected, $actual); + + $this->decoratedScoperProphecy->scope(Argument::cetera())->shouldHaveBeenCalledTimes($scopedCount); + } + + /** + * @dataProvider provideXmlFiles + */ + public function test_it_scopes_XML_files(string $contents, Whitelist $whitelist, string $expected, array $expectedClasses): void + { + $prefix = 'Humbug'; + $file = 'file.xml'; + $patchers = [create_fake_patcher()]; + + $actual = $this->scoper->scope($file, $contents, $prefix, $patchers, $whitelist); + + $this->assertSame($expected, $actual); + + $this->assertSame($expectedClasses, $whitelist->getRecordedWhitelistedClasses()); + $this->assertSame([], $whitelist->getRecordedWhitelistedFunctions()); + + $this->decoratedScoperProphecy->scope(Argument::cetera())->shouldHaveBeenCalledTimes(0); + } + + public function provideXmlFilesExtensions(): Generator + { + yield ['file.xml', true]; + yield ['file.XML', true]; + yield ['file.xm', false]; + yield ['file.ml', false]; + yield ['file', false]; + } + + public function provideXmlFiles(): Generator + { + yield [ + '', + Whitelist::create(true, true, true), + '', + [], + ]; + + yield [ + <<<'XML' + + + + + + + + + + required + + + + + + + + class_exists + + + + + + + + + + + + + + + + + + %kernel.cache_dir%/annotations.php + + #^Symfony\\(?:Component\\HttpKernel\\|Bundle\\FrameworkBundle\\Controller\\(?!AbstractController$|Controller$))# + %kernel.debug% + + + + + + + %kernel.cache_dir%/annotations.php + + + + + + + + + + +XML + , + Whitelist::create(true, true, true), + <<<'XML' + + + + + + + + + + required + + + + + + + + class_exists + + + + + + + + + + + + + + + + + + %kernel.cache_dir%/annotations.php + + #^Symfony\\(?:Humbug\\Component\\HttpKernel\\|Humbug\\Bundle\\FrameworkBundle\\Controller\\(?!AbstractController$|Controller$))# + %kernel.debug% + + + + + + + %kernel.cache_dir%/annotations.php + + + + + + + + + + +XML + , + [], + ]; + + yield [ + <<<'XML' + + + + + + + + + + + + +XML + , + Whitelist::create(true, true, true), + <<<'XML' + + + + + + + + + + + + +XML + , + [], + ]; + + yield [ + <<<'XML' + + + + + + + + + + +XML + , + Whitelist::create(true, true, true), + <<<'XML' + + + + + + + + + + +XML + , + [], + ]; + + yield [ + <<<'XML' + + + + + + + + + + + + +XML + , + Whitelist::create(true, true, true), + <<<'XML' + + + + + + + + + + + + +XML + , + [], + ]; + + yield [ + <<<'XML' + + + + + + + + + + +XML + , + Whitelist::create(true, true, true), + <<<'XML' + + + + + + + + + + +XML + , + [], + ]; + + yield [ + <<<'XML' + + + + + + + + + +XML + , + Whitelist::create(true, true, true, 'Acme\Foo'), + <<<'XML' + + + + + + + + + +XML + , + [ + ['Acme\Foo', 'Humbug\Acme\Foo'], + ], + ]; + + yield [ + <<<'XML' + + + + + + + + + + + +XML + , + Whitelist::create(true, true, true), + <<<'XML' + + + + + + + + + + + +XML + , + [], // Whitelisting global classes in the service definitions is not supported at the moment. Provide a PR + // if you are willing to add support for it. + ]; + + yield [ + <<<'XML' + + + + + + + + + + + + + +XML + , + Whitelist::create(true, true, true, 'Acme\*'), + <<<'XML' + + + + + + + + + + + + + +XML + , + [], + ]; + } +} diff --git a/tests/Scoper/Symfony/YamlScoperTest.php b/tests/Scoper/Symfony/YamlScoperTest.php new file mode 100644 index 00000000..01ec020c --- /dev/null +++ b/tests/Scoper/Symfony/YamlScoperTest.php @@ -0,0 +1,396 @@ +, + * Pádraic Brady + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Humbug\PhpScoper\Scoper\Symfony; + +use Generator; +use Humbug\PhpScoper\Scoper; +use Humbug\PhpScoper\Whitelist; +use PHPUnit\Framework\TestCase; +use Prophecy\Argument; +use Prophecy\Prophecy\ObjectProphecy; +use function Humbug\PhpScoper\create_fake_patcher; + +/** + * @covers \Humbug\PhpScoper\Scoper\Symfony\YamlScoper + */ +class YamlScoperTest extends TestCase +{ + /** + * @var Scoper + */ + private $scoper; + + /** + * @var Scoper|ObjectProphecy + */ + private $decoratedScoperProphecy; + + /** + * @var Scoper + */ + private $decoratedScoper; + + /** + * @inheritdoc + */ + public function setUp(): void + { + $this->decoratedScoperProphecy = $this->prophesize(Scoper::class); + $this->decoratedScoper = $this->decoratedScoperProphecy->reveal(); + + $this->scoper = new YamlScoper($this->decoratedScoper); + } + + public function test_it_is_a_Scoper(): void + { + $this->assertTrue(is_a(YamlScoper::class, Scoper::class, true)); + } + + /** + * @dataProvider provideYamlFilesExtensions + */ + public function test_it_can_scope_Yaml_files(string $file, bool $scoped): void + { + $prefix = 'Humbug'; + $patchers = [create_fake_patcher()]; + $whitelist = Whitelist::create(true, true, true, 'Foo'); + + $contents = ''; + + if (false === $scoped) { + $this->decoratedScoperProphecy->scope(Argument::cetera())->willReturn($expected = 'scoped by decorated scoper'); + $scopedCount = 1; + } else { + $expected = $contents; + $scopedCount = 0; + } + + $actual = $this->scoper->scope($file, $contents, $prefix, $patchers, $whitelist); + + $this->assertSame($expected, $actual); + + $this->decoratedScoperProphecy->scope(Argument::cetera())->shouldHaveBeenCalledTimes($scopedCount); + } + + /** + * @dataProvider provideYamlFiles + */ + public function test_it_scopes_Yaml_files(string $contents, Whitelist $whitelist, string $expected, array $expectedClasses): void + { + $prefix = 'Humbug'; + $file = 'file.yaml'; + $patchers = [create_fake_patcher()]; + + $actual = $this->scoper->scope($file, $contents, $prefix, $patchers, $whitelist); + + $this->assertSame($expected, $actual); + + $this->assertSame($expectedClasses, $whitelist->getRecordedWhitelistedClasses()); + $this->assertSame([], $whitelist->getRecordedWhitelistedFunctions()); + + $this->decoratedScoperProphecy->scope(Argument::cetera())->shouldHaveBeenCalledTimes(0); + } + + public function provideYamlFilesExtensions(): Generator + { + yield ['file.yaml', true]; + yield ['file.yml', true]; + yield ['file.YAML', true]; + yield ['file.YML', true]; + yield ['file.yam', false]; + yield ['file.aml', false]; + yield ['file', false]; + } + + public function provideYamlFiles(): Generator + { + yield [ + '', + Whitelist::create(true, true, true), + '', + [], + ]; + + yield [ + <<<'YAML' +services: + Symfony\Component\Console\Style\SymfonyStyle: ~ + Symfony\Component\Console\Input\InputInterface: + alias: 'Symfony\Component\Console\Input\ArgvInput' + Symfony\Component\Console\Output\OutputInterface: '@Symfony\Component\Console\Output\ConsoleOutput' +YAML + , + Whitelist::create(true, true, true), + <<<'YAML' +services: + Humbug\Symfony\Component\Console\Style\SymfonyStyle: ~ + Humbug\Symfony\Component\Console\Input\InputInterface: + alias: 'Humbug\Symfony\Component\Console\Input\ArgvInput' + Humbug\Symfony\Component\Console\Output\OutputInterface: '@Humbug\Symfony\Component\Console\Output\ConsoleOutput' +YAML + , + [], + ]; + + yield [ + <<<'YAML' +services: + "Symfony\\Component\\Console\\Style\\SymfonyStyle": ~ + "Symfony\\Component\\Console\\Input\\InputInterface": + alias: "Symfony\\Component\\Console\\Input\\ArgvInput" + "Symfony\\Component\\Console\\Output\\OutputInterface": "@Symfony\\Component\\Console\\Output\\ConsoleOutput" +YAML + , + Whitelist::create(true, true, true), + <<<'YAML' +services: + "Humbug\\Symfony\\Component\\Console\\Style\\SymfonyStyle": ~ + "Humbug\\Symfony\\Component\\Console\\Input\\InputInterface": + alias: "Humbug\\Symfony\\Component\\Console\\Input\\ArgvInput" + "Humbug\\Symfony\\Component\\Console\\Output\\OutputInterface": "@Humbug\\Symfony\\Component\\Console\\Output\\ConsoleOutput" +YAML + , + [], + ]; + + yield [ + <<<'YAML' +services: + "Symfony\\Component\\Console\\Style\\SymfonyStyle": ~ + "Symfony\\Component\\Console\\Input\\InputInterface": '@Symfony\Component\Console\Style\SymfonyStyle' +YAML + , + Whitelist::create(true, true, true), + <<<'YAML' +services: + "Humbug\\Symfony\\Component\\Console\\Style\\SymfonyStyle": ~ + "Humbug\\Symfony\\Component\\Console\\Input\\InputInterface": '@Humbug\Symfony\Component\Console\Style\SymfonyStyle' +YAML + , + [], + ]; + + yield [ + <<<'YAML' +services: + Acme\Controller\: + resource: "../src" +YAML + , + Whitelist::create(true, true, true), + <<<'YAML' +services: + Humbug\Acme\Controller\: + resource: "../src" +YAML + , + [], + ]; + + yield [ + <<<'YAML' +services: + Acme\Foo: '@Acme\Foo\Bar' + Acme\Foo: '@Acme\Bar\Acme\Foo' +YAML + , + Whitelist::create(true, true, true), + <<<'YAML' +services: + Humbug\Acme\Foo: '@Humbug\Acme\Foo\Bar' + Humbug\Acme\Foo: '@Humbug\Acme\Bar\Acme\Foo' +YAML + , + [], + ]; + + yield [ + <<<'YAML' +services: + Acme\Foo: + - '@Acme\Bar' +YAML + , + Whitelist::create(true, true, true), + <<<'YAML' +services: + Humbug\Acme\Foo: + - '@Humbug\Acme\Bar' +YAML + , + [], + ]; + + yield [ + <<<'YAML' +services: + foo: + class: 'Acme\Foo' + arguments: + - '@Acme\Bar' + tags: + - { name: my_tag, id: 'Acme\Baz' } +YAML + , + Whitelist::create(true, true, true), + <<<'YAML' +services: + foo: + class: 'Humbug\Acme\Foo' + arguments: + - '@Humbug\Acme\Bar' + tags: + - { name: my_tag, id: 'Humbug\Acme\Baz' } +YAML + , + [], + ]; + + yield [ + <<<'YAML' +services: + Acme\Foo: + - '@Acme\Bar' +YAML + , + Whitelist::create(true, true, true, 'Acme\Foo'), + <<<'YAML' +services: + Humbug\Acme\Foo: + - '@Humbug\Acme\Bar' +YAML + , + [ + ['Acme\Foo', 'Humbug\Acme\Foo'], + ], + ]; + + yield [ + <<<'YAML' +services: + Foo: + - '@Acme\Bar' + + Closure: ~ +YAML + , + Whitelist::create(true, true, true), + <<<'YAML' +services: + Foo: + - '@Humbug\Acme\Bar' + + Closure: ~ +YAML + , + [], // Whitelisting global classes in the service definitions is not supported at the moment. Provide a PR + // if you are willing to add support for it. + ]; + + yield [ + <<<'YAML' +services: + Acme\Foo: + - '@Acme\Bar' + Emca\Foo: + - '@Emca\Bar' +YAML + , + Whitelist::create(true, true, true, 'Acme\*'), + <<<'YAML' +services: + Acme\Foo: + - '@Acme\Bar' + Humbug\Emca\Foo: + - '@Humbug\Emca\Bar' +YAML + , + [], + ]; + + yield [ + <<<'YAML' +# This file is the entry point to configure your own services. +# Files in the packages/ subdirectory configure your dependencies. + +# Put parameters here that don't need to change on each machine where the app is deployed +# https://symfony.com/doc/current/best_practices/configuration.html#application-related-configuration +parameters: + +services: + # default configuration for services in *this* file + _defaults: + autowire: true # Automatically injects dependencies in your services. + autoconfigure: true # Automatically registers your services as commands, event subscribers, etc. + public: false # Allows optimizing the container by removing unused services; this also means + # fetching services directly from the container via $container->get() won't work. + # The best practice is to be explicit about your dependencies anyway. + + # makes classes in src/ available to be used as services + # this creates a service per class whose id is the fully-qualified class name + App\: + resource: '../src/*' + exclude: '../src/{DependencyInjection,Entity,Migrations,Tests,Kernel.php}' + + # controllers are imported separately to make sure services can be injected + # as action arguments even if you don't extend any base controller class + App\Controller\: + resource: '../src/Controller' + tags: ['controller.service_arguments'] + + # add more service definitions when explicit configuration is needed + # please note that last definitions always *replace* previous ones + +YAML + , + Whitelist::create(true, true, true), + <<<'YAML' +# This file is the entry point to configure your own services. +# Files in the packages/ subdirectory configure your dependencies. + +# Put parameters here that don't need to change on each machine where the app is deployed +# https://symfony.com/doc/current/best_practices/configuration.html#application-related-configuration +parameters: + +services: + # default configuration for services in *this* file + _defaults: + autowire: true # Automatically injects dependencies in your services. + autoconfigure: true # Automatically registers your services as commands, event subscribers, etc. + public: false # Allows optimizing the container by removing unused services; this also means + # fetching services directly from the container via $container->get() won't work. + # The best practice is to be explicit about your dependencies anyway. + + # makes classes in src/ available to be used as services + # this creates a service per class whose id is the fully-qualified class name + Humbug\App\: + resource: '../src/*' + exclude: '../src/{DependencyInjection,Entity,Migrations,Tests,Kernel.php}' + + # controllers are imported separately to make sure services can be injected + # as action arguments even if you don't extend any base controller class + Humbug\App\Controller\: + resource: '../src/Controller' + tags: ['controller.service_arguments'] + + # add more service definitions when explicit configuration is needed + # please note that last definitions always *replace* previous ones + +YAML + , + [], + ]; + } +}