Skip to content

Commit

Permalink
Fixes #435: Users are confused with api sub-commands. (acquia#449)
Browse files Browse the repository at this point in the history
* Fixes #435: Users are confused with api sub-commands.

* Make base class abstract.

* Add tests.

* Fix services.

* Fix namespace leak.
  • Loading branch information
grasmash authored Mar 2, 2021
1 parent efa1952 commit 8d03cc7
Show file tree
Hide file tree
Showing 6 changed files with 125 additions and 31 deletions.
4 changes: 2 additions & 2 deletions config/services.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,15 @@ services:

# Register nearly all Acquia CLI classes as services.
Acquia\Cli\:
exclude: [../src/Kernel.php, ../src/Command/Api/ApiCommandBase.php, ../src/DataStore/YamlStore.php]
exclude: [../src/Kernel.php, ../src/Command/Api/ApiCommandBase.php, ../src/Command/Api/ApiListCommandBase.php, ../src/DataStore/YamlStore.php]
public: true
resource: ../src

# All commands inherit from a common base and use the same DI parameters.
Acquia\Cli\Command\:
resource: ../src/Command
parent: Acquia\Cli\Command\CommandBase
exclude: [../src/Command/CommandBase.php, ../src/Command/Api/ApiCommandBase.php]
exclude: [../src/Command/CommandBase.php, ../src/Command/Api/ApiCommandBase.php, ../src/Command/Api/ApiListCommandBase.php]
Acquia\Cli\Command\CommandBase:
abstract: true

Expand Down
38 changes: 36 additions & 2 deletions src/Command/Api/ApiCommandHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Acquia\Cli\Command\Api;

use Acquia\Cli\Command\ListCommand;
use Acquia\Cli\DataStore\YamlStore;
use Acquia\Cli\Helpers\ClientService;
use Acquia\Cli\Helpers\CloudCredentials;
Expand Down Expand Up @@ -151,8 +152,11 @@ protected static function getCommandCache(): PhpArrayAdapter {
*/
public function getApiCommands(): array {
$acquia_cloud_spec = $this->getCloudApiSpec();
$api_commands = $this->generateApiCommandsFromSpec($acquia_cloud_spec);
$api_list_commands = $this->generateApiListCommands($api_commands);
$commands = array_merge($api_commands, $api_list_commands);

return $this->generateApiCommandsFromSpec($acquia_cloud_spec);
return $commands;
}

/**
Expand Down Expand Up @@ -466,7 +470,7 @@ protected function getCloudApiSpec(): array {
/**
* @param array $acquia_cloud_spec
*
* @return array
* @return ApiCommandBase[]
*/
protected function generateApiCommandsFromSpec(array $acquia_cloud_spec): array {
$api_commands = [];
Expand Down Expand Up @@ -647,4 +651,34 @@ public static function restoreRenamedParameter($prop_key) {
return $prop_key;
}

/**
* @param array $api_commands
*
* @return ApiListCommandBase[]
*/
protected function generateApiListCommands(array $api_commands): array {
$api_list_commands = [];
foreach ($api_commands as $api_command) {
$command_name_parts = explode(':', $api_command->getName());
if (count($command_name_parts) < 3) {
continue;
}
$namespace = $command_name_parts[1];
if (!array_key_exists($namespace, $api_list_commands)) {
$command = new ApiListCommandBase($this->cloudConfigFilepath,
$this->localMachineHelper, $this->datastoreCloud,
$this->datastoreAcli, $this->cloudCredentials, $this->telemetryHelper,
$this->acliConfigFilepath, $this->repoRoot,
$this->cloudApiClientService, $this->logstreamManager,
$this->sshHelper, $this->sshDir);
$name = 'api:' . $namespace;
$command->setName($name);
$command->setNamespace($name);
$command->setDescription("List all API commands for the {$namespace} resource");
$api_list_commands[$name] = $command;
}
}
return $api_list_commands;
}

}
17 changes: 8 additions & 9 deletions src/Command/Api/ApiListCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,34 +10,33 @@
/**
*
*/
class ApiListCommand extends CommandBase {
class ApiListCommand extends ApiListCommandBase {

protected static $defaultName = 'api:list';

/**
* {inheritdoc}.
*/
protected function configure() {
$this->setDescription("<fg=cyan>There are more hidden API commands! Run api:list to see them all.</>")
$this->setDescription("List all API commands")
->setAliases(['api']);
}

public function initialize(InputInterface $input, OutputInterface $output) {
parent::initialize($input, $output);
$this->namespace = 'api';
}

/**
* {@inheritdoc}
*
* @throws \Exception
*/
protected function execute(InputInterface $input, OutputInterface $output) {
// Un-hide api:* commands.
$api_commands = $this->getApplication()->all('api');
foreach ($api_commands as $api_command) {
$api_command->setHidden(FALSE);
}

$command = $this->getApplication()->find('list');
$arguments = [
'command' => 'list',
'namespace' => 'api',
'namespace' => $this->namespace,
];
$list_input = new ArrayInput($arguments);

Expand Down
55 changes: 55 additions & 0 deletions src/Command/Api/ApiListCommandBase.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<?php

namespace Acquia\Cli\Command\Api;

use Acquia\Cli\Command\CommandBase;
use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

/**
*
*/
class ApiListCommandBase extends CommandBase {

/**
* @var string
*/
protected $namespace;

/**
* @param string $namespace
*/
public function setNamespace(string $namespace): void {
$this->namespace = $namespace;
}

/**
* {@inheritdoc}
*
* @throws \Exception
*/
protected function execute(InputInterface $input, OutputInterface $output) {
$commands = $this->getApplication()->all();
foreach ($commands as $command) {
if ($command->getName() !== $this->namespace
&& strpos($command->getName(), $this->namespace . ':') !== FALSE
) {
$command->setHidden(FALSE);
}
else {
$command->setHidden(TRUE);
}
}

$command = $this->getApplication()->find('list');
$arguments = [
'command' => 'list',
'namespace' => 'api',
];
$list_input = new ArrayInput($arguments);

return $command->run($list_input, $output);
}

}
23 changes: 5 additions & 18 deletions src/Command/ListCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Acquia\Cli\Command;

use Acquia\Cli\Command\Api\ApiListCommandBase;
use Symfony\Component\Console\Helper\DescriptorHelper;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
Expand All @@ -18,10 +19,10 @@ protected function execute(InputInterface $input, OutputInterface $output) {
if ($input->getArgument('namespace') !== 'api') {
$all_commands = $this->getApplication()->all();
foreach ($all_commands as $command) {
if (strpos($command->getName(), 'api:') !== FALSE && $command->getName() !== 'api:list') {
if (!in_array($command->getName(), $this->getUnhiddenApiCommands(), TRUE)) {
$command->setHidden(TRUE);
}
if (!is_a($command, ApiListCommandBase::class)
&& strpos($command->getName(), 'api:') !== FALSE
) {
$command->setHidden(TRUE);
}
}
}
Expand All @@ -36,18 +37,4 @@ protected function execute(InputInterface $input, OutputInterface $output) {
return 0;
}

/**
* Show a few of the api commands! Give people a sense of what's there.
*
* @return array
*/
protected function getUnhiddenApiCommands(): array {
return [
'api:accounts:find',
'api:environments:code-deploy',
'api:environments:database-backup-create',
'api:environments:domain-clear-varnish',
];
}

}
19 changes: 19 additions & 0 deletions tests/phpunit/src/Commands/Api/ApiListCommandTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use Acquia\Cli\Command\Api\ApiCommandHelper;
use Acquia\Cli\Command\Api\ApiListCommand;
use Acquia\Cli\Command\Api\ApiListCommandBase;
use Acquia\Cli\Command\ListCommand;
use Acquia\Cli\Tests\CommandTestBase;
use Symfony\Component\Console\Command\Command;
Expand Down Expand Up @@ -47,6 +48,23 @@ public function testApiListCommand(): void {
$this->assertStringContainsString(' api:accounts:ssh-keys-list', $output);
}

/**
* Tests the 'api:*' list commands.
*
* @throws \Exception
*/
public function testApiNamespaceListCommand(): void {
$this->command = $this->injectCommand(ApiListCommandBase::class);
$name = 'api:accounts';
$this->command->setName($name);
$this->command->setNamespace($name);
$this->executeCommand();
$output = $this->getDisplay();
$this->assertStringContainsString('api:accounts:', $output);
$this->assertStringContainsString('api:accounts:ssh-keys-list', $output);
$this->assertStringNotContainsString('api:subscriptions', $output);
}

/**
* Tests the 'list' command.
*
Expand All @@ -56,6 +74,7 @@ public function testListCommand(): void {
$this->command = $this->injectCommand(ListCommand::class);
$this->executeCommand();
$output = $this->getDisplay();
$this->assertStringContainsString(' api:accounts', $output);
$this->assertStringNotContainsString(' api:accounts:ssh-keys-list', $output);
}

Expand Down

0 comments on commit 8d03cc7

Please sign in to comment.