diff --git a/composer.lock b/composer.lock index 26bc91aaa4..c43e82677e 100644 --- a/composer.lock +++ b/composer.lock @@ -2060,7 +2060,7 @@ }, { "name": "Gert de Pagter", - "email": "backendtea@gmail.com" + "email": "BackEndTea@gmail.com" } ], "description": "Symfony polyfill for ctype functions", @@ -3326,6 +3326,246 @@ ], "time": "2018-01-07T19:17:08+00:00" }, + { + "name": "composer/ca-bundle", + "version": "1.1.4", + "source": { + "type": "git", + "url": "https://github.com/composer/ca-bundle.git", + "reference": "558f321c52faeb4828c03e7dc0cfe39a09e09a2d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/ca-bundle/zipball/558f321c52faeb4828c03e7dc0cfe39a09e09a2d", + "reference": "558f321c52faeb4828c03e7dc0cfe39a09e09a2d", + "shasum": "" + }, + "require": { + "ext-openssl": "*", + "ext-pcre": "*", + "php": "^5.3.2 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5", + "psr/log": "^1.0", + "symfony/process": "^2.5 || ^3.0 || ^4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\CaBundle\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "Lets you find a path to the system CA bundle, and includes a fallback to the Mozilla CA bundle.", + "keywords": [ + "cabundle", + "cacert", + "certificate", + "ssl", + "tls" + ], + "time": "2019-01-28T09:30:10+00:00" + }, + { + "name": "composer/composer", + "version": "1.8.5", + "source": { + "type": "git", + "url": "https://github.com/composer/composer.git", + "reference": "949b116f9e7d98d8d276594fed74b580d125c0e6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/composer/zipball/949b116f9e7d98d8d276594fed74b580d125c0e6", + "reference": "949b116f9e7d98d8d276594fed74b580d125c0e6", + "shasum": "" + }, + "require": { + "composer/ca-bundle": "^1.0", + "composer/semver": "^1.0", + "composer/spdx-licenses": "^1.2", + "composer/xdebug-handler": "^1.1", + "justinrainbow/json-schema": "^3.0 || ^4.0 || ^5.0", + "php": "^5.3.2 || ^7.0", + "psr/log": "^1.0", + "seld/jsonlint": "^1.4", + "seld/phar-utils": "^1.0", + "symfony/console": "^2.7 || ^3.0 || ^4.0", + "symfony/filesystem": "^2.7 || ^3.0 || ^4.0", + "symfony/finder": "^2.7 || ^3.0 || ^4.0", + "symfony/process": "^2.7 || ^3.0 || ^4.0" + }, + "conflict": { + "symfony/console": "2.8.38" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35 || ^5.7", + "phpunit/phpunit-mock-objects": "^2.3 || ^3.0" + }, + "suggest": { + "ext-openssl": "Enabling the openssl extension allows you to access https URLs for repositories and packages", + "ext-zip": "Enabling the zip extension allows you to unzip archives", + "ext-zlib": "Allow gzip compression of HTTP requests" + }, + "bin": [ + "bin/composer" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.8-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\": "src/Composer" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nils Adermann", + "email": "naderman@naderman.de", + "homepage": "http://www.naderman.de" + }, + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "Composer helps you declare, manage and install dependencies of PHP projects, ensuring you have the right stack everywhere.", + "homepage": "https://getcomposer.org/", + "keywords": [ + "autoload", + "dependency", + "package" + ], + "time": "2019-04-09T15:46:48+00:00" + }, + { + "name": "composer/spdx-licenses", + "version": "1.5.1", + "source": { + "type": "git", + "url": "https://github.com/composer/spdx-licenses.git", + "reference": "a1aa51cf3ab838b83b0867b14e56fc20fbd55b3d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/spdx-licenses/zipball/a1aa51cf3ab838b83b0867b14e56fc20fbd55b3d", + "reference": "a1aa51cf3ab838b83b0867b14e56fc20fbd55b3d", + "shasum": "" + }, + "require": { + "php": "^5.3.2 || ^7.0 || ^8.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35 || ^5.7 || 6.5 - 7" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Spdx\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nils Adermann", + "email": "naderman@naderman.de", + "homepage": "http://www.naderman.de" + }, + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + }, + { + "name": "Rob Bast", + "email": "rob.bast@gmail.com", + "homepage": "http://robbast.nl" + } + ], + "description": "SPDX licenses list and validation library.", + "keywords": [ + "license", + "spdx", + "validator" + ], + "time": "2019-03-26T10:23:26+00:00" + }, + { + "name": "composer/xdebug-handler", + "version": "1.3.3", + "source": { + "type": "git", + "url": "https://github.com/composer/xdebug-handler.git", + "reference": "46867cbf8ca9fb8d60c506895449eb799db1184f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/46867cbf8ca9fb8d60c506895449eb799db1184f", + "reference": "46867cbf8ca9fb8d60c506895449eb799db1184f", + "shasum": "" + }, + "require": { + "php": "^5.3.2 || ^7.0", + "psr/log": "^1.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "Composer\\XdebugHandler\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "John Stevenson", + "email": "john-stevenson@blueyonder.co.uk" + } + ], + "description": "Restarts a process without xdebug.", + "keywords": [ + "Xdebug", + "performance" + ], + "time": "2019-05-27T17:52:04+00:00" + }, { "name": "doctrine/instantiator", "version": "1.0.5", @@ -5011,6 +5251,99 @@ "homepage": "https://github.com/sebastianbergmann/version", "time": "2016-10-03T07:35:21+00:00" }, + { + "name": "seld/jsonlint", + "version": "1.7.1", + "source": { + "type": "git", + "url": "https://github.com/Seldaek/jsonlint.git", + "reference": "d15f59a67ff805a44c50ea0516d2341740f81a38" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Seldaek/jsonlint/zipball/d15f59a67ff805a44c50ea0516d2341740f81a38", + "reference": "d15f59a67ff805a44c50ea0516d2341740f81a38", + "shasum": "" + }, + "require": { + "php": "^5.3 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0" + }, + "bin": [ + "bin/jsonlint" + ], + "type": "library", + "autoload": { + "psr-4": { + "Seld\\JsonLint\\": "src/Seld/JsonLint/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "JSON Linter", + "keywords": [ + "json", + "linter", + "parser", + "validator" + ], + "time": "2018-01-24T12:46:19+00:00" + }, + { + "name": "seld/phar-utils", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/Seldaek/phar-utils.git", + "reference": "7009b5139491975ef6486545a39f3e6dad5ac30a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Seldaek/phar-utils/zipball/7009b5139491975ef6486545a39f3e6dad5ac30a", + "reference": "7009b5139491975ef6486545a39f3e6dad5ac30a", + "shasum": "" + }, + "require": { + "php": ">=5.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Seld\\PharUtils\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be" + } + ], + "description": "PHAR file format utilities, for when PHP phars you up", + "keywords": [ + "phra" + ], + "time": "2015-10-13T18:44:15+00:00" + }, { "name": "squizlabs/php_codesniffer", "version": "3.4.2", @@ -5229,6 +5562,105 @@ "homepage": "https://symfony.com", "time": "2019-02-23T15:06:07+00:00" }, + { + "name": "symfony/filesystem", + "version": "v3.4.28", + "source": { + "type": "git", + "url": "https://github.com/symfony/filesystem.git", + "reference": "acf99758b1df8e9295e6b85aa69f294565c9fedb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/acf99758b1df8e9295e6b85aa69f294565c9fedb", + "reference": "acf99758b1df8e9295e6b85aa69f294565c9fedb", + "shasum": "" + }, + "require": { + "php": "^5.5.9|>=7.0.8", + "symfony/polyfill-ctype": "~1.8" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.4-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": "2019-02-04T21:34:32+00:00" + }, + { + "name": "symfony/finder", + "version": "v3.4.28", + "source": { + "type": "git", + "url": "https://github.com/symfony/finder.git", + "reference": "fa5d962a71f2169dfe1cbae217fa5a2799859f6c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/finder/zipball/fa5d962a71f2169dfe1cbae217fa5a2799859f6c", + "reference": "fa5d962a71f2169dfe1cbae217fa5a2799859f6c", + "shasum": "" + }, + "require": { + "php": "^5.5.9|>=7.0.8" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.4-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": "2019-05-24T12:25:55+00:00" + }, { "name": "symfony/phpunit-bridge", "version": "v3.4.26", diff --git a/core/composer.json b/core/composer.json index e5de4f6b2c..b843f2869c 100644 --- a/core/composer.json +++ b/core/composer.json @@ -56,6 +56,7 @@ "behat/mink": "1.7.x-dev", "behat/mink-goutte-driver": "^1.2", "behat/mink-selenium2-driver": "1.3.x-dev", + "composer/composer": "^1.8", "drupal/coder": "^8.3.2", "jcalderonzumba/gastonjs": "^1.0.2", "jcalderonzumba/mink-phantomjs-driver": "^0.3.1", diff --git a/core/lib/Drupal/Component/VendorCleanup/Config.php b/core/lib/Drupal/Component/VendorCleanup/Config.php new file mode 100644 index 0000000000..ba62a9aeec --- /dev/null +++ b/core/lib/Drupal/Component/VendorCleanup/Config.php @@ -0,0 +1,172 @@ + ['tests', 'driver-testsuite'], + 'behat/mink-browserkit-driver' => ['tests'], + 'behat/mink-goutte-driver' => ['tests'], + 'brumann/polyfill-unserialize' => ['tests'], + 'drupal/coder' => [ + 'coder_sniffer/Drupal/Test', + 'coder_sniffer/DrupalPractice/Test', + ], + 'doctrine/cache' => ['tests'], + 'doctrine/collections' => ['tests'], + 'doctrine/common' => ['tests'], + 'doctrine/inflector' => ['tests'], + 'doctrine/instantiator' => ['tests'], + 'egulias/email-validator' => ['documentation', 'tests'], + 'fabpot/goutte' => ['Goutte/Tests'], + 'guzzlehttp/promises' => ['tests'], + 'guzzlehttp/psr7' => ['tests'], + 'jcalderonzumba/gastonjs' => ['docs', 'examples', 'tests'], + 'jcalderonzumba/mink-phantomjs-driver' => ['tests'], + 'masterminds/html5' => ['test'], + 'mikey179/vfsStream' => ['src/test'], + 'paragonie/random_compat' => ['tests'], + 'pear/archive_tar' => ['tests'], + 'pear/console_getopt' => ['tests'], + 'pear/pear-core-minimal' => ['tests'], + 'pear/pear_exception' => ['tests'], + 'phpdocumentor/reflection-docblock' => ['tests'], + 'phpunit/php-code-coverage' => ['tests'], + 'phpunit/php-timer' => ['tests'], + 'phpunit/php-token-stream' => ['tests'], + 'phpunit/phpunit' => ['tests'], + 'phpunit/php-mock-objects' => ['tests'], + 'sebastian/comparator' => ['tests'], + 'sebastian/diff' => ['tests'], + 'sebastian/environment' => ['tests'], + 'sebastian/exporter' => ['tests'], + 'sebastian/global-state' => ['tests'], + 'sebastian/recursion-context' => ['tests'], + 'stack/builder' => ['tests'], + 'symfony/browser-kit' => ['Tests'], + 'symfony/class-loader' => ['Tests'], + 'symfony/console' => ['Tests'], + 'symfony/css-selector' => ['Tests'], + 'symfony/debug' => ['Tests'], + 'symfony/dependency-injection' => ['Tests'], + 'symfony/dom-crawler' => ['Tests'], + // @todo Add symfony/event-dispatcher during + // https://www.drupal.org/project/drupal/issues/3055040 + 'symfony/http-foundation' => ['Tests'], + 'symfony/http-kernel' => ['Tests'], + 'symfony/process' => ['Tests'], + 'symfony/psr-http-message-bridge' => ['Tests'], + 'symfony/routing' => ['Tests'], + 'symfony/serializer' => ['Tests'], + 'symfony/translation' => ['Tests'], + 'symfony/validator' => ['Tests', 'Resources'], + 'symfony/yaml' => ['Tests'], + 'symfony-cmf/routing' => ['Test', 'Tests'], + 'twig/twig' => ['doc', 'ext', 'test'], + ]; + + /** + * The root package. + * + * @var Composer\Package\RootPackageInterface + */ + protected $rootPackage; + + /** + * Configuration gleaned from the root package. + * + * @var array + */ + protected $configData = []; + + public function __construct(RootPackageInterface $root_package) { + $this->rootPackage = $root_package; + } + + /** + * Get the configuration from the root package. + * + * This is stored in composer.json extra:drupal-core-vendor-cleanup. + * + * @return [] + * An array keyed by package name. Each array value is an array of paths, + * relative to the package. + */ + protected function getPluginConfig() { + if ($this->configData) { + return $this->configData; + } + // Get the root package config. + $package_config = $this->rootPackage->getExtra(); + if (isset($package_config['drupal-core-vendor-cleanup'])) { + $this->configData = $package_config['drupal-core-vendor-cleanup']; + } + // Ensure the values are arrays. + foreach ($this->configData as $package => $paths) { + if (!is_array($paths)) { + $this->configData[$package] = [$paths]; + } + } + // Merge root config with defaults. + foreach (static::$defaultConfig as $package => $paths) { + if (isset($this->configData[$package])) { + $this->configData[$package] = array_merge($this->configData[$package], $paths); + } + else { + $this->configData[$package] = $paths; + } + } + return $this->configData; + } + + /** + * Get a list of paths to remove for the given package. + * + * @param string $package + * The package name. + * + * @return string[] + * Array of paths to remove, relative to the package. + */ + public function getPathsForPackage($package) { + $paths = []; + $config = $this->getPluginConfig(); + if (isset($config[$package])) { + $paths = $config[$package]; + } + else { + // Handle any mismatch in case between the package name and array key. For + // example, the array key 'mikey179/vfsStream' needs to be found when + // composer returns a package name of 'mikey179/vfsstream'. + foreach (array_keys($config) as $key) { + if (strtolower($key) == strtolower($package)) { + $paths = $config[$key]; + break; + } + } + } + return $paths; + } + + /** + * If there is no configuration in the root package, it is unconfigured. + */ + public function isUnconfigured() { + return empty($this->getPluginConfig()); + } + +} diff --git a/core/lib/Drupal/Component/VendorCleanup/LICENSE.txt b/core/lib/Drupal/Component/VendorCleanup/LICENSE.txt new file mode 100644 index 0000000000..94fb84639c --- /dev/null +++ b/core/lib/Drupal/Component/VendorCleanup/LICENSE.txt @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. diff --git a/core/lib/Drupal/Component/VendorCleanup/README.txt b/core/lib/Drupal/Component/VendorCleanup/README.txt new file mode 100644 index 0000000000..c4d51f12d3 --- /dev/null +++ b/core/lib/Drupal/Component/VendorCleanup/README.txt @@ -0,0 +1,40 @@ +The Drupal VendorCleanup Component + +Thanks for using this Drupal component. + +You can participate in its development on Drupal.org, through our issue system: +https://www.drupal.org/project/issues/drupal + +You can get the full Drupal repo here: +https://www.drupal.org/project/drupal/git-instructions + +You can browse the full Drupal repo here: +http://cgit.drupalcode.org/drupal + +What does it do? + +Require this Composer plugin into your project: + +composer require drupal/core-vendor-cleanup + +Then perform a clean install or update: + +$ rm -rf vendor/ +$ composer install + +When you install or update, this plugin will look through each the package and +remove directories it knows about. + +This is useful for removing test directories and other extraneous files from +your project's vendor/ directory. + +You can see the default projects for this plugin in DefaultConfiguration.php. + +You can also set your own package/directory pairs in the root package's extra +section, like this: + +"extra": { + "drupal-core-vendor-cleanup": { + "vendor/package": ["test", "documentation"] + } +} diff --git a/core/lib/Drupal/Component/VendorCleanup/TESTING.txt b/core/lib/Drupal/Component/VendorCleanup/TESTING.txt new file mode 100644 index 0000000000..125d9fd8a3 --- /dev/null +++ b/core/lib/Drupal/Component/VendorCleanup/TESTING.txt @@ -0,0 +1,18 @@ +HOW-TO: Test this Drupal component + +In order to test this component, you'll need to get the entire Drupal repo and +run the tests there. + +You'll find the tests under core/tests/Drupal/Tests/Component. + +You can get the full Drupal repo here: +https://www.drupal.org/project/drupal/git-instructions + +You can find more information about running PHPUnit tests with Drupal here: +https://www.drupal.org/node/2116263 + +Each component in the Drupal\Component namespace has its own annotated test +group. You can use this group to run only the tests for this component. Like +this: + +$ ./vendor/bin/phpunit -c core --group Annotation diff --git a/core/lib/Drupal/Component/VendorCleanup/VendorCleanupPlugin.php b/core/lib/Drupal/Component/VendorCleanup/VendorCleanupPlugin.php new file mode 100644 index 0000000000..d5855c4258 --- /dev/null +++ b/core/lib/Drupal/Component/VendorCleanup/VendorCleanupPlugin.php @@ -0,0 +1,145 @@ +composer = $composer; + $this->io = $io; + + // Set up configuration. + $this->config = new Config($this->composer->getPackage()); + } + + /** + * {@inheritdoc} + */ + public static function getSubscribedEvents() { + return [ + ScriptEvents::POST_PACKAGE_INSTALL => 'onPostPackageInstall', + ScriptEvents::POST_PACKAGE_UPDATE => 'onPostPackageUpdate', + ]; + } + + /** + * POST_PACKAGE_INSTALL event handler. + * + * @param \Composer\Installer\PackageEvent $event + */ + public function onPostPackageInstall(PackageEvent $event) { + /** @var \Composer\Package\CompletePackage $package */ + $package = $event->getOperation()->getPackage(); + $this->cleanPackage($this->composer->getConfig()->get('vendor-dir'), $package); + } + + /** + * POST_PACKAGE_UPDATE event handler. + * + * @param \Composer\Installer\PackageEvent $event + */ + public function onPostPackageUpdate(PackageEvent $event) { + /** @var \Composer\Package\CompletePackage $package */ + $package = $event->getOperation()->getTargetPackage(); + $this->cleanPackage($this->composer->getConfig()->get('vendor-dir'), $package); + } + + /** + * Clean out the package. + * + * @param \Composer\Package\CompletePackageInterface $package + */ + public function cleanPackage($vendor_dir, CompletePackageInterface $package) { + $package_name = $package->getName(); + $paths_for_package = $this->config->getPathsForPackage($package_name); + if ($paths_for_package) { + $package_dir = $vendor_dir . '/' . $package_name; + if (is_dir($package_dir)) { + $this->io->write(sprintf(" Package cleanup for %s", $package_name), TRUE, IOInterface::VERBOSE); + foreach ($paths_for_package as $cleanup_item) { + $cleanup_path = $package_dir . '/' . $cleanup_item; + if (is_dir($cleanup_path)) { + if ($this->deleteRecursive($cleanup_path)) { + $this->io->write(sprintf(" Removing directory '%s'", $cleanup_item), TRUE, IOInterface::VERY_VERBOSE); + } + else { + // Always display a message if this fails as it means something + // has gone wrong. Therefore the message has to include the + // package name as the first informational message might not + // exist. + $this->io->write(sprintf(" Failure removing directory '%s' in package %s.", $cleanup_item, $package_name), TRUE, IOInterface::NORMAL); + } + } + else { + // If the package has changed or the --prefer-dist version does not + // include the directory. This is not an error. + $this->io->write(sprintf(" Directory '%s' does not exist.", $cleanup_path), TRUE, IOInterface::VERBOSE); + } + } + $this->io->write('', TRUE, IOInterface::VERBOSE); + } + } + } + + /** + * Helper method to remove directories and the files they contain. + * + * @param string $path + * The directory or file to remove. It must exist. + * + * @return bool + * TRUE on success or FALSE on failure. + * + * @todo Make this part of the Filesystem or Utility component. + */ + protected function deleteRecursive($path) { + if (is_file($path) || is_link($path)) { + return unlink($path); + } + $success = TRUE; + $dir = dir($path); + while (($entry = $dir->read()) !== FALSE) { + if ($entry == '.' || $entry == '..') { + continue; + } + $entry_path = $path . '/' . $entry; + $success = $this->deleteRecursive($entry_path) && $success; + } + $dir->close(); + + return rmdir($path) && $success; + } + +} diff --git a/core/lib/Drupal/Component/VendorCleanup/composer.json b/core/lib/Drupal/Component/VendorCleanup/composer.json new file mode 100644 index 0000000000..bdff5de260 --- /dev/null +++ b/core/lib/Drupal/Component/VendorCleanup/composer.json @@ -0,0 +1,18 @@ +{ + "name": "drupal/core-vendor-cleanup", + "description": "Removes directories from the vendor directory.", + "keywords": ["drupal"], + "homepage": "https://www.drupal.org/project/drupal", + "license": "GPL-2.0-or-later", + "type": "composer-plugin", + "extra": { + "class": "Drupal\\Component\\VendorCleanup\\VendorCleanupPlugin" + }, + "require": { + "php": ">=7.0.8", + "composer-plugin-api": "^1.1" + }, + "autoload": { + "classmap": [""] + } +} diff --git a/core/tests/Drupal/Tests/Component/VendorCleanup/ConfigTest.php b/core/tests/Drupal/Tests/Component/VendorCleanup/ConfigTest.php new file mode 100644 index 0000000000..ea3db03781 --- /dev/null +++ b/core/tests/Drupal/Tests/Component/VendorCleanup/ConfigTest.php @@ -0,0 +1,86 @@ +getMockBuilder(Config::class) + ->setMethods(['getPluginConfig']) + ->disableOriginalConstructor() + ->getMock(); + + $config->expects($this->once()) + ->method('getPluginConfig') + ->willReturn(['PackAge' => ['path']]); + + $this->assertSame(['path'], $config->getPathsForPackage('pACKage')); + } + + /** + * @covers ::getPluginConfig + */ + public function testNoRootMergeConfig() { + // Root package has no extra field. + $root = $this->getMockBuilder(RootPackageInterface::class) + ->setMethods(['getExtra']) + ->getMockForAbstractClass(); + $root->expects($this->once()) + ->method('getExtra') + ->willReturn([]); + + $config = new Config($root); + + $ref_default = new \ReflectionProperty($config, 'defaultConfig'); + $ref_default->setAccessible(TRUE); + + $ref_plugin_config = new \ReflectionMethod($config, 'getPluginConfig'); + $ref_plugin_config->setAccessible(TRUE); + + $this->assertEquals( + $ref_default->getValue($config), $ref_plugin_config->invoke($config) + ); + } + + /** + * @covers ::getPluginConfig + */ + public function testRootMergeConfig() { + // Root package has configuration in extra. + $root = $this->getMockBuilder(RootPackageInterface::class) + ->setMethods(['getExtra']) + ->getMockForAbstractClass(); + $root->expects($this->once()) + ->method('getExtra') + ->willReturn([ + 'drupal-core-vendor-cleanup' => [ + 'isa/string' => 'test_dir', + 'an/array' => ['test_dir', 'doc_dir'], + ] + ]); + + $config = new Config($root); + + $ref_plugin_config = new \ReflectionMethod($config, 'getPluginConfig'); + $ref_plugin_config->setAccessible(TRUE); + + $plugin_config = $ref_plugin_config->invoke($config); + + $this->assertArraySubset([ + 'isa/string' => ['test_dir'], + 'an/array' => ['test_dir', 'doc_dir'], + ], $plugin_config); + } + +} diff --git a/core/tests/Drupal/Tests/Component/VendorCleanup/VendorCleanupPluginTest.php b/core/tests/Drupal/Tests/Component/VendorCleanup/VendorCleanupPluginTest.php new file mode 100644 index 0000000000..886e92124d --- /dev/null +++ b/core/tests/Drupal/Tests/Component/VendorCleanup/VendorCleanupPluginTest.php @@ -0,0 +1,68 @@ + [ + 'package' => [ + 'tests' => [ + 'SomeTest.php' => 'getMockBuilder(CompletePackageInterface::class) + ->setMethods(['getName']) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + $package->expects($this->once()) + ->method('getName') + ->willReturn('drupal/package'); + + $config = $this->getMockBuilder(Config::class) + ->setMethods(['getPathsForPackage']) + ->disableOriginalConstructor() + ->getMock(); + $config->expects($this->once()) + ->method('getPathsForPackage') + ->willReturn(['tests']); + + $plugin = new VendorCleanupPlugin(); + $ref_config = new \ReflectionProperty($plugin, 'config'); + $ref_config->setAccessible(TRUE); + $ref_config->setValue($plugin, $config); + + $io = $this->prophesize(IOInterface::class); + $ref_io = new \ReflectionProperty($plugin, 'io'); + $ref_io->setAccessible(TRUE); + $ref_io->setValue($plugin, $io->reveal()); + + $this->assertFileExists(vfsStream::url('vendor/drupal/package/tests/SomeTest.php')); + + $plugin->cleanPackage(vfsStream::url('vendor'), $package); + + $this->assertFileNotExists(vfsStream::url('vendor/drupal/package/tests')); + } + +} diff --git a/core/tests/Drupal/Tests/ComposerIntegrationTest.php b/core/tests/Drupal/Tests/ComposerIntegrationTest.php index 4bed30bcc9..1050641a94 100644 --- a/core/tests/Drupal/Tests/ComposerIntegrationTest.php +++ b/core/tests/Drupal/Tests/ComposerIntegrationTest.php @@ -63,6 +63,7 @@ protected function getPaths() { $this->root . '/core/lib/Drupal/Component/Transliteration', $this->root . '/core/lib/Drupal/Component/Utility', $this->root . '/core/lib/Drupal/Component/Uuid', + $this->root . '/core/lib/Drupal/Component/VendorCleanup', $this->root . '/core/lib/Drupal/Component/Version', ]; }