Skip to content

Commit

Permalink
Merge pull request #46 from acquia/ACMS-3658
Browse files Browse the repository at this point in the history
ACMS-3658: EnvironmentDetector using undefined method
  • Loading branch information
vishalkhode1 authored Mar 19, 2024
2 parents e6ccc08 + 39fd26a commit 2db4b83
Show file tree
Hide file tree
Showing 15 changed files with 322 additions and 151 deletions.
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,14 @@
"composer-plugin-api": "^2",
"acquia/drupal-environment-detector": "^1.5.3",
"consolidation/config": "^2.0.0",
"drush/drush": "^11.6 || ^12",
"grasmash/yaml-expander": "^3.0",
"loophp/phposinfo": "^1.7.1"
},
"require-dev": {
"acquia/coding-standards": "^2.0",
"composer/composer": "^2.2",
"dealerdirect/phpcodesniffer-composer-installer": "^1.0.0",
"drush/drush": "^11.6 || ^12",
"ergebnis/composer-normalize": "^2.30.2",
"phpro/grumphp-shim": "^2.2",
"phpunit/phpunit": "^9 || ^10"
Expand Down
6 changes: 0 additions & 6 deletions src/Common/Executor.php
Original file line number Diff line number Diff line change
Expand Up @@ -110,12 +110,6 @@ public function drush(mixed $command): ProcessExecutor {
* The unexecuted command.
*/
public function execute(mixed $command): ProcessExecutor {
// Backwards compatibility check for legacy commands.
if (!is_array($command)) {
$this->say($command);
$this->say(StringManipulator::stringToArrayMsg());
$command = StringManipulator::commandConvert($command);
}
/** @var \Robo\Common\ProcessExecutor $process_executor */
$process_executor = Robo::process(new Process($command));
return $process_executor->dir($this->getConfigValue('repo.root'))
Expand Down
23 changes: 23 additions & 0 deletions src/Common/IO.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,29 @@ protected function yell($text, $length = 40, $color = 'green'): void {
$this->formattedOutput($text, $length, $format);
}

/**
* Prints the message to terminal.
*
* @param string $message
* Given message to print.
* @param string $type
* Type of message. Ex: error, success, info etc.
* @param string $color
* Given background color.
*/
protected function print(string $message, string $type = "success", string $color = ""): void {
if (!$color) {
$color = match ($type) {
"warning" => "yellow",
"notice" => "cyan",
"error" => "red",
default => "green",
};
}
$message = " <fg=white;bg=$color;options=bold>[$type]</fg=white;bg=$color;options=bold> " . $message;
$this->say($message);
}

/**
* Format text as a question.
*
Expand Down
2 changes: 1 addition & 1 deletion src/Config/ConfigInitializer.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class ConfigInitializer {
/**
* ConfigInitializer constructor.
*
* @param \Consolidation\Config\ConfigInterface $config
* @param \Consolidation\Config\ConfigInterface|\Consolidation\Config\Config $config
* The config object.
* @param \Symfony\Component\Console\Input\InputInterface|null $input
* An input object or null.
Expand Down
22 changes: 9 additions & 13 deletions src/Drush/Commands/BaseDrushCommands.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
use Acquia\Drupal\RecommendedSettings\Config\DefaultDrushConfig;
use Acquia\Drupal\RecommendedSettings\Robo\Config\ConfigAwareTrait;
use Acquia\Drupal\RecommendedSettings\Robo\Tasks\LoadTasks;
use Consolidation\AnnotatedCommand\AnnotationData;
use Consolidation\AnnotatedCommand\Hooks\HookManager;
use Drush\Attributes as Cli;
use Drush\Commands\DrushCommands;
Expand All @@ -21,7 +20,6 @@
use Robo\Contract\ConfigAwareInterface;
use Robo\Contract\IOAwareInterface;
use Robo\LoadAllTasks;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Process\Process;

Expand All @@ -40,7 +38,7 @@ class BaseDrushCommands extends DrushCommands implements ConfigAwareInterface, L
* {@inheritdoc}
*/
#[CLI\Hook(type: HookManager::INITIALIZE)]
public function init(InputInterface $input, AnnotationData $annotationData): void {
public function init(): void {
$this->initializeConfig();
}

Expand Down Expand Up @@ -73,19 +71,17 @@ protected function invokeCommands(array $commands): void {
* The name of the command, e.g., 'status'.
* @param string[] $args
* An array of arguments to pass to the command.
*
* @throws \Acquia\Drupal\RecommendedSettings\Exceptions\SettingsException
* @param string[] $options
* An array of options to pass to the command.
* @param bool $display_command
* Decides if command should be displayed on terminal or not. Default is TRUE.
*/
protected function invokeCommand(string $command_name, array $args = []): void {
$options = $this->input()->getOptions();
foreach ($options as $key => $value) {
if ($value === NULL || $key === "define" || $value == FALSE) {
unset($options[$key]);
}
}
protected function invokeCommand(string $command_name, array $args = [], array $options = [], bool $display_command = TRUE): void {
$process = Drush::drush(Drush::aliasManager()->getSelf(), $command_name, $args, $options);
$this->output->writeln("<comment> > " . $command_name . "</comment>");
$output = $this->output();
if ($display_command) {
$output->writeln("<comment> > " . $command_name . "</comment>");
}
$process->setTty(Process::isTtySupported());
$process->run(static function ($type, $buffer) use ($output): void {
if (Process::ERR === $type) {
Expand Down
119 changes: 119 additions & 0 deletions src/Drush/Commands/SettingsDrushCommands.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
<?php

declare(strict_types=1);

namespace Acquia\Drupal\RecommendedSettings\Drush\Commands;

use Acquia\Drupal\RecommendedSettings\Common\RandomString;
use Acquia\Drupal\RecommendedSettings\Drush\Traits\SiteUriTrait;
use Acquia\Drupal\RecommendedSettings\Exceptions\SettingsException;
use Acquia\Drupal\RecommendedSettings\Settings;
use Consolidation\AnnotatedCommand\Hooks\HookManager;
use Drush\Attributes as Cli;
use Robo\ResultData;

/**
* The DRS Drush commands.
*/
class SettingsDrushCommands extends BaseDrushCommands {

use SiteUriTrait;

/**
* Command name for settings.php generation.
*/
const SETTINGS_COMMAND = "settings";

/**
* Command name for hash salt generation.
*/
const HASH_SALT_COMMAND = "drupal:hash-salt:init";

/**
* Generates the settings.php for given site.
*
* @param array<string> $options
* An array of input options.
*/
#[CLI\Command(name: self::SETTINGS_COMMAND, aliases: ["drs:init:settings", "dis", "init:settings"])]
#[CLI\Help(description: 'Generates the acquia recommended settings template files for given site.')]
#[CLI\Option(name: 'database', description: 'Local database name')]
#[CLI\Option(name: 'username', description: 'Local database username')]
#[CLI\Option(name: 'password', description: 'Local database password')]
#[CLI\Option(name: 'host', description: 'Local database host')]
#[CLI\Option(name: 'port', description: 'Local database port')]
#[CLI\Usage(
name: 'drush ' . self::SETTINGS_COMMAND . ' --database=mydb --username=myuser --password=mypass --host=127.0.0.1 --port=1234 --uri=site1',
description: 'Generates the settings.php for site2 passing db credentials.',
)]
public function initSettings(array $options = [
'database' => 'drupal',
'username' => 'drupal',
'password' => 'drupal',
'host' => 'localhost',
'port' => "3306",
]): int {
$db["drupal"]["db"] = [
'database' => $options['database'],
'username' => $options['username'],
'password' => $options['password'],
'host' => $options['host'],
'port' => $options['port'],
];
try {
$site_directory = $this->getSitesSubdirFromUri($this->getConfigValue("docroot"), $this->getConfigValue("drush.uri"));
$settings = new Settings($this->getConfigValue("docroot"), $site_directory);
$settings->generate($db);
if (!$this->output()->isQuiet()) {
$this->print(
sprintf("Settings generated successfully for site '%s'.", $this->getConfigValue("drush.uri"))
);
}
}
catch (SettingsException $e) {
if (!$this->output()->isQuiet()) {
$this->print($e->getMessage(), "error", "red");
if ($this->output()->isVerbose()) {
$this->io()->writeln($e->getTraceAsString());
}
}
return ResultData::EXITCODE_ERROR;
}
return ResultData::EXITCODE_OK;
}

/**
* Generates the hash salt.
*/
#[CLI\Command(name: self::HASH_SALT_COMMAND, aliases: ["dhsi", "setup:hash-salt"])]
public function hashSalt(): int {
return $this->postInitSettings();
}

/**
* Writes a hash salt to ${repo.root}/salt.txt if one does not exist.
*/
#[CLI\Hook(type: HookManager::POST_COMMAND_HOOK, target: self::SETTINGS_COMMAND)]
public function postInitSettings(): int {
$hash_salt_file = $this->getConfigValue('repo.root') . '/salt.txt';
if (!file_exists($hash_salt_file)) {
$this->say("Generating hash salt...");
$result = $this->taskWriteToFile($hash_salt_file)
->line(RandomString::string(55))
->run();

if (!$result->wasSuccessful()) {
$this->print(
sprintf("Unable to write hash salt at `%s`.", $hash_salt_file), "error",
);
}

return $result->getExitCode();
}
else {
$this->print("Hash salt already exists.", "notice");
}
return ResultData::EXITCODE_OK;
}

}
2 changes: 1 addition & 1 deletion src/Exceptions/SettingsException.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public function __construct(
$code = 0,
\Throwable $previous = NULL
) {
$message .= "\nFor troubleshooting guidance and support, see https://github.com/acquia/drupal-recommended-settings";
$message .= PHP_EOL . " For troubleshooting guidance and support, see https://github.com/acquia/drupal-recommended-settings";
parent::__construct($message, $code, $previous);

$this->transmitAnalytics();
Expand Down
35 changes: 12 additions & 23 deletions src/Helpers/EnvironmentDetector.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,6 @@ public static function getCiEnv(): string|bool {

/**
* Is CI.
*
* @throws \ReflectionException
*/
public static function isCiEnv(): bool {
return self::getCiEnv() || getenv('CI');
Expand All @@ -50,8 +48,6 @@ public static function isCiEnv(): bool {
*
* @return string
* Settings file full path and filename.
*
* @throws \ReflectionException
*/
public static function getCiSettingsFile(): string {
return sprintf("%s/vendor/acquia/drupal-recommended-settings/settings/%s.settings.php", dirname(DRUPAL_ROOT), self::getCiEnv());
Expand Down Expand Up @@ -94,35 +90,27 @@ public static function isPantheonProdEnv(): bool {

/**
* Is local.
*
* @throws \ReflectionException
*/
public static function isLocalEnv(): bool {
return parent::isLocalEnv() && !self::isPantheonEnv() && !self::isCiEnv();
}

/**
* Is dev.
*
* @throws \ReflectionException
*/
public static function isDevEnv(): bool {
return self::isAhDevEnv() || self::isPantheonDevEnv();
}

/**
* Is stage.
*
* @throws \ReflectionException
*/
public static function isStageEnv(): bool {
return self::isAhStageEnv() || self::isPantheonStageEnv();
}

/**
* Is prod.
*
* @throws \ReflectionException
*/
public static function isProdEnv(): bool {
return self::isAhProdEnv() || self::isPantheonProdEnv();
Expand Down Expand Up @@ -175,8 +163,6 @@ public static function isDarwin(): bool {
*
* @return string|null
* Site name.
*
* @throws \ReflectionException
*/
public static function getSiteName(string $site_path): ?string {
if (self::isAcsfEnv()) {
Expand All @@ -189,21 +175,19 @@ public static function getSiteName(string $site_path): ?string {
// factory site is active. The hostname must have a corresponding entry
// under the multisites key.
$input = new ArgvInput($argv);
$config = new DefaultConfig(self::getRepoRoot());
$config = new DefaultConfig(self::getDrupalRoot());
$config_initializer = new ConfigInitializer($config, $input);
$drs_config = $config_initializer->initialize();

$drs_config = $config_initializer->initialize()->loadAllConfig()->processConfig();
// The hostname must match the pattern local.[site-name].com, where
// [site-name] is a value in the multisites array.
$domain_fragments = explode('.', getenv('HTTP_HOST'));
if (isset($domain_fragments[1])) {
if (isset($domain_fragments[1]) && $drs_config->has('multisites')) {
$name = $domain_fragments[1];
$acsf_sites = $drs_config->get('multisites');
if (in_array($name, $acsf_sites, TRUE)) {
return $name;
}
}

}

return str_replace('sites/', '', $site_path);
Expand All @@ -221,23 +205,28 @@ public static function getSiteName(string $site_path): ?string {
* The repo root as an absolute path.
*/
public static function getRepoRoot(): string {
if (defined('DRUPAL_ROOT')) {
if (self::getDrupalRoot()) {
// This is a web or Drush request.
return dirname(DRUPAL_ROOT);
return dirname(self::getDrupalRoot());
}
// phpcs:ignore
global $repo_root;
// phpcs:enable
return $repo_root;
}

/**
* Returns the Drupal root path.
*/
public static function getDrupalRoot(): string {
return defined('DRUPAL_ROOT') ? DRUPAL_ROOT : "";
}

/**
* List detectable environments and whether they are currently active.
*
* @return string[]
* Returns an array of environments.
*
* @throws \ReflectionException
*/
public static function getEnvironments(): array {
return [
Expand Down
Loading

0 comments on commit 2db4b83

Please sign in to comment.