public function createAliases(Project $project, $projectRoot, $environments, $original = null, $merge = true)
{
$localProject = new LocalProject();
$config = $localProject->getProjectConfig($projectRoot);
$group = !empty($config['alias-group']) ? $config['alias-group'] : $project['id'];
$autoRemoveKey = $this->getAutoRemoveKey();
// Ensure the existence of the .drush directory.
$drushDir = $this->homeDir . '/.drush';
if (!is_dir($drushDir)) {
mkdir($drushDir);
}
$filename = $drushDir . '/' . $group . '.aliases.drushrc.php';
if (!is_writable($drushDir) || file_exists($filename) && !is_writable($filename)) {
throw new \Exception("Drush alias file not writable: {$filename}");
}
// Include the previous alias file(s) so that the user's own
// modifications can be merged. This may create a PHP parse error for
// invalid syntax, but in that case the user could not run Drush anyway.
$aliases = [];
$originalFiles = [$filename];
if ($original) {
array_unshift($originalFiles, $drushDir . '/' . $original . '.aliases.drushrc.php');
}
if ($merge) {
foreach ($originalFiles as $originalFile) {
if (file_exists($originalFile)) {
include $originalFile;
}
}
}
// Gather applications.
$apps = LocalApplication::getApplications($projectRoot, $this->config);
$drupalApps = $apps;
$multiApp = false;
if (count($apps) > 1) {
$multiApp = true;
// Remove non-Drupal applications.
foreach ($drupalApps as $key => $app) {
if (!Drupal::isDrupal($app->getRoot())) {
unset($drupalApps[$key]);
}
}
}
// Generate aliases for the remote environments and applications.
$autoGenerated = '';
foreach ($environments as $environment) {
foreach ($drupalApps as $app) {
$newAlias = $this->generateRemoteAlias($environment, $app, $multiApp);
if (!$newAlias) {
continue;
}
$aliasName = $environment->id;
if (count($drupalApps) > 1) {
$aliasName .= '--' . $app->getId();
}
// If the alias already exists, recursively replace existing
// settings with new ones.
if (isset($aliases[$aliasName])) {
$newAlias = array_replace_recursive($aliases[$aliasName], $newAlias);
unset($aliases[$aliasName]);
}
$autoGenerated .= sprintf("\n// Automatically generated alias for the environment \"%s\", application \"%s\".\n", $environment->title, $app->getId());
$autoGenerated .= $this->exportAlias($aliasName, $newAlias);
}
}
// Generate an alias for the local environment, for each app.
$localAlias = '';
$localWebRoot = $this->config->get('local.web_root');
foreach ($drupalApps as $app) {
$appId = $app->getId();
$localAliasName = '_local';
$webRoot = $projectRoot . '/' . $localWebRoot;
if (count($drupalApps) > 1) {
$localAliasName .= '--' . $appId;
}
if ($multiApp) {
$webRoot .= '/' . $appId;
}
$local = ['root' => $webRoot, $autoRemoveKey => true];
if (isset($aliases[$localAliasName])) {
$local = array_replace_recursive($aliases[$localAliasName], $local);
unset($aliases[$localAliasName]);
}
$localAlias .= sprintf("\n// Automatically generated alias for the local environment, application \"%s\".\n", $appId) . $this->exportAlias($localAliasName, $local);
}
// Add any user-defined (pre-existing) aliases.
$userDefined = '';
foreach ($aliases as $name => $alias) {
if (!empty($alias[$autoRemoveKey])) {
// This is probably for a deleted environment.
continue;
}
$userDefined .= $this->exportAlias($name, $alias) . "\n";
}
if ($userDefined) {
$userDefined = "\n// User-defined aliases.\n" . $userDefined;
}
$header = "<?php\n" . "/**\n * @file" . "\n * Drush aliases for the " . $this->config->get('service.name') . " project \"{$project->title}\"." . "\n *" . "\n * This file is auto-generated by the " . $this->config->get('application.name') . "." . "\n *" . "\n * WARNING" . "\n * This file may be regenerated at any time." . "\n * - User-defined aliases will be preserved." . "\n * - Aliases for active environments (including any custom additions) will be preserved." . "\n * - Aliases for deleted or inactive environments will be deleted." . "\n * - All other information will be deleted." . "\n */\n\n";
$export = $header . $userDefined . $localAlias . $autoGenerated;
$this->writeAliasFile($filename, $export);
return true;
}