From 1a5df7351328f228296ba15a4de4ebed112a2cb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFck=20Piera?= Date: Thu, 28 Mar 2024 13:56:30 +0100 Subject: [PATCH] Add a way to dynamically autocomplete task arguments/options --- CHANGELOG.md | 1 + doc/getting-started/installation.md | 17 +- doc/going-further/index.md | 2 +- .../interacting-with-castor/autocomplete.md | 94 + examples/args.php | 21 + src/Attribute/AsArgument.php | 6 +- src/Attribute/AsOption.php | 8 +- src/Console/Command/TaskCommand.php | 24 +- src/Stub/StubsGenerator.php | 1 + .../ArgsAutocompleteArgumentTest.php | 22 + ...rgsAutocompleteArgumentTest.php.output.txt | 4 + .../Generated/AutocompleteInvalidTest.php | 22 + .../AutocompleteInvalidTest.php.err.txt | 8 + .../AutocompleteInvalidTest.php.output.txt | 0 .../Generated/ListTest.php.output.txt | 1 + .../autocomplete-invalid/.castor.stub.php | 4170 +++++++++++++++++ .../broken/autocomplete-invalid/castor.php | 21 + 17 files changed, 4402 insertions(+), 20 deletions(-) create mode 100644 doc/going-further/interacting-with-castor/autocomplete.md create mode 100644 tests/Examples/Generated/ArgsAutocompleteArgumentTest.php create mode 100644 tests/Examples/Generated/ArgsAutocompleteArgumentTest.php.output.txt create mode 100644 tests/Examples/Generated/AutocompleteInvalidTest.php create mode 100644 tests/Examples/Generated/AutocompleteInvalidTest.php.err.txt create mode 100644 tests/Examples/Generated/AutocompleteInvalidTest.php.output.txt create mode 100644 tests/Examples/fixtures/broken/autocomplete-invalid/.castor.stub.php create mode 100644 tests/Examples/fixtures/broken/autocomplete-invalid/castor.php diff --git a/CHANGELOG.md b/CHANGELOG.md index b8055ea2..fb9a34dd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ * Add a option `ignoreValidationErrors` on `AsTask` attribute to ignore parameters & options validation errors +* Add a way to dynamically autocomplete task arguments/options * Add a way to merge an application `box.json` config file used by `castor:repack`command * Deprecate `Context::withPath()` in favor of `Context::withWorkingDirectory()` * Deprecate `path` argument in `capture()`, `exit_code()`, `run()`, `with()` in favor of `workingDirectory` diff --git a/doc/getting-started/installation.md b/doc/getting-started/installation.md index 51cf3e03..45a3f3bc 100644 --- a/doc/getting-started/installation.md +++ b/doc/getting-started/installation.md @@ -165,21 +165,10 @@ jobs: ## Autocomplete -If you use bash, you can enable autocomplete for castor by running the -following task: +Castor provides a built-in autocomplete to ease its usage in shell. -``` -castor completion | sudo tee /etc/bash_completion.d/castor -``` - -Then reload your shell. - -Others shells are also supported (zsh, fish, etc). To get the list of supported -shells and their dedicated instructions, run: - -``` -castor completion --help -``` +See [the dedicated documentation](../going-further/interacting-with-castor/autocomplete.md) +to see how to install it, and also how to autocomplete your arguments. ## Stubs diff --git a/doc/going-further/index.md b/doc/going-further/index.md index e99d8a04..17db1faf 100644 --- a/doc/going-further/index.md +++ b/doc/going-further/index.md @@ -5,7 +5,7 @@ This section contains more advanced topics about Castor. * [Helpers](helpers/console-and-io.md): all builtin features that Castor provides to help you write your tasks. * [Interacting with Castor](interacting-with-castor/advanced-context.md): how to -interact with Castor's output, context, logs, etc. +interact with Castor's output, context, logs, autocomplete, etc. * [Extending Castor](extending-castor/events.md): how to wire some logic inside Castor, how to redistribute your project as your own phar or static binary. diff --git a/doc/going-further/interacting-with-castor/autocomplete.md b/doc/going-further/interacting-with-castor/autocomplete.md new file mode 100644 index 00000000..d9c542f0 --- /dev/null +++ b/doc/going-further/interacting-with-castor/autocomplete.md @@ -0,0 +1,94 @@ +# Autocomplete + +## Installation + +If you use bash, you can enable autocomplete for castor by running the +following task: + +``` +castor completion | sudo tee /etc/bash_completion.d/castor +``` + +Then reload your shell. + +Others shells are also supported (zsh, fish, etc). To get the list of supported +shells and their dedicated instructions, run: + +``` +castor completion --help +``` + +## Autocomplete arguments + +You have to options to make your arguments autocompleted. + +### Static suggestions + +In case your suggestions are fixed, you can pass them in the `suggestedValues` +property of the `AsArgument` and `AsOption` attributes: + +```php +#[AsTask()] +function my_task( + #[AsArgument(name: 'argument', suggestedValues: ['foo', 'bar', 'baz'])] + string $argument, +): void { +} +``` + +When trying to autocomplete the arguments, your shell will now suggest these +values: + +```bash +$ castor my-task [TAB] +bar baz foo +``` + +### Dynamic suggestions + +In case you need some logic to list the suggestions (like suggesting paths or +docker services, making a database query or HTTP request to determine some +values, etc.), you can use the `autocomplete` property of the `AsArgument` and +`AsOption` attributes to provide the function that will return the suggestions: + +```php +namespace example; + +use Symfony\Component\Console\Completion\CompletionInput; + +#[AsTask()] +function autocomplete_argument( + #[AsArgument(name: 'argument', autocomplete: 'example\get_argument_autocompletion')] + string $argument, +): void { +} + +function get_argument_autocompletion(CompletionInput $input): array +{ + // You can search for a file on the filesystem, make a network call, etc. + + return [ + 'foo', + 'bar', + 'baz', + ]; +} +``` + +>[!NOTE] +> Because the syntax `my_callback(...)` is not allowed on attribute, you need to +> specify the `autocomplete` callback with either: +> - the string syntax (`my_namespace\my_function` or `'MyNamespace\MyClass::myFunction'`) +> - the array syntax (`['MyNamespace\MyClass', 'myFunction']`). + +This function receives an optional `Symfony\Component\Console\Completion\CompletionInput` +argument to allow you to pre-filter the suggestions returned to the shell. + +>[!TIP] +> The shell script is able to handle huge amounts of suggestions and will +> automatically filter the suggested values based on the existing input from the +> user. You do not have to implement any filter logic in the function. +> +> You may use CompletionInput::getCompletionValue() to get the current input if +> that helps improving performance (e.g. by reducing the number of rows fetched +> from the database). diff --git a/examples/args.php b/examples/args.php index 088a9f90..6e4ca0e7 100644 --- a/examples/args.php +++ b/examples/args.php @@ -6,6 +6,7 @@ use Castor\Attribute\AsOption; use Castor\Attribute\AsRawTokens; use Castor\Attribute\AsTask; +use Symfony\Component\Console\Completion\CompletionInput; use function Castor\io; @@ -42,3 +43,23 @@ function passthru(#[AsRawTokens] array $rawTokens): void { var_dump($rawTokens); } + +#[AsTask(description: 'Provides autocomplete for an argument')] +function autocomplete_argument( + #[AsArgument(name: 'argument', description: 'This is an argument with autocompletion', autocomplete: 'args\get_argument_autocompletion')] + string $argument, +): void { + var_dump(\func_get_args()); +} + +/** @return string[] */ +function get_argument_autocompletion(CompletionInput $input): array +{ + // You can search for a file on the filesystem, make a network call, etc. + + return [ + 'foo', + 'bar', + 'baz', + ]; +} diff --git a/src/Attribute/AsArgument.php b/src/Attribute/AsArgument.php index 953e3000..c122f040 100644 --- a/src/Attribute/AsArgument.php +++ b/src/Attribute/AsArgument.php @@ -2,16 +2,20 @@ namespace Castor\Attribute; +use Symfony\Component\Console\Completion\CompletionInput; + #[\Attribute(\Attribute::TARGET_PARAMETER)] class AsArgument extends AsCommandArgument { /** - * @param array $suggestedValues + * @param array $suggestedValues + * @param mixed|callable(CompletionInput): array $autocomplete */ public function __construct( ?string $name = null, public readonly string $description = '', public readonly array $suggestedValues = [], + public readonly mixed $autocomplete = null, ) { parent::__construct($name); } diff --git a/src/Attribute/AsOption.php b/src/Attribute/AsOption.php index fa93cfa4..1304853d 100644 --- a/src/Attribute/AsOption.php +++ b/src/Attribute/AsOption.php @@ -2,12 +2,15 @@ namespace Castor\Attribute; +use Symfony\Component\Console\Completion\CompletionInput; + #[\Attribute(\Attribute::TARGET_PARAMETER)] class AsOption extends AsCommandArgument { /** - * @param string|array|null $shortcut - * @param array $suggestedValues + * @param string|array|null $shortcut + * @param array $suggestedValues + * @param mixed|callable(CompletionInput): array $autocomplete */ public function __construct( ?string $name = null, @@ -15,6 +18,7 @@ public function __construct( public readonly ?int $mode = null, public readonly string $description = '', public readonly array $suggestedValues = [], + public readonly mixed $autocomplete = null, ) { parent::__construct($name); } diff --git a/src/Console/Command/TaskCommand.php b/src/Console/Command/TaskCommand.php index 8c9e1a30..c2491d2d 100644 --- a/src/Console/Command/TaskCommand.php +++ b/src/Console/Command/TaskCommand.php @@ -117,7 +117,7 @@ protected function configure(): void $mode, $taskArgumentAttribute->description, $parameter->isOptional() ? $parameter->getDefaultValue() : null, - $taskArgumentAttribute->suggestedValues, + $this->getSuggestedValues($taskArgumentAttribute), ); } elseif ($taskArgumentAttribute instanceof AsOption) { if ('verbose' === $name) { @@ -143,7 +143,7 @@ protected function configure(): void $mode, $taskArgumentAttribute->description, $defaultValue, - $taskArgumentAttribute->suggestedValues, + $this->getSuggestedValues($taskArgumentAttribute), ); } } catch (LogicException $e) { @@ -220,4 +220,24 @@ private function getParameterName(\ReflectionParameter $parameter): string { return $this->argumentsMap[$parameter->getName()]; } + + /** + * @return array|\Closure + */ + private function getSuggestedValues(AsArgument|AsOption $attribute): array|\Closure + { + if ($attribute->suggestedValues && null !== $attribute->autocomplete) { + throw new FunctionConfigurationException(sprintf('You cannot define both "suggestedValues" and "autocomplete" option on parameter "%s".', $attribute->name), $this->function); + } + + if (null === $attribute->autocomplete) { + return $attribute->suggestedValues; + } + + if (!\is_callable($attribute->autocomplete)) { + throw new FunctionConfigurationException(sprintf('The value provided in the "autocomplete" option on parameter "%s" is not callable.', $attribute->name), $this->function); + } + + return \Closure::fromCallable($attribute->autocomplete); + } } diff --git a/src/Stub/StubsGenerator.php b/src/Stub/StubsGenerator.php index 2130c322..2711e913 100644 --- a/src/Stub/StubsGenerator.php +++ b/src/Stub/StubsGenerator.php @@ -61,6 +61,7 @@ public function generateStubs(string $dest): void // Add some very frequently used classes $frequentlyUsedClasses = [ \Symfony\Component\Console\Application::class, + \Symfony\Component\Console\Completion\CompletionInput::class, \Symfony\Component\Console\Input\InputArgument::class, \Symfony\Component\Console\Input\InputInterface::class, \Symfony\Component\Console\Input\InputOption::class, diff --git a/tests/Examples/Generated/ArgsAutocompleteArgumentTest.php b/tests/Examples/Generated/ArgsAutocompleteArgumentTest.php new file mode 100644 index 00000000..b2b600ee --- /dev/null +++ b/tests/Examples/Generated/ArgsAutocompleteArgumentTest.php @@ -0,0 +1,22 @@ +runTask(['args:autocomplete-argument', 'FIXME(argument)']); + + $this->assertSame(0, $process->getExitCode()); + $this->assertStringEqualsFile(__FILE__ . '.output.txt', $process->getOutput()); + if (file_exists(__FILE__ . '.err.txt')) { + $this->assertStringEqualsFile(__FILE__ . '.err.txt', $process->getErrorOutput()); + } else { + $this->assertSame('', $process->getErrorOutput()); + } + } +} diff --git a/tests/Examples/Generated/ArgsAutocompleteArgumentTest.php.output.txt b/tests/Examples/Generated/ArgsAutocompleteArgumentTest.php.output.txt new file mode 100644 index 00000000..dca76eab --- /dev/null +++ b/tests/Examples/Generated/ArgsAutocompleteArgumentTest.php.output.txt @@ -0,0 +1,4 @@ +array(1) { + [0]=> + string(15) "FIXME(argument)" +} diff --git a/tests/Examples/Generated/AutocompleteInvalidTest.php b/tests/Examples/Generated/AutocompleteInvalidTest.php new file mode 100644 index 00000000..03b5c992 --- /dev/null +++ b/tests/Examples/Generated/AutocompleteInvalidTest.php @@ -0,0 +1,22 @@ +runTask([], '{{ base }}/tests/Examples/fixtures/broken/autocomplete-invalid'); + + $this->assertSame(1, $process->getExitCode()); + $this->assertStringEqualsFile(__FILE__ . '.output.txt', $process->getOutput()); + if (file_exists(__FILE__ . '.err.txt')) { + $this->assertStringEqualsFile(__FILE__ . '.err.txt', $process->getErrorOutput()); + } else { + $this->assertSame('', $process->getErrorOutput()); + } + } +} diff --git a/tests/Examples/Generated/AutocompleteInvalidTest.php.err.txt b/tests/Examples/Generated/AutocompleteInvalidTest.php.err.txt new file mode 100644 index 00000000..737f0c76 --- /dev/null +++ b/tests/Examples/Generated/AutocompleteInvalidTest.php.err.txt @@ -0,0 +1,8 @@ + +In TaskCommand.php line 238: + + Function "autocomplete_argument()" is not properly configured: + The value provided in the "autocomplete" option on parameter "argument" is not callable. + Defined in "castor.php" line 8. + + diff --git a/tests/Examples/Generated/AutocompleteInvalidTest.php.output.txt b/tests/Examples/Generated/AutocompleteInvalidTest.php.output.txt new file mode 100644 index 00000000..e69de29b diff --git a/tests/Examples/Generated/ListTest.php.output.txt b/tests/Examples/Generated/ListTest.php.output.txt index 7e5315ea..ac0e2a63 100644 --- a/tests/Examples/Generated/ListTest.php.output.txt +++ b/tests/Examples/Generated/ListTest.php.output.txt @@ -6,6 +6,7 @@ list List commands no-namespace Task without a namespace args:another-args Dumps all arguments and options, without configuration args:args Dumps all arguments and options, with custom configuration +args:autocomplete-argument Provides autocomplete for an argument args:passthru Dumps all arguments and options, without configuration nor validation bar:bar Prints bar, but also executes foo cache:complex Cache with usage of CacheItemInterface diff --git a/tests/Examples/fixtures/broken/autocomplete-invalid/.castor.stub.php b/tests/Examples/fixtures/broken/autocomplete-invalid/.castor.stub.php new file mode 100644 index 00000000..f868c532 --- /dev/null +++ b/tests/Examples/fixtures/broken/autocomplete-invalid/.castor.stub.php @@ -0,0 +1,4170 @@ +|null $shortcut + * @param array $suggestedValues + * @param ?callable(CompletionInput): array $autocomplete + */ + public function __construct(?string $name = null, public readonly string|array|null $shortcut = null, public readonly ?int $mode = null, public readonly string $description = '', public readonly array $suggestedValues = [], public readonly array|string|null $autocomplete = null) + { + } +} +namespace Castor\Attribute; + +#[\Attribute(\Attribute::TARGET_PARAMETER)] +class AsRawTokens +{ +} +namespace Castor\Attribute; + +#[\Attribute(\Attribute::TARGET_CLASS)] +class AsSymfonyTask +{ + /** + * @param string[] $console How to start the Symfony application + */ + public function __construct(public ?string $name = null, public ?string $originalName = null, public readonly array $console = [\PHP_BINARY, 'bin/console']) + { + } +} +namespace Castor\Attribute; + +#[\Attribute(\Attribute::TARGET_FUNCTION)] +class AsTask +{ + /** + * @param array $aliases + * @param array $onSignals + */ + public function __construct(public string $name = '', public ?string $namespace = null, public string $description = '', public array $aliases = [], public array $onSignals = [], public string|bool $enabled = true, public bool $ignoreValidationErrors = false) + { + } +} +namespace Castor\Console\Command; + +#[\Symfony\Component\Console\Attribute\AsCommand(name: 'castor:debug', description: 'Debug the application', hidden: true, aliases: ['debug'])] +final class DebugCommand extends \Symfony\Component\Console\Command\Command +{ + public function __construct(private readonly string $rootDir, private readonly string $cacheDir, private readonly \Castor\ContextRegistry $contextRegistry) + { + } + protected function execute(\Symfony\Component\Console\Input\InputInterface $input, \Symfony\Component\Console\Output\OutputInterface $output) : int + { + } +} +namespace Castor\Console\Output; + +class SectionDetails +{ + public function __construct(public \Symfony\Component\Console\Output\ConsoleSectionOutput $section, public \Symfony\Component\Console\Output\ConsoleSectionOutput $progressBarSection, public float $start, public string $index) + { + } +} +namespace Castor\Console\Output; + +enum VerbosityLevel : int +{ + case NOT_CONFIGURED = -1; + case QUIET = 0; + case NORMAL = 1; + case VERBOSE = 2; + case VERY_VERBOSE = 3; + case DEBUG = 4; + public static function fromSymfonyOutput(\Symfony\Component\Console\Output\OutputInterface $output) : self + { + } + public function isNotConfigured() : bool + { + } + public function isQuiet() : bool + { + } + public function isVerbose() : bool + { + } + public function isVeryVerbose() : bool + { + } + public function isDebug() : bool + { + } +} +namespace Castor; + +class Context implements \ArrayAccess +{ + public readonly string $workingDirectory; + /** + * @phpstan-param ContextData $data The input parameter accepts an array or an Object + * + * @param array $environment A list of environment variables to add to the task + */ + public function __construct( + public readonly array $data = [], + public readonly array $environment = [], + ?string $workingDirectory = null, + public readonly bool $tty = false, + public readonly bool $pty = true, + public readonly ?float $timeout = null, + public readonly bool $quiet = false, + public readonly bool $allowFailure = false, + public readonly bool $notify = false, + public readonly \Castor\Console\Output\VerbosityLevel|\Castor\VerbosityLevel $verbosityLevel = \Castor\Console\Output\VerbosityLevel::NOT_CONFIGURED, + // Do not use this argument, it is only used internally by the application + public readonly string $name = '' + ) + { + } + public function __debugInfo() + { + } + /** + * @param array<(int|string), mixed> $data + * + * @throws \Exception + */ + public function withData(array $data, bool $keepExisting = true, bool $recursive = true) : self + { + } + /** @param array $environment */ + public function withEnvironment(array $environment, bool $keepExisting = true) : self + { + } + public function withPath(string $path) : self + { + } + public function withWorkingDirectory(string $workingDirectory) : self + { + } + public function withTty(bool $tty = true) : self + { + } + public function withPty(bool $pty = true) : self + { + } + public function withTimeout(?float $timeout) : self + { + } + public function withQuiet(bool $quiet = true) : self + { + } + public function withAllowFailure(bool $allowFailure = true) : self + { + } + public function withNotify(bool $notify = true) : self + { + } + public function withVerbosityLevel(\Castor\Console\Output\VerbosityLevel|\Castor\VerbosityLevel $verbosityLevel) : self + { + } + public function withName(string $name) : self + { + } + public function offsetExists(mixed $offset) : bool + { + } + public function offsetGet(mixed $offset) : mixed + { + } + public function offsetSet(mixed $offset, mixed $value) : void + { + } + public function offsetUnset(mixed $offset) : void + { + } + /** + * @param array<(int|string), mixed> $array1 + * @param array<(int|string), mixed> $array2 + * + * @return array<(int|string), mixed> + */ + private function arrayMergeRecursiveDistinct(array $array1, array $array2) : array + { + } +} +namespace Castor\Descriptor; + +class ListenerDescriptor +{ + public function __construct(public readonly \Castor\Attribute\AsListener $asListener, public readonly \ReflectionFunction $reflectionFunction) + { + } +} +namespace Castor\Descriptor; + +class TaskDescriptorCollection +{ + /** + * @param TaskDescriptor[] $taskDescriptors + * @param SymfonyTaskDescriptor[] $symfonyTaskDescriptors + */ + public function __construct(public readonly array $taskDescriptors, public readonly array $symfonyTaskDescriptors) + { + } +} +namespace Castor\Event; + +class AfterApplicationInitializationEvent +{ + public function __construct(public readonly \Castor\Console\Application $application, public \Castor\Descriptor\TaskDescriptorCollection $taskDescriptorCollection) + { + } +} +namespace Castor\Event; + +class AfterExecuteTaskEvent +{ + public function __construct(public readonly \Castor\Console\Command\TaskCommand $task, public readonly mixed $result) + { + } +} +namespace Castor\Event; + +class BeforeExecuteTaskEvent +{ + public function __construct(public readonly \Castor\Console\Command\TaskCommand $task) + { + } +} +namespace Castor\Event; + +class ProcessStartEvent +{ + public function __construct(public readonly \Symfony\Component\Process\Process $process) + { + } +} +namespace Castor\Event; + +class ProcessTerminateEvent +{ + public function __construct(public readonly \Symfony\Component\Process\Process $process) + { + } +} +namespace Castor; + +class EventDispatcher implements \Symfony\Component\EventDispatcher\EventDispatcherInterface +{ + public function __construct(private \Symfony\Component\EventDispatcher\EventDispatcherInterface $eventDispatcher = new \Symfony\Component\EventDispatcher\EventDispatcher(), private \Psr\Log\LoggerInterface $logger = new \Psr\Log\NullLogger()) + { + } + public function dispatch(object $event, ?string $eventName = null) : object + { + } + public function addListener(string $eventName, callable $listener, int $priority = 0) : void + { + } + public function removeListener(string $eventName, callable $listener) : void + { + } + public function addSubscriber(\Symfony\Component\EventDispatcher\EventSubscriberInterface $subscriber) : void + { + } + public function removeSubscriber(\Symfony\Component\EventDispatcher\EventSubscriberInterface $subscriber) : void + { + } + public function getListeners(?string $eventName = null) : array + { + } + public function getListenerPriority(string $eventName, callable $listener) : ?int + { + } + public function hasListeners(?string $eventName = null) : bool + { + } +} +namespace Castor\Exception; + +class ExecutableNotFoundException extends \RuntimeException +{ + public function __construct(readonly string $executableName) + { + } +} +namespace Castor\Exception; + +class FunctionConfigurationException extends \InvalidArgumentException +{ + public function __construct(string $message, \ReflectionFunction|\ReflectionClass $function, ?\Throwable $e = null) + { + } +} +namespace Castor\Exception; + +class MinimumVersionRequirementNotMetException extends \RuntimeException +{ + public function __construct(readonly string $requiredVersion, readonly string $currentVersion) + { + } +} +namespace Castor\Exception\WaitFor; + +class DockerContainerStateException extends \RuntimeException +{ + public function __construct(readonly string $containerName, readonly string $state) + { + } +} +namespace Castor\Exception\WaitFor; + +class ExitedBeforeTimeoutException extends \RuntimeException +{ + public function __construct(string $message = 'Callback check returned null, exiting before timeout.') + { + } +} +namespace Castor\Exception\WaitFor; + +class TimeoutReachedException extends \Exception +{ + public function __construct(int $timeout) + { + } +} +namespace Castor; + +class ExpressionLanguage extends \Symfony\Component\ExpressionLanguage\ExpressionLanguage +{ + public function __construct(private readonly ContextRegistry $contextRegistry) + { + } +} +namespace Castor\Fingerprint; + +enum FileHashStrategy +{ + case Content; + case MTimes; +} +namespace Castor; + +class GlobalHelper +{ + private static \Castor\Console\Application $application; + public static function setApplication(\Castor\Console\Application $application) : void + { + } + public static function getApplication() : \Castor\Console\Application + { + } + public static function getContextRegistry() : ContextRegistry + { + } + public static function getEventDispatcher() : EventDispatcher + { + } + public static function getFilesystem() : \Symfony\Component\Filesystem\Filesystem + { + } + public static function getHttpClient() : \Symfony\Contracts\HttpClient\HttpClientInterface + { + } + public static function getCache() : \Psr\Cache\CacheItemPoolInterface&\Symfony\Contracts\Cache\CacheInterface + { + } + public static function getLogger() : \Monolog\Logger + { + } + public static function getInput() : \Symfony\Component\Console\Input\InputInterface + { + } + public static function getSectionOutput() : \Castor\Console\Output\SectionOutput + { + } + public static function getOutput() : \Symfony\Component\Console\Output\OutputInterface + { + } + public static function getSymfonyStyle() : \Symfony\Component\Console\Style\SymfonyStyle + { + } + /** + * @return ($allowNull is true ? ?Command : Command) + */ + public static function getCommand(bool $allowNull = false) : ?\Symfony\Component\Console\Command\Command + { + } + public static function getContext(?string $name = null) : Context + { + } + public static function getVariable(string $key, mixed $default = null) : mixed + { + } +} +namespace Castor; + +class HasherHelper +{ + private readonly \HashContext $hashContext; + /** + * @see https://www.php.net/manual/en/function.hash-algos.php + */ + public function __construct(private readonly \Castor\Console\Application $application, private readonly \Psr\Log\LoggerInterface $logger = new \Psr\Log\NullLogger(), string $algo = 'xxh128') + { + } + public function write(string $value) : self + { + } + public function writeFile(string $path, \Castor\Fingerprint\FileHashStrategy $strategy = \Castor\Fingerprint\FileHashStrategy::MTimes) : self + { + } + public function writeWithFinder(\Symfony\Component\Finder\Finder $finder, \Castor\Fingerprint\FileHashStrategy $strategy = \Castor\Fingerprint\FileHashStrategy::MTimes) : self + { + } + public function writeGlob(string $pattern, \Castor\Fingerprint\FileHashStrategy $strategy = \Castor\Fingerprint\FileHashStrategy::MTimes) : self + { + } + public function writeTaskName() : self + { + } + public function writeTaskArgs(string ...$args) : self + { + } + public function writeTask(string ...$args) : self + { + } + public function finish() : string + { + } +} +namespace Castor\Listener; + +class GenerateStubsListener implements \Symfony\Component\EventDispatcher\EventSubscriberInterface +{ + public function __construct(private readonly \Castor\Stub\StubsGenerator $stubsGenerator, private readonly string $rootDir) + { + } + public function generateStubs(\Symfony\Component\Console\Event\ConsoleCommandEvent $event) : void + { + } + public static function getSubscribedEvents() : array + { + } +} +namespace Castor\Listener; + +class UpdateCastorListener implements \Symfony\Component\EventDispatcher\EventSubscriberInterface +{ + public function __construct(private readonly \Psr\Cache\CacheItemPoolInterface&\Symfony\Contracts\Cache\CacheInterface $cache, private readonly \Symfony\Contracts\HttpClient\HttpClientInterface $httpClient, private readonly \Psr\Log\LoggerInterface $logger = new \Psr\Log\NullLogger()) + { + } + public function checkUpdate(\Symfony\Component\Console\Event\ConsoleCommandEvent $event) : void + { + } + public static function getSubscribedEvents() : array + { + } + private function displayUpdateWarningIfNeeded(\Symfony\Component\Console\Input\InputInterface $input, \Symfony\Component\Console\Output\OutputInterface $output) : void + { + } +} +namespace Castor\Monolog\Processor; + +class ProcessProcessor implements \Monolog\Processor\ProcessorInterface +{ + public function __invoke(\Monolog\LogRecord $record) : \Monolog\LogRecord + { + } + /** + * @return array{cwd: ?string, env: array, runnable: string} + */ + private function formatProcess(\Symfony\Component\Process\Process $process) : array + { + } +} +namespace Castor; + +class PathHelper +{ + public static function getRoot() : string + { + } + public static function realpath(string $path) : string + { + } + public static function makeRelative(string $path) : string + { + } +} +namespace Castor; + +trigger_deprecation('castor', '0.15.0', 'The "%s" class is deprecated, use "%s" instead.', TaskDescriptorCollection::class, \Castor\Descriptor\TaskDescriptorCollection::class); +/** + * @deprecated since Castor 0.15.0, use Castor\Descriptor\TaskDescriptorCollection instead + */ +class TaskDescriptorCollection extends \Castor\Descriptor\TaskDescriptorCollection +{ +} +namespace Castor; + +trigger_deprecation('castor/console', '0.15', 'The "%s" enum is deprecated and will be removed in 1.0. Use "%s" instead.', VerbosityLevel::class, Console\Output\VerbosityLevel::class); +/** + * @deprecated since castor/console 0.15, to be removed in 1.0. Use \Castor\Console\Output\VerbosityLevel instead. + */ +enum VerbosityLevel : int +{ + case NOT_CONFIGURED = -1; + case QUIET = 0; + case NORMAL = 1; + case VERBOSE = 2; + case VERY_VERBOSE = 3; + case DEBUG = 4; + public static function fromSymfonyOutput(\Symfony\Component\Console\Output\OutputInterface $output) : self + { + } + public function isNotConfigured() : bool + { + } + public function isQuiet() : bool + { + } + public function isVerbose() : bool + { + } + public function isVeryVerbose() : bool + { + } + public function isDebug() : bool + { + } +} +namespace Castor; + +/** + * @return array + */ +function parallel(callable ...$callbacks) : array +{ +} +/** + * @param string|array $command + * @param array|null $environment + * @param (callable(string, string, Process) :void)|null $callback + */ +function run(string|array $command, ?array $environment = null, ?string $workingDirectory = null, ?bool $tty = null, ?bool $pty = null, ?float $timeout = null, ?bool $quiet = null, ?bool $allowFailure = null, ?bool $notify = null, ?callable $callback = null, ?Context $context = null, ?string $path = null) : \Symfony\Component\Process\Process +{ +} +/** + * @param string|array $command + * @param array|null $environment + */ +function capture(string|array $command, ?array $environment = null, ?string $workingDirectory = null, ?float $timeout = null, ?bool $allowFailure = null, ?string $onFailure = null, ?Context $context = null, ?string $path = null) : string +{ +} +/** + * @param string|array $command + * @param array|null $environment + */ +function exit_code(string|array $command, ?array $environment = null, ?string $workingDirectory = null, ?float $timeout = null, ?bool $quiet = null, ?Context $context = null, ?string $path = null) : int +{ +} +function get_exit_code(...$args) : int +{ +} +/** + * This function is considered experimental and may change in the future. + * + * @param array{ + * 'port'?: int, + * 'path_private_key'?: string, + * 'jump_host'?: string, + * 'multiplexing_control_path'?: string, + * 'multiplexing_control_persist'?: string, + * 'enable_strict_check'?: bool, + * 'password_authentication'?: bool, + * } $sshOptions + */ +function ssh_run(string $command, string $host, string $user, array $sshOptions = [], ?string $path = null, ?bool $quiet = null, ?bool $allowFailure = null, ?bool $notify = null, ?float $timeout = null) : \Symfony\Component\Process\Process +{ +} +function ssh(...$args) : \Symfony\Component\Process\Process +{ +} +/** + * This function is considered experimental and may change in the future. + * + * @param array{ + * 'port'?: int, + * 'path_private_key'?: string, + * 'jump_host'?: string, + * 'multiplexing_control_path'?: string, + * 'multiplexing_control_persist'?: string, + * 'enable_strict_check'?: bool, + * 'password_authentication'?: bool, + * } $sshOptions + */ +function ssh_upload(string $sourcePath, string $destinationPath, string $host, string $user, array $sshOptions = [], ?bool $quiet = null, ?bool $allowFailure = null, ?bool $notify = null, ?float $timeout = null) : \Symfony\Component\Process\Process +{ +} +/** + * This function is considered experimental and may change in the future. + * + * @param array{ + * 'port'?: int, + * 'path_private_key'?: string, + * 'jump_host'?: string, + * 'multiplexing_control_path'?: string, + * 'multiplexing_control_persist'?: string, + * 'enable_strict_check'?: bool, + * 'password_authentication'?: bool, + * } $sshOptions + */ +function ssh_download(string $sourcePath, string $destinationPath, string $host, string $user, array $sshOptions = [], ?bool $quiet = null, ?bool $allowFailure = null, ?bool $notify = null, ?float $timeout = null) : \Symfony\Component\Process\Process +{ +} +function notify(string $message) : void +{ +} +/** + * @param string|non-empty-array $path + * @param (callable(string, string) : (false|void|null)) $function + */ +function watch(string|array $path, callable $function, ?Context $context = null) : void +{ +} +/** + * @param array $context + * + * @phpstan-param \Monolog\Level|\Psr\Log\LogLevel::* $level + */ +function log(string|\Stringable $message, mixed $level = 'info', array $context = []) : void +{ +} +function logger() : \Monolog\Logger +{ +} +function app() : \Castor\Console\Application +{ +} +function get_application() : \Castor\Console\Application +{ +} +function input() : \Symfony\Component\Console\Input\InputInterface +{ +} +function get_input() : \Symfony\Component\Console\Input\InputInterface +{ +} +function output() : \Symfony\Component\Console\Output\OutputInterface +{ +} +/** + * @deprecated + */ +function get_output() : \Symfony\Component\Console\Output\OutputInterface +{ +} +function io() : \Symfony\Component\Console\Style\SymfonyStyle +{ +} +function add_context(string $name, \Closure $callable, bool $default = false) : void +{ +} +function context(?string $name = null) : Context +{ +} +function get_context() : Context +{ +} +/** + * @template TKey of key-of + * @template TDefault + * + * @param TKey|string $key + * @param TDefault $default + * + * @phpstan-return ($key is TKey ? ContextData[TKey] : TDefault) + */ +function variable(string $key, mixed $default = null) : mixed +{ +} +/** + * @return ($allowNull is true ? ?Command : Command) + */ +function task(bool $allowNull = false) : ?\Symfony\Component\Console\Command\Command +{ +} +function get_command() : \Symfony\Component\Console\Command\Command +{ +} +function fs() : \Symfony\Component\Filesystem\Filesystem +{ +} +function finder() : \Symfony\Component\Finder\Finder +{ +} +/** + * @param string $key The key of the item to retrieve from the cache + * @param (callable(CacheItemInterface,bool):T)|(callable(ItemInterface,bool):T)|CallbackInterface $or Use this callback to compute the value + * + * @return T + * + * @see CacheInterface::get() + * + * @template T + */ +function cache(string $key, callable $or) : mixed +{ +} +function get_cache() : \Psr\Cache\CacheItemPoolInterface&\Symfony\Contracts\Cache\CacheInterface +{ +} +/** + * @param array $options + * + * @see HttpClientInterface::OPTIONS_DEFAULTS + */ +function request(string $method, string $url, array $options = []) : \Symfony\Contracts\HttpClient\ResponseInterface +{ +} +function http_client() : \Symfony\Contracts\HttpClient\HttpClientInterface +{ +} +function import(string $path) : void +{ +} +/** + * @return array + */ +function load_dot_env(?string $path = null) : array +{ +} +/** + * @template T + * + * @param (callable(Context) :T) $callback + * @param array|null $data + * @param array|null $environment + */ +function with(callable $callback, ?array $data = null, ?array $environment = null, ?string $workingDirectory = null, ?bool $tty = null, ?bool $pty = null, ?float $timeout = null, ?bool $quiet = null, ?bool $allowFailure = null, ?bool $notify = null, Context|string|null $context = null, ?string $path = null) : mixed +{ +} +/** + * @see https://www.php.net/manual/en/function.hash-algos.php + */ +function hasher(string $algo = 'xxh128') : HasherHelper +{ +} +function fingerprint_exists(string $fingerprint) : bool +{ +} +function fingerprint_save(string $fingerprint) : void +{ +} +function fingerprint(callable $callback, string $fingerprint, bool $force = false) : bool +{ +} +/** + * @throws TimeoutReachedException + * @throws ExitedBeforeTimeoutException + */ +function wait_for(callable $callback, int $timeout = 10, bool $quiet = false, int $intervalMs = 100, string $message = 'Waiting for callback to be available...') : void +{ +} +/** + * @throws TimeoutReachedException + * @throws ExitedBeforeTimeoutException + */ +function wait_for_port(int $port, string $host = '127.0.0.1', int $timeout = 10, bool $quiet = false, int $intervalMs = 100, ?string $message = null) : void +{ +} +/** + * @throws TimeoutReachedException + * @throws ExitedBeforeTimeoutException + */ +function wait_for_url(string $url, int $timeout = 10, bool $quiet = false, int $intervalMs = 100, ?string $message = null) : void +{ +} +/** + * @throws TimeoutReachedException + * @throws ExitedBeforeTimeoutException + */ +function wait_for_http_status(string $url, int $status = 200, int $timeout = 10, bool $quiet = false, int $intervalMs = 100, ?string $message = null) : void +{ +} +/** + * @throws TimeoutReachedException + * @throws ExitedBeforeTimeoutException + */ +function wait_for_http_response(string $url, ?callable $responseChecker = null, int $timeout = 10, bool $quiet = false, int $intervalMs = 100, ?string $message = null) : void +{ +} +/** + * @throws TimeoutReachedException + */ +function wait_for_docker_container(string $containerName, int $timeout = 10, bool $quiet = false, int $intervalMs = 100, ?string $message = null, ?callable $containerChecker = null) : void +{ +} +/** + * @see Yaml::parse() + */ +function yaml_parse(string $content, int $flags = 0) : mixed +{ +} +/** + * @see Yaml::dump() + */ +function yaml_dump(mixed $input, int $inline = 2, int $indent = 4, int $flags = 0) : string +{ +} +function guard_min_version(string $minVersion) : void +{ +} +function open(string ...$urls) : void +{ +} +namespace Symfony\Component\Console; + +/** + * An Application is the container for a collection of commands. + * + * It is the main entry point of a Console application. + * + * This class is optimized for a standard CLI environment. + * + * Usage: + * + * $app = new Application('myapp', '1.0 (stable)'); + * $app->add(new SimpleCommand()); + * $app->run(); + * + * @author Fabien Potencier + */ +class Application implements \Symfony\Contracts\Service\ResetInterface +{ + private array $commands = []; + private bool $wantHelps = false; + private ?\Symfony\Component\Console\Command\Command $runningCommand = null; + private string $name; + private string $version; + private ?\Symfony\Component\Console\CommandLoader\CommandLoaderInterface $commandLoader = null; + private bool $catchExceptions = true; + private bool $catchErrors = false; + private bool $autoExit = true; + private \Symfony\Component\Console\Input\InputDefinition $definition; + private \Symfony\Component\Console\Helper\HelperSet $helperSet; + private ?\Symfony\Contracts\EventDispatcher\EventDispatcherInterface $dispatcher = null; + private Terminal $terminal; + private string $defaultCommand; + private bool $singleCommand = false; + private bool $initialized = false; + private ?\Symfony\Component\Console\SignalRegistry\SignalRegistry $signalRegistry = null; + private array $signalsToDispatchEvent = []; + public function __construct(string $name = 'UNKNOWN', string $version = 'UNKNOWN') + { + } + /** + * @final + */ + public function setDispatcher(\Symfony\Contracts\EventDispatcher\EventDispatcherInterface $dispatcher) : void + { + } + /** + * @return void + */ + public function setCommandLoader(\Symfony\Component\Console\CommandLoader\CommandLoaderInterface $commandLoader) + { + } + public function getSignalRegistry() : \Symfony\Component\Console\SignalRegistry\SignalRegistry + { + } + /** + * @return void + */ + public function setSignalsToDispatchEvent(int ...$signalsToDispatchEvent) + { + } + /** + * Runs the current application. + * + * @return int 0 if everything went fine, or an error code + * + * @throws \Exception When running fails. Bypass this when {@link setCatchExceptions()}. + */ + public function run(\Symfony\Component\Console\Input\InputInterface $input = null, \Symfony\Component\Console\Output\OutputInterface $output = null) : int + { + } + /** + * Runs the current application. + * + * @return int 0 if everything went fine, or an error code + */ + public function doRun(\Symfony\Component\Console\Input\InputInterface $input, \Symfony\Component\Console\Output\OutputInterface $output) + { + } + /** + * @return void + */ + public function reset() + { + } + /** + * @return void + */ + public function setHelperSet(\Symfony\Component\Console\Helper\HelperSet $helperSet) + { + } + /** + * Get the helper set associated with the command. + */ + public function getHelperSet() : \Symfony\Component\Console\Helper\HelperSet + { + } + /** + * @return void + */ + public function setDefinition(\Symfony\Component\Console\Input\InputDefinition $definition) + { + } + /** + * Gets the InputDefinition related to this Application. + */ + public function getDefinition() : \Symfony\Component\Console\Input\InputDefinition + { + } + /** + * Adds suggestions to $suggestions for the current completion input (e.g. option or argument). + */ + public function complete(\Symfony\Component\Console\Completion\CompletionInput $input, \Symfony\Component\Console\Completion\CompletionSuggestions $suggestions) : void + { + } + /** + * Gets the help message. + */ + public function getHelp() : string + { + } + /** + * Gets whether to catch exceptions or not during commands execution. + */ + public function areExceptionsCaught() : bool + { + } + /** + * Sets whether to catch exceptions or not during commands execution. + * + * @return void + */ + public function setCatchExceptions(bool $boolean) + { + } + /** + * Sets whether to catch errors or not during commands execution. + */ + public function setCatchErrors(bool $catchErrors = true) : void + { + } + /** + * Gets whether to automatically exit after a command execution or not. + */ + public function isAutoExitEnabled() : bool + { + } + /** + * Sets whether to automatically exit after a command execution or not. + * + * @return void + */ + public function setAutoExit(bool $boolean) + { + } + /** + * Gets the name of the application. + */ + public function getName() : string + { + } + /** + * Sets the application name. + * + * @return void + */ + public function setName(string $name) + { + } + /** + * Gets the application version. + */ + public function getVersion() : string + { + } + /** + * Sets the application version. + * + * @return void + */ + public function setVersion(string $version) + { + } + /** + * Returns the long version of the application. + * + * @return string + */ + public function getLongVersion() + { + } + /** + * Registers a new command. + */ + public function register(string $name) : \Symfony\Component\Console\Command\Command + { + } + /** + * Adds an array of command objects. + * + * If a Command is not enabled it will not be added. + * + * @param Command[] $commands An array of commands + * + * @return void + */ + public function addCommands(array $commands) + { + } + /** + * Adds a command object. + * + * If a command with the same name already exists, it will be overridden. + * If the command is not enabled it will not be added. + * + * @return Command|null + */ + public function add(\Symfony\Component\Console\Command\Command $command) + { + } + /** + * Returns a registered command by name or alias. + * + * @return Command + * + * @throws CommandNotFoundException When given command name does not exist + */ + public function get(string $name) + { + } + /** + * Returns true if the command exists, false otherwise. + */ + public function has(string $name) : bool + { + } + /** + * Returns an array of all unique namespaces used by currently registered commands. + * + * It does not return the global namespace which always exists. + * + * @return string[] + */ + public function getNamespaces() : array + { + } + /** + * Finds a registered namespace by a name or an abbreviation. + * + * @throws NamespaceNotFoundException When namespace is incorrect or ambiguous + */ + public function findNamespace(string $namespace) : string + { + } + /** + * Finds a command by name or alias. + * + * Contrary to get, this command tries to find the best + * match if you give it an abbreviation of a name or alias. + * + * @return Command + * + * @throws CommandNotFoundException When command name is incorrect or ambiguous + */ + public function find(string $name) + { + } + /** + * Gets the commands (registered in the given namespace if provided). + * + * The array keys are the full names and the values the command instances. + * + * @return Command[] + */ + public function all(string $namespace = null) + { + } + /** + * Returns an array of possible abbreviations given a set of names. + * + * @return string[][] + */ + public static function getAbbreviations(array $names) : array + { + } + public function renderThrowable(\Throwable $e, \Symfony\Component\Console\Output\OutputInterface $output) : void + { + } + protected function doRenderThrowable(\Throwable $e, \Symfony\Component\Console\Output\OutputInterface $output) : void + { + } + /** + * Configures the input and output instances based on the user arguments and options. + * + * @return void + */ + protected function configureIO(\Symfony\Component\Console\Input\InputInterface $input, \Symfony\Component\Console\Output\OutputInterface $output) + { + } + /** + * Runs the current command. + * + * If an event dispatcher has been attached to the application, + * events are also dispatched during the life-cycle of the command. + * + * @return int 0 if everything went fine, or an error code + */ + protected function doRunCommand(\Symfony\Component\Console\Command\Command $command, \Symfony\Component\Console\Input\InputInterface $input, \Symfony\Component\Console\Output\OutputInterface $output) + { + } + /** + * Gets the name of the command based on input. + */ + protected function getCommandName(\Symfony\Component\Console\Input\InputInterface $input) : ?string + { + } + /** + * Gets the default input definition. + */ + protected function getDefaultInputDefinition() : \Symfony\Component\Console\Input\InputDefinition + { + } + /** + * Gets the default commands that should always be available. + * + * @return Command[] + */ + protected function getDefaultCommands() : array + { + } + /** + * Gets the default helper set with the helpers that should always be available. + */ + protected function getDefaultHelperSet() : \Symfony\Component\Console\Helper\HelperSet + { + } + /** + * Returns abbreviated suggestions in string format. + */ + private function getAbbreviationSuggestions(array $abbrevs) : string + { + } + /** + * Returns the namespace part of the command name. + * + * This method is not part of public API and should not be used directly. + */ + public function extractNamespace(string $name, int $limit = null) : string + { + } + /** + * Finds alternative of $name among $collection, + * if nothing is found in $collection, try in $abbrevs. + * + * @return string[] + */ + private function findAlternatives(string $name, iterable $collection) : array + { + } + /** + * Sets the default Command name. + * + * @return $this + */ + public function setDefaultCommand(string $commandName, bool $isSingleCommand = false) : static + { + } + private function splitStringByWidth(string $string, int $width) : array + { + } + /** + * Returns all namespaces of the command name. + * + * @return string[] + */ + private function extractAllNamespaces(string $name) : array + { + } + private function init() : void + { + } +} +namespace Symfony\Component\Console\Completion; + +/** + * An input specialized for shell completion. + * + * This input allows unfinished option names or values and exposes what kind of + * completion is expected. + * + * @author Wouter de Jong + */ +final class CompletionInput extends \Symfony\Component\Console\Input\ArgvInput +{ + public const TYPE_ARGUMENT_VALUE = 'argument_value'; + public const TYPE_OPTION_VALUE = 'option_value'; + public const TYPE_OPTION_NAME = 'option_name'; + public const TYPE_NONE = 'none'; + private array $tokens; + private int $currentIndex; + private string $completionType; + private ?string $completionName = null; + private string $completionValue = ''; + /** + * Converts a terminal string into tokens. + * + * This is required for shell completions without COMP_WORDS support. + */ + public static function fromString(string $inputStr, int $currentIndex) : self + { + } + /** + * Create an input based on an COMP_WORDS token list. + * + * @param string[] $tokens the set of split tokens (e.g. COMP_WORDS or argv) + * @param $currentIndex the index of the cursor (e.g. COMP_CWORD) + */ + public static function fromTokens(array $tokens, int $currentIndex) : self + { + } + public function bind(\Symfony\Component\Console\Input\InputDefinition $definition) : void + { + } + /** + * Returns the type of completion required. + * + * TYPE_ARGUMENT_VALUE when completing the value of an input argument + * TYPE_OPTION_VALUE when completing the value of an input option + * TYPE_OPTION_NAME when completing the name of an input option + * TYPE_NONE when nothing should be completed + * + * TYPE_OPTION_NAME and TYPE_NONE are already implemented by the Console component. + * + * @return self::TYPE_* + */ + public function getCompletionType() : string + { + } + /** + * The name of the input option or argument when completing a value. + * + * @return string|null returns null when completing an option name + */ + public function getCompletionName() : ?string + { + } + /** + * The value already typed by the user (or empty string). + */ + public function getCompletionValue() : string + { + } + public function mustSuggestOptionValuesFor(string $optionName) : bool + { + } + public function mustSuggestArgumentValuesFor(string $argumentName) : bool + { + } + protected function parseToken(string $token, bool $parseOptions) : bool + { + } + private function getOptionFromToken(string $optionToken) : ?\Symfony\Component\Console\Input\InputOption + { + } + /** + * The token of the cursor, or the last token if the cursor is at the end of the input. + */ + private function getRelevantToken() : string + { + } + /** + * Whether the cursor is "free" (i.e. at the end of the input preceded by a space). + */ + private function isCursorFree() : bool + { + } + public function __toString() + { + } +} +namespace Symfony\Component\Console\Input; + +/** + * Represents a command line argument. + * + * @author Fabien Potencier + */ +class InputArgument +{ + public const REQUIRED = 1; + public const OPTIONAL = 2; + public const IS_ARRAY = 4; + private string $name; + private int $mode; + private string|int|bool|array|null|float $default; + private array|\Closure $suggestedValues; + private string $description; + /** + * @param string $name The argument name + * @param int|null $mode The argument mode: a bit mask of self::REQUIRED, self::OPTIONAL and self::IS_ARRAY + * @param string $description A description text + * @param string|bool|int|float|array|null $default The default value (for self::OPTIONAL mode only) + * @param array|\Closure(CompletionInput,CompletionSuggestions):list $suggestedValues The values used for input completion + * + * @throws InvalidArgumentException When argument mode is not valid + */ + public function __construct(string $name, int $mode = null, string $description = '', string|bool|int|float|array $default = null, \Closure|array $suggestedValues = []) + { + } + /** + * Returns the argument name. + */ + public function getName() : string + { + } + /** + * Returns true if the argument is required. + * + * @return bool true if parameter mode is self::REQUIRED, false otherwise + */ + public function isRequired() : bool + { + } + /** + * Returns true if the argument can take multiple values. + * + * @return bool true if mode is self::IS_ARRAY, false otherwise + */ + public function isArray() : bool + { + } + /** + * Sets the default value. + * + * @return void + * + * @throws LogicException When incorrect default value is given + */ + public function setDefault(string|bool|int|float|array $default = null) + { + } + /** + * Returns the default value. + */ + public function getDefault() : string|bool|int|float|array|null + { + } + public function hasCompletion() : bool + { + } + /** + * Adds suggestions to $suggestions for the current completion input. + * + * @see Command::complete() + */ + public function complete(\Symfony\Component\Console\Completion\CompletionInput $input, \Symfony\Component\Console\Completion\CompletionSuggestions $suggestions) : void + { + } + /** + * Returns the description text. + */ + public function getDescription() : string + { + } +} +namespace Symfony\Component\Console\Input; + +/** + * InputInterface is the interface implemented by all input classes. + * + * @author Fabien Potencier + * + * @method string __toString() Returns a stringified representation of the args passed to the command. + * InputArguments MUST be escaped as well as the InputOption values passed to the command. + */ +interface InputInterface +{ + /** + * Returns the first argument from the raw parameters (not parsed). + */ + public function getFirstArgument() : ?string; + /** + * Returns true if the raw parameters (not parsed) contain a value. + * + * This method is to be used to introspect the input parameters + * before they have been validated. It must be used carefully. + * Does not necessarily return the correct result for short options + * when multiple flags are combined in the same option. + * + * @param string|array $values The values to look for in the raw parameters (can be an array) + * @param bool $onlyParams Only check real parameters, skip those following an end of options (--) signal + */ + public function hasParameterOption(string|array $values, bool $onlyParams = false) : bool; + /** + * Returns the value of a raw option (not parsed). + * + * This method is to be used to introspect the input parameters + * before they have been validated. It must be used carefully. + * Does not necessarily return the correct result for short options + * when multiple flags are combined in the same option. + * + * @param string|array $values The value(s) to look for in the raw parameters (can be an array) + * @param string|bool|int|float|array|null $default The default value to return if no result is found + * @param bool $onlyParams Only check real parameters, skip those following an end of options (--) signal + * + * @return mixed + */ + public function getParameterOption(string|array $values, string|bool|int|float|array|null $default = false, bool $onlyParams = false); + /** + * Binds the current Input instance with the given arguments and options. + * + * @return void + * + * @throws RuntimeException + */ + public function bind(InputDefinition $definition); + /** + * Validates the input. + * + * @return void + * + * @throws RuntimeException When not enough arguments are given + */ + public function validate(); + /** + * Returns all the given arguments merged with the default values. + * + * @return array + */ + public function getArguments() : array; + /** + * Returns the argument value for a given argument name. + * + * @return mixed + * + * @throws InvalidArgumentException When argument given doesn't exist + */ + public function getArgument(string $name); + /** + * Sets an argument value by name. + * + * @return void + * + * @throws InvalidArgumentException When argument given doesn't exist + */ + public function setArgument(string $name, mixed $value); + /** + * Returns true if an InputArgument object exists by name or position. + */ + public function hasArgument(string $name) : bool; + /** + * Returns all the given options merged with the default values. + * + * @return array + */ + public function getOptions() : array; + /** + * Returns the option value for a given option name. + * + * @return mixed + * + * @throws InvalidArgumentException When option given doesn't exist + */ + public function getOption(string $name); + /** + * Sets an option value by name. + * + * @return void + * + * @throws InvalidArgumentException When option given doesn't exist + */ + public function setOption(string $name, mixed $value); + /** + * Returns true if an InputOption object exists by name. + */ + public function hasOption(string $name) : bool; + /** + * Is this input means interactive? + */ + public function isInteractive() : bool; + /** + * Sets the input interactivity. + * + * @return void + */ + public function setInteractive(bool $interactive); +} +namespace Symfony\Component\Console\Input; + +/** + * Represents a command line option. + * + * @author Fabien Potencier + */ +class InputOption +{ + /** + * Do not accept input for the option (e.g. --yell). This is the default behavior of options. + */ + public const VALUE_NONE = 1; + /** + * A value must be passed when the option is used (e.g. --iterations=5 or -i5). + */ + public const VALUE_REQUIRED = 2; + /** + * The option may or may not have a value (e.g. --yell or --yell=loud). + */ + public const VALUE_OPTIONAL = 4; + /** + * The option accepts multiple values (e.g. --dir=/foo --dir=/bar). + */ + public const VALUE_IS_ARRAY = 8; + /** + * The option may have either positive or negative value (e.g. --ansi or --no-ansi). + */ + public const VALUE_NEGATABLE = 16; + private string $name; + private string|array|null $shortcut; + private int $mode; + private string|int|bool|array|null|float $default; + private array|\Closure $suggestedValues; + private string $description; + /** + * @param string|array|null $shortcut The shortcuts, can be null, a string of shortcuts delimited by | or an array of shortcuts + * @param int|null $mode The option mode: One of the VALUE_* constants + * @param string|bool|int|float|array|null $default The default value (must be null for self::VALUE_NONE) + * @param array|\Closure(CompletionInput,CompletionSuggestions):list $suggestedValues The values used for input completion + * + * @throws InvalidArgumentException If option mode is invalid or incompatible + */ + public function __construct(string $name, string|array $shortcut = null, int $mode = null, string $description = '', string|bool|int|float|array $default = null, array|\Closure $suggestedValues = []) + { + } + /** + * Returns the option shortcut. + */ + public function getShortcut() : ?string + { + } + /** + * Returns the option name. + */ + public function getName() : string + { + } + /** + * Returns true if the option accepts a value. + * + * @return bool true if value mode is not self::VALUE_NONE, false otherwise + */ + public function acceptValue() : bool + { + } + /** + * Returns true if the option requires a value. + * + * @return bool true if value mode is self::VALUE_REQUIRED, false otherwise + */ + public function isValueRequired() : bool + { + } + /** + * Returns true if the option takes an optional value. + * + * @return bool true if value mode is self::VALUE_OPTIONAL, false otherwise + */ + public function isValueOptional() : bool + { + } + /** + * Returns true if the option can take multiple values. + * + * @return bool true if mode is self::VALUE_IS_ARRAY, false otherwise + */ + public function isArray() : bool + { + } + public function isNegatable() : bool + { + } + /** + * @return void + */ + public function setDefault(string|bool|int|float|array $default = null) + { + } + /** + * Returns the default value. + */ + public function getDefault() : string|bool|int|float|array|null + { + } + /** + * Returns the description text. + */ + public function getDescription() : string + { + } + public function hasCompletion() : bool + { + } + /** + * Adds suggestions to $suggestions for the current completion input. + * + * @see Command::complete() + */ + public function complete(\Symfony\Component\Console\Completion\CompletionInput $input, \Symfony\Component\Console\Completion\CompletionSuggestions $suggestions) : void + { + } + /** + * Checks whether the given option equals this one. + */ + public function equals(self $option) : bool + { + } +} +namespace Symfony\Component\Console\Output; + +/** + * OutputInterface is the interface implemented by all Output classes. + * + * @author Fabien Potencier + */ +interface OutputInterface +{ + public const VERBOSITY_QUIET = 16; + public const VERBOSITY_NORMAL = 32; + public const VERBOSITY_VERBOSE = 64; + public const VERBOSITY_VERY_VERBOSE = 128; + public const VERBOSITY_DEBUG = 256; + public const OUTPUT_NORMAL = 1; + public const OUTPUT_RAW = 2; + public const OUTPUT_PLAIN = 4; + /** + * Writes a message to the output. + * + * @param bool $newline Whether to add a newline + * @param int $options A bitmask of options (one of the OUTPUT or VERBOSITY constants), + * 0 is considered the same as self::OUTPUT_NORMAL | self::VERBOSITY_NORMAL + * + * @return void + */ + public function write(string|iterable $messages, bool $newline = false, int $options = 0); + /** + * Writes a message to the output and adds a newline at the end. + * + * @param int $options A bitmask of options (one of the OUTPUT or VERBOSITY constants), + * 0 is considered the same as self::OUTPUT_NORMAL | self::VERBOSITY_NORMAL + * + * @return void + */ + public function writeln(string|iterable $messages, int $options = 0); + /** + * Sets the verbosity of the output. + * + * @param self::VERBOSITY_* $level + * + * @return void + */ + public function setVerbosity(int $level); + /** + * Gets the current verbosity of the output. + * + * @return self::VERBOSITY_* + */ + public function getVerbosity() : int; + /** + * Returns whether verbosity is quiet (-q). + */ + public function isQuiet() : bool; + /** + * Returns whether verbosity is verbose (-v). + */ + public function isVerbose() : bool; + /** + * Returns whether verbosity is very verbose (-vv). + */ + public function isVeryVerbose() : bool; + /** + * Returns whether verbosity is debug (-vvv). + */ + public function isDebug() : bool; + /** + * Sets the decorated flag. + * + * @return void + */ + public function setDecorated(bool $decorated); + /** + * Gets the decorated flag. + */ + public function isDecorated() : bool; + /** + * @return void + */ + public function setFormatter(\Symfony\Component\Console\Formatter\OutputFormatterInterface $formatter); + /** + * Returns current output formatter instance. + */ + public function getFormatter() : \Symfony\Component\Console\Formatter\OutputFormatterInterface; +} +namespace Symfony\Component\Console\Style; + +/** + * Output decorator helpers for the Symfony Style Guide. + * + * @author Kevin Bond + */ +class SymfonyStyle extends OutputStyle +{ + public const MAX_LINE_LENGTH = 120; + private \Symfony\Component\Console\Input\InputInterface $input; + private \Symfony\Component\Console\Output\OutputInterface $output; + private \Symfony\Component\Console\Helper\SymfonyQuestionHelper $questionHelper; + private \Symfony\Component\Console\Helper\ProgressBar $progressBar; + private int $lineLength; + private \Symfony\Component\Console\Output\TrimmedBufferOutput $bufferedOutput; + public function __construct(\Symfony\Component\Console\Input\InputInterface $input, \Symfony\Component\Console\Output\OutputInterface $output) + { + } + /** + * Formats a message as a block of text. + * + * @return void + */ + public function block(string|array $messages, string $type = null, string $style = null, string $prefix = ' ', bool $padding = false, bool $escape = true) + { + } + /** + * @return void + */ + public function title(string $message) + { + } + /** + * @return void + */ + public function section(string $message) + { + } + /** + * @return void + */ + public function listing(array $elements) + { + } + /** + * @return void + */ + public function text(string|array $message) + { + } + /** + * Formats a command comment. + * + * @return void + */ + public function comment(string|array $message) + { + } + /** + * @return void + */ + public function success(string|array $message) + { + } + /** + * @return void + */ + public function error(string|array $message) + { + } + /** + * @return void + */ + public function warning(string|array $message) + { + } + /** + * @return void + */ + public function note(string|array $message) + { + } + /** + * Formats an info message. + * + * @return void + */ + public function info(string|array $message) + { + } + /** + * @return void + */ + public function caution(string|array $message) + { + } + /** + * @return void + */ + public function table(array $headers, array $rows) + { + } + /** + * Formats a horizontal table. + * + * @return void + */ + public function horizontalTable(array $headers, array $rows) + { + } + /** + * Formats a list of key/value horizontally. + * + * Each row can be one of: + * * 'A title' + * * ['key' => 'value'] + * * new TableSeparator() + * + * @return void + */ + public function definitionList(string|array|\Symfony\Component\Console\Helper\TableSeparator ...$list) + { + } + public function ask(string $question, string $default = null, callable $validator = null) : mixed + { + } + public function askHidden(string $question, callable $validator = null) : mixed + { + } + public function confirm(string $question, bool $default = true) : bool + { + } + public function choice(string $question, array $choices, mixed $default = null, bool $multiSelect = false) : mixed + { + } + /** + * @return void + */ + public function progressStart(int $max = 0) + { + } + /** + * @return void + */ + public function progressAdvance(int $step = 1) + { + } + /** + * @return void + */ + public function progressFinish() + { + } + public function createProgressBar(int $max = 0) : \Symfony\Component\Console\Helper\ProgressBar + { + } + /** + * @see ProgressBar::iterate() + * + * @template TKey + * @template TValue + * + * @param iterable $iterable + * @param int|null $max Number of steps to complete the bar (0 if indeterminate), if null it will be inferred from $iterable + * + * @return iterable + */ + public function progressIterate(iterable $iterable, int $max = null) : iterable + { + } + public function askQuestion(\Symfony\Component\Console\Question\Question $question) : mixed + { + } + /** + * @return void + */ + public function writeln(string|iterable $messages, int $type = self::OUTPUT_NORMAL) + { + } + /** + * @return void + */ + public function write(string|iterable $messages, bool $newline = false, int $type = self::OUTPUT_NORMAL) + { + } + /** + * @return void + */ + public function newLine(int $count = 1) + { + } + /** + * Returns a new instance which makes use of stderr if available. + */ + public function getErrorStyle() : self + { + } + public function createTable() : \Symfony\Component\Console\Helper\Table + { + } + private function getProgressBar() : \Symfony\Component\Console\Helper\ProgressBar + { + } + private function autoPrependBlock() : void + { + } + private function autoPrependText() : void + { + } + private function writeBuffer(string $message, bool $newLine, int $type) : void + { + } + private function createBlock(iterable $messages, string $type = null, string $style = null, string $prefix = ' ', bool $padding = false, bool $escape = false) : array + { + } +} +namespace Symfony\Component\Filesystem\Exception; + +/** + * Exception interface for all exceptions thrown by the component. + * + * @author Romain Neutron + */ +interface ExceptionInterface extends \Throwable +{ +} +namespace Symfony\Component\Filesystem; + +/** + * Provides basic utility to manipulate the file system. + * + * @author Fabien Potencier + */ +class Filesystem +{ + private static ?string $lastError = null; + /** + * Copies a file. + * + * If the target file is older than the origin file, it's always overwritten. + * If the target file is newer, it is overwritten only when the + * $overwriteNewerFiles option is set to true. + * + * @return void + * + * @throws FileNotFoundException When originFile doesn't exist + * @throws IOException When copy fails + */ + public function copy(string $originFile, string $targetFile, bool $overwriteNewerFiles = false) + { + } + /** + * Creates a directory recursively. + * + * @return void + * + * @throws IOException On any directory creation failure + */ + public function mkdir(string|iterable $dirs, int $mode = 0777) + { + } + /** + * Checks the existence of files or directories. + */ + public function exists(string|iterable $files) : bool + { + } + /** + * Sets access and modification time of file. + * + * @param int|null $time The touch time as a Unix timestamp, if not supplied the current system time is used + * @param int|null $atime The access time as a Unix timestamp, if not supplied the current system time is used + * + * @return void + * + * @throws IOException When touch fails + */ + public function touch(string|iterable $files, ?int $time = null, ?int $atime = null) + { + } + /** + * Removes files or directories. + * + * @return void + * + * @throws IOException When removal fails + */ + public function remove(string|iterable $files) + { + } + private static function doRemove(array $files, bool $isRecursive) : void + { + } + /** + * Change mode for an array of files or directories. + * + * @param int $mode The new mode (octal) + * @param int $umask The mode mask (octal) + * @param bool $recursive Whether change the mod recursively or not + * + * @return void + * + * @throws IOException When the change fails + */ + public function chmod(string|iterable $files, int $mode, int $umask = 00, bool $recursive = false) + { + } + /** + * Change the owner of an array of files or directories. + * + * @param string|int $user A user name or number + * @param bool $recursive Whether change the owner recursively or not + * + * @return void + * + * @throws IOException When the change fails + */ + public function chown(string|iterable $files, string|int $user, bool $recursive = false) + { + } + /** + * Change the group of an array of files or directories. + * + * @param string|int $group A group name or number + * @param bool $recursive Whether change the group recursively or not + * + * @return void + * + * @throws IOException When the change fails + */ + public function chgrp(string|iterable $files, string|int $group, bool $recursive = false) + { + } + /** + * Renames a file or a directory. + * + * @return void + * + * @throws IOException When target file or directory already exists + * @throws IOException When origin cannot be renamed + */ + public function rename(string $origin, string $target, bool $overwrite = false) + { + } + /** + * Tells whether a file exists and is readable. + * + * @throws IOException When windows path is longer than 258 characters + */ + private function isReadable(string $filename) : bool + { + } + /** + * Creates a symbolic link or copy a directory. + * + * @return void + * + * @throws IOException When symlink fails + */ + public function symlink(string $originDir, string $targetDir, bool $copyOnWindows = false) + { + } + /** + * Creates a hard link, or several hard links to a file. + * + * @param string|string[] $targetFiles The target file(s) + * + * @return void + * + * @throws FileNotFoundException When original file is missing or not a file + * @throws IOException When link fails, including if link already exists + */ + public function hardlink(string $originFile, string|iterable $targetFiles) + { + } + /** + * @param string $linkType Name of the link type, typically 'symbolic' or 'hard' + */ + private function linkException(string $origin, string $target, string $linkType) : never + { + } + /** + * Resolves links in paths. + * + * With $canonicalize = false (default) + * - if $path does not exist or is not a link, returns null + * - if $path is a link, returns the next direct target of the link without considering the existence of the target + * + * With $canonicalize = true + * - if $path does not exist, returns null + * - if $path exists, returns its absolute fully resolved final version + */ + public function readlink(string $path, bool $canonicalize = false) : ?string + { + } + /** + * Given an existing path, convert it to a path relative to a given starting path. + */ + public function makePathRelative(string $endPath, string $startPath) : string + { + } + /** + * Mirrors a directory to another. + * + * Copies files and directories from the origin directory into the target directory. By default: + * + * - existing files in the target directory will be overwritten, except if they are newer (see the `override` option) + * - files in the target directory that do not exist in the source directory will not be deleted (see the `delete` option) + * + * @param \Traversable|null $iterator Iterator that filters which files and directories to copy, if null a recursive iterator is created + * @param array $options An array of boolean options + * Valid options are: + * - $options['override'] If true, target files newer than origin files are overwritten (see copy(), defaults to false) + * - $options['copy_on_windows'] Whether to copy files instead of links on Windows (see symlink(), defaults to false) + * - $options['delete'] Whether to delete files that are not in the source directory (defaults to false) + * + * @return void + * + * @throws IOException When file type is unknown + */ + public function mirror(string $originDir, string $targetDir, ?\Traversable $iterator = null, array $options = []) + { + } + /** + * Returns whether the file path is an absolute path. + */ + public function isAbsolutePath(string $file) : bool + { + } + /** + * Creates a temporary file with support for custom stream wrappers. + * + * @param string $prefix The prefix of the generated temporary filename + * Note: Windows uses only the first three characters of prefix + * @param string $suffix The suffix of the generated temporary filename + * + * @return string The new temporary filename (with path), or throw an exception on failure + */ + public function tempnam(string $dir, string $prefix, string $suffix = '') : string + { + } + /** + * Atomically dumps content into a file. + * + * @param string|resource $content The data to write into the file + * + * @return void + * + * @throws IOException if the file cannot be written to + */ + public function dumpFile(string $filename, $content) + { + } + /** + * Appends content to an existing file. + * + * @param string|resource $content The content to append + * @param bool $lock Whether the file should be locked when writing to it + * + * @return void + * + * @throws IOException If the file is not writable + */ + public function appendToFile(string $filename, $content) + { + } + private function toIterable(string|iterable $files) : iterable + { + } + /** + * Gets a 2-tuple of scheme (may be null) and hierarchical part of a filename (e.g. file:///tmp -> [file, tmp]). + */ + private function getSchemeAndHierarchy(string $filename) : array + { + } + private static function assertFunctionExists(string $func) : void + { + } + private static function box(string $func, mixed ...$args) : mixed + { + } +} +namespace Symfony\Component\Filesystem; + +/** + * Contains utility methods for handling path strings. + * + * The methods in this class are able to deal with both UNIX and Windows paths + * with both forward and backward slashes. All methods return normalized parts + * containing only forward slashes and no excess "." and ".." segments. + * + * @author Bernhard Schussek + * @author Thomas Schulz + * @author Théo Fidry + */ +final class Path +{ + /** + * The number of buffer entries that triggers a cleanup operation. + */ + private const CLEANUP_THRESHOLD = 1250; + /** + * The buffer size after the cleanup operation. + */ + private const CLEANUP_SIZE = 1000; + /** + * Buffers input/output of {@link canonicalize()}. + * + * @var array + */ + private static array $buffer = []; + private static int $bufferSize = 0; + /** + * Canonicalizes the given path. + * + * During normalization, all slashes are replaced by forward slashes ("/"). + * Furthermore, all "." and ".." segments are removed as far as possible. + * ".." segments at the beginning of relative paths are not removed. + * + * ```php + * echo Path::canonicalize("\symfony\puli\..\css\style.css"); + * // => /symfony/css/style.css + * + * echo Path::canonicalize("../css/./style.css"); + * // => ../css/style.css + * ``` + * + * This method is able to deal with both UNIX and Windows paths. + */ + public static function canonicalize(string $path) : string + { + } + /** + * Normalizes the given path. + * + * During normalization, all slashes are replaced by forward slashes ("/"). + * Contrary to {@link canonicalize()}, this method does not remove invalid + * or dot path segments. Consequently, it is much more efficient and should + * be used whenever the given path is known to be a valid, absolute system + * path. + * + * This method is able to deal with both UNIX and Windows paths. + */ + public static function normalize(string $path) : string + { + } + /** + * Returns the directory part of the path. + * + * This method is similar to PHP's dirname(), but handles various cases + * where dirname() returns a weird result: + * + * - dirname() does not accept backslashes on UNIX + * - dirname("C:/symfony") returns "C:", not "C:/" + * - dirname("C:/") returns ".", not "C:/" + * - dirname("C:") returns ".", not "C:/" + * - dirname("symfony") returns ".", not "" + * - dirname() does not canonicalize the result + * + * This method fixes these shortcomings and behaves like dirname() + * otherwise. + * + * The result is a canonical path. + * + * @return string The canonical directory part. Returns the root directory + * if the root directory is passed. Returns an empty string + * if a relative path is passed that contains no slashes. + * Returns an empty string if an empty string is passed. + */ + public static function getDirectory(string $path) : string + { + } + /** + * Returns canonical path of the user's home directory. + * + * Supported operating systems: + * + * - UNIX + * - Windows8 and upper + * + * If your operating system or environment isn't supported, an exception is thrown. + * + * The result is a canonical path. + * + * @throws RuntimeException If your operating system or environment isn't supported + */ + public static function getHomeDirectory() : string + { + } + /** + * Returns the root directory of a path. + * + * The result is a canonical path. + * + * @return string The canonical root directory. Returns an empty string if + * the given path is relative or empty. + */ + public static function getRoot(string $path) : string + { + } + /** + * Returns the file name without the extension from a file path. + * + * @param string|null $extension if specified, only that extension is cut + * off (may contain leading dot) + */ + public static function getFilenameWithoutExtension(string $path, ?string $extension = null) : string + { + } + /** + * Returns the extension from a file path (without leading dot). + * + * @param bool $forceLowerCase forces the extension to be lower-case + */ + public static function getExtension(string $path, bool $forceLowerCase = false) : string + { + } + /** + * Returns whether the path has an (or the specified) extension. + * + * @param string $path the path string + * @param string|string[]|null $extensions if null or not provided, checks if + * an extension exists, otherwise + * checks for the specified extension + * or array of extensions (with or + * without leading dot) + * @param bool $ignoreCase whether to ignore case-sensitivity + */ + public static function hasExtension(string $path, $extensions = null, bool $ignoreCase = false) : bool + { + } + /** + * Changes the extension of a path string. + * + * @param string $path The path string with filename.ext to change. + * @param string $extension new extension (with or without leading dot) + * + * @return string the path string with new file extension + */ + public static function changeExtension(string $path, string $extension) : string + { + } + public static function isAbsolute(string $path) : bool + { + } + public static function isRelative(string $path) : bool + { + } + /** + * Turns a relative path into an absolute path in canonical form. + * + * Usually, the relative path is appended to the given base path. Dot + * segments ("." and "..") are removed/collapsed and all slashes turned + * into forward slashes. + * + * ```php + * echo Path::makeAbsolute("../style.css", "/symfony/puli/css"); + * // => /symfony/puli/style.css + * ``` + * + * If an absolute path is passed, that path is returned unless its root + * directory is different than the one of the base path. In that case, an + * exception is thrown. + * + * ```php + * Path::makeAbsolute("/style.css", "/symfony/puli/css"); + * // => /style.css + * + * Path::makeAbsolute("C:/style.css", "C:/symfony/puli/css"); + * // => C:/style.css + * + * Path::makeAbsolute("C:/style.css", "/symfony/puli/css"); + * // InvalidArgumentException + * ``` + * + * If the base path is not an absolute path, an exception is thrown. + * + * The result is a canonical path. + * + * @param string $basePath an absolute base path + * + * @throws InvalidArgumentException if the base path is not absolute or if + * the given path is an absolute path with + * a different root than the base path + */ + public static function makeAbsolute(string $path, string $basePath) : string + { + } + /** + * Turns a path into a relative path. + * + * The relative path is created relative to the given base path: + * + * ```php + * echo Path::makeRelative("/symfony/style.css", "/symfony/puli"); + * // => ../style.css + * ``` + * + * If a relative path is passed and the base path is absolute, the relative + * path is returned unchanged: + * + * ```php + * Path::makeRelative("style.css", "/symfony/puli/css"); + * // => style.css + * ``` + * + * If both paths are relative, the relative path is created with the + * assumption that both paths are relative to the same directory: + * + * ```php + * Path::makeRelative("style.css", "symfony/puli/css"); + * // => ../../../style.css + * ``` + * + * If both paths are absolute, their root directory must be the same, + * otherwise an exception is thrown: + * + * ```php + * Path::makeRelative("C:/symfony/style.css", "/symfony/puli"); + * // InvalidArgumentException + * ``` + * + * If the passed path is absolute, but the base path is not, an exception + * is thrown as well: + * + * ```php + * Path::makeRelative("/symfony/style.css", "symfony/puli"); + * // InvalidArgumentException + * ``` + * + * If the base path is not an absolute path, an exception is thrown. + * + * The result is a canonical path. + * + * @throws InvalidArgumentException if the base path is not absolute or if + * the given path has a different root + * than the base path + */ + public static function makeRelative(string $path, string $basePath) : string + { + } + /** + * Returns whether the given path is on the local filesystem. + */ + public static function isLocal(string $path) : bool + { + } + /** + * Returns the longest common base path in canonical form of a set of paths or + * `null` if the paths are on different Windows partitions. + * + * Dot segments ("." and "..") are removed/collapsed and all slashes turned + * into forward slashes. + * + * ```php + * $basePath = Path::getLongestCommonBasePath( + * '/symfony/css/style.css', + * '/symfony/css/..' + * ); + * // => /symfony + * ``` + * + * The root is returned if no common base path can be found: + * + * ```php + * $basePath = Path::getLongestCommonBasePath( + * '/symfony/css/style.css', + * '/puli/css/..' + * ); + * // => / + * ``` + * + * If the paths are located on different Windows partitions, `null` is + * returned. + * + * ```php + * $basePath = Path::getLongestCommonBasePath( + * 'C:/symfony/css/style.css', + * 'D:/symfony/css/..' + * ); + * // => null + * ``` + */ + public static function getLongestCommonBasePath(string ...$paths) : ?string + { + } + /** + * Joins two or more path strings into a canonical path. + */ + public static function join(string ...$paths) : string + { + } + /** + * Returns whether a path is a base path of another path. + * + * Dot segments ("." and "..") are removed/collapsed and all slashes turned + * into forward slashes. + * + * ```php + * Path::isBasePath('/symfony', '/symfony/css'); + * // => true + * + * Path::isBasePath('/symfony', '/symfony'); + * // => true + * + * Path::isBasePath('/symfony', '/symfony/..'); + * // => false + * + * Path::isBasePath('/symfony', '/puli'); + * // => false + * ``` + */ + public static function isBasePath(string $basePath, string $ofPath) : bool + { + } + /** + * @return string[] + */ + private static function findCanonicalParts(string $root, string $pathWithoutRoot) : array + { + } + /** + * Splits a canonical path into its root directory and the remainder. + * + * If the path has no root directory, an empty root directory will be + * returned. + * + * If the root directory is a Windows style partition, the resulting root + * will always contain a trailing slash. + * + * list ($root, $path) = Path::split("C:/symfony") + * // => ["C:/", "symfony"] + * + * list ($root, $path) = Path::split("C:") + * // => ["C:/", ""] + * + * @return array{string, string} an array with the root directory and the remaining relative path + */ + private static function split(string $path) : array + { + } + private static function toLower(string $string) : string + { + } + private function __construct() + { + } +} +namespace Symfony\Component\Finder; + +/** + * Finder allows to build rules to find files and directories. + * + * It is a thin wrapper around several specialized iterator classes. + * + * All rules may be invoked several times. + * + * All methods return the current Finder object to allow chaining: + * + * $finder = Finder::create()->files()->name('*.php')->in(__DIR__); + * + * @author Fabien Potencier + * + * @implements \IteratorAggregate + */ +class Finder implements \IteratorAggregate, \Countable +{ + public const IGNORE_VCS_FILES = 1; + public const IGNORE_DOT_FILES = 2; + public const IGNORE_VCS_IGNORED_FILES = 4; + private int $mode = 0; + private array $names = []; + private array $notNames = []; + private array $exclude = []; + private array $filters = []; + private array $pruneFilters = []; + private array $depths = []; + private array $sizes = []; + private bool $followLinks = false; + private bool $reverseSorting = false; + private \Closure|int|false $sort = false; + private int $ignore = 0; + private array $dirs = []; + private array $dates = []; + private array $iterators = []; + private array $contains = []; + private array $notContains = []; + private array $paths = []; + private array $notPaths = []; + private bool $ignoreUnreadableDirs = false; + private static array $vcsPatterns = ['.svn', '_svn', 'CVS', '_darcs', '.arch-params', '.monotone', '.bzr', '.git', '.hg']; + public function __construct() + { + } + /** + * Creates a new Finder. + */ + public static function create() : static + { + } + /** + * Restricts the matching to directories only. + * + * @return $this + */ + public function directories() : static + { + } + /** + * Restricts the matching to files only. + * + * @return $this + */ + public function files() : static + { + } + /** + * Adds tests for the directory depth. + * + * Usage: + * + * $finder->depth('> 1') // the Finder will start matching at level 1. + * $finder->depth('< 3') // the Finder will descend at most 3 levels of directories below the starting point. + * $finder->depth(['>= 1', '< 3']) + * + * @param string|int|string[]|int[] $levels The depth level expression or an array of depth levels + * + * @return $this + * + * @see DepthRangeFilterIterator + * @see NumberComparator + */ + public function depth(string|int|array $levels) : static + { + } + /** + * Adds tests for file dates (last modified). + * + * The date must be something that strtotime() is able to parse: + * + * $finder->date('since yesterday'); + * $finder->date('until 2 days ago'); + * $finder->date('> now - 2 hours'); + * $finder->date('>= 2005-10-15'); + * $finder->date(['>= 2005-10-15', '<= 2006-05-27']); + * + * @param string|string[] $dates A date range string or an array of date ranges + * + * @return $this + * + * @see strtotime + * @see DateRangeFilterIterator + * @see DateComparator + */ + public function date(string|array $dates) : static + { + } + /** + * Adds rules that files must match. + * + * You can use patterns (delimited with / sign), globs or simple strings. + * + * $finder->name('/\.php$/') + * $finder->name('*.php') // same as above, without dot files + * $finder->name('test.php') + * $finder->name(['test.py', 'test.php']) + * + * @param string|string[] $patterns A pattern (a regexp, a glob, or a string) or an array of patterns + * + * @return $this + * + * @see FilenameFilterIterator + */ + public function name(string|array $patterns) : static + { + } + /** + * Adds rules that files must not match. + * + * @param string|string[] $patterns A pattern (a regexp, a glob, or a string) or an array of patterns + * + * @return $this + * + * @see FilenameFilterIterator + */ + public function notName(string|array $patterns) : static + { + } + /** + * Adds tests that file contents must match. + * + * Strings or PCRE patterns can be used: + * + * $finder->contains('Lorem ipsum') + * $finder->contains('/Lorem ipsum/i') + * $finder->contains(['dolor', '/ipsum/i']) + * + * @param string|string[] $patterns A pattern (string or regexp) or an array of patterns + * + * @return $this + * + * @see FilecontentFilterIterator + */ + public function contains(string|array $patterns) : static + { + } + /** + * Adds tests that file contents must not match. + * + * Strings or PCRE patterns can be used: + * + * $finder->notContains('Lorem ipsum') + * $finder->notContains('/Lorem ipsum/i') + * $finder->notContains(['lorem', '/dolor/i']) + * + * @param string|string[] $patterns A pattern (string or regexp) or an array of patterns + * + * @return $this + * + * @see FilecontentFilterIterator + */ + public function notContains(string|array $patterns) : static + { + } + /** + * Adds rules that filenames must match. + * + * You can use patterns (delimited with / sign) or simple strings. + * + * $finder->path('some/special/dir') + * $finder->path('/some\/special\/dir/') // same as above + * $finder->path(['some dir', 'another/dir']) + * + * Use only / as dirname separator. + * + * @param string|string[] $patterns A pattern (a regexp or a string) or an array of patterns + * + * @return $this + * + * @see FilenameFilterIterator + */ + public function path(string|array $patterns) : static + { + } + /** + * Adds rules that filenames must not match. + * + * You can use patterns (delimited with / sign) or simple strings. + * + * $finder->notPath('some/special/dir') + * $finder->notPath('/some\/special\/dir/') // same as above + * $finder->notPath(['some/file.txt', 'another/file.log']) + * + * Use only / as dirname separator. + * + * @param string|string[] $patterns A pattern (a regexp or a string) or an array of patterns + * + * @return $this + * + * @see FilenameFilterIterator + */ + public function notPath(string|array $patterns) : static + { + } + /** + * Adds tests for file sizes. + * + * $finder->size('> 10K'); + * $finder->size('<= 1Ki'); + * $finder->size(4); + * $finder->size(['> 10K', '< 20K']) + * + * @param string|int|string[]|int[] $sizes A size range string or an integer or an array of size ranges + * + * @return $this + * + * @see SizeRangeFilterIterator + * @see NumberComparator + */ + public function size(string|int|array $sizes) : static + { + } + /** + * Excludes directories. + * + * Directories passed as argument must be relative to the ones defined with the `in()` method. For example: + * + * $finder->in(__DIR__)->exclude('ruby'); + * + * @param string|array $dirs A directory path or an array of directories + * + * @return $this + * + * @see ExcludeDirectoryFilterIterator + */ + public function exclude(string|array $dirs) : static + { + } + /** + * Excludes "hidden" directories and files (starting with a dot). + * + * This option is enabled by default. + * + * @return $this + * + * @see ExcludeDirectoryFilterIterator + */ + public function ignoreDotFiles(bool $ignoreDotFiles) : static + { + } + /** + * Forces the finder to ignore version control directories. + * + * This option is enabled by default. + * + * @return $this + * + * @see ExcludeDirectoryFilterIterator + */ + public function ignoreVCS(bool $ignoreVCS) : static + { + } + /** + * Forces Finder to obey .gitignore and ignore files based on rules listed there. + * + * This option is disabled by default. + * + * @return $this + */ + public function ignoreVCSIgnored(bool $ignoreVCSIgnored) : static + { + } + /** + * Adds VCS patterns. + * + * @see ignoreVCS() + * + * @param string|string[] $pattern VCS patterns to ignore + * + * @return void + */ + public static function addVCSPattern(string|array $pattern) + { + } + /** + * Sorts files and directories by an anonymous function. + * + * The anonymous function receives two \SplFileInfo instances to compare. + * + * This can be slow as all the matching files and directories must be retrieved for comparison. + * + * @return $this + * + * @see SortableIterator + */ + public function sort(\Closure $closure) : static + { + } + /** + * Sorts files and directories by extension. + * + * This can be slow as all the matching files and directories must be retrieved for comparison. + * + * @return $this + * + * @see SortableIterator + */ + public function sortByExtension() : static + { + } + /** + * Sorts files and directories by name. + * + * This can be slow as all the matching files and directories must be retrieved for comparison. + * + * @return $this + * + * @see SortableIterator + */ + public function sortByName(bool $useNaturalSort = false) : static + { + } + /** + * Sorts files and directories by name case insensitive. + * + * This can be slow as all the matching files and directories must be retrieved for comparison. + * + * @return $this + * + * @see SortableIterator + */ + public function sortByCaseInsensitiveName(bool $useNaturalSort = false) : static + { + } + /** + * Sorts files and directories by size. + * + * This can be slow as all the matching files and directories must be retrieved for comparison. + * + * @return $this + * + * @see SortableIterator + */ + public function sortBySize() : static + { + } + /** + * Sorts files and directories by type (directories before files), then by name. + * + * This can be slow as all the matching files and directories must be retrieved for comparison. + * + * @return $this + * + * @see SortableIterator + */ + public function sortByType() : static + { + } + /** + * Sorts files and directories by the last accessed time. + * + * This is the time that the file was last accessed, read or written to. + * + * This can be slow as all the matching files and directories must be retrieved for comparison. + * + * @return $this + * + * @see SortableIterator + */ + public function sortByAccessedTime() : static + { + } + /** + * Reverses the sorting. + * + * @return $this + */ + public function reverseSorting() : static + { + } + /** + * Sorts files and directories by the last inode changed time. + * + * This is the time that the inode information was last modified (permissions, owner, group or other metadata). + * + * On Windows, since inode is not available, changed time is actually the file creation time. + * + * This can be slow as all the matching files and directories must be retrieved for comparison. + * + * @return $this + * + * @see SortableIterator + */ + public function sortByChangedTime() : static + { + } + /** + * Sorts files and directories by the last modified time. + * + * This is the last time the actual contents of the file were last modified. + * + * This can be slow as all the matching files and directories must be retrieved for comparison. + * + * @return $this + * + * @see SortableIterator + */ + public function sortByModifiedTime() : static + { + } + /** + * Filters the iterator with an anonymous function. + * + * The anonymous function receives a \SplFileInfo and must return false + * to remove files. + * + * @param \Closure(SplFileInfo): bool $closure + * @param bool $prune Whether to skip traversing directories further + * + * @return $this + * + * @see CustomFilterIterator + */ + public function filter(\Closure $closure) : static + { + } + /** + * Forces the following of symlinks. + * + * @return $this + */ + public function followLinks() : static + { + } + /** + * Tells finder to ignore unreadable directories. + * + * By default, scanning unreadable directories content throws an AccessDeniedException. + * + * @return $this + */ + public function ignoreUnreadableDirs(bool $ignore = true) : static + { + } + /** + * Searches files and directories which match defined rules. + * + * @param string|string[] $dirs A directory path or an array of directories + * + * @return $this + * + * @throws DirectoryNotFoundException if one of the directories does not exist + */ + public function in(string|array $dirs) : static + { + } + /** + * Returns an Iterator for the current Finder configuration. + * + * This method implements the IteratorAggregate interface. + * + * @return \Iterator + * + * @throws \LogicException if the in() method has not been called + */ + public function getIterator() : \Iterator + { + } + /** + * Appends an existing set of files/directories to the finder. + * + * The set can be another Finder, an Iterator, an IteratorAggregate, or even a plain array. + * + * @return $this + * + * @throws \InvalidArgumentException when the given argument is not iterable + */ + public function append(iterable $iterator) : static + { + } + /** + * Check if any results were found. + */ + public function hasResults() : bool + { + } + /** + * Counts all the results collected by the iterators. + */ + public function count() : int + { + } + private function searchInDirectory(string $dir) : \Iterator + { + } + /** + * Normalizes given directory names by removing trailing slashes. + * + * Excluding: (s)ftp:// or ssh2.(s)ftp:// wrapper + */ + private function normalizeDir(string $dir) : string + { + } +} +namespace Symfony\Component\Process\Exception; + +/** + * Marker Interface for the Process Component. + * + * @author Johannes M. Schmitt + */ +interface ExceptionInterface extends \Throwable +{ +} +namespace Symfony\Component\Process; + +/** + * Generic executable finder. + * + * @author Fabien Potencier + * @author Johannes M. Schmitt + */ +class ExecutableFinder +{ + private array $suffixes = ['.exe', '.bat', '.cmd', '.com']; + /** + * Replaces default suffixes of executable. + * + * @return void + */ + public function setSuffixes(array $suffixes) + { + } + /** + * Adds new possible suffix to check for executable. + * + * @return void + */ + public function addSuffix(string $suffix) + { + } + /** + * Finds an executable by name. + * + * @param string $name The executable name (without the extension) + * @param string|null $default The default to return if no executable is found + * @param array $extraDirs Additional dirs to check into + */ + public function find(string $name, ?string $default = null, array $extraDirs = []) : ?string + { + } +} +namespace Symfony\Component\Process; + +/** + * Process is a thin wrapper around proc_* functions to easily + * start independent PHP processes. + * + * @author Fabien Potencier + * @author Romain Neutron + * + * @implements \IteratorAggregate + */ +class Process implements \IteratorAggregate +{ + public const ERR = 'err'; + public const OUT = 'out'; + public const STATUS_READY = 'ready'; + public const STATUS_STARTED = 'started'; + public const STATUS_TERMINATED = 'terminated'; + public const STDIN = 0; + public const STDOUT = 1; + public const STDERR = 2; + // Timeout Precision in seconds. + public const TIMEOUT_PRECISION = 0.2; + public const ITER_NON_BLOCKING = 1; + // By default, iterating over outputs is a blocking call, use this flag to make it non-blocking + public const ITER_KEEP_OUTPUT = 2; + // By default, outputs are cleared while iterating, use this flag to keep them in memory + public const ITER_SKIP_OUT = 4; + // Use this flag to skip STDOUT while iterating + public const ITER_SKIP_ERR = 8; + // Use this flag to skip STDERR while iterating + private ?\Closure $callback = null; + private array|string $commandline; + private ?string $cwd; + private array $env = []; + /** @var resource|string|\Iterator|null */ + private $input; + private ?float $starttime = null; + private ?float $lastOutputTime = null; + private ?float $timeout = null; + private ?float $idleTimeout = null; + private ?int $exitcode = null; + private array $fallbackStatus = []; + private array $processInformation; + private bool $outputDisabled = false; + /** @var resource */ + private $stdout; + /** @var resource */ + private $stderr; + /** @var resource|null */ + private $process; + private string $status = self::STATUS_READY; + private int $incrementalOutputOffset = 0; + private int $incrementalErrorOutputOffset = 0; + private bool $tty = false; + private bool $pty; + private array $options = ['suppress_errors' => true, 'bypass_shell' => true]; + private \Symfony\Component\Process\Pipes\WindowsPipes|\Symfony\Component\Process\Pipes\UnixPipes $processPipes; + private ?int $latestSignal = null; + private static ?bool $sigchild = null; + /** + * Exit codes translation table. + * + * User-defined errors must use exit codes in the 64-113 range. + */ + public static $exitCodes = [ + 0 => 'OK', + 1 => 'General error', + 2 => 'Misuse of shell builtins', + 126 => 'Invoked command cannot execute', + 127 => 'Command not found', + 128 => 'Invalid exit argument', + // signals + 129 => 'Hangup', + 130 => 'Interrupt', + 131 => 'Quit and dump core', + 132 => 'Illegal instruction', + 133 => 'Trace/breakpoint trap', + 134 => 'Process aborted', + 135 => 'Bus error: "access to undefined portion of memory object"', + 136 => 'Floating point exception: "erroneous arithmetic operation"', + 137 => 'Kill (terminate immediately)', + 138 => 'User-defined 1', + 139 => 'Segmentation violation', + 140 => 'User-defined 2', + 141 => 'Write to pipe with no one reading', + 142 => 'Signal raised by alarm', + 143 => 'Termination (request to terminate)', + // 144 - not defined + 145 => 'Child process terminated, stopped (or continued*)', + 146 => 'Continue if stopped', + 147 => 'Stop executing temporarily', + 148 => 'Terminal stop signal', + 149 => 'Background process attempting to read from tty ("in")', + 150 => 'Background process attempting to write to tty ("out")', + 151 => 'Urgent data available on socket', + 152 => 'CPU time limit exceeded', + 153 => 'File size limit exceeded', + 154 => 'Signal raised by timer counting virtual time: "virtual timer expired"', + 155 => 'Profiling timer expired', + // 156 - not defined + 157 => 'Pollable event', + // 158 - not defined + 159 => 'Bad syscall', + ]; + /** + * @param array $command The command to run and its arguments listed as separate entries + * @param string|null $cwd The working directory or null to use the working dir of the current PHP process + * @param array|null $env The environment variables or null to use the same environment as the current PHP process + * @param mixed $input The input as stream resource, scalar or \Traversable, or null for no input + * @param int|float|null $timeout The timeout in seconds or null to disable + * + * @throws LogicException When proc_open is not installed + */ + public function __construct(array $command, ?string $cwd = null, ?array $env = null, mixed $input = null, ?float $timeout = 60) + { + } + /** + * Creates a Process instance as a command-line to be run in a shell wrapper. + * + * Command-lines are parsed by the shell of your OS (/bin/sh on Unix-like, cmd.exe on Windows.) + * This allows using e.g. pipes or conditional execution. In this mode, signals are sent to the + * shell wrapper and not to your commands. + * + * In order to inject dynamic values into command-lines, we strongly recommend using placeholders. + * This will save escaping values, which is not portable nor secure anyway: + * + * $process = Process::fromShellCommandline('my_command "${:MY_VAR}"'); + * $process->run(null, ['MY_VAR' => $theValue]); + * + * @param string $command The command line to pass to the shell of the OS + * @param string|null $cwd The working directory or null to use the working dir of the current PHP process + * @param array|null $env The environment variables or null to use the same environment as the current PHP process + * @param mixed $input The input as stream resource, scalar or \Traversable, or null for no input + * @param int|float|null $timeout The timeout in seconds or null to disable + * + * @throws LogicException When proc_open is not installed + */ + public static function fromShellCommandline(string $command, ?string $cwd = null, ?array $env = null, mixed $input = null, ?float $timeout = 60) : static + { + } + public function __sleep() : array + { + } + /** + * @return void + */ + public function __wakeup() + { + } + public function __destruct() + { + } + public function __clone() + { + } + /** + * Runs the process. + * + * The callback receives the type of output (out or err) and + * some bytes from the output in real-time. It allows to have feedback + * from the independent process during execution. + * + * The STDOUT and STDERR are also available after the process is finished + * via the getOutput() and getErrorOutput() methods. + * + * @param callable|null $callback A PHP callback to run whenever there is some + * output available on STDOUT or STDERR + * + * @return int The exit status code + * + * @throws RuntimeException When process can't be launched + * @throws RuntimeException When process is already running + * @throws ProcessTimedOutException When process timed out + * @throws ProcessSignaledException When process stopped after receiving signal + * @throws LogicException In case a callback is provided and output has been disabled + * + * @final + */ + public function run(?callable $callback = null, array $env = []) : int + { + } + /** + * Runs the process. + * + * This is identical to run() except that an exception is thrown if the process + * exits with a non-zero exit code. + * + * @return $this + * + * @throws ProcessFailedException if the process didn't terminate successfully + * + * @final + */ + public function mustRun(?callable $callback = null, array $env = []) : static + { + } + /** + * Starts the process and returns after writing the input to STDIN. + * + * This method blocks until all STDIN data is sent to the process then it + * returns while the process runs in the background. + * + * The termination of the process can be awaited with wait(). + * + * The callback receives the type of output (out or err) and some bytes from + * the output in real-time while writing the standard input to the process. + * It allows to have feedback from the independent process during execution. + * + * @param callable|null $callback A PHP callback to run whenever there is some + * output available on STDOUT or STDERR + * + * @return void + * + * @throws RuntimeException When process can't be launched + * @throws RuntimeException When process is already running + * @throws LogicException In case a callback is provided and output has been disabled + */ + public function start(?callable $callback = null, array $env = []) + { + } + /** + * Restarts the process. + * + * Be warned that the process is cloned before being started. + * + * @param callable|null $callback A PHP callback to run whenever there is some + * output available on STDOUT or STDERR + * + * @throws RuntimeException When process can't be launched + * @throws RuntimeException When process is already running + * + * @see start() + * + * @final + */ + public function restart(?callable $callback = null, array $env = []) : static + { + } + /** + * Waits for the process to terminate. + * + * The callback receives the type of output (out or err) and some bytes + * from the output in real-time while writing the standard input to the process. + * It allows to have feedback from the independent process during execution. + * + * @param callable|null $callback A valid PHP callback + * + * @return int The exitcode of the process + * + * @throws ProcessTimedOutException When process timed out + * @throws ProcessSignaledException When process stopped after receiving signal + * @throws LogicException When process is not yet started + */ + public function wait(?callable $callback = null) : int + { + } + /** + * Waits until the callback returns true. + * + * The callback receives the type of output (out or err) and some bytes + * from the output in real-time while writing the standard input to the process. + * It allows to have feedback from the independent process during execution. + * + * @throws RuntimeException When process timed out + * @throws LogicException When process is not yet started + * @throws ProcessTimedOutException In case the timeout was reached + */ + public function waitUntil(callable $callback) : bool + { + } + /** + * Returns the Pid (process identifier), if applicable. + * + * @return int|null The process id if running, null otherwise + */ + public function getPid() : ?int + { + } + /** + * Sends a POSIX signal to the process. + * + * @param int $signal A valid POSIX signal (see https://php.net/pcntl.constants) + * + * @return $this + * + * @throws LogicException In case the process is not running + * @throws RuntimeException In case --enable-sigchild is activated and the process can't be killed + * @throws RuntimeException In case of failure + */ + public function signal(int $signal) : static + { + } + /** + * Disables fetching output and error output from the underlying process. + * + * @return $this + * + * @throws RuntimeException In case the process is already running + * @throws LogicException if an idle timeout is set + */ + public function disableOutput() : static + { + } + /** + * Enables fetching output and error output from the underlying process. + * + * @return $this + * + * @throws RuntimeException In case the process is already running + */ + public function enableOutput() : static + { + } + /** + * Returns true in case the output is disabled, false otherwise. + */ + public function isOutputDisabled() : bool + { + } + /** + * Returns the current output of the process (STDOUT). + * + * @throws LogicException in case the output has been disabled + * @throws LogicException In case the process is not started + */ + public function getOutput() : string + { + } + /** + * Returns the output incrementally. + * + * In comparison with the getOutput method which always return the whole + * output, this one returns the new output since the last call. + * + * @throws LogicException in case the output has been disabled + * @throws LogicException In case the process is not started + */ + public function getIncrementalOutput() : string + { + } + /** + * Returns an iterator to the output of the process, with the output type as keys (Process::OUT/ERR). + * + * @param int $flags A bit field of Process::ITER_* flags + * + * @return \Generator + * + * @throws LogicException in case the output has been disabled + * @throws LogicException In case the process is not started + */ + public function getIterator(int $flags = 0) : \Generator + { + } + /** + * Clears the process output. + * + * @return $this + */ + public function clearOutput() : static + { + } + /** + * Returns the current error output of the process (STDERR). + * + * @throws LogicException in case the output has been disabled + * @throws LogicException In case the process is not started + */ + public function getErrorOutput() : string + { + } + /** + * Returns the errorOutput incrementally. + * + * In comparison with the getErrorOutput method which always return the + * whole error output, this one returns the new error output since the last + * call. + * + * @throws LogicException in case the output has been disabled + * @throws LogicException In case the process is not started + */ + public function getIncrementalErrorOutput() : string + { + } + /** + * Clears the process output. + * + * @return $this + */ + public function clearErrorOutput() : static + { + } + /** + * Returns the exit code returned by the process. + * + * @return int|null The exit status code, null if the Process is not terminated + */ + public function getExitCode() : ?int + { + } + /** + * Returns a string representation for the exit code returned by the process. + * + * This method relies on the Unix exit code status standardization + * and might not be relevant for other operating systems. + * + * @return string|null A string representation for the exit status code, null if the Process is not terminated + * + * @see http://tldp.org/LDP/abs/html/exitcodes.html + * @see http://en.wikipedia.org/wiki/Unix_signal + */ + public function getExitCodeText() : ?string + { + } + /** + * Checks if the process ended successfully. + */ + public function isSuccessful() : bool + { + } + /** + * Returns true if the child process has been terminated by an uncaught signal. + * + * It always returns false on Windows. + * + * @throws LogicException In case the process is not terminated + */ + public function hasBeenSignaled() : bool + { + } + /** + * Returns the number of the signal that caused the child process to terminate its execution. + * + * It is only meaningful if hasBeenSignaled() returns true. + * + * @throws RuntimeException In case --enable-sigchild is activated + * @throws LogicException In case the process is not terminated + */ + public function getTermSignal() : int + { + } + /** + * Returns true if the child process has been stopped by a signal. + * + * It always returns false on Windows. + * + * @throws LogicException In case the process is not terminated + */ + public function hasBeenStopped() : bool + { + } + /** + * Returns the number of the signal that caused the child process to stop its execution. + * + * It is only meaningful if hasBeenStopped() returns true. + * + * @throws LogicException In case the process is not terminated + */ + public function getStopSignal() : int + { + } + /** + * Checks if the process is currently running. + */ + public function isRunning() : bool + { + } + /** + * Checks if the process has been started with no regard to the current state. + */ + public function isStarted() : bool + { + } + /** + * Checks if the process is terminated. + */ + public function isTerminated() : bool + { + } + /** + * Gets the process status. + * + * The status is one of: ready, started, terminated. + */ + public function getStatus() : string + { + } + /** + * Stops the process. + * + * @param int|float $timeout The timeout in seconds + * @param int|null $signal A POSIX signal to send in case the process has not stop at timeout, default is SIGKILL (9) + * + * @return int|null The exit-code of the process or null if it's not running + */ + public function stop(float $timeout = 10, ?int $signal = null) : ?int + { + } + /** + * Gets the last output time in seconds. + */ + public function getLastOutputTime() : ?float + { + } + /** + * Gets the command line to be executed. + */ + public function getCommandLine() : string + { + } + /** + * Gets the process timeout in seconds (max. runtime). + */ + public function getTimeout() : ?float + { + } + /** + * Gets the process idle timeout in seconds (max. time since last output). + */ + public function getIdleTimeout() : ?float + { + } + /** + * Sets the process timeout (max. runtime) in seconds. + * + * To disable the timeout, set this value to null. + * + * @return $this + * + * @throws InvalidArgumentException if the timeout is negative + */ + public function setTimeout(?float $timeout) : static + { + } + /** + * Sets the process idle timeout (max. time since last output) in seconds. + * + * To disable the timeout, set this value to null. + * + * @return $this + * + * @throws LogicException if the output is disabled + * @throws InvalidArgumentException if the timeout is negative + */ + public function setIdleTimeout(?float $timeout) : static + { + } + /** + * Enables or disables the TTY mode. + * + * @return $this + * + * @throws RuntimeException In case the TTY mode is not supported + */ + public function setTty(bool $tty) : static + { + } + /** + * Checks if the TTY mode is enabled. + */ + public function isTty() : bool + { + } + /** + * Sets PTY mode. + * + * @return $this + */ + public function setPty(bool $bool) : static + { + } + /** + * Returns PTY state. + */ + public function isPty() : bool + { + } + /** + * Gets the working directory. + */ + public function getWorkingDirectory() : ?string + { + } + /** + * Sets the current working directory. + * + * @return $this + */ + public function setWorkingDirectory(string $cwd) : static + { + } + /** + * Gets the environment variables. + */ + public function getEnv() : array + { + } + /** + * Sets the environment variables. + * + * @param array $env The new environment variables + * + * @return $this + */ + public function setEnv(array $env) : static + { + } + /** + * Gets the Process input. + * + * @return resource|string|\Iterator|null + */ + public function getInput() + { + } + /** + * Sets the input. + * + * This content will be passed to the underlying process standard input. + * + * @param string|resource|\Traversable|self|null $input The content + * + * @return $this + * + * @throws LogicException In case the process is running + */ + public function setInput(mixed $input) : static + { + } + /** + * Performs a check between the timeout definition and the time the process started. + * + * In case you run a background process (with the start method), you should + * trigger this method regularly to ensure the process timeout + * + * @return void + * + * @throws ProcessTimedOutException In case the timeout was reached + */ + public function checkTimeout() + { + } + /** + * @throws LogicException in case process is not started + */ + public function getStartTime() : float + { + } + /** + * Defines options to pass to the underlying proc_open(). + * + * @see https://php.net/proc_open for the options supported by PHP. + * + * Enabling the "create_new_console" option allows a subprocess to continue + * to run after the main process exited, on both Windows and *nix + * + * @return void + */ + public function setOptions(array $options) + { + } + /** + * Returns whether TTY is supported on the current operating system. + */ + public static function isTtySupported() : bool + { + } + /** + * Returns whether PTY is supported on the current operating system. + */ + public static function isPtySupported() : bool + { + } + /** + * Creates the descriptors needed by the proc_open. + */ + private function getDescriptors(bool $hasCallback) : array + { + } + /** + * Builds up the callback used by wait(). + * + * The callbacks adds all occurred output to the specific buffer and calls + * the user callback (if present) with the received output. + * + * @param callable|null $callback The user defined PHP callback + */ + protected function buildCallback(?callable $callback = null) : \Closure + { + } + /** + * Updates the status of the process, reads pipes. + * + * @param bool $blocking Whether to use a blocking read call + * + * @return void + */ + protected function updateStatus(bool $blocking) + { + } + /** + * Returns whether PHP has been compiled with the '--enable-sigchild' option or not. + */ + protected function isSigchildEnabled() : bool + { + } + /** + * Reads pipes for the freshest output. + * + * @param string $caller The name of the method that needs fresh outputs + * @param bool $blocking Whether to use blocking calls or not + * + * @throws LogicException in case output has been disabled or process is not started + */ + private function readPipesForOutput(string $caller, bool $blocking = false) : void + { + } + /** + * Validates and returns the filtered timeout. + * + * @throws InvalidArgumentException if the given timeout is a negative number + */ + private function validateTimeout(?float $timeout) : ?float + { + } + /** + * Reads pipes, executes callback. + * + * @param bool $blocking Whether to use blocking calls or not + * @param bool $close Whether to close file handles or not + */ + private function readPipes(bool $blocking, bool $close) : void + { + } + /** + * Closes process resource, closes file handles, sets the exitcode. + * + * @return int The exitcode + */ + private function close() : int + { + } + /** + * Resets data related to the latest run of the process. + */ + private function resetProcessData() : void + { + } + /** + * Sends a POSIX signal to the process. + * + * @param int $signal A valid POSIX signal (see https://php.net/pcntl.constants) + * @param bool $throwException Whether to throw exception in case signal failed + * + * @throws LogicException In case the process is not running + * @throws RuntimeException In case --enable-sigchild is activated and the process can't be killed + * @throws RuntimeException In case of failure + */ + private function doSignal(int $signal, bool $throwException) : bool + { + } + private function prepareWindowsCommandLine(string $cmd, array &$env) : string + { + } + /** + * Ensures the process is running or terminated, throws a LogicException if the process has a not started. + * + * @throws LogicException if the process has not run + */ + private function requireProcessIsStarted(string $functionName) : void + { + } + /** + * Ensures the process is terminated, throws a LogicException if the process has a status different than "terminated". + * + * @throws LogicException if the process is not yet terminated + */ + private function requireProcessIsTerminated(string $functionName) : void + { + } + /** + * Escapes a string to be used as a shell argument. + */ + private function escapeArgument(?string $argument) : string + { + } + private function replacePlaceholders(string $commandline, array $env) : string + { + } + private function getDefaultEnv() : array + { + } +} +namespace Symfony\Contracts\HttpClient\Exception; + +/** + * The base interface for all exceptions in the contract. + * + * @author Nicolas Grekas + */ +interface ExceptionInterface extends \Throwable +{ +} +namespace Symfony\Contracts\HttpClient; + +/** + * Provides flexible methods for requesting HTTP resources synchronously or asynchronously. + * + * @see HttpClientTestCase for a reference test suite + * + * @author Nicolas Grekas + */ +interface HttpClientInterface +{ + public const OPTIONS_DEFAULTS = [ + 'auth_basic' => null, + // array|string - an array containing the username as first value, and optionally the + // password as the second one; or string like username:password - enabling HTTP Basic + // authentication (RFC 7617) + 'auth_bearer' => null, + // string - a token enabling HTTP Bearer authorization (RFC 6750) + 'query' => [], + // string[] - associative array of query string values to merge with the request's URL + 'headers' => [], + // iterable|string[]|string[][] - headers names provided as keys or as part of values + 'body' => '', + // array|string|resource|\Traversable|\Closure - the callback SHOULD yield a string + // smaller than the amount requested as argument; the empty string signals EOF; if + // an array is passed, it is meant as a form payload of field names and values + 'json' => null, + // mixed - if set, implementations MUST set the "body" option to the JSON-encoded + // value and set the "content-type" header to a JSON-compatible value if it is not + // explicitly defined in the headers option - typically "application/json" + 'user_data' => null, + // mixed - any extra data to attach to the request (scalar, callable, object...) that + // MUST be available via $response->getInfo('user_data') - not used internally + 'max_redirects' => 20, + // int - the maximum number of redirects to follow; a value lower than or equal to 0 + // means redirects should not be followed; "Authorization" and "Cookie" headers MUST + // NOT follow except for the initial host name + 'http_version' => null, + // string - defaults to the best supported version, typically 1.1 or 2.0 + 'base_uri' => null, + // string - the URI to resolve relative URLs, following rules in RFC 3986, section 2 + 'buffer' => true, + // bool|resource|\Closure - whether the content of the response should be buffered or not, + // or a stream resource where the response body should be written, + // or a closure telling if/where the response should be buffered based on its headers + 'on_progress' => null, + // callable(int $dlNow, int $dlSize, array $info) - throwing any exceptions MUST abort + // the request; it MUST be called on DNS resolution, on arrival of headers and on + // completion; it SHOULD be called on upload/download of data and at least 1/s + 'resolve' => [], + // string[] - a map of host to IP address that SHOULD replace DNS resolution + 'proxy' => null, + // string - by default, the proxy-related env vars handled by curl SHOULD be honored + 'no_proxy' => null, + // string - a comma separated list of hosts that do not require a proxy to be reached + 'timeout' => null, + // float - the idle timeout (in seconds) - defaults to ini_get('default_socket_timeout') + 'max_duration' => 0, + // float - the maximum execution time (in seconds) for the request+response as a whole; + // a value lower than or equal to 0 means it is unlimited + 'bindto' => '0', + // string - the interface or the local socket to bind to + 'verify_peer' => true, + // see https://php.net/context.ssl for the following options + 'verify_host' => true, + 'cafile' => null, + 'capath' => null, + 'local_cert' => null, + 'local_pk' => null, + 'passphrase' => null, + 'ciphers' => null, + 'peer_fingerprint' => null, + 'capture_peer_cert_chain' => false, + 'crypto_method' => \STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT, + // STREAM_CRYPTO_METHOD_TLSv*_CLIENT - minimum TLS version + 'extra' => [], + ]; + /** + * Requests an HTTP resource. + * + * Responses MUST be lazy, but their status code MUST be + * checked even if none of their public methods are called. + * + * Implementations are not required to support all options described above; they can also + * support more custom options; but in any case, they MUST throw a TransportExceptionInterface + * when an unsupported option is passed. + * + * @throws TransportExceptionInterface When an unsupported option is passed + */ + public function request(string $method, string $url, array $options = []) : ResponseInterface; + /** + * Yields responses chunk by chunk as they complete. + * + * @param ResponseInterface|iterable $responses One or more responses created by the current HTTP client + * @param float|null $timeout The idle timeout before yielding timeout chunks + */ + public function stream(ResponseInterface|iterable $responses, float $timeout = null) : ResponseStreamInterface; + /** + * Returns a new instance of the client with new default options. + */ + public function withOptions(array $options) : static; +} +namespace Symfony\Contracts\HttpClient; + +/** + * A (lazily retrieved) HTTP response. + * + * @author Nicolas Grekas + */ +interface ResponseInterface +{ + /** + * Gets the HTTP status code of the response. + * + * @throws TransportExceptionInterface when a network error occurs + */ + public function getStatusCode() : int; + /** + * Gets the HTTP headers of the response. + * + * @param bool $throw Whether an exception should be thrown on 3/4/5xx status codes + * + * @return string[][] The headers of the response keyed by header names in lowercase + * + * @throws TransportExceptionInterface When a network error occurs + * @throws RedirectionExceptionInterface On a 3xx when $throw is true and the "max_redirects" option has been reached + * @throws ClientExceptionInterface On a 4xx when $throw is true + * @throws ServerExceptionInterface On a 5xx when $throw is true + */ + public function getHeaders(bool $throw = true) : array; + /** + * Gets the response body as a string. + * + * @param bool $throw Whether an exception should be thrown on 3/4/5xx status codes + * + * @throws TransportExceptionInterface When a network error occurs + * @throws RedirectionExceptionInterface On a 3xx when $throw is true and the "max_redirects" option has been reached + * @throws ClientExceptionInterface On a 4xx when $throw is true + * @throws ServerExceptionInterface On a 5xx when $throw is true + */ + public function getContent(bool $throw = true) : string; + /** + * Gets the response body decoded as array, typically from a JSON payload. + * + * @param bool $throw Whether an exception should be thrown on 3/4/5xx status codes + * + * @throws DecodingExceptionInterface When the body cannot be decoded to an array + * @throws TransportExceptionInterface When a network error occurs + * @throws RedirectionExceptionInterface On a 3xx when $throw is true and the "max_redirects" option has been reached + * @throws ClientExceptionInterface On a 4xx when $throw is true + * @throws ServerExceptionInterface On a 5xx when $throw is true + */ + public function toArray(bool $throw = true) : array; + /** + * Closes the response stream and all related buffers. + * + * No further chunk will be yielded after this method has been called. + */ + public function cancel() : void; + /** + * Returns info coming from the transport layer. + * + * This method SHOULD NOT throw any ExceptionInterface and SHOULD be non-blocking. + * The returned info is "live": it can be empty and can change from one call to + * another, as the request/response progresses. + * + * The following info MUST be returned: + * - canceled (bool) - true if the response was canceled using ResponseInterface::cancel(), false otherwise + * - error (string|null) - the error message when the transfer was aborted, null otherwise + * - http_code (int) - the last response code or 0 when it is not known yet + * - http_method (string) - the HTTP verb of the last request + * - redirect_count (int) - the number of redirects followed while executing the request + * - redirect_url (string|null) - the resolved location of redirect responses, null otherwise + * - response_headers (array) - an array modelled after the special $http_response_header variable + * - start_time (float) - the time when the request was sent or 0.0 when it's pending + * - url (string) - the last effective URL of the request + * - user_data (mixed) - the value of the "user_data" request option, null if not set + * + * When the "capture_peer_cert_chain" option is true, the "peer_certificate_chain" + * attribute SHOULD list the peer certificates as an array of OpenSSL X.509 resources. + * + * Other info SHOULD be named after curl_getinfo()'s associative return value. + * + * @return mixed An array of all available info, or one of them when $type is + * provided, or null when an unsupported type is requested + */ + public function getInfo(string $type = null) : mixed; +} \ No newline at end of file diff --git a/tests/Examples/fixtures/broken/autocomplete-invalid/castor.php b/tests/Examples/fixtures/broken/autocomplete-invalid/castor.php new file mode 100644 index 00000000..3d211c8e --- /dev/null +++ b/tests/Examples/fixtures/broken/autocomplete-invalid/castor.php @@ -0,0 +1,21 @@ +