Skip to content

Commit

Permalink
Fix text prompts (#5976)
Browse files Browse the repository at this point in the history
* Fix text prompts

* Fixup prompt fallback and use PasswordPrompt in site:install

* reduce baseline
  • Loading branch information
weitzman committed May 1, 2024
1 parent 4b22734 commit 995bca1
Show file tree
Hide file tree
Showing 7 changed files with 29 additions and 57 deletions.
25 changes: 0 additions & 25 deletions phpstan-baseline.neon
@@ -1,35 +1,10 @@
parameters:
ignoreErrors:
-
message: "#^Call to an undefined method Symfony\\\\Component\\\\Console\\\\Style\\\\SymfonyStyle\\:\\:askWithCompletion\\(\\)\\.$#"
count: 1
path: src/Commands/DrushCommands.php

-
message: "#^Call to an undefined method Symfony\\\\Component\\\\Console\\\\Style\\\\SymfonyStyle\\:\\:secret\\(\\)\\.$#"
count: 1
path: src/Commands/DrushCommands.php

-
message: "#^Call to an undefined method Drupal\\\\migrate\\\\Plugin\\\\MigrationInterface\\:\\:set\\(\\)\\.$#"
count: 1
path: src/Commands/core/MigrateRunnerCommands.php

-
message: "#^Result of method Drush\\\\Style\\\\DrushStyle\\:\\:text\\(\\) \\(void\\) is used\\.$#"
count: 6
path: src/Commands/core/SiteInstallCommands.php

-
message: "#^Result of method Drush\\\\Style\\\\DrushStyle\\:\\:text\\(\\) \\(void\\) is used\\.$#"
count: 2
path: src/Commands/field/FieldBaseOverrideCreateCommands.php

-
message: "#^Result of method Drush\\\\Style\\\\DrushStyle\\:\\:text\\(\\) \\(void\\) is used\\.$#"
count: 4
path: src/Commands/field/FieldCreateCommands.php

-
message: "#^Call to an undefined method Drupal\\\\Core\\\\DependencyInjection\\\\ServiceModifierInterface\\:\\:check\\(\\)\\.$#"
count: 1
Expand Down
22 changes: 12 additions & 10 deletions src-symfony-compatibility/v6/Style/DrushStyle.php
Expand Up @@ -13,6 +13,7 @@
use Laravel\Prompts\SelectPrompt;
use Laravel\Prompts\Spinner;
use Laravel\Prompts\SuggestPrompt;
use Laravel\Prompts\TextPrompt;
use Symfony\Component\Console\Question\Question;
use Symfony\Component\Console\Style\SymfonyStyle;

Expand Down Expand Up @@ -50,23 +51,24 @@ public function choice(string $question, array $choices, mixed $default = null,
/**
* Prompt the user for text input.
*/
public function text(
$label,
string $placeholder = '',
string $default = '',
public function ask(
\Stringable|string $question,
?string $default = null,
#[Deprecated('Use $validate parameter instead.')]
?callable $validator = null,
\Stringable|string $placeholder = '',
bool|string $required = false,
?\Closure $validate = null,
string $hint = ''
): void
{
// @todo return type of parent has changed
// return (new TextPrompt($label, $placeholder, $default, $required, $validate, $hint))->prompt();
\Stringable|string $hint = ''
): mixed {
assert($validator === null, 'The $validator parameter is non-functional. Use $validate instead.');
return (new TextPrompt($question, $placeholder, (string)$default, $required, $validate, $hint))->prompt();
}

/**
* Prompt the user for input, hiding the value.
*/
public function password(string $label, string $placeholder = '', bool|string $required = false, ?\Closure $validate = null, string $hint = ''): string
public function password(\Stringable|string $label, \Stringable|string $placeholder = '', bool|string $required = false, ?\Closure $validate = null, \Stringable|string $hint = ''): string
{
return (new PasswordPrompt($label, $placeholder, $required, $validate, $hint))->prompt();
}
Expand Down
7 changes: 2 additions & 5 deletions src/Commands/ConfiguresPrompts.php
Expand Up @@ -6,7 +6,6 @@

namespace Drush\Commands;

use Drush\Exceptions\UserAbortException;
use Drush\Runtime\Runtime;
use Laravel\Prompts\ConfirmPrompt;
use Laravel\Prompts\MultiSearchPrompt;
Expand Down Expand Up @@ -47,8 +46,7 @@ protected function configurePrompts(InputInterface $input)
));

PasswordPrompt::fallbackUsing(fn (PasswordPrompt $prompt) => $this->promptUntilValid(
// @todo there is no secret().
fn () => (new SymfonyStyle($this->input, $this->output))->secret($prompt->label) ?? '',
fn() => (new SymfonyStyle($this->input, $this->output))->askHidden($prompt->label) ?? '',
$prompt->required,
$prompt->validate
));
Expand Down Expand Up @@ -87,8 +85,7 @@ protected function configurePrompts(InputInterface $input)
});

SuggestPrompt::fallbackUsing(fn (SuggestPrompt $prompt) => $this->promptUntilValid(
// @todo No askWithCompletion
fn () => (new SymfonyStyle($this->input, $this->output))->askWithCompletion($prompt->label, $prompt->options, $prompt->default ?: null) ?? '',
fn() => (new SymfonyStyle($this->input, $this->output))->choice($prompt->label, $prompt->options, $prompt->default ?: null) ?? '',
$prompt->required,
$prompt->validate
));
Expand Down
15 changes: 7 additions & 8 deletions src/Commands/core/SiteInstallCommands.php
Expand Up @@ -302,44 +302,43 @@ public function validate(CommandData $commandData): void
'driver' => $driverList[$driverNamespace]->getDriverName(),
'module' => $driverList[$driverNamespace]->getModule()->getName(),
];
$databaseInfo['database'] = $this->io()->text(
$databaseInfo['database'] = $this->io()->ask(
$formOptions['database']['#title'],
default: $formOptions['database']['#default_value'] ?: 'drupal',
hint: (string) ($formOptions['database']['#description'] ?? null),
);
if (isset($formOptions['username'])) {
$databaseInfo['username'] = $this->io()->text(
$databaseInfo['username'] = $this->io()->ask(
$formOptions['username']['#title'],
default: 'drupal',
hint: (string) ($formOptions['username']['#description'] ?? null),
);
}
if (isset($formOptions['password'])) {
$databaseInfo['password'] = $this->io()->text(
$databaseInfo['password'] = $this->io()->password(
$formOptions['password']['#title'],
default: 'drupal',
hint: (string) ($formOptions['password']['#description'] ?? null),
);
}
if (isset($formOptions['advanced_options']['host'])) {
$databaseInfo['host'] = $this->io()->text(
$databaseInfo['host'] = $this->io()->ask(
$formOptions['advanced_options']['host']['#title'],
default: $formOptions['advanced_options']['host']['#default_value'],
hint: (string) ($formOptions['advanced_options']['host']['#description'] ?? null),
);
}
if (isset($formOptions['advanced_options']['port'])) {
$databaseInfo['port'] = $this->io()->text(
$databaseInfo['port'] = $this->io()->ask(
$formOptions['advanced_options']['port']['#title'],
default: $formOptions['advanced_options']['port']['#default_value'],
hint: (string) ($formOptions['advanced_options']['port']['#description'] ?? null),
);
}
if (isset($formOptions['advanced_options']['prefix'])) {
$databaseInfo['prefix'] = $this->io()->text(
$databaseInfo['prefix'] = $this->io()->ask(
$formOptions['advanced_options']['prefix']['#title'],
default: $formOptions['advanced_options']['prefix']['#default_value'],
hint: (string) ($formOptions['advanced_options']['prefix']['#description'] ?? null),
hint: MailFormatHelper::htmlToText($formOptions['advanced_options']['prefix']['#description'] ?? null),
);
}
$connectionClass = $driverNamespace . '\\Connection';
Expand Down
4 changes: 2 additions & 2 deletions src/Commands/field/FieldBaseOverrideCreateCommands.php
Expand Up @@ -151,12 +151,12 @@ protected function askFieldName(string $entityType): ?string

protected function askFieldLabel(string $default): string
{
return $this->io()->text('Field label', default: $default);
return $this->io()->ask('Field label', default: $default);
}

protected function askFieldDescription(?string $default): ?string
{
return $this->io()->text('Field description', default: $default);
return $this->io()->ask('Field description', default: $default);
}

protected function askRequired(bool $default): bool
Expand Down
12 changes: 6 additions & 6 deletions src/Commands/field/FieldCreateCommands.php
Expand Up @@ -101,8 +101,8 @@ public function setContentTranslationManager(?ContentTranslationManagerInterface
#[CLI\Option(name: 'existing-field-name', description: 'The name of an existing field you want to re-use. Only used in non-interactive context.')]
#[CLI\Option(name: 'show-machine-names', description: 'Show machine names instead of labels in option lists.')]
#[CLI\Usage(name: self::CREATE, description: 'Create a field by answering the prompts.')]
#[CLI\Usage(name: 'field-create taxonomy_term tag', description: 'Create a field and fill in the remaining information through prompts.')]
#[CLI\Usage(name: 'field-create taxonomy_term tag --field-name=field_tag_label --field-label=Label --field-type=string --field-widget=string_textfield --is-required=1 --cardinality=2', description: 'Create a field in a completely non-interactive way.')]
#[CLI\Usage(name: 'field:create taxonomy_term tag', description: 'Create a field and fill in the remaining information through prompts.')]
#[CLI\Usage(name: 'field:create taxonomy_term tag --field-name=field_tag_label --field-label=Label --field-type=string --field-widget=string_textfield --is-required=1 --cardinality=2', description: 'Create a field in a completely non-interactive way.')]
#[CLI\Complete(method_name_or_callable: 'complete')]
#[CLI\Version(version: '11.0')]
public function fieldCreate(?string $entityType = null, ?string $bundle = null, array $options = [
Expand Down Expand Up @@ -280,7 +280,7 @@ protected function askFieldName(): string
}

while (!$fieldName) {
$answer = $this->io()->text('Field name', default: $machineName, required: true, validate: function ($answer) use ($entityType) {
$answer = $this->io()->ask('Field name', default: $machineName, required: true, validate: function ($answer) use ($entityType) {
if (!preg_match('/^[_a-z]+[_a-z0-9]*$/', $answer)) {
return'Only lowercase alphanumeric chars/underscores allowed; only letters/underscore allowed as first character.';
}
Expand All @@ -302,12 +302,12 @@ protected function askFieldName(): string

protected function askFieldLabel(): string
{
return $this->io()->text('Field label', required: true);
return $this->io()->ask('Field label', required: true);
}

protected function askFieldDescription(): ?string
{
return $this->io()->text('Field description');
return $this->io()->ask('Field description');
}

protected function askFieldType(): string
Expand Down Expand Up @@ -391,7 +391,7 @@ protected function askCardinality(): int

$limit = FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED;
while ($cardinality === 'Limited' && $limit < 1) {
$limit = (int) $this->io()->text('Allowed number of values', default: '1');
$limit = (int)$this->io()->ask('Allowed number of values', default: '1');
}

return $limit;
Expand Down
1 change: 0 additions & 1 deletion src/Preflight/Preflight.php
Expand Up @@ -206,7 +206,6 @@ public function loadSymfonyCompatabilityAutoloader(): ClassLoader
4 => 'v4', // Drupal 9
5 => 'v4', // Early Drupal 10 (Symfony 5 works with Symfony 4 classes, so we don't keep an extra copy)
6 => 'v6', // Drupal 10
// @TODO Revisit if needed.
7 => 'v6', // Drupal 11
];

Expand Down

0 comments on commit 995bca1

Please sign in to comment.