decodelabs/terminus

简单的 CLI 交互

v0.10.5 2024-08-21 20:52 UTC

README

PHP from Packagist Latest Version Total Downloads GitHub Workflow Status PHPStan License

PHP 的简单 CLI 交互

Terminus 提供了构建高度交互式、美观的 CLI 流程所需的一切。

DecodeLabs 博客 上获取新闻和更新。

安装

composer require decodelabs/terminus

用法

写入输出

将标准文本写入输出

use DecodeLabs\Terminus as Cli;

Cli::write('Normal text'); // no newline
Cli::writeLine(' - end of line'); // with newline

错误输出以 Error 作为方法名的方式工作

use DecodeLabs\Terminus as Cli;

Cli::writeError('Error text'); // no newline
Cli::writeErrorLine(' - end of line'); // with newline

读取输入

从用户读取输入:注意,PHP 默认缓冲输入流,因此需要按下回车键才能读取输入。

use DecodeLabs\Terminus as Cli;

$data = Cli::read(3); // Read 3 bytes
$line = Cli::readLine();

如果连接的终端支持 stty(大多数 Unix 模拟器),则可以关闭缓冲以实现即时输入

use DecodeLabs\Terminus as Cli;

Cli::toggleInputBuffer(false);
Cli::writeLine('Yes or no?')
$char = Cli::read(1); // y or n
Cli::toggleInputBuffer(true);

更多关于扩展 ANSIstty 支持的信息见下文。

颜色和样式

如果连接的终端可以支持 ANSI 代码,则可以使用界面上的快捷方式轻松地设置样式

use DecodeLabs\Terminus as Cli;

Cli::{'blue'}('This is blue ');
Cli::{'yellow'}('This is yellow ');
Cli::{'red|green|underline'}(' This is red on green, underlined');
Cli::{'+'}('This starts on a new line');
Cli::{'.'}('- this ends on a new line');
Cli::{'>>'}('This is tabbed, twice!');
Cli::{'<'}(' - this backspaces the last character');
Cli::writeLine();
Cli::{'++>..:146|#CCC|bold|underline'}('A whole mix of parameters');

可以使用以下方法检查对 ANSI 代码的支持

use DecodeLabs\Terminus as Cli;

if(Cli::isAnsi()) {
    // do stuff
}

样式前缀的格式如下

<修饰符>前景?|背景?|选项1?|选项2?...

修饰符按照它们连续出现的次数应用。

  • 修饰符
    • ^ 清除上面的行
    • + 在前面添加行
    • . 在后面添加行
    • > 在前面添加制表符
    • < 删除前面的输出
    • ! 被视为错误
    • !! 不被视为错误
  • 前景/背景
    • black (ANSI)
    • red (ANSI)
    • green (ANSI)
    • yellow (ANSI)
    • blue (ANSI)
    • magenta (ANSI)
    • cyan (ANSI)
    • white (ANSI)
    • reset (ANSI)
    • brightBlack (ANSI)
    • brightRed (ANSI)
    • brightGreen (ANSI)
    • brightYellow (ANSI)
    • brightBlue (ANSI)
    • brightMagenta (ANSI)
    • brightCyan (ANSI)
    • brightWhite (ANSI)
    • :0 to :255 8位颜色代码
    • #000000 to #FFFFFF 24位十六进制颜色
  • 选项
    • 加粗
    • 淡色
    • 斜体
    • 下划线
    • 闪烁
    • 闪烁
    • 反转
    • 私人
    • 删除线

注意,许多终端模拟器上不支持或仅部分支持某些选项。

行控制

直接控制行和光标:以下所有方法都允许传递一个数值以控制其应用的次数。

use DecodeLabs\Terminus as Cli;

Cli::newLine(); // Write to a new line
Cli::newLine(5); // Write 5 new lines
Cli::deleteLine(); // Delete the previous line
Cli::clearLine(); // Clear the current line
Cli::clearLineBefore(); // Clear the current line from cursor to start
Cli::clearLineAfter(); // Clear the current line from cursor to end
Cli::backspace(); // Clear the previous character
Cli::tab(); // Write \t to output

Cli::cursorUp(); // Move cursor up vertically
Cli::cursorLineUp(); // Move cursor up to start of previous line
Cli::cursorDown(); // Move cursor down vertically
Cli::cursorLineDown(); // Move cursor down to start of next line
Cli::cursorLeft(); // Move cursor left
Cli::cursorRight(); // Move cursor right

Cli::setCursor(5); // Set cursor horizontally to index 5
Cli::setCursorLine(30, 10); // Set absolute cursor position

[$line, $pos] = Cli::getCursor(); // Attempt to get absolute cursor position
$pos = Cli::getCursorH(); // Attempt to get horizontal cursor position
$line = Cli::getCursorV(); // Attempt to get vertical cursor position

Cli::saveCursor(); // Store cursor position in terminal memory
Cli::restoreCursor(); // Attempt to restore cursor position from terminal memory

$width = Cli::getWidth(); // Get line width of terminal
$height = Cli::getHeight(); // Get line height of terminal

stty

一些扩展功能依赖于 stty 的可用性(大多数 Unix 模拟器)。

use DecodeLabs\Terminus as Cli;

Cli::toggleInputEcho(false); // Hide input characters
Cli::toggleInputBuffer(false); // Don't wait on return key for input

stty 可以使用以下方法进行控制

use DecodeLabs\Terminus as Cli;

if(Cli::hasStty()) {
    $snapshot = Cli::snapshotStty(); // Take a snapshot of current settings
    Cli::toggleInputEcho(false);
    // do some stuff

    Cli::restoreStty($snapshot); // Restore settings
    // or
    Cli::resetStty(); // Reset to original settings at the start of execution
}

小部件

使用内置小部件简化常见用例

问题

use DecodeLabs\Terminus as Cli;

$answer = Cli::newQuestion('How are you?')
    ->setOptions('Great', 'Fine', 'OK')
    ->setDefaultValue('great')
    ->prompt();


// Or direct..
$answer = Cli::ask('How are you?', 'great');

Cli::{'..green'}('You are: '.$answer);

密码

$password = Cli::newPasswordQuestion('Now enter a password...')
    ->setRequired(true)
    ->setRepeat(true)
    ->prompt();

// Or direct
$password = Cli::askPassword('Now enter a password...', true, true);

Cli::{'..green'}('Your password is: '.$password);

确认

use DecodeLabs\Terminus as Cli;

if (Cli::confirm('Do you like green?', true)) {
    Cli::{'..brightGreen'}('Awesome!');
} else {
    Cli::{'..brightRed'}('Boo!');
}

旋转器

use DecodeLabs\Terminus as Cli;

Cli::{'.'}('Progress spinner: ');
$spinner = Cli::newSpinner();

for ($i = 0; $i < 60; $i++) {
    usleep(20000);
    $spinner->advance();
}

$spinner->complete('Done!');

进度条

use DecodeLabs\Terminus as Cli;

Cli::{'.'}('Progress bar: ');
$spinner = Cli::newProgressBar(10, 50);

for ($i = 0; $i < 80; $i++) {
    usleep(20000);
    $spinner->advance(($i / 2) + 11);
}

$spinner->complete();

将 Terminus 作为 PSR Logger 使用

use DecodeLabs\Terminus as Cli;

Cli::debug('This is a debug');
Cli::info('This is an info message');
Cli::notice('This is a notice');
Cli::success('You\'ve done a success, well done!');
Cli::warning('This is a warning');
Cli::error('Hold tight, we have an error');
Cli::critical('This is CRITICAL');
Cli::alert('alert alert alert');
Cli::emergency('Oh no this is an emergency!');

参数解析

快速解析请求中的输入参数到会话

use DecodeLabs\Terminus as Cli;

Cli::$command
    ->setHelp('Test out Terminus functionality')
    ->addArgument('action', 'Unnamed action argument')
    ->addArgument('?-test|t=Test arg', 'Named test argument with default value');

$action = Cli::$command['action'];
$test = Cli::$command['test'];

会话

Terminus 将默认创建一个标准会话,通过 PHP 的 STDINSTDOUTSTDERR 流进行通信,并使用 $_SERVER['argv'] 中的参数。

您可以通过创建自己的会话并设置主Terminus界面来自定义会话。有关控制IO流的信息,请参阅Deliverance Broker

use DecodeLabs\Deliverance;
use DecodeLabs\Terminus as Cli;

$session = Cli::newSession(
    Cli::newRequest(['list', 'of', 'argv', 'params']),

    // The Io Broker is optional, defaults to best fit
    Deliverance::newIoBroker()
        ->addInputProvider($inputStream)
        ->addOutputReceiver($outputStream)
        ->addErrorReceiver($errorStream)
);

Cli::setSession($session);

层压板

Terminus使用VeneerDecodeLabs\Terminus下提供统一的界面。您可以通过这个静态界面访问所有主要功能,而不会影响测试和依赖注入。

许可

Terminus遵循MIT许可。请参阅LICENSE以获取完整的许可文本。