Skip to content

Commit

Permalink
Support aliases for commands
Browse files Browse the repository at this point in the history
Signed-off-by: Joas Schilling <coding@schilljs.com>
  • Loading branch information
nickvergessen committed Feb 8, 2019
1 parent 357aa54 commit 2922d5f
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 45 deletions.
14 changes: 14 additions & 0 deletions lib/Chat/Command/Executor.php
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,20 @@ public function __construct(EventDispatcherInterface $dispatcher,
}

public function exec(Room $room, IComment $message, Command $command, string $arguments): void {
try {
$command = $this->commandService->resolveAlias($command);
} catch (DoesNotExistException $e) {
$user = $message->getActorType() === 'users' ? $message->getActorId() : '';
$message->setMessage(json_encode([
'user' => $user,
'visibility' => $command->getResponse(),
'output' => $e->getMessage(),
]));
$message->setActor('bots', $command->getName());
$message->setVerb('command');
return;
}

if ($command->getApp() === '' && $command->getCommand() === 'help') {
$output = $this->execHelp($room, $message, $arguments);
} else if ($command->getApp() !== '') {
Expand Down
112 changes: 67 additions & 45 deletions lib/Service/CommandService.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,30 +58,6 @@ public function create(string $app, string $cmd, string $name, string $script, i
} catch (DoesNotExistException $e) {
}

if (preg_match('/^[a-z0-9]{1..64}$/', $cmd)) {
throw new \InvalidArgumentException('command', 1);
}

if (preg_match('/^.{1..64}$/', $name)) {
throw new \InvalidArgumentException('name', 2);
}

if ($app === '' && $cmd !== 'help') {
try {
$this->shellExecutor->execShell($script, '--help');
} catch (\InvalidArgumentException $e) {
throw new \InvalidArgumentException('script', 3);
}
}

if (!\in_array($response, [Command::RESPONSE_NONE, Command::RESPONSE_USER, Command::RESPONSE_ALL], true)) {
throw new \InvalidArgumentException('response', 4);
}

if (!\in_array($enabled, [Command::ENABLED_OFF, Command::ENABLED_MODERATOR, Command::ENABLED_USERS, Command::ENABLED_ALL], true)) {
throw new \InvalidArgumentException('enabled', 5);
}

$command = new Command();
$command->setApp($app);
$command->setCommand($cmd);
Expand All @@ -90,6 +66,8 @@ public function create(string $app, string $cmd, string $name, string $script, i
$command->setResponse($response);
$command->setEnabled($enabled);

$this->validateCommand($command);

return $this->mapper->insert($command);
}

Expand Down Expand Up @@ -123,48 +101,92 @@ public function update(int $id, string $cmd, string $name, string $script, int $
throw new \InvalidArgumentException('app', 0);
}

if (preg_match('/^[a-z0-9]{1..64}$/', $cmd)) {
$command->setName($name);
$command->setScript($script);
$command->setResponse($response);
$command->setEnabled($enabled);

if ($cmd !== $command->getCommand()) {
try {
$this->mapper->find('', $cmd);
throw new \InvalidArgumentException('command', 1);
} catch (DoesNotExistException $e) {
$command->setCommand($cmd);
}
}

$this->validateCommand($command);

return $this->mapper->update($command);
}

/**
* @param Command $command
* @throws \InvalidArgumentException
*/
protected function validateCommand(Command $command): void {
if (preg_match('/^[a-z0-9]{1..64}$/', $command->getCommand())) {
throw new \InvalidArgumentException('command', 1);
}

if (preg_match('/^.{1..64}$/', $name)) {
if (preg_match('/^.{1..64}$/', $command->getName())) {
throw new \InvalidArgumentException('name', 2);
}

if ($command->getApp() === '') {
try {
$this->shellExecutor->execShell($script, '--help');
} catch (\InvalidArgumentException $e) {
throw new \InvalidArgumentException('script', 3);
$script = $command->getScript();
if (strpos($script, 'alias:') === 0) {
try {
$this->resolveAlias($command);
} catch (DoesNotExistException $e) {
throw new \InvalidArgumentException('script', 3);
}
} else {
try {
$this->shellExecutor->execShell($script, '--help');
} catch (\InvalidArgumentException $e) {
throw new \InvalidArgumentException('script', 3);
}
}
}

if (!\in_array($response, [Command::RESPONSE_NONE, Command::RESPONSE_USER, Command::RESPONSE_ALL], true)) {
if (!\in_array($command->getResponse(), [Command::RESPONSE_NONE, Command::RESPONSE_USER, Command::RESPONSE_ALL], true)) {
throw new \InvalidArgumentException('response', 4);
}

if (!\in_array($enabled, [Command::ENABLED_OFF, Command::ENABLED_MODERATOR, Command::ENABLED_USERS, Command::ENABLED_ALL], true)) {
if (!\in_array($command->getEnabled(), [Command::ENABLED_OFF, Command::ENABLED_MODERATOR, Command::ENABLED_USERS, Command::ENABLED_ALL], true)) {
throw new \InvalidArgumentException('enabled', 5);
}
}

/**
* @param Command $command
* @return Command
* @throws DoesNotExistException
*/
public function resolveAlias(Command $command): Command {
$script = $command->getScript();
if (strpos($script, 'alias:') === 0) {
$alias = explode(':', $script, 3);
if (isset($alias[2])) {
[, $app, $cmd] = $alias;
} else {
$app = '';
$cmd = $alias[1];
}

if ($app === $command->getApp() && $cmd === $command->getCommand()) {
throw new DoesNotExistException('The command is an alias for itself');
}

if ($cmd !== $command->getCommand()) {
try {
$this->mapper->find('', $cmd);
throw new \InvalidArgumentException('command', 1);
return $this->find($app, $cmd);
} catch (DoesNotExistException $e) {
$command->setCommand($cmd);
throw new DoesNotExistException('The command for ' . $command->getCommand() . ' does not exist');
}
}

// FIXME Validate "bot name"
$command->setName($name);
// FIXME Validate "script"
$command->setScript($script);

$command->setResponse($response);
$command->setEnabled($enabled);

return $this->mapper->update($command);
return $command;
}

/**
Expand Down

0 comments on commit 2922d5f

Please sign in to comment.