setName(self::ROUTE) ->setDescription('View Backends settings.') ->addOption('select-backends', 's', InputOption::VALUE_REQUIRED, 'Select backends. comma , seperated.') ->addOption('exclude', null, InputOption::VALUE_NONE, 'Inverse --select-backends logic.') ->addOption('expose', 'x', InputOption::VALUE_NONE, 'Expose the secret tokens in the view.') ->addArgument( 'filter', InputArgument::OPTIONAL, 'Can be any key from servers.yaml, use dot notion to access sub keys, for example [webhook.token]' ) ->setHelp( r( <<[ FAQ ] ------- # How to show one backend information? The flag [-s, --select-backends] accept comma seperated list of backends name, Using the flag in combination with [--exclude] flag will flip the logic to exclude the selected backends rather than include them. {cmd} {route} --select-backends my_backend # How to show specific key? The key can be any value that already exists in the list. to access sub-keys use dot notation for example, To see if the value of import.enabled you would run: {cmd} {route} -- import.enabled HELP, [ 'cmd' => trim(commandContext()), 'route' => self::ROUTE, ] ) ); } /** * Run the command. * * @param InputInterface $input The input object. * @param OutputInterface $output The output object. * * @return int The exit code. */ protected function runCommand(InputInterface $input, OutputInterface $output): int { $selectBackends = (string)$input->getOption('select-backends'); $list = []; $selected = array_map('trim', explode(',', $selectBackends)); $isCustom = !empty($selectBackends) && count($selected) >= 1; $filter = $input->getArgument('filter'); foreach (Config::get('servers', []) as $backendName => $backend) { if ($isCustom && $input->getOption('exclude') === in_array($backendName, $selected)) { $output->writeln(r('Ignoring backend \'{backend}\' as requested by [-s, --select-backends].', [ 'backend' => $backendName ]), OutputInterface::VERBOSITY_VERY_VERBOSE); continue; } $list[$backendName] = ['name' => $backendName, ...$backend]; } if (empty($list)) { throw new RuntimeException( $isCustom ? '[-s, --select-backends] did not return any backend.' : 'No backends were found.' ); } $x = 0; $count = count($list); $rows = []; foreach ($list as $backendName => $backend) { $x++; $rows[] = [ $backendName, $this->filterData($backend, $filter, $input->getOption('expose')) ]; if ($x < $count) { $rows[] = new TableSeparator(); } } $mode = $input->getOption('output'); if ('table' === $mode) { (new Table($output))->setStyle('box') ->setHeaders(['Backend', 'Data (Filter: ' . (empty($filter) ? 'None' : $filter) . ')'] )->setRows($rows) ->render(); } else { $this->displayContent($list, $output, $mode); } return self::SUCCESS; } /** * Completes the suggestion for filter input. * * @param CompletionInput $input The input for completion. * @param CompletionSuggestions $suggestions The completion suggestions. */ public function complete(CompletionInput $input, CompletionSuggestions $suggestions): void { parent::complete($input, $suggestions); if ($input->mustSuggestArgumentValuesFor('filter')) { $currentValue = $input->getCompletionValue(); $suggest = []; foreach (require __DIR__ . '/../../../config/backend.spec.php' as $name => $val) { if (true === $val && (empty($currentValue) || str_starts_with($name, $currentValue))) { $suggest[] = $name; } } $suggestions->suggestValues($suggest); } } /** * Filters the given backend data based on the provided filter and expose parameters. * * @param array $backend The backend data to filter. * @param string|null $filter The filter criteria. * @param bool $expose Whether to expose hidden values or not. * * @return string The filtered data in YAML format. */ private function filterData(array $backend, string|null $filter = null, bool $expose = false): string { if (null === $filter && true !== $expose) { foreach ($this->hidden as $hideValue) { if (true === ag_exists($backend, $hideValue)) { $backend = ag_set($backend, $hideValue, '*HIDDEN*'); } } } if (null === $filter || false === str_contains($filter, ',')) { return trim(Yaml::dump(ag($backend, $filter, 'Not configured, or invalid key.'), 8, 2)); } $filters = array_map(fn($val) => trim($val), explode(',', $filter)); $list = []; foreach ($filters as $fil) { $list[$fil] = ag($backend, $fil, 'Not configured, or invalid key.'); } return trim(Yaml::dump($list, 8, 2)); } }