Newer
Older
<?php
/**
* @file
* Contains \LakeDrops\Docker4Drupal\Handler.
*/
namespace LakeDrops\Docker4Drupal;
use Composer\Package\PackageInterface;
use Composer\Composer;
use Composer\IO\IOInterface;
use Composer\Script\Event as ScriptEvent;
use Symfony\Component\Filesystem\Filesystem;

jurgenhaas
committed
use Symfony\Component\Yaml\Yaml;
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
class Handler {
/**
* @var \Composer\Composer
*/
protected $composer;
/**
* @var \Composer\IO\IOInterface
*/
protected $io;
/**
* @var PackageInterface
*/
protected $drupalCorePackage;
/**
* Handler constructor.
*
* @param Composer $composer
* @param IOInterface $io
*/
public function __construct(Composer $composer, IOInterface $io) {
$this->composer = $composer;
$this->io = $io;
}
/**
* Look up the Drupal core package object, or return it from where we cached
* it in the $drupalCorePackage field.
*
* @return PackageInterface
*/
protected function getDrupalCorePackage() {
if (!isset($this->drupalCorePackage)) {
$this->drupalCorePackage = $this->getPackage('drupal/core');
}
return $this->drupalCorePackage;
}
/**
* Retrieve a package from the current composer process.
*
* @param string $name
* Name of the package to get from the current composer installation.
*
* @return PackageInterface
*/
protected function getPackage($name) {
return $this->composer->getRepositoryManager()->getLocalRepository()->findPackage($name, '*');
}
/**
* Configure Drupal Project for Docker.
*
* @param ScriptEvent $event
*/

jurgenhaas
committed
public function configureProject($event) {
// We only do the fancy stuff for developers
if (!$event->isDevMode()) {
return;
}
$options = $this->getOptions();
$fs = new Filesystem();
$installationManager = $this->composer->getInstallationManager();
$drupalCorePackage = $this->getDrupalCorePackage();
if (!$drupalCorePackage) {
// We are called too early, Drupal core is not available yet.
return;
}
$corePath = $installationManager->getInstallPath($drupalCorePackage);
// Directory where the root project is being created
$projectRoot = getcwd();
// Directory where Drupal's index.php is located
$webRoot = dirname($corePath);
// Directory where this plugin is being installed
$pluginRoot = $installationManager->getInstallPath($this->getPackage('lakedrops/docker4drupal'));

jurgenhaas
committed
// If the d8-project-scaffold plugin is present we only execute this one
// if $force is TRUE. This way we can make sure that we get executed after
// d8-project-scaffold.
$settingsPath = $webRoot . '/sites/default';
if ($this->getPackage('lakedrops/d8-project-scaffold')) {
if (!$fs->exists($projectRoot . '/settings/default')) {
return;
}
$settingsPath = 'settings/default';
}
$twig_loader = new \Twig_Loader_Array([]);
$twig = new \Twig_Environment($twig_loader);

jurgenhaas
committed
foreach ($this->getFiles($projectRoot, $webRoot, $settingsPath) as $template => $def) {
$file = $def['dest'] . '/' . $template;
if (!$fs->exists($file)) {
$twig_loader->setTemplate($template, file_get_contents($pluginRoot . '/templates/' . $template . '.twig'));
$rendered = $twig->render($template, $options);
file_put_contents($file, $rendered);
}

jurgenhaas
committed
if (isset($def['link']) && ($def['link'] != $settingsPath)) {
$link = $def['link'] . '/' . $template;
if (!$fs->exists($link)) {
$rel = substr($fs->makePathRelative($file, $projectRoot . '/' . $link), 3, -1);
$fs->symlink($rel, $link);
}
}
$fs->chmod($file, 0664);
}
// Make sure that settings.docker.php gets called from settings.php

jurgenhaas
committed
$settingsPhpFile = $settingsPath . '/settings.php';
if ($fs->exists(($settingsPhpFile))) {
$settingsPhp = file_get_contents($settingsPhpFile);
if (strpos($settingsPhp, 'settings.docker.php') === FALSE) {

jurgenhaas
committed
$settingsPhp .= "\n\nif (file_exists(__DIR__ . '/settings.docker.php')) {\n include __DIR__ . '/settings.docker.php';\n}\n";

jurgenhaas
committed
file_put_contents($settingsPhpFile, $settingsPhp);
}

jurgenhaas
committed
foreach ($this->getFiles($projectRoot, $webRoot, $settingsPath) as $template => $def) {
$this->git('ignore ' . $template);
}
}
catch (\Exception $ex) {
// We're ignoring this for now
}

jurgenhaas
committed
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
// Update host wider traefik container
$traefikPath = $_SERVER['HOME'] . '/.traefik';
$traefikFile = $traefikPath . '/docker-compose.yml';
if ($fs->exists($traefikFile)) {
$traefik = Yaml::parse(file_get_contents($traefikFile));
}
else {
$fs->mkdir($traefikPath);
$traefik = [
'version' => '2',
'services' => [
'traefik' => [
'image' => 'traefik',
'restart' => 'unless-stopped',
'command' => '-c /dev/null --web --docker --logLevel=DEBUG',
'networks' => [],
'ports' => [
'8000:80',
'8080:8080',
],
'volumes' => [
'/var/run/docker.sock:/var/run/docker.sock',
],
],
],
'networks' => [],
];
}
if (!in_array($options['projectname'], $traefik['services']['traefik']['networks'])) {
$traefik['services']['traefik']['networks'][] = $options['projectname'];
$traefik['networks'][$options['projectname']] = [
'external' => [
'name' => $options['projectname'] . '_default',
],
];

jurgenhaas
committed
file_put_contents($traefikFile, Yaml::dump($traefik, 9, 2));
exec('docker network create ' . $options['projectname'] . '_default');
exec('docker-compose -f ' . $traefikFile . ' --project-name traefik stop');
exec('docker-compose -f ' . $traefikFile . ' --project-name traefik up -d');

jurgenhaas
committed
}

jurgenhaas
committed
protected function getFiles($projectRoot, $webRoot, $settingsPath) {

jurgenhaas
committed
'dest' => $projectRoot . '/' . $settingsPath,

jurgenhaas
committed
'aliases.drushrc.php' => [
'dest' => $projectRoot . '/drush',
],
'drushrc.php' => [
'dest' => $projectRoot . '/drush',
],
'.env' => [
'dest' => $projectRoot,
],
];
}
/**
* Retrieve excludes from optional "extra" configuration.
*
* @return array
*/
protected function getOptions() {
$extra = $this->composer->getPackage()->getExtra() + ['docker4drupal' => []];
$options = $extra['docker4drupal'] + [

jurgenhaas
committed
'projectname' => str_replace([' ', '-', '_', '.'], '', basename(getcwd())),

jurgenhaas
committed
'drupal' => [
'version' => '8',
],
'php' => [
'version' => '7.0',# 5.3|5.6|7.1
'xdebug' => 1,
],
'nginx' => [
'version' => '1.10',
],
'varnish' => [
'enable' => 0,
],
'solr' => [
'enable' => 0,
],
'node' => [
'enable' => 0,
],
];
return $options;
}
/**
* Wrapper for git command in the root directory.
*
* @param $command
* Git command name, arguments and/or options.
* @throws \Exception
*/
protected function git($command) {
passthru(escapeshellcmd('git -c "user.email=d8-project@lakedrops.com" ' . $command), $exit_code);
if ($exit_code !== 0) {
throw new \Exception('Git returned a non-zero exit code');
}
}
}