Command.php
1 year ago
CompleteCommand.php
1 year ago
DumpCompletionCommand.php
2 years ago
HelpCommand.php
2 years ago
LazyCommand.php
1 year ago
ListCommand.php
2 years ago
LockableTrait.php
1 year ago
SignalableCommandInterface.php
2 years ago
DumpCompletionCommand.php
124 lines
| 1 | <?php |
| 2 | |
| 3 | /* |
| 4 | * This file is part of the Symfony package. |
| 5 | * |
| 6 | * (c) Fabien Potencier <fabien@symfony.com> |
| 7 | * |
| 8 | * For the full copyright and license information, please view the LICENSE |
| 9 | * file that was distributed with this source code. |
| 10 | */ |
| 11 | namespace Matomo\Dependencies\Symfony\Component\Console\Command; |
| 12 | |
| 13 | use Matomo\Dependencies\Symfony\Component\Console\Completion\CompletionInput; |
| 14 | use Matomo\Dependencies\Symfony\Component\Console\Completion\CompletionSuggestions; |
| 15 | use Matomo\Dependencies\Symfony\Component\Console\Input\InputArgument; |
| 16 | use Matomo\Dependencies\Symfony\Component\Console\Input\InputInterface; |
| 17 | use Matomo\Dependencies\Symfony\Component\Console\Input\InputOption; |
| 18 | use Matomo\Dependencies\Symfony\Component\Console\Output\ConsoleOutputInterface; |
| 19 | use Matomo\Dependencies\Symfony\Component\Console\Output\OutputInterface; |
| 20 | use Symfony\Component\Process\Process; |
| 21 | /** |
| 22 | * Dumps the completion script for the current shell. |
| 23 | * |
| 24 | * @author Wouter de Jong <wouter@wouterj.nl> |
| 25 | */ |
| 26 | final class DumpCompletionCommand extends Command |
| 27 | { |
| 28 | protected static $defaultName = 'completion'; |
| 29 | protected static $defaultDescription = 'Dump the shell completion script'; |
| 30 | public function complete(CompletionInput $input, CompletionSuggestions $suggestions) : void |
| 31 | { |
| 32 | if ($input->mustSuggestArgumentValuesFor('shell')) { |
| 33 | $suggestions->suggestValues($this->getSupportedShells()); |
| 34 | } |
| 35 | } |
| 36 | protected function configure() |
| 37 | { |
| 38 | $fullCommand = $_SERVER['PHP_SELF']; |
| 39 | $commandName = basename($fullCommand); |
| 40 | $fullCommand = @realpath($fullCommand) ?: $fullCommand; |
| 41 | $this->setHelp(<<<EOH |
| 42 | The <info>%command.name%</> command dumps the shell completion script required |
| 43 | to use shell autocompletion (currently only bash completion is supported). |
| 44 | |
| 45 | <comment>Static installation |
| 46 | -------------------</> |
| 47 | |
| 48 | Dump the script to a global completion file and restart your shell: |
| 49 | |
| 50 | <info>%command.full_name% bash | sudo tee /etc/bash_completion.d/{$commandName}</> |
| 51 | |
| 52 | Or dump the script to a local file and source it: |
| 53 | |
| 54 | <info>%command.full_name% bash > completion.sh</> |
| 55 | |
| 56 | <comment># source the file whenever you use the project</> |
| 57 | <info>source completion.sh</> |
| 58 | |
| 59 | <comment># or add this line at the end of your "~/.bashrc" file:</> |
| 60 | <info>source /path/to/completion.sh</> |
| 61 | |
| 62 | <comment>Dynamic installation |
| 63 | --------------------</> |
| 64 | |
| 65 | Add this to the end of your shell configuration file (e.g. <info>"~/.bashrc"</>): |
| 66 | |
| 67 | <info>eval "\$({$fullCommand} completion bash)"</> |
| 68 | EOH |
| 69 | )->addArgument('shell', InputArgument::OPTIONAL, 'The shell type (e.g. "bash"), the value of the "$SHELL" env var will be used if this is not given')->addOption('debug', null, InputOption::VALUE_NONE, 'Tail the completion debug log'); |
| 70 | } |
| 71 | protected function execute(InputInterface $input, OutputInterface $output) : int |
| 72 | { |
| 73 | $commandName = basename($_SERVER['argv'][0]); |
| 74 | if ($input->getOption('debug')) { |
| 75 | $this->tailDebugLog($commandName, $output); |
| 76 | return 0; |
| 77 | } |
| 78 | $shell = $input->getArgument('shell') ?? self::guessShell(); |
| 79 | $completionFile = __DIR__ . '/../Resources/completion.' . $shell; |
| 80 | if (!file_exists($completionFile)) { |
| 81 | $supportedShells = $this->getSupportedShells(); |
| 82 | if ($output instanceof ConsoleOutputInterface) { |
| 83 | $output = $output->getErrorOutput(); |
| 84 | } |
| 85 | if ($shell) { |
| 86 | $output->writeln(sprintf('<error>Detected shell "%s", which is not supported by Symfony shell completion (supported shells: "%s").</>', $shell, implode('", "', $supportedShells))); |
| 87 | } else { |
| 88 | $output->writeln(sprintf('<error>Shell not detected, Symfony shell completion only supports "%s").</>', implode('", "', $supportedShells))); |
| 89 | } |
| 90 | return 2; |
| 91 | } |
| 92 | $output->write(str_replace(['{{ COMMAND_NAME }}', '{{ VERSION }}'], [$commandName, $this->getApplication()->getVersion()], file_get_contents($completionFile))); |
| 93 | return 0; |
| 94 | } |
| 95 | private static function guessShell() : string |
| 96 | { |
| 97 | return basename($_SERVER['SHELL'] ?? ''); |
| 98 | } |
| 99 | private function tailDebugLog(string $commandName, OutputInterface $output) : void |
| 100 | { |
| 101 | $debugFile = sys_get_temp_dir() . '/sf_' . $commandName . '.log'; |
| 102 | if (!file_exists($debugFile)) { |
| 103 | touch($debugFile); |
| 104 | } |
| 105 | $process = new Process(['tail', '-f', $debugFile], null, null, null, 0); |
| 106 | $process->run(function (string $type, string $line) use($output) : void { |
| 107 | $output->write($line); |
| 108 | }); |
| 109 | } |
| 110 | /** |
| 111 | * @return string[] |
| 112 | */ |
| 113 | private function getSupportedShells() : array |
| 114 | { |
| 115 | $shells = []; |
| 116 | foreach (new \DirectoryIterator(__DIR__ . '/../Resources/') as $file) { |
| 117 | if (str_starts_with($file->getBasename(), 'completion.') && $file->isFile()) { |
| 118 | $shells[] = $file->getExtension(); |
| 119 | } |
| 120 | } |
| 121 | return $shells; |
| 122 | } |
| 123 | } |
| 124 |