Skip to content

Commit

Permalink
Add Valkey support
Browse files Browse the repository at this point in the history
  • Loading branch information
pjcdawkins committed Jan 7, 2025
1 parent fadf626 commit fc38278
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 71 deletions.
75 changes: 4 additions & 71 deletions src/Command/Service/RedisCliCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,79 +4,12 @@

namespace Platformsh\Cli\Command\Service;

use Platformsh\Cli\Selector\SelectorConfig;
use Platformsh\Cli\Service\Io;
use Platformsh\Cli\Selector\Selector;
use Platformsh\Cli\Command\CommandBase;
use Platformsh\Cli\Model\Host\RemoteHost;
use Platformsh\Cli\Service\Relationships;
use Platformsh\Cli\Service\Ssh;
use Platformsh\Cli\Util\OsUtil;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

#[AsCommand(name: 'service:redis-cli', description: 'Access the Redis CLI', aliases: ['redis'])]
class RedisCliCommand extends CommandBase
class RedisCliCommand extends ValkeyCliCommandBase
{
public function __construct(private readonly Io $io, private readonly Relationships $relationships, private readonly Selector $selector)
{
parent::__construct();
}
protected function configure(): void
{
$this->addArgument('args', InputArgument::OPTIONAL | InputArgument::IS_ARRAY, 'Arguments to add to the Redis command');
Relationships::configureInput($this->getDefinition());
Ssh::configureInput($this->getDefinition());
$this->selector->addProjectOption($this->getDefinition());
$this->selector->addEnvironmentOption($this->getDefinition());
$this->selector->addAppOption($this->getDefinition());
$this->addCompleter($this->selector);
$this->addExample('Open the redis-cli shell');
$this->addExample('Ping the Redis server', 'ping');
$this->addExample('Show Redis status information', 'info');
$this->addExample('Scan keys', "-- --scan");
$this->addExample('Scan keys matching a pattern', '-- "--scan --pattern \'*-11*\'"');
}

protected function execute(InputInterface $input, OutputInterface $output): int
{
if ($this->runningViaMulti && !$input->getArgument('args')) {
throw new \RuntimeException('The redis-cli command cannot run as a shell via multi');
}

$selection = $this->selector->getSelection($input, new SelectorConfig(
allowLocalHost: $this->relationships->hasLocalEnvVar(),
chooseEnvFilter: SelectorConfig::filterEnvsMaybeActive(),
));
$host = $this->selector->getHostFromSelection($input, $selection);

$service = $this->relationships->chooseService($host, $input, $output, ['redis']);
if (!$service) {
return 1;
}

$redisCommand = sprintf(
'redis-cli -h %s -p %d',
OsUtil::escapePosixShellArg($service['host']),
$service['port'],
);
if ($args = $input->getArgument('args')) {
if (count($args) === 1) {
$redisCommand .= ' ' . $args[0];
} else {
$redisCommand .= ' ' . implode(' ', array_map(OsUtil::escapePosixShellArg(...), $args));
}
} elseif ($this->io->isTerminal(STDIN) && $host instanceof RemoteHost) {
// Force TTY output when the input is a terminal.
$host->setExtraSshOptions(['RequestTTY yes']);
}

$this->stdErr->writeln(
sprintf('Connecting to Redis service via relationship <info>%s</info> on <info>%s</info>', $service['_relationship_name'], $host->getLabel()),
);

return $host->runCommandDirect($redisCommand);
}
protected string $dbName = 'redis';
protected string $dbTitle = 'Redis';
protected string $dbCommand = 'redis-cli';
}
10 changes: 10 additions & 0 deletions src/Command/Service/ValkeyCliCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

declare(strict_types=1);

namespace Platformsh\Cli\Command\Service;

use Symfony\Component\Console\Attribute\AsCommand;

#[AsCommand(name: 'service:valkey-cli', description: 'Access the Valkey CLI', aliases: ['valkey'])]
class ValkeyCliCommand extends ValkeyCliCommandBase {}
85 changes: 85 additions & 0 deletions src/Command/Service/ValkeyCliCommandBase.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
<?php

declare(strict_types=1);

namespace Platformsh\Cli\Command\Service;

use Platformsh\Cli\Selector\SelectorConfig;
use Platformsh\Cli\Service\Io;
use Platformsh\Cli\Selector\Selector;
use Platformsh\Cli\Command\CommandBase;
use Platformsh\Cli\Model\Host\RemoteHost;
use Platformsh\Cli\Service\Relationships;
use Platformsh\Cli\Service\Ssh;
use Platformsh\Cli\Util\OsUtil;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

abstract class ValkeyCliCommandBase extends CommandBase
{
protected string $dbName = 'valkey';
protected string $dbTitle = 'valkey';
protected string $dbCommand = 'valkey-cli';

public function __construct(private readonly Io $io, private readonly Relationships $relationships, private readonly Selector $selector)
{
parent::__construct();
}
protected function configure(): void
{
$this->addArgument('args', InputArgument::OPTIONAL | InputArgument::IS_ARRAY, sprintf('Arguments to add to the %s command', $this->dbCommand));
Relationships::configureInput($this->getDefinition());
Ssh::configureInput($this->getDefinition());
$this->selector->addProjectOption($this->getDefinition());
$this->selector->addEnvironmentOption($this->getDefinition());
$this->selector->addAppOption($this->getDefinition());
$this->addCompleter($this->selector);
$this->addExample(sprintf('Open the %s shell', $this->dbCommand));
$this->addExample(sprintf('Ping the %s server', $this->dbTitle), 'ping');
$this->addExample(sprintf('Show %s status information', $this->dbTitle), 'info');
$this->addExample('Scan keys', "-- --scan");
$this->addExample('Scan keys matching a pattern', '-- "--scan --pattern \'*-11*\'"');
}

protected function execute(InputInterface $input, OutputInterface $output): int
{
if ($this->runningViaMulti && !$input->getArgument('args')) {
throw new \RuntimeException(sprintf('The %s command cannot run as a shell via multi', $this->dbCommand));
}

$selection = $this->selector->getSelection($input, new SelectorConfig(
allowLocalHost: $this->relationships->hasLocalEnvVar(),
chooseEnvFilter: SelectorConfig::filterEnvsMaybeActive(),
));
$host = $this->selector->getHostFromSelection($input, $selection);

$service = $this->relationships->chooseService($host, $input, $output, [$this->dbName]);
if (!$service) {
return 1;
}

$command = sprintf(
'%s -h %s -p %d',
$this->dbCommand,
OsUtil::escapePosixShellArg($service['host']),
$service['port'],
);
if ($args = $input->getArgument('args')) {
if (count($args) === 1) {
$command .= ' ' . $args[0];
} else {
$command .= ' ' . implode(' ', array_map(OsUtil::escapePosixShellArg(...), $args));
}
} elseif ($this->io->isTerminal(STDIN) && $host instanceof RemoteHost) {
// Force TTY output when the input is a terminal.
$host->setExtraSshOptions(['RequestTTY yes']);
}

$this->stdErr->writeln(
sprintf('Connecting to %s service via relationship <info>%s</info> on <info>%s</info>', $this->dbTitle, $service['_relationship_name'], $host->getLabel()),
);

return $host->runCommandDirect($command);
}
}

0 comments on commit fc38278

Please sign in to comment.