Tweak commands
This commit is contained in:
@ -22,7 +22,7 @@
|
||||
"repositories": {
|
||||
"slotdb-client": {
|
||||
"type": "vcs",
|
||||
"url": "../slotdb-client-php"
|
||||
"url": "git@dev.noccylabs.info:slotdb/slotdb-client-php.git"
|
||||
}
|
||||
},
|
||||
"bin": [
|
||||
|
8
composer.lock
generated
8
composer.lock
generated
@ -4,7 +4,7 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "9dc3a3ca30d0b0d1698b2e4e26577e67",
|
||||
"content-hash": "8140c4572894cc393ef74de8ad3fe56c",
|
||||
"packages": [
|
||||
{
|
||||
"name": "guzzlehttp/guzzle",
|
||||
@ -593,8 +593,8 @@
|
||||
"version": "dev-master",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "../slotdb-client-php",
|
||||
"reference": "4734ca5fe4ed02da5bc3e0df3c9ecbabc3474af3"
|
||||
"url": "git@dev.noccylabs.info:slotdb/slotdb-client-php.git",
|
||||
"reference": "e6e1e980eaa9500fc38bfd22dfdc23ca13258ad3"
|
||||
},
|
||||
"require": {
|
||||
"psr/http-client": "^1.0"
|
||||
@ -620,7 +620,7 @@
|
||||
}
|
||||
],
|
||||
"description": "SlotDB PHP Client",
|
||||
"time": "2025-03-14T14:34:28+00:00"
|
||||
"time": "2025-03-15T13:25:21+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/console",
|
||||
|
@ -16,8 +16,8 @@ class Application extends \Symfony\Component\Console\Application
|
||||
$psr = new Client();
|
||||
$client = new SlotDbClient($psr, $baseUrl);
|
||||
|
||||
$this->add(new Command\ImportCommand());
|
||||
$this->add(new Command\ExportCommand());
|
||||
$this->add(new Command\ImportCommand($client));
|
||||
$this->add(new Command\ExportCommand($client));
|
||||
|
||||
$this->add(new Command\Slot\SlotCreateCommand($client));
|
||||
$this->add(new Command\Slot\SlotQueryCommand($client));
|
||||
|
@ -2,10 +2,73 @@
|
||||
|
||||
namespace SlotDb\Cli\Command;
|
||||
|
||||
use SlotDb\Client\SlotDbClient;
|
||||
use Symfony\Component\Console\Attribute\AsCommand;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
#[AsCommand(name:"export", description:"Export the database to a file")]
|
||||
class ExportCommand extends BaseCommand
|
||||
{
|
||||
public function __construct(
|
||||
private readonly SlotDbClient $client
|
||||
)
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
protected function configure()
|
||||
{
|
||||
$this->addOption("all-props", "A", InputOption::VALUE_NONE, "Include all slot properties. If not specified, properties that match the group property will be stripped.");
|
||||
$this->addOption("output", "o", InputOption::VALUE_REQUIRED, "Write to file instead of standard output");
|
||||
}
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output): int
|
||||
{
|
||||
// TODO implement paging
|
||||
|
||||
$groups = $this->client->findGroups();
|
||||
$indexedGroups = array_combine(
|
||||
array_map(fn($group) => $group['_group'], $groups),
|
||||
array_values($groups)
|
||||
);
|
||||
|
||||
$slots = $this->client->findSlots();
|
||||
if (!$input->getOption("all-props")) {
|
||||
foreach ($slots as &$slot) {
|
||||
if ($slot['_group'] && isset($indexedGroups[$slot['_group']])) {
|
||||
$group = $indexedGroups[$slot['_group']];
|
||||
foreach ($slot as $k=>$v) {
|
||||
if (str_starts_with($k,"_")) continue;
|
||||
if (isset($group[$k]) && $group[$k] == $v) {
|
||||
unset($slot[$k]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$export = json_encode([
|
||||
'comment' => "This is an exported SlotDB database.",
|
||||
'timestamp' => date('Y-m-d H:i:s P'),
|
||||
'generator' => "SlotCLI v".APP_VERSION." (".APP_BUILT.")",
|
||||
'export' => [
|
||||
'schemas' => [],
|
||||
'hooks' => [],
|
||||
'groups' => $groups,
|
||||
'slots' => $slots,
|
||||
],
|
||||
], JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES);
|
||||
|
||||
if ($input->getOption("output")) {
|
||||
$file = $input->getOption("output");
|
||||
file_put_contents($file, $export."\n");
|
||||
} else {
|
||||
$output->writeln($export);
|
||||
}
|
||||
|
||||
return self::SUCCESS;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -42,8 +42,14 @@ class GroupFindCommand extends Command
|
||||
foreach ($groups as $group) {
|
||||
$row = [];
|
||||
foreach ($keys as $key) {
|
||||
$row[] = isset($group[$key]) ? json_encode($group[$key]) : null;
|
||||
$row[] = isset($group[$key]) ? $group[$key] : null;
|
||||
}
|
||||
$row = array_map(fn($v) => match(true) {
|
||||
is_bool($v) => "<fg=magenta>".($v?"true":"false")."</>",
|
||||
is_int($v) => "<fg=cyan>{$v}</>",
|
||||
is_string($v) => "<fg=yellow>{$v}</>",
|
||||
default => $v,
|
||||
}, $row);
|
||||
$table->addRow($row);
|
||||
}
|
||||
|
||||
|
@ -32,7 +32,7 @@ class GroupQueryCommand extends Command
|
||||
try {
|
||||
$group = $this->client->queryGroup($groupId);
|
||||
} catch (\RuntimeException $e) {
|
||||
$output->writeln("<error>Invalid group id: {$slotId}</>");
|
||||
$output->writeln("<error>Invalid group id: {$groupId}</>");
|
||||
return self::INVALID;
|
||||
}
|
||||
|
||||
|
@ -2,10 +2,68 @@
|
||||
|
||||
namespace SlotDb\Cli\Command;
|
||||
|
||||
use SlotDb\Client\SlotDbClient;
|
||||
use Symfony\Component\Console\Attribute\AsCommand;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\Console\Style\SymfonyStyle;
|
||||
|
||||
#[AsCommand(name:"import", description:"Import database from file")]
|
||||
class ImportCommand extends BaseCommand
|
||||
{
|
||||
public function __construct(
|
||||
private readonly SlotDbClient $client
|
||||
)
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
protected function configure()
|
||||
{
|
||||
$this->addOption("hard-reset", "R", InputOption::VALUE_NONE, "Completely wipe the database before importing the new data.");
|
||||
$this->addArgument("filename", InputArgument::OPTIONAL, "Filename to read from, if omitted read standard input.");
|
||||
$this->addOption("assume-yes", "y", InputOption::VALUE_NONE, "Assume yes on all questions.");
|
||||
}
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output): int
|
||||
{
|
||||
if ($input->getArgument("filename")) {
|
||||
$file = $input->getArgument("filename");
|
||||
$json = file_get_contents($file);
|
||||
} else {
|
||||
$json = stream_get_contents(STDIN);
|
||||
}
|
||||
|
||||
$export = json_decode($json);
|
||||
|
||||
$output->writeln("File was generated <fg=yellow>{$export->timestamp}</>");
|
||||
$output->writeln("Generated using <fg=yellow>{$export->generator}</>");
|
||||
$output->writeln("");
|
||||
if (!$input->getOption("assume-yes")) {
|
||||
$confirm = (new SymfonyStyle($input, $output))->confirm("Do you want to continue", false);
|
||||
if (!$confirm) {
|
||||
return self::FAILURE;
|
||||
}
|
||||
$output->writeln("");
|
||||
}
|
||||
|
||||
$output->writeln("+ <options=bold>Importing schemas...</>");
|
||||
|
||||
$output->writeln("+ <options=bold>Importing hooks...</>");
|
||||
|
||||
$output->writeln("+ <options=bold>Importing groups...</>");
|
||||
foreach ($export->export->groups as $group) {
|
||||
$output->writeln(" - <fg=green>".$group->_group."</>");
|
||||
}
|
||||
|
||||
$output->writeln("+ <options=bold>Importing slots...</>");
|
||||
foreach ($export->export->slots as $slot) {
|
||||
$output->writeln(" - <fg=green>".$slot->_slot."</>");
|
||||
}
|
||||
|
||||
return self::SUCCESS;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ class SlotCreateCommand extends Command
|
||||
protected function configure()
|
||||
{
|
||||
$this
|
||||
->addOption("name", "n", InputOption::VALUE_REQUIRED, "Set slot name")
|
||||
->addOption("name", "N", InputOption::VALUE_REQUIRED, "Set slot name")
|
||||
->addArgument("slot", InputArgument::REQUIRED, "Slot ID")
|
||||
->addArgument("properties", InputArgument::IS_ARRAY, "Properties to assign to the slot")
|
||||
;
|
||||
@ -32,8 +32,25 @@ class SlotCreateCommand extends Command
|
||||
protected function execute(InputInterface $input, OutputInterface $output): int
|
||||
{
|
||||
|
||||
// $slotId = $input->getArgument("slot");
|
||||
// $slot = $this->client->querySlot($slotId);
|
||||
$slotId = $input->getArgument("slot");
|
||||
$slotName = $input->getOption("name") ?? $slotId;
|
||||
|
||||
$props = [];
|
||||
foreach ($input->getArgument("properties") as $prop) {
|
||||
if (!str_contains($prop, '=')) {
|
||||
$output->writeln("<error>Invalid property \"{$prop}\", should be in the form of key=value.</>");
|
||||
return self::INVALID;
|
||||
}
|
||||
[$k, $v] = explode("=", $prop, 2);
|
||||
$props[$k] = match ($v) {
|
||||
'true','false','null' => json_decode($v),
|
||||
default => json_decode($v) ?? $v,
|
||||
};
|
||||
}
|
||||
|
||||
$slot = $this->client->createSlot($slotId, $slotName, $props);
|
||||
|
||||
var_dump($slot);
|
||||
|
||||
return self::SUCCESS;
|
||||
}
|
||||
|
@ -55,8 +55,14 @@ class SlotFindCommand extends Command
|
||||
foreach ($slots as $slot) {
|
||||
$row = [];
|
||||
foreach ($keys as $key) {
|
||||
$row[] = isset($slot[$key]) ? json_encode($slot[$key]) : null;
|
||||
$row[] = isset($slot[$key]) ? $slot[$key] : null;
|
||||
}
|
||||
$row = array_map(fn($v) => match(true) {
|
||||
is_bool($v) => "<fg=magenta>".($v?"true":"false")."</>",
|
||||
is_int($v) => "<fg=cyan>{$v}</>",
|
||||
is_string($v) => "<fg=yellow>{$v}</>",
|
||||
default => $v,
|
||||
}, $row);
|
||||
$table->addRow($row);
|
||||
}
|
||||
|
||||
|
@ -2,6 +2,12 @@
|
||||
|
||||
require_once __DIR__."/../vendor/autoload.php";
|
||||
|
||||
$buildInfo = (file_exists(__DIR__."/build.php"))
|
||||
? include __DIR__."/build.php"
|
||||
: [ 'version' => '0.0.0', 'builddate' => 'never' ];
|
||||
define("APP_VERSION", $buildInfo['version']);
|
||||
define("APP_BUILT", $buildInfo['builddate']);
|
||||
|
||||
$app = new SlotDb\Cli\Application();
|
||||
|
||||
$app->run();
|
||||
|
Reference in New Issue
Block a user