diff --git a/.scenarios.lock/phpunit4/composer.json b/.scenarios.lock/phpunit4/composer.json
index 52d5a59..eb5fa02 100644
--- a/.scenarios.lock/phpunit4/composer.json
+++ b/.scenarios.lock/phpunit4/composer.json
@@ -4,7 +4,7 @@
"type": "composer-plugin",
"license": "GPL-2.0-or-later",
"require": {
- "php": ">=5.4.5",
+ "php": "^5.5.9|>=7.0.8",
"composer-plugin-api": "^1.0.0",
"composer/semver": "^1.4"
},
diff --git a/.scenarios.lock/phpunit4/composer.lock b/.scenarios.lock/phpunit4/composer.lock
index 084a62b..c234829 100644
--- a/.scenarios.lock/phpunit4/composer.lock
+++ b/.scenarios.lock/phpunit4/composer.lock
@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
- "content-hash": "445ab29fa63d93c2f4ff7da62f90de16",
+ "content-hash": "421671c61c80e5b56a0317e25a7c457b",
"packages": [
{
"name": "composer/semver",
@@ -72,16 +72,16 @@
"packages-dev": [
{
"name": "composer/ca-bundle",
- "version": "1.1.1",
+ "version": "1.1.3",
"source": {
"type": "git",
"url": "https://github.com/composer/ca-bundle.git",
- "reference": "d2c0a83b7533d6912e8d516756ebd34f893e9169"
+ "reference": "8afa52cd417f4ec417b4bfe86b68106538a87660"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/composer/ca-bundle/zipball/d2c0a83b7533d6912e8d516756ebd34f893e9169",
- "reference": "d2c0a83b7533d6912e8d516756ebd34f893e9169",
+ "url": "https://api.github.com/repos/composer/ca-bundle/zipball/8afa52cd417f4ec417b4bfe86b68106538a87660",
+ "reference": "8afa52cd417f4ec417b4bfe86b68106538a87660",
"shasum": ""
},
"require": {
@@ -124,7 +124,7 @@
"ssl",
"tls"
],
- "time": "2018-03-29T19:57:20+00:00"
+ "time": "2018-10-18T06:09:13+00:00"
},
{
"name": "composer/composer",
@@ -132,12 +132,12 @@
"source": {
"type": "git",
"url": "https://github.com/composer/composer.git",
- "reference": "837ad7c14e8ce364296e0d0600d04c415b6e359d"
+ "reference": "154ae6fae28c210cd6cf5d76aace04aefef1ca65"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/composer/composer/zipball/837ad7c14e8ce364296e0d0600d04c415b6e359d",
- "reference": "837ad7c14e8ce364296e0d0600d04c415b6e359d",
+ "url": "https://api.github.com/repos/composer/composer/zipball/154ae6fae28c210cd6cf5d76aace04aefef1ca65",
+ "reference": "154ae6fae28c210cd6cf5d76aace04aefef1ca65",
"shasum": ""
},
"require": {
@@ -173,7 +173,7 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.7-dev"
+ "dev-master": "1.9-dev"
}
},
"autoload": {
@@ -204,20 +204,20 @@
"dependency",
"package"
],
- "time": "2018-06-07T09:15:18+00:00"
+ "time": "2019-01-03T09:53:00+00:00"
},
{
"name": "composer/spdx-licenses",
- "version": "1.4.0",
+ "version": "1.5.0",
"source": {
"type": "git",
"url": "https://github.com/composer/spdx-licenses.git",
- "reference": "cb17687e9f936acd7e7245ad3890f953770dec1b"
+ "reference": "7a9556b22bd9d4df7cad89876b00af58ef20d3a2"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/composer/spdx-licenses/zipball/cb17687e9f936acd7e7245ad3890f953770dec1b",
- "reference": "cb17687e9f936acd7e7245ad3890f953770dec1b",
+ "url": "https://api.github.com/repos/composer/spdx-licenses/zipball/7a9556b22bd9d4df7cad89876b00af58ef20d3a2",
+ "reference": "7a9556b22bd9d4df7cad89876b00af58ef20d3a2",
"shasum": ""
},
"require": {
@@ -265,20 +265,20 @@
"spdx",
"validator"
],
- "time": "2018-04-30T10:33:04+00:00"
+ "time": "2018-11-01T09:45:54+00:00"
},
{
"name": "composer/xdebug-handler",
- "version": "1.1.0",
+ "version": "1.3.1",
"source": {
"type": "git",
"url": "https://github.com/composer/xdebug-handler.git",
- "reference": "c919dc6c62e221fc6406f861ea13433c0aa24f08"
+ "reference": "dc523135366eb68f22268d069ea7749486458562"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/c919dc6c62e221fc6406f861ea13433c0aa24f08",
- "reference": "c919dc6c62e221fc6406f861ea13433c0aa24f08",
+ "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/dc523135366eb68f22268d069ea7749486458562",
+ "reference": "dc523135366eb68f22268d069ea7749486458562",
"shasum": ""
},
"require": {
@@ -309,7 +309,7 @@
"Xdebug",
"performance"
],
- "time": "2018-04-11T15:42:36+00:00"
+ "time": "2018-11-29T10:59:02+00:00"
},
{
"name": "doctrine/instantiator",
@@ -367,16 +367,16 @@
},
{
"name": "g1a/composer-test-scenarios",
- "version": "2.1.0",
+ "version": "2.2.0",
"source": {
"type": "git",
"url": "https://github.com/g1a/composer-test-scenarios.git",
- "reference": "4c2b990712dbcb87a0ab618e46f908c731c3a0bb"
+ "reference": "a166fd15191aceab89f30c097e694b7cf3db4880"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/g1a/composer-test-scenarios/zipball/4c2b990712dbcb87a0ab618e46f908c731c3a0bb",
- "reference": "4c2b990712dbcb87a0ab618e46f908c731c3a0bb",
+ "url": "https://api.github.com/repos/g1a/composer-test-scenarios/zipball/a166fd15191aceab89f30c097e694b7cf3db4880",
+ "reference": "a166fd15191aceab89f30c097e694b7cf3db4880",
"shasum": ""
},
"bin": [
@@ -396,7 +396,7 @@
}
],
"description": "Useful scripts for testing multiple sets of Composer dependencies.",
- "time": "2018-06-10T21:56:28+00:00"
+ "time": "2018-08-08T23:37:23+00:00"
},
{
"name": "justinrainbow/json-schema",
@@ -612,16 +612,16 @@
},
{
"name": "phpspec/prophecy",
- "version": "1.7.6",
+ "version": "1.8.0",
"source": {
"type": "git",
"url": "https://github.com/phpspec/prophecy.git",
- "reference": "33a7e3c4fda54e912ff6338c48823bd5c0f0b712"
+ "reference": "4ba436b55987b4bf311cb7c6ba82aa528aac0a06"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/phpspec/prophecy/zipball/33a7e3c4fda54e912ff6338c48823bd5c0f0b712",
- "reference": "33a7e3c4fda54e912ff6338c48823bd5c0f0b712",
+ "url": "https://api.github.com/repos/phpspec/prophecy/zipball/4ba436b55987b4bf311cb7c6ba82aa528aac0a06",
+ "reference": "4ba436b55987b4bf311cb7c6ba82aa528aac0a06",
"shasum": ""
},
"require": {
@@ -633,12 +633,12 @@
},
"require-dev": {
"phpspec/phpspec": "^2.5|^3.2",
- "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5"
+ "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5 || ^7.1"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.7.x-dev"
+ "dev-master": "1.8.x-dev"
}
},
"autoload": {
@@ -671,7 +671,7 @@
"spy",
"stub"
],
- "time": "2018-04-18T13:57:24+00:00"
+ "time": "2018-08-05T17:53:17+00:00"
},
{
"name": "phpunit/php-code-coverage",
@@ -1051,16 +1051,16 @@
},
{
"name": "psr/log",
- "version": "1.0.2",
+ "version": "1.1.0",
"source": {
"type": "git",
"url": "https://github.com/php-fig/log.git",
- "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d"
+ "reference": "6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/php-fig/log/zipball/4ebe3a8bf773a19edfe0a84b6585ba3d401b724d",
- "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d",
+ "url": "https://api.github.com/repos/php-fig/log/zipball/6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd",
+ "reference": "6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd",
"shasum": ""
},
"require": {
@@ -1094,7 +1094,7 @@
"psr",
"psr-3"
],
- "time": "2016-10-10T12:19:37+00:00"
+ "time": "2018-11-20T15:27:04+00:00"
},
{
"name": "sebastian/comparator",
@@ -1563,16 +1563,16 @@
},
{
"name": "squizlabs/php_codesniffer",
- "version": "2.9.1",
+ "version": "2.9.2",
"source": {
"type": "git",
"url": "https://github.com/squizlabs/PHP_CodeSniffer.git",
- "reference": "dcbed1074f8244661eecddfc2a675430d8d33f62"
+ "reference": "2acf168de78487db620ab4bc524135a13cfe6745"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/dcbed1074f8244661eecddfc2a675430d8d33f62",
- "reference": "dcbed1074f8244661eecddfc2a675430d8d33f62",
+ "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/2acf168de78487db620ab4bc524135a13cfe6745",
+ "reference": "2acf168de78487db620ab4bc524135a13cfe6745",
"shasum": ""
},
"require": {
@@ -1637,20 +1637,20 @@
"phpcs",
"standards"
],
- "time": "2017-05-22T02:43:20+00:00"
+ "time": "2018-11-07T22:31:41+00:00"
},
{
"name": "symfony/console",
- "version": "v3.4.11",
+ "version": "v3.4.21",
"source": {
"type": "git",
"url": "https://github.com/symfony/console.git",
- "reference": "36f83f642443c46f3cf751d4d2ee5d047d757a27"
+ "reference": "a700b874d3692bc8342199adfb6d3b99f62cc61a"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/console/zipball/36f83f642443c46f3cf751d4d2ee5d047d757a27",
- "reference": "36f83f642443c46f3cf751d4d2ee5d047d757a27",
+ "url": "https://api.github.com/repos/symfony/console/zipball/a700b874d3692bc8342199adfb6d3b99f62cc61a",
+ "reference": "a700b874d3692bc8342199adfb6d3b99f62cc61a",
"shasum": ""
},
"require": {
@@ -1706,20 +1706,20 @@
],
"description": "Symfony Console Component",
"homepage": "https://symfony.com",
- "time": "2018-05-16T08:49:21+00:00"
+ "time": "2019-01-04T04:42:43+00:00"
},
{
"name": "symfony/debug",
- "version": "v3.4.11",
+ "version": "v3.4.21",
"source": {
"type": "git",
"url": "https://github.com/symfony/debug.git",
- "reference": "b28fd73fefbac341f673f5efd707d539d6a19f68"
+ "reference": "26d7f23b9bd0b93bee5583e4d6ca5cb1ab31b186"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/debug/zipball/b28fd73fefbac341f673f5efd707d539d6a19f68",
- "reference": "b28fd73fefbac341f673f5efd707d539d6a19f68",
+ "url": "https://api.github.com/repos/symfony/debug/zipball/26d7f23b9bd0b93bee5583e4d6ca5cb1ab31b186",
+ "reference": "26d7f23b9bd0b93bee5583e4d6ca5cb1ab31b186",
"shasum": ""
},
"require": {
@@ -1762,20 +1762,20 @@
],
"description": "Symfony Debug Component",
"homepage": "https://symfony.com",
- "time": "2018-05-16T14:03:39+00:00"
+ "time": "2019-01-01T13:45:19+00:00"
},
{
"name": "symfony/filesystem",
- "version": "v3.4.11",
+ "version": "v3.4.21",
"source": {
"type": "git",
"url": "https://github.com/symfony/filesystem.git",
- "reference": "8e03ca3fa52a0f56b87506f38cf7bd3f9442b3a0"
+ "reference": "c24ce3d18ccc9bb9d7e1d6ce9330fcc6061cafde"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/filesystem/zipball/8e03ca3fa52a0f56b87506f38cf7bd3f9442b3a0",
- "reference": "8e03ca3fa52a0f56b87506f38cf7bd3f9442b3a0",
+ "url": "https://api.github.com/repos/symfony/filesystem/zipball/c24ce3d18ccc9bb9d7e1d6ce9330fcc6061cafde",
+ "reference": "c24ce3d18ccc9bb9d7e1d6ce9330fcc6061cafde",
"shasum": ""
},
"require": {
@@ -1812,20 +1812,20 @@
],
"description": "Symfony Filesystem Component",
"homepage": "https://symfony.com",
- "time": "2018-05-16T08:49:21+00:00"
+ "time": "2019-01-01T13:45:19+00:00"
},
{
"name": "symfony/finder",
- "version": "v3.4.11",
+ "version": "v3.4.21",
"source": {
"type": "git",
"url": "https://github.com/symfony/finder.git",
- "reference": "472a92f3df8b247b49ae364275fb32943b9656c6"
+ "reference": "3f2a2ab6315dd7682d4c16dcae1e7b95c8b8555e"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/finder/zipball/472a92f3df8b247b49ae364275fb32943b9656c6",
- "reference": "472a92f3df8b247b49ae364275fb32943b9656c6",
+ "url": "https://api.github.com/repos/symfony/finder/zipball/3f2a2ab6315dd7682d4c16dcae1e7b95c8b8555e",
+ "reference": "3f2a2ab6315dd7682d4c16dcae1e7b95c8b8555e",
"shasum": ""
},
"require": {
@@ -1861,29 +1861,32 @@
],
"description": "Symfony Finder Component",
"homepage": "https://symfony.com",
- "time": "2018-05-16T08:49:21+00:00"
+ "time": "2019-01-01T13:45:19+00:00"
},
{
"name": "symfony/polyfill-ctype",
- "version": "v1.8.0",
+ "version": "v1.10.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-ctype.git",
- "reference": "7cc359f1b7b80fc25ed7796be7d96adc9b354bae"
+ "reference": "e3d826245268269cd66f8326bd8bc066687b4a19"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/7cc359f1b7b80fc25ed7796be7d96adc9b354bae",
- "reference": "7cc359f1b7b80fc25ed7796be7d96adc9b354bae",
+ "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/e3d826245268269cd66f8326bd8bc066687b4a19",
+ "reference": "e3d826245268269cd66f8326bd8bc066687b4a19",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
+ "suggest": {
+ "ext-ctype": "For best performance"
+ },
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.8-dev"
+ "dev-master": "1.9-dev"
}
},
"autoload": {
@@ -1916,20 +1919,20 @@
"polyfill",
"portable"
],
- "time": "2018-04-30T19:57:29+00:00"
+ "time": "2018-08-06T14:22:27+00:00"
},
{
"name": "symfony/polyfill-mbstring",
- "version": "v1.8.0",
+ "version": "v1.10.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-mbstring.git",
- "reference": "3296adf6a6454a050679cde90f95350ad604b171"
+ "reference": "c79c051f5b3a46be09205c73b80b346e4153e494"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/3296adf6a6454a050679cde90f95350ad604b171",
- "reference": "3296adf6a6454a050679cde90f95350ad604b171",
+ "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/c79c051f5b3a46be09205c73b80b346e4153e494",
+ "reference": "c79c051f5b3a46be09205c73b80b346e4153e494",
"shasum": ""
},
"require": {
@@ -1941,7 +1944,7 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.8-dev"
+ "dev-master": "1.9-dev"
}
},
"autoload": {
@@ -1975,20 +1978,20 @@
"portable",
"shim"
],
- "time": "2018-04-26T10:06:28+00:00"
+ "time": "2018-09-21T13:07:52+00:00"
},
{
"name": "symfony/process",
- "version": "v3.4.11",
+ "version": "v3.4.21",
"source": {
"type": "git",
"url": "https://github.com/symfony/process.git",
- "reference": "4cbf2db9abcb01486a21b7a059e03a62fae63187"
+ "reference": "0d41dd7d95ed179aed6a13393b0f4f97bfa2d25c"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/process/zipball/4cbf2db9abcb01486a21b7a059e03a62fae63187",
- "reference": "4cbf2db9abcb01486a21b7a059e03a62fae63187",
+ "url": "https://api.github.com/repos/symfony/process/zipball/0d41dd7d95ed179aed6a13393b0f4f97bfa2d25c",
+ "reference": "0d41dd7d95ed179aed6a13393b0f4f97bfa2d25c",
"shasum": ""
},
"require": {
@@ -2024,20 +2027,20 @@
],
"description": "Symfony Process Component",
"homepage": "https://symfony.com",
- "time": "2018-05-16T08:49:21+00:00"
+ "time": "2019-01-02T21:24:08+00:00"
},
{
"name": "symfony/yaml",
- "version": "v3.4.11",
+ "version": "v3.4.21",
"source": {
"type": "git",
"url": "https://github.com/symfony/yaml.git",
- "reference": "c5010cc1692ce1fa328b1fb666961eb3d4a85bb0"
+ "reference": "554a59a1ccbaac238a89b19c8e551a556fd0e2ea"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/yaml/zipball/c5010cc1692ce1fa328b1fb666961eb3d4a85bb0",
- "reference": "c5010cc1692ce1fa328b1fb666961eb3d4a85bb0",
+ "url": "https://api.github.com/repos/symfony/yaml/zipball/554a59a1ccbaac238a89b19c8e551a556fd0e2ea",
+ "reference": "554a59a1ccbaac238a89b19c8e551a556fd0e2ea",
"shasum": ""
},
"require": {
@@ -2083,24 +2086,25 @@
],
"description": "Symfony Yaml Component",
"homepage": "https://symfony.com",
- "time": "2018-05-03T23:18:14+00:00"
+ "time": "2019-01-01T13:45:19+00:00"
},
{
"name": "webmozart/assert",
- "version": "1.3.0",
+ "version": "1.4.0",
"source": {
"type": "git",
"url": "https://github.com/webmozart/assert.git",
- "reference": "0df1908962e7a3071564e857d86874dad1ef204a"
+ "reference": "83e253c8e0be5b0257b881e1827274667c5c17a9"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/webmozart/assert/zipball/0df1908962e7a3071564e857d86874dad1ef204a",
- "reference": "0df1908962e7a3071564e857d86874dad1ef204a",
+ "url": "https://api.github.com/repos/webmozart/assert/zipball/83e253c8e0be5b0257b881e1827274667c5c17a9",
+ "reference": "83e253c8e0be5b0257b881e1827274667c5c17a9",
"shasum": ""
},
"require": {
- "php": "^5.3.3 || ^7.0"
+ "php": "^5.3.3 || ^7.0",
+ "symfony/polyfill-ctype": "^1.8"
},
"require-dev": {
"phpunit/phpunit": "^4.6",
@@ -2133,7 +2137,7 @@
"check",
"validate"
],
- "time": "2018-01-29T19:49:41+00:00"
+ "time": "2018-12-25T11:19:39+00:00"
}
],
"aliases": [],
@@ -2144,7 +2148,7 @@
"prefer-stable": false,
"prefer-lowest": false,
"platform": {
- "php": ">=5.4.5"
+ "php": "^5.5.9|>=7.0.8"
},
"platform-dev": [],
"platform-overrides": {
diff --git a/.travis.yml b/.travis.yml
index ba2f61e..6e47b29 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -37,6 +37,7 @@ install:
before_script:
- git config --global user.email "travisci@example.com"
- git config --global user.name "Travis CI Test"
+ - export COMPOSER_PROCESS_TIMEOUT=600
script:
- composer test
diff --git a/README.md b/README.md
index 8e7291e..69f179a 100644
--- a/README.md
+++ b/README.md
@@ -51,6 +51,21 @@ The `source` option may be used to specify the URL to download the
scaffold files from; the default source is drupal.org. The literal string
`{version}` in the `source` option is replaced with the current version of
Drupal core being updated prior to download.
+You can also define `source` as an array to have fallbacks in case of
+any HTTP issues.
+
+```json
+{
+ "extra": {
+ "drupal-scaffold": {
+ "source": [
+ "https://cgit.drupalcode.org/drupal/plain/{path}?h={version}",
+ "https://raw.githubusercontent.com/drupal/drupal/{version}/{path}"
+ ]
+ }
+ }
+}
+```
With the `drupal-scaffold` option `excludes`, you can provide additional paths
that should not be copied or overwritten. The plugin provides no excludes by
diff --git a/composer.lock b/composer.lock
index 707e504..2fa2c27 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
- "content-hash": "cc2cd84cd41c52965cd00f2e515bb6d3",
+ "content-hash": "c6f275dbfe63c4cfa101ba653aac235e",
"packages": [
{
"name": "composer/semver",
@@ -2481,7 +2481,7 @@
"prefer-stable": false,
"prefer-lowest": false,
"platform": {
- "php": ">=5.4.5"
+ "php": "^5.5.9|>=7.0.8"
},
"platform-dev": [],
"platform-overrides": {
diff --git a/src/FileFetcher.php b/src/FileFetcher.php
index 59b9227..ac38390 100644
--- a/src/FileFetcher.php
+++ b/src/FileFetcher.php
@@ -49,13 +49,19 @@ class FileFetcher {
*/
protected $fs;
+ /**
+ * @var array
+ *
+ * A list of potential errors.
+ */
+ protected $errors = [];
+
/**
* Constructs this FileFetcher object.
*/
- public function __construct(RemoteFilesystem $remoteFilesystem, $source, IOInterface $io, $progress = TRUE) {
+ public function __construct(RemoteFilesystem $remoteFilesystem, IOInterface $io, $progress = TRUE) {
$this->remoteFilesystem = $remoteFilesystem;
$this->io = $io;
- $this->source = $source;
$this->fs = new Filesystem();
$this->progress = $progress;
}
@@ -64,23 +70,39 @@ public function __construct(RemoteFilesystem $remoteFilesystem, $source, IOInter
* Downloads all required files and writes it to the file system.
*/
public function fetch($version, $destination, $override) {
+ $errors = [];
+
foreach ($this->filenames as $sourceFilename => $filename) {
$target = "$destination/$filename";
if ($override || !file_exists($target)) {
$url = $this->getUri($sourceFilename, $version);
$this->fs->ensureDirectoryExists($destination . '/' . dirname($filename));
+
if ($this->progress) {
$this->io->writeError(" - $filename ($url): ", FALSE);
- $this->remoteFilesystem->copy($url, $url, $target, $this->progress);
- // Used to put a new line because the remote file system does not put
- // one.
+ try {
+ $this->remoteFilesystem->copy($url, $url, $target, $this->progress);
+ } catch(\Exception $e) {
+ $errors[] = $url;
+ }
+ // New line because the remoteFilesystem does not put one.
$this->io->writeError('');
}
else {
- $this->remoteFilesystem->copy($url, $url, $target, $this->progress);
+ try {
+ $this->remoteFilesystem->copy($url, $url, $target, $this->progress);
+ } catch(\Exception $e) {
+ $errors[] = $url;
+ }
}
}
}
+
+ if ($errors) {
+ $this->addError('Failed to download: ' . "\r\n" . implode("\r\n", $errors));
+ return FALSE;
+ }
+ return TRUE;
}
/**
@@ -90,6 +112,27 @@ public function setFilenames(array $filenames) {
$this->filenames = $filenames;
}
+ /**
+ * Set source.
+ */
+ public function setSource($source) {
+ $this->source = $source;
+ }
+
+ /**
+ * Set error.
+ */
+ public function addError($error) {
+ $this->errors[] = $error;
+ }
+
+ /**
+ * Get errors.
+ */
+ public function getErrors() {
+ return $this->errors;
+ }
+
/**
* Replace filename and version in the source pattern with their values.
*/
diff --git a/src/Handler.php b/src/Handler.php
index 23cb9d9..51f1233 100644
--- a/src/Handler.php
+++ b/src/Handler.php
@@ -149,6 +149,7 @@ public function downloadScaffold() {
// Collect options, excludes and settings files.
$options = $this->getOptions();
$files = array_diff($this->getIncludes(), $this->getExcludes());
+ $files = array_combine($files, $files);
// Call any pre-scaffold scripts that may be defined.
$dispatcher = new EventDispatcher($this->composer, $this->io);
@@ -158,12 +159,39 @@ public function downloadScaffold() {
$remoteFs = new RemoteFilesystem($this->io);
- $fetcher = new PrestissimoFileFetcher($remoteFs, $options['source'], $this->io, $this->progress, $this->composer->getConfig());
- $fetcher->setFilenames(array_combine($files, $files));
- $fetcher->fetch($version, $webroot, TRUE);
+ $fetcher = new PrestissimoFileFetcher($remoteFs, $this->io, $this->progress, $this->composer->getConfig());
+ $sources = (array) $options['source'];
+ $all_succeeded = FALSE;
- $fetcher->setFilenames($this->getInitial());
- $fetcher->fetch($version, $webroot, FALSE);
+ do {
+ $source = current($sources);
+
+ $fetcher->setSource($source);
+
+ $fetcher->setFilenames($files);
+ if ($fetcher->fetch($version, $webroot, TRUE)) {
+ $fetcher->setFilenames($this->getInitial());
+ if ($fetcher->fetch($version, $webroot, FALSE)) {
+ $all_succeeded = TRUE;
+ break;
+ }
+ }
+
+ // If here, it means that the fetch for this source has failed.
+ $next_source = next($sources);
+
+ $this->io->writeError('');
+ $this->io->writeError(" - Has failed with the " . (!$next_source ? 'last ' : '') . "source: $source", TRUE);
+ if ($next_source) {
+ $this->io->writeError(" - Now trying with the source: $next_source", TRUE);
+ }
+ $this->io->writeError('');
+
+ } while($next_source);
+
+ if (!$all_succeeded) {
+ throw new \Exception(implode("\r\n\r\n", $fetcher->getErrors()));
+ }
// Call post-scaffold scripts.
$dispatcher->dispatch(self::POST_DRUPAL_SCAFFOLD_CMD);
@@ -343,8 +371,10 @@ protected function getOptions() {
'excludes' => [],
'includes' => [],
'initial' => [],
- 'source' => 'https://cgit.drupalcode.org/drupal/plain/{path}?h={version}',
- // Github: https://raw.githubusercontent.com/drupal/drupal/{version}/{path}
+ 'source' => [
+ 'https://cgit.drupalcode.org/drupal/plain/{path}?h={version}',
+ 'https://raw.githubusercontent.com/drupal/drupal/{version}/{path}'
+ ],
];
return $options;
}
diff --git a/src/PrestissimoFileFetcher.php b/src/PrestissimoFileFetcher.php
index 30b7c23..25dccd7 100644
--- a/src/PrestissimoFileFetcher.php
+++ b/src/PrestissimoFileFetcher.php
@@ -22,8 +22,8 @@ class PrestissimoFileFetcher extends FileFetcher {
/**
* Constructs this PrestissimoFileFetcher object.
*/
- public function __construct(RemoteFilesystem $remoteFilesystem, $source, IOInterface $io, $progress = TRUE, Config $config) {
- parent::__construct($remoteFilesystem, $source, $io, $progress);
+ public function __construct(RemoteFilesystem $remoteFilesystem, IOInterface $io, $progress = TRUE, Config $config) {
+ parent::__construct($remoteFilesystem, $io, $progress);
$this->config = $config;
}
@@ -32,10 +32,9 @@ public function __construct(RemoteFilesystem $remoteFilesystem, $source, IOInter
*/
public function fetch($version, $destination, $override) {
if (class_exists(CurlMulti::class)) {
- $this->fetchWithPrestissimo($version, $destination, $override);
- return;
+ return $this->fetchWithPrestissimo($version, $destination, $override);
}
- parent::fetch($version, $destination, $override);
+ return parent::fetch($version, $destination, $override);
}
/**
@@ -57,7 +56,7 @@ protected function fetchWithPrestissimo($version, $destination, $override) {
$errors = [];
$totalCnt = count($requests);
if ($totalCnt == 0) {
- return;
+ return TRUE;
}
$multi = new CurlMulti();
@@ -70,6 +69,9 @@ protected function fetchWithPrestissimo($version, $destination, $override) {
$failureCnt += $result['failureCnt'];
if (isset($result['errors'])) {
$errors += $result['errors'];
+ foreach ($result['errors'] as $url => $error) {
+ $this->io->writeError(" - Downloading $successCnt/$totalCnt: $url (failed)", TRUE);
+ }
}
if ($this->progress) {
foreach ($result['urls'] as $url) {
@@ -78,10 +80,20 @@ protected function fetchWithPrestissimo($version, $destination, $override) {
}
} while ($multi->remain());
- $urls = array_keys($errors);
- if ($urls) {
- throw new \Exception('Failed to download ' . implode(", ", $urls));
+ if ($errors) {
+ $this->addError('Failed to download: ' . "\r\n" . implode("\r\n", array_keys($errors)));
+ $errors_extra = [];
+ foreach($errors as $error) {
+ if ($error !== "0: " && !isset($errors_extra[$error])) {
+ $errors_extra[$error] = $error;
+ }
+ }
+ if ($errors_extra) {
+ $this->addError(implode("\r\n", $errors_extra));
+ }
+ return FALSE;
}
+ return TRUE;
}
}
diff --git a/tests/FetcherTest.php b/tests/FetcherTest.php
index ea822f9..df2a973 100644
--- a/tests/FetcherTest.php
+++ b/tests/FetcherTest.php
@@ -57,7 +57,8 @@ protected function ensureDirectoryExistsAndClear($directory) {
}
public function testFetch() {
- $fetcher = new FileFetcher(new RemoteFilesystem(new NullIO()), 'https://cgit.drupalcode.org/drupal/plain/{path}?h={version}', new NullIO());
+ $fetcher = new FileFetcher(new RemoteFilesystem(new NullIO()), new NullIO());
+ $fetcher->setSource('https://cgit.drupalcode.org/drupal/plain/{path}?h={version}');
$fetcher->setFilenames([
'.htaccess' => '.htaccess',
'sites/default/default.settings.php' => 'sites/default/default.settings.php',
@@ -68,7 +69,8 @@ public function testFetch() {
}
public function testInitialFetch() {
- $fetcher = new FileFetcher(new RemoteFilesystem(new NullIO()), 'https://cgit.drupalcode.org/drupal/plain/{path}?h={version}', new NullIO());
+ $fetcher = new FileFetcher(new RemoteFilesystem(new NullIO()), new NullIO());
+ $fetcher->setSource('https://cgit.drupalcode.org/drupal/plain/{path}?h={version}');
$fetcher->setFilenames([
'sites/default/default.settings.php' => 'sites/default/settings.php',
]);