joetannenbaum/laravel-interactive-console

此包已被废弃,不再维护。作者建议使用 joetannenbaum/terminalia 包。

Laravel 美观的命令行输出。

0.3.3 2023-05-16 00:42 UTC

README

Terminalia

重要
嘿!这是一个有趣的项目,我学到了很多东西。不过它并不算最稳定的。我推荐使用 Laravel Prompts。它(比这个)做得更好,经过良好测试且稳定。

Clack 的用户体验,Laravel 的开发者体验(DX)为你 Artisan 命令。

功能

  • 使用 Laravel 内置验证器进行行内输入验证
  • 文本、选择和确认的交互式提示
  • 用于长时间运行进程的旋转器

演示

Demo

安装

composer require joetannenbaum/terminalia

此包实现了一个控制台混合器,安装包时将自动注册。

如果服务提供者没有自动注册(即你使用 Laravel Zero),请将以下内容添加到你的 config/app.php 文件中

'providers' => [
    // ...
    Terminalia\Providers\TerminaliaServiceProvider::class,
],

获取输入

输入验证

这些方法中的 rules 参数使用 Laravel 内置验证器,因此它接受你可以传递给 Validator::make 的任何内容。

注意:如果你在 Laravel Zero 应用中使用验证,请记住在 config/app.php 文件中注册你的 ValidationServiceProvider::classTranslationServiceProvider::class,并在项目根目录中包含一个 lang 目录。

termAsk

termAsk 方法提示用户输入并返回响应。它接受以下参数

  • question (字符串):要问用户的问题
  • rules (字符串|数组):应用于响应的验证规则数组
  • hidden (布尔值):是否隐藏用户的输入(对密码很有用)
  • default (字符串):默认值
$answer = $this->termAsk(
    question: 'What is your favorite color?',
    rules: ['required'],
);

$password = $this->termAsk(
    question: 'What is your password?',
    rules: ['required'],
    hidden: true,
);

termChoice

termChoice 方法提示用户从一系列选择中选取一个或多个项目。它接受以下参数

  • question (字符串):要问用户的问题
  • choices (数组|Collection|Helpers\Choices):要显示给用户的选项数组
  • multiple (布尔值):是否允许用户选择多个选项
  • rules (字符串|数组):应用于响应的验证规则数组
  • filterable (布尔值):是否允许用户过滤选项
  • minFilterLength (整数,默认为 5):在启用过滤之前列表中选项的最小数量
  • default (字符串|数组):默认值(数组)

如果 multiple 设置为 true 并且您将一个 Collection 作为 choices 参数传递,则 choices 将以 Collection 的形式返回,否则将返回一个数组。

$answer = $this->termChoice(
    question: 'What is your favorite color?',
    choices: ['red', 'green', 'blue'],
    rules: ['required'],
);

$favoriteThings = $this->termChoice(
    question: 'Which are your favorite things:',
    choices: [
        'raindrops on roses',
        'whiskers on kittens',
        'bright copper kettles',
        'warm woolen mittens',
        'brown paper packages tied up with strings',
        'cream colored ponies',
        'crisp apple strudels',
        'doorbells',
        'sleigh bells',
        'schnitzel with noodles',
    ],
    multiple: true,
    rules: ['required'],
    filterable: true,
);

除了传递一个简单的数组作为 choices 参数之外,您还可以使用 Choices 辅助函数传递嵌套数组或集合。这允许您为列表中的每个项目指定标签和值。标签将显示给用户,而值将在用户选择项目时返回。

use Terminalia\Helpers\Choices;

$users = User::all();

// Choices will display the user's name and return a User model
$user = $this->termChoice(
    question: 'Which user would you like to edit?',
    choices: Choices::from($users, 'name'),
);

// Choices will display the user's name and return the user ID
$user = $this->termChoice(
    question: 'Which user would you like to edit?',
    choices: Choices::from($users, 'name', 'id'),
);

// Choices will be displayed with the user's full name, will return a User model
$user = $this->termChoice(
    question: 'Which user would you like to edit?',
    choices: Choices::from($users, fn($user) => "{$user->firstName} {$user->lastName}"),
);

// Choices will be displayed with the user's full name, will return the user ID
$user = $this->termChoice(
    question: 'Which user would you like to edit?',
    choices: Choices::from(
        $users,
        fn($user) => "{$user->firstName} {$user->lastName}",
        fn($user) => $user->id,
    ),
);

// Defaults will be determined by the display value when no return value is specified
$user = $this->termChoice(
    question: 'Which user would you like to edit?',
    choices: Choices::from($users, 'name'),
    default: 'Joe',
);

// Defaults will be determined by the return value if it is specified
$user = $this->termChoice(
    question: 'Which user would you like to edit?',
    choices: Choices::from($users, 'name', 'id'),
    default: 123,
);

termConfirm

termConfirm 方法会提示用户确认一个问题。它接受以下参数

  • question (字符串):要问用户的问题
  • default (布尔值): 问题的默认答案
$answer = $this->termConfirm(
    question: 'Are you sure you want to do this?',
);

写入输出

termIntro

termIntro 方法将简介消息写入输出。它接受以下参数

  • text (字符串): 要写入输出的消息
$this->termIntro("Welcome! Let's get started.");

termOutro

termOutro 方法将结束语消息写入输出。它接受以下参数

  • text (字符串): 要写入输出的消息
$this->termOutro('All set!');

termInfotermCommenttermErrortermWarning

与 Laravel 内置的输出方法一致,Terminalia 提供了用于以一致样式在不同颜色中写入输出的方法。它们接受以下参数

  • text (字符串或数组): 要写入输出的消息
$this->termInfo('Here is the URL: https://bellows.dev');

$this->termComment([
    'This is a multi-line comment! I have a lot to say, and it is easier to write as an array.',
    'Here is the second part of what I have to say. Not to worry, Terminalia will handle all of the formatting.',
]);

$this->termError('Whoops! That did not go so well.');

$this->termWarning('Heads up! Output may be *too* beautiful.');

Demo

termNote

termNote 方法允许您向用户显示一条较长的消息。如果您有多个行,可以可选地传递一个字符串数组作为第一个参数,还可以可选地传递一个作为第二个参数的标题。

// Regular note
$this->termNote(
    "You really did it. We are so proud of you. Thank you for telling us all about yourself. We can't wait to get to know you better.",
    'Congratulations',
);

// Multiple lines via an array
$this->termNote(
    [
        'You really did it. We are so proud of you. Thank you for telling us all about yourself.',
        "We can't wait to get to know you better."
    ],
    'Congratulations',
);

// No title
$this->termNote(
    [
        'You really did it. We are so proud of you. Thank you for telling us all about yourself.',
        "We can't wait to get to know you better."
    ],
);

Demo

termSpinner

termSpinner 方法允许您在不确定的过程运行时显示一个旋转器。它允许自定义,您可以通知用户过程正在运行的情况。旋转器的结果将来自 task 参数的返回值。

重要:需要注意的是,task 在一个分支进程中运行,因此任务本身不应该在您的应用程序中创建任何副作用。它应该只处理一些内容并返回一个结果。

简单

$site = $this->termSpinner(
    title: 'Creating site...',
    task: function () {
        // Do something here that takes a little while
        $site = Site::create();
        $site->deploy();

        return $site;
    },
    message: 'Site created!',
);

Demo

根据任务的最终结果显示变量消息

$site = $this->termSpinner(
    title: 'Creating site...',
    task: function () {
        // Do something here that takes a little while
        $site = Site::create();
        $site->deploy();

        return $site->wasDeployed;
    },
    message: fn($result) => $result ? 'Site created!' : 'Error creating site.',
);

Demo

在工作过程中更新用户进度

$site = $this->termSpinner(
    title: 'Creating site...',
    task: function (SpinnerMessenger $messenger) {
        // Do something here that takes a little while
        $site = Site::create();

        $messenger->send('Site created, deploying');
        $site->deploy();

        $messenger->send('Verifying deployment');
        $site->verifyDeployment();

        return $site->wasDeployed;
    },
    message: fn($result) => $result ? 'Site created!' : 'Error creating site.',
);

Demo

在等待期间向用户提供鼓励信息

$site = $this->termSpinner(
    title: 'Creating site...',
    task: function () {
        // Do something here that takes a little while
        $site = Site::create();
        $site->deploy();
        $site->verifyDeployment();

        return $site->wasDeployed;
    },
    // seconds => message
    longProcessMessages: [
        3  => 'One moment',
        7  => 'Almost done',
        11 => 'Wrapping up',
    ],
);

Demo

进度条

进度条的 API 与 Laravel 控制台进度条 非常相似,只有一个小的补充:您可以传递一个可选的标题作为进度条的参数。

$this->withTermProgressBar(collect(range(1, 20)), function () {
    usleep(300_000);
}, 'Progress is being made...');

Demo

$items = range(1, 10);
$progress = $this->createTermProgressBar(count($items), 'Updating users...');

$progress->start();

foreach ($items as $item) {
    $progress->advance();
    usleep(300_000);
}

$progress->finish();

Demo

$this->withTermProgressBar(collect(range(1, 20)), function () {
    usleep(300_000);
});

Demo