Skip to content

Commit 653e86e

Browse files
Add an 'initial' element to the Drupal Scaffold 'extras' section, to allow files to be scaffolded iff the target file does not yet exist (e.g. to copy from a default file to the user-customized file on first install only).
1 parent 92b81ac commit 653e86e

File tree

5 files changed

+65
-1
lines changed

5 files changed

+65
-1
lines changed

README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@ of your root `composer.json`.
3838
"includes": [
3939
"sites/default/example.settings.my.php"
4040
],
41+
"initial": {
42+
"sites/default/default.services.yml": "sites/default/services.yml",
43+
"sites/default/default.settings.php": "sites/default/settings.php"
44+
},
4145
"omit-defaults": false
4246
}
4347
}
@@ -77,6 +81,10 @@ listed in the `excludes` and `includes` options will be considered. If
7781
`omit-defaults` is `false` (the default), then any items listed in `excludes`
7882
or `includes` will be in addition to the usual defaults.
7983

84+
The `initial` hash lists files that should be copied over only if they do not
85+
exist in the destination. The key specifies the path to the source file, and
86+
the value indicates the path to the destination file.
87+
8088
## Limitation
8189

8290
When using Composer to install or update the Drupal development branch, the

src/FileFetcher.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@ class FileFetcher {
1717
*/
1818
protected $remoteFilesystem;
1919

20+
protected $source;
21+
protected $filenames;
22+
protected $fs;
23+
2024
public function __construct(RemoteFilesystem $remoteFilesystem, $source, $filenames = []) {
2125
$this->remoteFilesystem = $remoteFilesystem;
2226
$this->source = $source;

src/Handler.php

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,9 +114,14 @@ public function downloadScaffold() {
114114
$version = substr($version, 0, -4);
115115
}
116116

117-
$fetcher = new FileFetcher(new RemoteFilesystem($this->io), $options['source'], $files);
117+
$remoteFs = new RemoteFilesystem($this->io);
118+
119+
$fetcher = new FileFetcher($remoteFs, $options['source'], $files);
118120
$fetcher->fetch($version, $webroot);
119121

122+
$initialFileFetcher = new InitialFileFetcher($remoteFs, $options['source'], $this->getInitial());
123+
$initialFileFetcher->fetch($version, $webroot);
124+
120125
// Call post-scaffold scripts.
121126
$dispatcher->dispatch(self::POST_DRUPAL_SCAFFOLD_CMD);
122127
}
@@ -239,6 +244,15 @@ protected function getIncludes() {
239244
return $this->getNamedOptionList('includes', 'getIncludesDefault');
240245
}
241246

247+
/**
248+
* Retrieve list of initial files from optional "extra" configuration.
249+
*
250+
* @return array
251+
*/
252+
protected function getInitial() {
253+
return $this->getNamedOptionList('initial', 'getInitialDefault');
254+
}
255+
242256
/**
243257
* Retrieve a named list of options from optional "extra" configuration.
244258
* Respects 'omit-defaults', and either includes or does not include the
@@ -268,6 +282,7 @@ protected function getOptions() {
268282
'omit-defaults' => FALSE,
269283
'excludes' => [],
270284
'includes' => [],
285+
'initial' => [],
271286
'source' => 'http://cgit.drupalcode.org/drupal/plain/{path}?h={version}',
272287
// Github: https://raw.githubusercontent.com/drupal/drupal/{version}/{path}
273288
];
@@ -304,4 +319,11 @@ protected function getIncludesDefault() {
304319
];
305320
}
306321

322+
/**
323+
* Holds default initial files.
324+
*/
325+
protected function getInitialDefault() {
326+
return [];
327+
}
328+
307329
}

src/InitialFileFetcher.php

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
3+
/**
4+
* @file
5+
* Contains \DrupalComposer\DrupalScaffold\FileFetcher.
6+
*/
7+
8+
namespace DrupalComposer\DrupalScaffold;
9+
10+
use Composer\Util\Filesystem;
11+
use Composer\Util\RemoteFilesystem;
12+
13+
class InitialFileFetcher extends FileFetcher {
14+
public function fetch($version, $destination) {
15+
array_walk($this->filenames, function ($filename, $sourceFilename) use ($version, $destination) {
16+
$target = "$destination/$filename";
17+
if (!file_exists($target)) {
18+
$url = $this->getUri($sourceFilename, $version);
19+
$this->fs->ensureDirectoryExists($destination . '/' . dirname($filename));
20+
$this->remoteFilesystem->copy($url, $url, $target);
21+
}
22+
});
23+
}
24+
}

tests/FetcherTest.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
use Composer\Util\Filesystem;
1212
use Composer\Util\RemoteFilesystem;
1313
use DrupalComposer\DrupalScaffold\FileFetcher;
14+
use DrupalComposer\DrupalScaffold\InitialFileFetcher;
1415

1516
class FetcherTest extends \PHPUnit_Framework_TestCase {
1617

@@ -67,4 +68,9 @@ public function testFetch() {
6768
$this->assertFileExists($this->tmpDir . '/sites/default/default.settings.php');
6869
}
6970

71+
public function testInitialFetch() {
72+
$fetcher = new InitialFileFetcher(new RemoteFilesystem(new NullIO()), 'http://cgit.drupalcode.org/drupal/plain/{path}?h={version}', ['sites/default/default.settings.php' => 'sites/default/settings.php']);
73+
$fetcher->fetch('8.1.1', $this->tmpDir);
74+
$this->assertFileExists($this->tmpDir . '/sites/default/settings.php');
75+
}
7076
}

0 commit comments

Comments
 (0)