Skip to content

Commit 15027ee

Browse files
authored
Added new config 'excludes'
1 parent 739e3fc commit 15027ee

File tree

4 files changed

+142
-25
lines changed

4 files changed

+142
-25
lines changed

.travis/test-script.sh

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,3 +180,20 @@ if [ -L "$SITE_WEB/customfile.php" ]; then
180180
else
181181
echo "${MSG_OK} 'composer drupal:paranoia' command did not re-create the web directory with WRONG extra symlinks"
182182
fi
183+
184+
##
185+
# Test "excludes" config.
186+
# Run the command 'composer drupal:paranoia' and check if the excluded paths were not symlinked or stubbed.
187+
#
188+
echo "${MSG_INFO} Add paths to 'excludes' config and check if they have not been stubbed or symlinked."
189+
composer config extra.drupal-paranoia.excludes token_list_files; sed -i -e "s/\"token_list_files\"/\[\"core\/install.php\"\,\"core\/tests\"\]/" composer.json
190+
191+
# Rebuild web directory.
192+
composer drupal:paranoia || exit 1
193+
194+
if [ -f "$SITE_WEB/core/install.php" ] || [ -d "$SITE_WEB/core/tests" ]; then
195+
echo "${MSG_ERROR} 'composer drupal:paranoia' command re-created the web directory with excluded files and folders"
196+
exit 1
197+
else
198+
echo "${MSG_OK} 'composer drupal:paranoia' command did not re-create the web directory with excluded files and folders"
199+
fi

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
## Releases
44

5+
### 1.0.0-beta4, 2019-01-24
6+
- [PR#13] Added new config 'excludes' to be able to exclude paths to be symlinked or stubbed in web folder.
7+
- Performance enhancement: Added sites public files path to exclude list when searching for asset files.
8+
59
### 1.0.0-beta3, 2019-01-23
610
- [PR#12] Namespaced composer config. See: https://github.com/drupal-composer/drupal-paranoia/pull/12.
711

README.md

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,28 @@ By the purpose of this plugin, the following files types are __not allowed__ and
135135
*.theme
136136
```
137137

138+
### Exclude paths
139+
With the drupal-paranoia option excludes, you can provide paths that should not be symlinked or stubbed to `/web` folder. The plugin provides no excludes by default.
140+
141+
```json
142+
"extra": {
143+
"drupal-paranoia": {
144+
"app-dir": "app",
145+
"web-dir": "web",
146+
"excludes": [
147+
"core/install.php",
148+
"sites/simpletest"
149+
]
150+
},
151+
"..."
152+
}
153+
```
154+
155+
__NOTE:__ Consider to exclude `/install.php` from your site. There are security concerns when this URL is publicly available, it can be used to create a list of contributed modules existing on the site.
156+
You can exclude it via plugin as described above or via `.htaccess` rules.
157+
- [DO#2840973: Install system should not produce PHP errors](https://www.drupal.org/node/2840973)
158+
- https://www.drupalxray.com
159+
138160
### Web server docroot
139161
Change the document root config of your web server to point to `/web` folder.
140162

@@ -181,7 +203,7 @@ class MyClass implements PluginInterface, EventSubscriberInterface
181203
```
182204

183205
## Local development
184-
Every time you install or update a Drupal package via Composer, the `/web` folder will recreated.
206+
Every time you install or update a Drupal package via Composer, the `/web` folder will be recreated.
185207

186208
```
187209
composer require drupal/devel:~1.0

src/Installer.php

Lines changed: 98 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,13 @@ class Installer {
7474
*/
7575
public $webDir;
7676

77+
/**
78+
* List of paths that should not be symlinked or stubbed.
79+
*
80+
* @var array
81+
*/
82+
public $excludes;
83+
7784
/**
7885
* Installer constructor.
7986
*
@@ -86,53 +93,74 @@ public function __construct(Composer $composer, IOInterface $io) {
8693
$this->composer = $composer;
8794
$this->io = $io;
8895

89-
$app_dir = $this->getConfig('app-dir');
90-
if (!$app_dir) {
96+
$appDir = $this->getConfig('app-dir');
97+
if (!$appDir) {
9198
throw new \RuntimeException('Please configure app-dir in your composer.json');
9299
}
93100

94-
$web_dir = $this->getConfig('web-dir');
95-
if (!$web_dir) {
101+
$webDir = $this->getConfig('web-dir');
102+
if (!$webDir) {
96103
throw new \RuntimeException('Please configure web-dir in your composer.json');
97104
}
98105

99-
$this->appDir = $app_dir;
100-
$this->webDir = $web_dir;
106+
$this->appDir = $appDir;
107+
$this->webDir = $webDir;
101108

102109
$this->setAssetFileTypes();
110+
111+
$this->excludes = $this->getConfig('excludes', array());
103112
}
104113

105114
/**
106115
* Returns the value of a plugin config.
107116
*
108117
* @param string $name
109118
* The config name.
119+
* @param mixed $default
120+
* The default value to return if the config does not exist.
110121
*
111122
* @return mixed
112123
* The config value.
113124
*/
114-
public function getConfig($name) {
125+
public function getConfig($name, $default = NULL) {
115126
$extra = $this->composer->getPackage()->getExtra();
116127

117128
// TODO: Backward compatibility for old configs. Remove on stable version.
118-
$legacy_configs = array(
129+
$legacyConfigs = array(
119130
'drupal-app-dir',
120131
'drupal-web-dir',
121132
'drupal-asset-files',
122133
);
123-
if (in_array("drupal-$name", $legacy_configs) && isset($extra["drupal-$name"])) {
134+
if (in_array("drupal-$name", $legacyConfigs) && isset($extra["drupal-$name"])) {
124135
return $extra["drupal-$name"];
125136
}
126137

127138
if (!isset($extra['drupal-paranoia'])) {
128-
return NULL;
139+
return $default;
129140
}
130141

131142
if (isset($extra['drupal-paranoia'][$name])) {
132143
return $extra['drupal-paranoia'][$name];
133144
}
134145

135-
return NULL;
146+
return $default;
147+
}
148+
149+
/**
150+
* Checks whether a path exists in the excludes list.
151+
*
152+
* @param string $path
153+
* The path.
154+
*
155+
* @return bool
156+
* Returns TRUE if the path is listed, FALSE otherwise.
157+
*/
158+
public function isExcludedPath($path) {
159+
if (!$this->excludes) {
160+
return FALSE;
161+
}
162+
163+
return in_array($path, $this->excludes);
136164
}
137165

138166
/**
@@ -163,8 +191,8 @@ public function isDrupalPackage(PackageEvent $event) {
163191
return FALSE;
164192
}
165193

166-
$package_type = $package->getType();
167-
if (!$package_type) {
194+
$packageType = $package->getType();
195+
if (!$packageType) {
168196
return FALSE;
169197
}
170198

@@ -181,7 +209,7 @@ public function isDrupalPackage(PackageEvent $event) {
181209
*
182210
* @TODO: Add support for custom package types: 'oomphinc/composer-installers-extender' and 'davidbarratt/custom-installer'.
183211
*/
184-
if ((bool) preg_match("/(drupal)?-(core|module|theme|library|profile|drush|custom-module|custom-theme)/", $package_type)) {
212+
if ((bool) preg_match("/(drupal)?-(core|module|theme|library|profile|drush|custom-module|custom-theme)/", $packageType)) {
185213
return TRUE;
186214
}
187215

@@ -253,19 +281,42 @@ public function install() {
253281
}
254282

255283
/**
256-
* Symlink the public files folder.
284+
* Returns a list containing the sites public files path.
285+
*
286+
* @return array
287+
* The path list.
257288
*/
258-
public function createPublicFilesSymlink() {
259-
$cfs = new ComposerFilesystem();
289+
public function getSitesPublicFilesPath() {
260290
$finder = new Finder();
261-
262291
$finder->in($this->appDir . '/sites')
263292
->depth(0);
264293

294+
$directories = array();
295+
265296
/** @var \Symfony\Component\Finder\SplFileInfo $directory */
266297
foreach ($finder->directories() as $directory) {
267-
$cfs->ensureDirectoryExists($this->webDir . '/sites/' . $directory->getFilename());
268-
$cfs->relativeSymlink($directory->getRealPath() . '/files', realpath($this->webDir) . '/sites/' . $directory->getFilename() . '/files');
298+
$publicFilesPath = 'sites/' . $directory->getFilename() . '/files';
299+
300+
if (!is_dir($this->appDir . '/' . $publicFilesPath)) {
301+
continue;
302+
}
303+
304+
$directories[] = $publicFilesPath;
305+
}
306+
307+
return $directories;
308+
}
309+
310+
/**
311+
* Symlink the public files folder.
312+
*/
313+
public function createPublicFilesSymlink() {
314+
$cfs = new ComposerFilesystem();
315+
$publicFilesPaths = $this->getSitesPublicFilesPath();
316+
317+
foreach ($publicFilesPaths as $path) {
318+
$cfs->ensureDirectoryExists($this->webDir . '/' . dirname($path));
319+
$cfs->relativeSymlink(realpath($this->appDir) . '/' . $path, realpath($this->webDir) . '/' . $path);
269320
}
270321
}
271322

@@ -277,10 +328,12 @@ public function createAssetSymlinks() {
277328

278329
$finder->ignoreDotFiles(FALSE)->in($this->appDir);
279330

331+
// Add asset files types to the search.
280332
foreach ($this->assetFileTypes as $name) {
281333
$finder->name($name);
282334
}
283-
$finder->exclude('sites/default/files');
335+
336+
// Default extensions to exclude from the search.
284337
$finder->notName('*.inc');
285338
$finder->notName('*.install');
286339
$finder->notName('*.module');
@@ -289,6 +342,23 @@ public function createAssetSymlinks() {
289342
$finder->notName('*.profile');
290343
$finder->notName('*.theme');
291344

345+
// Ignores excluded paths.
346+
foreach ($this->excludes as $excludedPath) {
347+
// If is a file.
348+
if (isset(pathinfo($excludedPath)['extension'])) {
349+
$finder->notName($excludedPath);
350+
continue;
351+
}
352+
353+
// Is a folder.
354+
$finder->exclude($excludedPath);
355+
}
356+
357+
// Ignores sites public files path.
358+
foreach ($this->getSitesPublicFilesPath() as $publicFilesPath) {
359+
$finder->exclude($publicFilesPath);
360+
}
361+
292362
$cfs = new ComposerFilesystem();
293363

294364
foreach ($finder->files() as $file) {
@@ -304,6 +374,10 @@ public function createAssetSymlinks() {
304374
* The PHP file from the app directory.
305375
*/
306376
public function createStubPhpFile($path) {
377+
if ($this->isExcludedPath($path)) {
378+
return;
379+
}
380+
307381
$appDir = realpath($this->appDir);
308382
$webDir = realpath($this->webDir);
309383

@@ -348,9 +422,9 @@ public function setAssetFileTypes() {
348422
);
349423

350424
// Allow people to extend the list from a composer extra key.
351-
$extra_asset_files = $this->getConfig('asset-files');
352-
if ($extra_asset_files) {
353-
$this->assetFileTypes = array_merge($this->assetFileTypes, $extra_asset_files);
425+
$extraAssetFiles = $this->getConfig('asset-files');
426+
if ($extraAssetFiles) {
427+
$this->assetFileTypes = array_merge($this->assetFileTypes, $extraAssetFiles);
354428
}
355429

356430
// Allow other plugins to alter the list of files.

0 commit comments

Comments
 (0)