Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve docroot resolver #3

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
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
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,13 @@ export PATH="$HOME/.composer/vendor/bin:$PATH"

To execute update test for your installed Drupal 8 site, you can execute following command:
```
update-tester.php test:update /source/project/path /clone/destination/path --db-name=drupal_clone --db-username='user_clone' --db-password='password_clone'
update-tester.php test:update /source/project/path /clone/destination/path
```

**NOTE:** If project has complicated deployment process. For example: docroot is not inside project folder but in other location, composer scripts that expect parts of projects to be in specific locations and so on. Then project has to be installed manually and composer update can be executed manually too.
```
update-tester.php update:packages
composer update
```

## Travis CI Integration
Expand Down
4 changes: 2 additions & 2 deletions scripts/update-tester.php
Original file line number Diff line number Diff line change
Expand Up @@ -210,9 +210,9 @@ public function testUpdate(
$resultStatus = $drushCmd->run();

if ($resultStatus->wasSuccessful()) {
$sourceSiteStatus = json_decode($resultStatus->getOutputData(), TRUE);
$destinationSiteStatus = json_decode($resultStatus->getOutputData(), TRUE);

$validateSite = $this->task(ValidateSite::class, $sourceSiteStatus);
$validateSite = $this->task(ValidateSite::class, $destinationSiteStatus);
$resultValidation = $validateSite->run();

if ($resultValidation->wasSuccessful()) {
Expand Down
57 changes: 56 additions & 1 deletion src/Task/CloneSite.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,12 @@
use Robo\Common\IO;
use Robo\Result;
use Robo\Task\BaseTask;
use Robo\Task\Composer\DumpAutoload;
use Robo\Task\FileSystem\loadTasks as FileSystemTasks;
use Thunder\UpdateTester\Exec\Drush;
use Thunder\UpdateTester\Task\Drupal\CloneDatabase;
use Thunder\UpdateTester\Task\Drupal\ReplaceComposerPaths;
use Thunder\UpdateTester\Task\Drupal\SetAutoload;
use Thunder\UpdateTester\Task\Drupal\ValidateSite;
use Thunder\UpdateTester\Task\Drupal\CloneFiles;
use Thunder\UpdateTester\Task\FileSystem\CreateDestination;
Expand All @@ -22,6 +25,16 @@ class CloneSite extends BaseTask {
use FileSystemTasks;
use IO;

/**
* Sub directory inside destination directory for absolute docroot directory.
*
* It's directory where absolute path docroot will be placed inside
* cloning destination directory.
*
* @var string
*/
protected static $absoluteDocrootDir = '_cloned_docroot';

/**
* Source folder.
*
Expand All @@ -43,6 +56,11 @@ class CloneSite extends BaseTask {
*/
protected $sourceSiteStatus;

/**
* Status of destination site fetched by Drush.
*
* @var array
*/
protected $destinationSiteStatus;

/**
Expand Down Expand Up @@ -184,7 +202,7 @@ protected function getDatabaseSettings() {
* {@inheritdoc}
*/
public function run() {
$this->say('Starting cloning of site ...');
$this->printTaskInfo(sprintf('Starting cloning of site from %s to %s', $this->getSource(), $this->getDestination()));

$status = $this->getSourceSiteStatus();
if (empty($status)) {
Expand Down Expand Up @@ -229,6 +247,43 @@ public function collection() {
$cloneFiles->setOutput($this->output());
$collection->add($cloneFiles);

// If docroot source is not inside cloning source folder then it has to be
// cloned too into destination folder and composer.json has to be adjusted.
$sourceDocroot = DocrootResolver::getDocroot(realpath($this->getSource()));
if (strpos($sourceDocroot, realpath($this->getSource()) . '/') !== 0) {
$destinationDocroot = $this->getDestination() . '/' . static::$absoluteDocrootDir;

// Create destination directory for docroot.
$createDocrootDestination = new CreateDestination($destinationDocroot);
$createDocrootDestination->inflect($this);
$createDocrootDestination->setOutput($this->output());
$collection->add($createDocrootDestination);

// Clone docroot files, since they are not inside cloned directory.
$cloneDocrootFiles = new CloneFiles($sourceDocroot, $destinationDocroot);
$cloneDocrootFiles->inflect($this);
$cloneDocrootFiles->setOutput($this->output());
$collection->add($cloneDocrootFiles);

// Set docroot related install paths to new path.
$updateInstallPaths = new ReplaceComposerPaths($this->getDestination() . '/composer.json', $sourceDocroot, $destinationDocroot);
$updateInstallPaths->inflect($this);
$updateInstallPaths->setOutput($this->output());
$collection->add($updateInstallPaths);

// Set proper path in autoload.php in docroot to composer autoload.php.
$setAutoload = new SetAutoload($destinationDocroot, $this->getDestination());
$setAutoload->inflect($this);
$setAutoload->setOutput($this->output());
$collection->add($setAutoload);

// Composer autoload files has to be triggered to take new paths.
$dumpAutoload = new DumpAutoload();
$dumpAutoload->dir($this->getDestination());
$dumpAutoload->inflect($this);
$collection->add($dumpAutoload);
}

$cloneDatabase = new CloneDatabase($this->getSource(), $this->getDestination(), $this->getDatabaseSettings());
$cloneDatabase->inflect($this);
$cloneDatabase->setOutput($this->output());
Expand Down
24 changes: 17 additions & 7 deletions src/Task/Drupal/CloneDatabase.php
Original file line number Diff line number Diff line change
Expand Up @@ -75,14 +75,24 @@ protected function getSource() {
return $this->source;
}

/**
* Get destination folder as it's provided for command.
*
* @return string
* Returns destination folder (can be also relative path).
*/
public function getDestination() {
return $this->destination;
}

/**
* Get database dump file name.
*
* @return string
* File used to dump database.
*/
protected function getDumpFileName() {
return realpath($this->destination) . '/db-dump.sql';
return realpath($this->getDestination()) . '/db-dump.sql';
}

/**
Expand All @@ -91,12 +101,12 @@ protected function getDumpFileName() {
* @return string
* Docroot to destination site.
*/
protected function getDocRoot() {
protected function getDestinationDocroot() {
if (isset($this->destinationDocroot)) {
return $this->destinationDocroot;
}

$this->destinationDocroot = DocrootResolver::getDocroot($this->destination);
$this->destinationDocroot = DocrootResolver::getDocroot($this->getDestination());

return $this->destinationDocroot;
}
Expand All @@ -105,11 +115,11 @@ protected function getDocRoot() {
* {@inheritdoc}
*/
public function run() {
if (empty($this->getDocRoot())) {
if (empty($this->getDestinationDocroot())) {
return Result::error($this, 'Unable to get destination docroot.');
}

$this->say('Cloning database ... ');
$this->printTaskInfo(sprintf('Cloning database from %s to %s site', $this->getSource(), $this->getDestination()));

return $this->collection()->run();
}
Expand All @@ -123,7 +133,7 @@ public function run() {
public function collection() {
$collection = new Collection();

$setDatabaseSettings = new SetDatabaseSettings($this->destination, $this->databaseSettings);
$setDatabaseSettings = new SetDatabaseSettings($this->getDestination(), $this->databaseSettings);
$setDatabaseSettings->inflect($this);
$setDatabaseSettings->setOutput($this->output());
$collection->add($setDatabaseSettings);
Expand All @@ -144,7 +154,7 @@ public function collection() {

$importDatabase = new Exec(sprintf('drush --yes sql-cli < %s', $dumpFile));
$importDatabase->inflect($this);
$importDatabase->dir(realpath($this->getDocRoot()));
$importDatabase->dir(realpath($this->getDestinationDocroot()));
$collection->add($importDatabase);

return $collection;
Expand Down
2 changes: 1 addition & 1 deletion src/Task/Drupal/CloneFiles.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public function __construct($source, $destination) {
* {@inheritdoc}
*/
public function run() {
$this->say('Cloning files ... ');
$this->printTaskInfo(sprintf('Cloning files from %s to %s', $this->source, $this->destination));

if (!is_dir($this->source)) {
return Result::error($this, 'Provided source folder is not valid.');
Expand Down
2 changes: 1 addition & 1 deletion src/Task/Drupal/Database/CreateDatabaseRequirements.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public function __construct(array $databaseSettings) {
* {@inheritdoc}
*/
public function run() {
$this->say('Creating database requirements ... ');
$this->printTaskInfo('Creating database requirements (database, user, grants)');

$dbSettings = $this->databaseSettings;

Expand Down
15 changes: 4 additions & 11 deletions src/Task/Drupal/Database/SetDatabaseSettings.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use Robo\Common\IO;
use Robo\Task\BaseTask;
use Robo\Task\Docker\Result;
use Thunder\UpdateTester\Util\DocrootResolver;

/**
* Task to set database settings in destination site.
Expand Down Expand Up @@ -49,17 +50,7 @@ public function __construct($destination, array $databaseSettings) {
* Absolute path for settings.php file.
*/
protected function getFileName() {
$fileName = realpath($this->destination . '/sites/default/settings.php');

if (!is_file($fileName)) {
$fileName = realpath($this->destination . '/docroot/sites/default/settings.php');

if (!is_file($fileName)) {
return '';
}
}

return $fileName;
return DocrootResolver::getDocroot($this->destination) . '/sites/default/settings.php';
}

/**
Expand All @@ -71,6 +62,8 @@ public function run() {
return Result::error($this, 'Unable to find settings.php file in destination folder.');
}

$this->printTaskInfo(sprintf('Set database settings in %s', $fileName));

if (!is_writable($fileName)) {
$this->say('File settings.php in destination folder is not writable. Trying to change it to writable.');

Expand Down
90 changes: 90 additions & 0 deletions src/Task/Drupal/ReplaceComposerPaths.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
<?php

namespace Thunder\UpdateTester\Task\Drupal;

use Robo\Common\IO;
use Robo\Task\BaseTask;
use Robo\Task\Docker\Result;

/**
* Task to replace install paths in composer.json.
*
* @package Thunder\UpdateTester\Task\Composer
*/
class ReplaceComposerPaths extends BaseTask {

use IO;

/**
* Path to composer.json file.
*
* @var string
*/
protected $composerFile;

/**
* Install path that should be replaced.
*
* @var string
*/
protected $fromPath;

/**
* Install path that should be set.
*
* @var string
*/
protected $toPath;

/**
* Constructor for replace install paths task.
*
* @param string $composerFile
* Composer file path.
* @param string $fromPath
* Path that should be replaced from.
* @param string $toPath
* Path that should be replaced to.
*/
public function __construct($composerFile, $fromPath, $toPath) {
$this->composerFile = $composerFile;
$this->fromPath = $fromPath;
$this->toPath = $toPath;
}

/**
* {@inheritdoc}
*/
public function run() {
$composerFile = realpath($this->composerFile);
$fromPath = $this->fromPath;
$toPath = $this->toPath;

$this->printTaskInfo(sprintf('Replacing install paths in composer file %s', $composerFile));

$jsonData = json_decode(file_get_contents($composerFile), TRUE);
if (empty($jsonData) || empty($jsonData['extra']['installer-paths'])) {
return Result::error($this, sprintf('Unable to get data from %s', $composerFile));
}

// Adjust install paths.
$this->say(sprintf('Change install path from %s to %s.', $fromPath, $toPath));
$installPaths = $jsonData['extra']['installer-paths'];
foreach (array_keys($installPaths) as $path) {
if (strpos($path, $fromPath) === 0) {
$newPath = $toPath . substr($path, strlen($fromPath));

$this->say(sprintf('Changing %s into %s.', $path, $newPath));

$installPaths[$newPath] = $installPaths[$path];
unset($installPaths[$path]);
}
}
$jsonData['extra']['installer-paths'] = $installPaths;

file_put_contents($composerFile, json_encode($jsonData, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE));

return Result::success($this, sprintf('Composer file %s successfully modified with new install paths.', $composerFile));
}

}
Loading