Skip to content

Commit

Permalink
Merge pull request #59 from statamic/prompts
Browse files Browse the repository at this point in the history
Prompts
  • Loading branch information
jackmcdade authored Aug 14, 2023
2 parents 144e3a2 + 932d1ba commit c573e1b
Show file tree
Hide file tree
Showing 8 changed files with 375 additions and 92 deletions.
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@
"keywords": ["statamic"],
"license": "MIT",
"require": {
"php": ">=7.2.5",
"php": "^8.1",
"guzzlehttp/guzzle": "^6.5.5|^7.0.1",
"laravel/prompts": "^0.1.3",
"symfony/console": "^4.0|^5.0|^6.0",
"symfony/process": "^4.2|^5.0|^6.0"
},
Expand Down
96 changes: 96 additions & 0 deletions src/Concerns/ConfiguresPrompts.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
<?php

namespace Statamic\Cli\Concerns;

use Laravel\Prompts\ConfirmPrompt;
use Laravel\Prompts\Prompt;
use Laravel\Prompts\SelectPrompt;
use Laravel\Prompts\SuggestPrompt;
use Laravel\Prompts\TextPrompt;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Question\Question;
use Symfony\Component\Console\Style\SymfonyStyle;

trait ConfiguresPrompts
{
/**
* Configure the prompt fallbacks.
*
* @return void
*/
protected function configurePrompts(InputInterface $input, OutputInterface $output)
{
Prompt::fallbackWhen(! $input->isInteractive() || PHP_OS_FAMILY === 'Windows');

TextPrompt::fallbackUsing(fn (TextPrompt $prompt) => $this->promptUntilValid(
fn () => (new SymfonyStyle($input, $output))->ask($prompt->label, $prompt->default ?: null) ?? '',
$prompt->required,
$prompt->validate,
$output
));

ConfirmPrompt::fallbackUsing(fn (ConfirmPrompt $prompt) => $this->promptUntilValid(
fn () => (new SymfonyStyle($input, $output))->confirm($prompt->label, $prompt->default),
$prompt->required,
$prompt->validate,
$output
));

SelectPrompt::fallbackUsing(fn (SelectPrompt $prompt) => $this->promptUntilValid(
fn () => (new SymfonyStyle($input, $output))->choice($prompt->label, $prompt->options, $prompt->default),
false,
$prompt->validate,
$output
));

SuggestPrompt::fallbackUsing(fn (SuggestPrompt $prompt) => $this->promptUntilValid(
function () use ($prompt, $input, $output) {
$question = new Question($prompt->label, $prompt->default);

is_callable($prompt->options)
? $question->setAutocompleterCallback($prompt->options)
: $question->setAutocompleterValues($prompt->options);

return (new SymfonyStyle($input, $output))->askQuestion($question);
},
$prompt->required,
$prompt->validate,
$output
));
}

/**
* Prompt the user until the given validation callback passes.
*
* @param \Closure $prompt
* @param bool|string $required
* @param \Closure|null $validate
* @param \Symfony\Component\Console\Output\OutputInterface $output
* @return mixed
*/
protected function promptUntilValid($prompt, $required, $validate, $output)
{
while (true) {
$result = $prompt();

if ($required && ($result === '' || $result === [] || $result === false)) {
$output->writeln('<error>'.(is_string($required) ? $required : 'Required.').'</error>');

continue;
}

if ($validate) {
$error = $validate($result);

if (is_string($error) && strlen($error) > 0) {
$output->writeln("<error>{$error}</error>");

continue;
}
}

return $result;
}
}
}
Loading

0 comments on commit c573e1b

Please sign in to comment.