From 2f01aafb3ef9e421745c62c71eb86fc8dbf39a3a Mon Sep 17 00:00:00 2001 From: Matthew Brabham Date: Wed, 25 Sep 2024 13:56:32 -0700 Subject: [PATCH 1/7] Add CLI setup for Acquia Cloud authentication Introduced a new `CliSetup` class to handle CLI authentication setup with Acquia Cloud. Modified the main CLI script to prompt for API credentials if they are not already set, ensuring necessary configurations are in place. --- bin/osu-acquia-cli.php | 8 ++++ src/CliSetup.php | 87 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 95 insertions(+) create mode 100644 src/CliSetup.php diff --git a/bin/osu-acquia-cli.php b/bin/osu-acquia-cli.php index c896f3f..a144a15 100755 --- a/bin/osu-acquia-cli.php +++ b/bin/osu-acquia-cli.php @@ -2,11 +2,14 @@ // If we're running from phar load the phar autoload file. use OsuWams\Cli\AcquiaCli; +use OsuWams\CliSetup; use Robo\Robo; use Symfony\Component\Console\Input\ArgvInput; use Symfony\Component\Console\Output\ConsoleOutput; use Symfony\Component\Filesystem\Path; +const EX_CONFIG = 78; + $pharPath = Phar::running(TRUE); if ($pharPath) { $root = $pharPath; @@ -59,6 +62,11 @@ $config->set('acquia.key', $environment['acquia']['key']); $config->set('acquia.secret', $environment['acquia']['secret']); } +if (is_null($config->get('acquia.key')) || is_null($config->get('acquia.secret'))) { + $setupHelper = new CliSetup($input, $output); + $setupHelper->cliSetupHelper(); + exit(EX_CONFIG); +} $app = new AcquiaCli($config, $input, $output); $statusCode = $app->run($input, $output); exit($statusCode); diff --git a/src/CliSetup.php b/src/CliSetup.php new file mode 100644 index 0000000..3e74fed --- /dev/null +++ b/src/CliSetup.php @@ -0,0 +1,87 @@ +input = $input; + $this->output = $output; + } + + /** + * Helper method for setting up CLI authentication with Acquia Cloud. + * + * Prompts the user to confirm whether they want to set up authentication. + * If confirmed, it asks for the Acquia Cloud API Key and Secret, then attempts to save the credentials. + * Provides feedback on the success or failure of saving the credentials. + * + * @return void + */ + public function cliSetupHelper() { + $startConfirm = $this->confirm("Not yet configured to authenticate with Acquia Cloud, do you want to setup?", "y"); + if ($startConfirm) { + $apiKey = $this->askHidden("Please enter an Acquia Cloud API Key"); + $apiSecret = $this->askHidden("Please enter an Acquia Cloud Secret"); + + if ($this->saveCredentials($apiKey, $apiSecret)) { + $this->say("Credentials saved successfully."); + } + else { + $this->say("Failed to save credentials."); + } + } + else { + $this->say("Setup cancelled. Exiting..."); + } + } + + private function saveCredentials(string $apiKey, string $apiSecret): bool { + $configDir = $this->getConfigDir(); + if (!is_dir($configDir) && !mkdir($configDir, 0777, TRUE)) { + return FALSE; + } + + $configPath = "$configDir/acquia-cli.yml"; + $configContent = sprintf("acquia:\n key: '%s'\n secret: '%s'\n", $apiKey, $apiSecret); + + return file_put_contents($configPath, $configContent) !== FALSE; + } + + private function getConfigDir(): string { + return join(DIRECTORY_SEPARATOR, [ + getenv('HOME') ?: getenv('USERPROFILE'), + '.acquia', + ]); + } + +} From c416088a16aa7dd4cf309cc41a72faca4bc82e81 Mon Sep 17 00:00:00 2001 From: Matthew Brabham Date: Wed, 25 Sep 2024 13:59:26 -0700 Subject: [PATCH 2/7] Add documentation for saveCredentials and getConfigDir methods Added PHPDoc blocks to the saveCredentials and getConfigDir methods in CliSetup.php. These comments describe the purpose, parameters, and return values of the methods, improving code readability and maintainability. --- src/CliSetup.php | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/CliSetup.php b/src/CliSetup.php index 3e74fed..e4878c0 100644 --- a/src/CliSetup.php +++ b/src/CliSetup.php @@ -65,6 +65,14 @@ public function cliSetupHelper() { } } + /** + * Saves the provided API credentials to a configuration file. + * + * @param string $apiKey The API key. + * @param string $apiSecret The API secret. + * + * @return bool TRUE on success, FALSE on failure. + */ private function saveCredentials(string $apiKey, string $apiSecret): bool { $configDir = $this->getConfigDir(); if (!is_dir($configDir) && !mkdir($configDir, 0777, TRUE)) { @@ -77,6 +85,11 @@ private function saveCredentials(string $apiKey, string $apiSecret): bool { return file_put_contents($configPath, $configContent) !== FALSE; } + /** + * Retrieves the configuration directory path. + * + * @return string The path to the configuration directory. + */ private function getConfigDir(): string { return join(DIRECTORY_SEPARATOR, [ getenv('HOME') ?: getenv('USERPROFILE'), From 1995dbe1f6fd37ebf757df853788b62ffc4c557a Mon Sep 17 00:00:00 2001 From: Matthew Brabham Date: Wed, 25 Sep 2024 14:07:21 -0700 Subject: [PATCH 3/7] Integrate Symfony YAML component for configuration dumping This commit replaces manual YAML string formatting with Symfony's YAML component for dumping configuration data. This ensures more robust and readable YAML output, improving maintainability and reducing potential formatting issues. --- src/CliSetup.php | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/CliSetup.php b/src/CliSetup.php index e4878c0..d1e3e0c 100644 --- a/src/CliSetup.php +++ b/src/CliSetup.php @@ -5,6 +5,7 @@ use Robo\Tasks; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Yaml\Yaml; /** * This class handles the CLI setup for authenticating with Acquia Cloud. @@ -42,8 +43,9 @@ public function __construct(InputInterface $input, OutputInterface $output) { * Helper method for setting up CLI authentication with Acquia Cloud. * * Prompts the user to confirm whether they want to set up authentication. - * If confirmed, it asks for the Acquia Cloud API Key and Secret, then attempts to save the credentials. - * Provides feedback on the success or failure of saving the credentials. + * If confirmed, it asks for the Acquia Cloud API Key and Secret, then + * attempts to save the credentials. Provides feedback on the success or + * failure of saving the credentials. * * @return void */ @@ -80,8 +82,13 @@ private function saveCredentials(string $apiKey, string $apiSecret): bool { } $configPath = "$configDir/acquia-cli.yml"; - $configContent = sprintf("acquia:\n key: '%s'\n secret: '%s'\n", $apiKey, $apiSecret); - + $configData = [ + 'acquia' => [ + 'key' => $apiKey, + 'secret' => $apiSecret, + ], + ]; + $configContent = Yaml::dump($configData, 4, 2); return file_put_contents($configPath, $configContent) !== FALSE; } From d0fb0a6e6fa0aae41b6ec93a736d7d3c90a9799b Mon Sep 17 00:00:00 2001 From: Matthew Brabham Date: Thu, 26 Sep 2024 12:47:14 -0700 Subject: [PATCH 4/7] Add docblock to run method in AcquiaCli.php This commit adds a detailed docblock to the run method in AcquiaCli.php. The docblock provides descriptions for the input and output parameters and specifies the return type, improving code readability and maintainability. --- src/Cli/AcquiaCli.php | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/Cli/AcquiaCli.php b/src/Cli/AcquiaCli.php index 6322d83..c731194 100644 --- a/src/Cli/AcquiaCli.php +++ b/src/Cli/AcquiaCli.php @@ -59,7 +59,14 @@ public function __construct( $this->runner->setSelfUpdateRepository(self::REPOSITORY); } - + /** + * Executes the runner's run method with the provided input and output interfaces. + * + * @param InputInterface $input The input interface to be processed by the runner. + * @param OutputInterface $output The output interface where the runner's results will be directed. + * + * @return mixed The result of the runner's run method. + */ public function run(InputInterface $input, OutputInterface $output) { return $this->runner->run($input, $output); } From f348bbde2cac910c413ab7df7300dcf5a4d98c1e Mon Sep 17 00:00:00 2001 From: Matthew Brabham Date: Thu, 26 Sep 2024 12:59:21 -0700 Subject: [PATCH 5/7] Add FileSaveException class Introduce a new exception class, FileSaveException, to handle file saving errors specifically. This class resides in the OsuWams\Exception namespace and extends the base PHP Exception class. --- src/Exception/FileSaveException.php | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 src/Exception/FileSaveException.php diff --git a/src/Exception/FileSaveException.php b/src/Exception/FileSaveException.php new file mode 100644 index 0000000..bc3ed0a --- /dev/null +++ b/src/Exception/FileSaveException.php @@ -0,0 +1,7 @@ + Date: Thu, 26 Sep 2024 12:59:40 -0700 Subject: [PATCH 6/7] Add detailed exit codes and handle FileSaveException Introduce specific exit codes for normal and configuration error states in cliSetupHelper method. Handle FileSaveException in saveCredentials method to provide clear error messages and appropriate exit statuses. --- src/CliSetup.php | 58 +++++++++++++++++++++++++++++++++++++----------- 1 file changed, 45 insertions(+), 13 deletions(-) diff --git a/src/CliSetup.php b/src/CliSetup.php index d1e3e0c..61de37b 100644 --- a/src/CliSetup.php +++ b/src/CliSetup.php @@ -2,6 +2,7 @@ namespace OsuWams; +use OsuWams\Exception\FileSaveException; use Robo\Tasks; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; @@ -12,6 +13,24 @@ */ class CliSetup extends Tasks { + /** + * Exit status code indicating a configuration error. + * + * The value of this constant is 78. + * + * @var int + */ + private const EX_CONFIG = 78; + + /** + * Exit status code for normal operations. + * + * The value of this constant is 0; + * + * @var int + */ + private const EX_NORMAL = 0; + /** * The input interface. * @@ -47,37 +66,46 @@ public function __construct(InputInterface $input, OutputInterface $output) { * attempts to save the credentials. Provides feedback on the success or * failure of saving the credentials. * - * @return void + * @return int */ - public function cliSetupHelper() { + public function cliSetupHelper(): int { $startConfirm = $this->confirm("Not yet configured to authenticate with Acquia Cloud, do you want to setup?", "y"); if ($startConfirm) { $apiKey = $this->askHidden("Please enter an Acquia Cloud API Key"); $apiSecret = $this->askHidden("Please enter an Acquia Cloud Secret"); - - if ($this->saveCredentials($apiKey, $apiSecret)) { - $this->say("Credentials saved successfully."); + try { + if ($this->saveCredentials($apiKey, $apiSecret)) { + $this->say("Credentials saved successfully."); + return self::EX_NORMAL; + } + else { + $this->say("Failed to save credentials."); + return self::EX_CONFIG; + } } - else { - $this->say("Failed to save credentials."); + catch (FileSaveException $e) { + $this->writeln($e->getMessage()); + return $e->getCode() ?: 1; } } else { $this->say("Setup cancelled. Exiting..."); + return self::EX_NORMAL; } } /** - * Saves the provided API credentials to a configuration file. + * Saves API credentials to a configuration file. * - * @param string $apiKey The API key. - * @param string $apiSecret The API secret. + * @param string $apiKey The API key to be saved. + * @param string $apiSecret The API secret to be saved. * - * @return bool TRUE on success, FALSE on failure. + * @return bool Returns TRUE on success, FALSE on failure. + * @throws \OsuWams\Exception\FileSaveException */ private function saveCredentials(string $apiKey, string $apiSecret): bool { $configDir = $this->getConfigDir(); - if (!is_dir($configDir) && !mkdir($configDir, 0777, TRUE)) { + if (!is_dir($configDir) && !mkdir($configDir, 0755, TRUE)) { return FALSE; } @@ -89,7 +117,11 @@ private function saveCredentials(string $apiKey, string $apiSecret): bool { ], ]; $configContent = Yaml::dump($configData, 4, 2); - return file_put_contents($configPath, $configContent) !== FALSE; + + if (file_put_contents($configPath, $configContent) === FALSE) { + throw new FileSaveException("Failed to save the file: $configPath"); + } + return TRUE; } /** From 8d985e5c6dbacc06facca23550dd5dedc31e6d09 Mon Sep 17 00:00:00 2001 From: Matthew Brabham Date: Thu, 26 Sep 2024 12:59:45 -0700 Subject: [PATCH 7/7] Update exit logic in setup helper to use returned status code Previously, the setup helper exited with a predefined config status code. Now, it captures the status code returned from the setup helper method and exits accordingly, ensuring more flexible error handling. --- bin/osu-acquia-cli.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bin/osu-acquia-cli.php b/bin/osu-acquia-cli.php index a144a15..5f48be8 100755 --- a/bin/osu-acquia-cli.php +++ b/bin/osu-acquia-cli.php @@ -64,8 +64,8 @@ } if (is_null($config->get('acquia.key')) || is_null($config->get('acquia.secret'))) { $setupHelper = new CliSetup($input, $output); - $setupHelper->cliSetupHelper(); - exit(EX_CONFIG); + $statusCode = $setupHelper->cliSetupHelper(); + exit($statusCode); } $app = new AcquiaCli($config, $input, $output); $statusCode = $app->run($input, $output);