Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .scenarios.lock/phpunit4/composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
},
Expand Down
188 changes: 96 additions & 92 deletions .scenarios.lock/phpunit4/composer.lock

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ install:
before_script:
- git config --global user.email "[email protected]"
- git config --global user.name "Travis CI Test"
- export COMPOSER_PROCESS_TIMEOUT=600

script:
- composer test
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

55 changes: 49 additions & 6 deletions src/FileFetcher.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand All @@ -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(" - <info>$filename</info> (<comment>$url</comment>): ", 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;
}

/**
Expand All @@ -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.
*/
Expand Down
44 changes: 37 additions & 7 deletions src/Handler.php
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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: <error>$source</error>", TRUE);
if ($next_source) {
$this->io->writeError(" - Now trying with the source: <warning>$next_source</warning>", 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);
Expand Down Expand Up @@ -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;
}
Expand Down
30 changes: 21 additions & 9 deletions src/PrestissimoFileFetcher.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand All @@ -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);
}

/**
Expand All @@ -57,7 +56,7 @@ protected function fetchWithPrestissimo($version, $destination, $override) {
$errors = [];
$totalCnt = count($requests);
if ($totalCnt == 0) {
return;
return TRUE;
}

$multi = new CurlMulti();
Expand All @@ -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 <comment>$successCnt</comment>/<comment>$totalCnt</comment>: <info>$url</info> (<error>failed</error>)", TRUE);
}
}
if ($this->progress) {
foreach ($result['urls'] as $url) {
Expand All @@ -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;
}

}
6 changes: 4 additions & 2 deletions tests/FetcherTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand All @@ -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',
]);
Expand Down