diff --git a/src/Command/Auth/AuthAcsfLoginCommand.php b/src/Command/Auth/AuthAcsfLoginCommand.php
index 861a180fd..04f27177d 100644
--- a/src/Command/Auth/AuthAcsfLoginCommand.php
+++ b/src/Command/Auth/AuthAcsfLoginCommand.php
@@ -11,7 +11,7 @@
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
-#[AsCommand(name: 'auth:acsf-login', description: 'Register your Site Factory API key and secret to use API functionality')]
+#[AsCommand(name: 'auth:acsf-login', description: 'Register Acquia Site Factory API credentials')]
final class AuthAcsfLoginCommand extends CommandBase {
protected function configure(): void {
diff --git a/src/Command/Auth/AuthAcsfLogoutCommand.php b/src/Command/Auth/AuthAcsfLogoutCommand.php
index 171272e27..2625c4725 100644
--- a/src/Command/Auth/AuthAcsfLogoutCommand.php
+++ b/src/Command/Auth/AuthAcsfLogoutCommand.php
@@ -10,7 +10,7 @@
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
-#[AsCommand(name: 'auth:acsf-logout', description: 'Remove your Site Factory key and secret from your local machine.')]
+#[AsCommand(name: 'auth:acsf-logout', description: 'Remove Acquia Site Factory API credentials')]
final class AuthAcsfLogoutCommand extends CommandBase {
protected function execute(InputInterface $input, OutputInterface $output): int {
diff --git a/src/Command/Auth/AuthLoginCommand.php b/src/Command/Auth/AuthLoginCommand.php
index 321665e83..c6196403e 100644
--- a/src/Command/Auth/AuthLoginCommand.php
+++ b/src/Command/Auth/AuthLoginCommand.php
@@ -11,7 +11,7 @@
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
-#[AsCommand(name: 'auth:login', description: 'Register your Cloud API key and secret to use API functionality', aliases: ['login'])]
+#[AsCommand(name: 'auth:login', description: 'Register Acquia Cloud API credentials', aliases: ['login'])]
final class AuthLoginCommand extends CommandBase {
protected function configure(): void {
diff --git a/src/Command/Auth/AuthLogoutCommand.php b/src/Command/Auth/AuthLogoutCommand.php
index 9edda39f7..d8c22ead6 100644
--- a/src/Command/Auth/AuthLogoutCommand.php
+++ b/src/Command/Auth/AuthLogoutCommand.php
@@ -5,24 +5,35 @@
namespace Acquia\Cli\Command\Auth;
use Acquia\Cli\Command\CommandBase;
+use Acquia\Cli\Exception\AcquiaCliException;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
-#[AsCommand(name: 'auth:logout', description: 'Remove Cloud API key and secret from local machine.', aliases: ['logout'])]
+#[AsCommand(name: 'auth:logout', description: 'Remove Acquia Cloud API credentials', aliases: ['logout'])]
final class AuthLogoutCommand extends CommandBase {
+ protected function configure(): void {
+ $this->addOption('delete', NULL, InputOption::VALUE_NEGATABLE, 'Delete the active Acquia Cloud API credentials');
+ }
+
protected function execute(InputInterface $input, OutputInterface $output): int {
- if ($this->cloudApiClientService->isMachineAuthenticated()) {
- $answer = $this->io->confirm('Are you sure you\'d like to unset the Acquia Cloud API key for Acquia CLI?');
- if (!$answer) {
- return Command::SUCCESS;
- }
+ if (!$this->cloudApiClientService->isMachineAuthenticated()) {
+ throw new AcquiaCliException('You are not authenticated and therefore cannot logout');
}
+ $activeKey = $this->datastoreCloud->get('acli_key');
+ $output->writeln("The active key $activeKey> will be unset. You may also delete the active credentials entirely.");
+ $delete = $this->determineOption('delete', FALSE, NULL, NULL, TRUE);
$this->datastoreCloud->remove('acli_key');
-
- $output->writeln("Unset the Acquia Cloud API key for Acquia CLI");
+ if ($delete) {
+ $this->datastoreCloud->remove("keys.$activeKey");
+ $output->writeln("The active Acquia Cloud API credentials were deleted");
+ }
+ else {
+ $output->writeln("The active Acquia Cloud API credentials were unset");
+ }
return Command::SUCCESS;
}
diff --git a/src/Command/CommandBase.php b/src/Command/CommandBase.php
index 73be130d9..316e702ab 100644
--- a/src/Command/CommandBase.php
+++ b/src/Command/CommandBase.php
@@ -62,6 +62,7 @@
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Question\ChoiceQuestion;
+use Symfony\Component\Console\Question\ConfirmationQuestion;
use Symfony\Component\Console\Question\Question;
use Symfony\Component\Console\Style\SymfonyStyle;
use Symfony\Component\Console\Terminal;
@@ -1349,7 +1350,7 @@ protected function determineApiSecret(): string {
* explicitly or by default. In other words, we can't prompt for the value of
* an option that already has a default value.
*/
- protected function determineOption(string $optionName, bool $hidden = FALSE, ?Closure $validator = NULL, ?Closure $normalizer = NULL, ?string $default = NULL): string|int|null {
+ protected function determineOption(string $optionName, bool $hidden = FALSE, ?Closure $validator = NULL, ?Closure $normalizer = NULL, string|bool|null $default = NULL): string|int|bool|null {
if ($optionValue = $this->input->getOption($optionName)) {
if (isset($normalizer)) {
$optionValue = $normalizer($optionValue);
@@ -1360,18 +1361,32 @@ protected function determineOption(string $optionName, bool $hidden = FALSE, ?Cl
return $optionValue;
}
$option = $this->getDefinition()->getOption($optionName);
+ if ($option->isNegatable() && $this->input->getOption("no-$optionName")) {
+ return FALSE;
+ }
$optionShortcut = $option->getShortcut();
$description = lcfirst($option->getDescription());
if ($optionShortcut) {
- $message = "Enter $description (option -$optionShortcut>, --$optionName>)";
+ $optionString = "option -$optionShortcut>, --$optionName>";
+ }
+ else {
+ $optionString = "option --$optionName>";
+ }
+ if ($option->acceptValue()) {
+ $message = "Enter $description ($optionString)";
}
else {
- $message = "Enter $description (option --$optionName>)";
+ $message = "Do you want to $description ($optionString)?";
}
$optional = $option->isValueOptional();
$message .= $optional ? ' (optional)' : '';
$message .= $hidden ? ' (input will be hidden)' : '';
- $question = new Question($message, $default);
+ if ($option->acceptValue()) {
+ $question = new Question($message, $default);
+ }
+ else {
+ $question = new ConfirmationQuestion($message, $default);
+ }
$question->setHidden($this->localMachineHelper->useTty() && $hidden);
$question->setHiddenFallback($hidden);
if (isset($normalizer)) {
diff --git a/tests/phpunit/src/Application/KernelTest.php b/tests/phpunit/src/Application/KernelTest.php
index fc858a044..edac959cb 100644
--- a/tests/phpunit/src/Application/KernelTest.php
+++ b/tests/phpunit/src/Application/KernelTest.php
@@ -60,10 +60,10 @@ private function getEnd(): string {
archive
archive:export Export an archive of the Drupal application including code, files, and database
auth
- auth:acsf-login Register your Site Factory API key and secret to use API functionality
- auth:acsf-logout Remove your Site Factory key and secret from your local machine.
- auth:login [login] Register your Cloud API key and secret to use API functionality
- auth:logout [logout] Remove Cloud API key and secret from local machine.
+ auth:acsf-login Register Acquia Site Factory API credentials
+ auth:acsf-logout Remove Acquia Site Factory API credentials
+ auth:login [login] Register Acquia Cloud API credentials
+ auth:logout [logout] Remove Acquia Cloud API credentials
codestudio
codestudio:php-version Change the PHP version in Code Studio
codestudio:wizard [cs:wizard] Create and/or configure a new Code Studio project for a given Acquia Cloud application
diff --git a/tests/phpunit/src/Commands/Auth/AuthLogoutCommandTest.php b/tests/phpunit/src/Commands/Auth/AuthLogoutCommandTest.php
index 4f7f241a2..8f9467210 100644
--- a/tests/phpunit/src/Commands/Auth/AuthLogoutCommandTest.php
+++ b/tests/phpunit/src/Commands/Auth/AuthLogoutCommandTest.php
@@ -7,6 +7,7 @@
use Acquia\Cli\Command\Auth\AuthLogoutCommand;
use Acquia\Cli\Config\CloudDataConfig;
use Acquia\Cli\DataStore\CloudDataStore;
+use Acquia\Cli\Exception\AcquiaCliException;
use Acquia\Cli\Tests\CommandTestBase;
use Symfony\Component\Console\Command\Command;
@@ -19,36 +20,43 @@ protected function createCommand(): Command {
return $this->injectCommand(AuthLogoutCommand::class);
}
- /**
- * @return array
- */
- public function providerTestAuthLogoutCommand(): array {
- return [
- [FALSE, []],
- [
- TRUE,
- // Are you sure you'd like to remove your Cloud API login credentials from this machine?
- ['y'],
- ],
- ];
+ public function testAuthLogoutCommand(): void {
+ $this->executeCommand();
+ $output = $this->getDisplay();
+ $this->assertFileExists($this->cloudConfigFilepath);
+ $config = new CloudDataStore($this->localMachineHelper, new CloudDataConfig(), $this->cloudConfigFilepath);
+ $this->assertFalse($config->exists('acli_key'));
+ $this->assertEmpty($config->get('keys'));
+ $this->assertStringContainsString('The active Acquia Cloud API credentials were deleted', $output);
+ }
+
+ public function testAuthLogoutCommandNotAuthenticated(): void {
+ $this->clientServiceProphecy->isMachineAuthenticated()->willReturn(FALSE);
+ $this->removeMockCloudConfigFile();
+
+ $this->expectException(AcquiaCliException::class);
+ $this->expectExceptionMessage('You are not authenticated and therefore cannot logout');
+ $this->executeCommand();
+ }
+
+ public function testAuthLogoutCommandNoDeleteArg(): void {
+ $this->executeCommand(['--no-delete' => TRUE]);
+ $output = $this->getDisplay();
+ $this->assertFileExists($this->cloudConfigFilepath);
+ $config = new CloudDataStore($this->localMachineHelper, new CloudDataConfig(), $this->cloudConfigFilepath);
+ $this->assertFalse($config->exists('acli_key'));
+ $this->assertNotEmpty($config->get('keys'));
+ $this->assertStringContainsString('The active Acquia Cloud API credentials were unset', $output);
}
- /**
- * @dataProvider providerTestAuthLogoutCommand
- * @param array $inputs
- */
- public function testAuthLogoutCommand(bool $machineIsAuthenticated, array $inputs): void {
- if (!$machineIsAuthenticated) {
- $this->clientServiceProphecy->isMachineAuthenticated()->willReturn(FALSE);
- $this->removeMockCloudConfigFile();
- }
-
- $this->executeCommand([], $inputs);
+ public function testAuthLogoutCommandNoDeleteInput(): void {
+ $this->executeCommand([], ['n']);
$output = $this->getDisplay();
- // Assert creds are removed locally.
$this->assertFileExists($this->cloudConfigFilepath);
$config = new CloudDataStore($this->localMachineHelper, new CloudDataConfig(), $this->cloudConfigFilepath);
$this->assertFalse($config->exists('acli_key'));
+ $this->assertNotEmpty($config->get('keys'));
+ $this->assertStringContainsString('The active Acquia Cloud API credentials were unset', $output);
}
}