innmind / cli
构建CLI工具的库
Requires
- php: ~8.2
- innmind/immutable: ~4.15|~5.0
- innmind/operating-system: ~4.0|~5.0
- innmind/stack-trace: ~4.0
- innmind/stream: ~4.0
- innmind/url: ~4.0
Requires (Dev)
- innmind/black-box: ~5.5
- innmind/coding-standard: ~2.0
- phpunit/phpunit: ~10.2
- vimeo/psalm: ~5.15
README
CLI是一个小型库,用于封装构建命令行工具所需的所有信息。这个想法是在阅读ponylang的文档时产生的,意识到其他语言使用类似的方法来处理应用程序的入口点,因此我决定为PHP也实现类似的功能。
该方法是有一个main
函数作为代码执行的起点。这个函数有一个环境参数,因此不需要全局变量。然而,由于并非所有内容都可以作为参数传递(这将使接口复杂化),可以行使环境权限(正如常规PHP脚本中那样)。
重要:为了正确使用此库,您必须使用vimeo/psalm
验证您的代码。
安装
composer require innmind/cli
使用
要开始一个新的CLI工具,您需要以下样板代码
# cli.php <?php declare(strict_types = 1); require 'path/to/composer/autoload.php'; use Innmind\CLI\{ Main, Environment, }; use Innmind\OperatingSystem\OperatingSystem; new class extends Main { protected function main(Environment $env, OperatingSystem $os): Environment { //your code here return $env; } };
这将直接调用main
函数。变量$env
让您可以访问3个标准流(stdin
、stdout
、stderr
)、传递给cli的参数列表、所有环境变量、工作目录、终端是否交互式以及指定退出状态码的方法。
注意:调用$env->exit(1)
将不会直接退出您的程序,您必须调用return $env->exit(1);
才能使main
函数停止。
命令
当构建简单的工具时,直接使用main
函数就足够了,但您通常希望在同一个工具中提供多个命令(与参数/选项验证相关联)。此库提供了实现此功能的方法。以下是一个示例
use Innmind\CLI\{ Commands, Command, Command\Arguments, Command\Options, Console, }; function main(Environment $env, OperatingSystem $os): void { $run = Commands::of( new class implements Command { public function __invoke(Console $console): Console { //your code here } public function usage(): string { return 'foo'; } } ); return $run($env); };
在您的终端中,您可以像这样调用此命令:php cli.php foo
。但是,由于这里定义了一个单独的命令,您可以简单地调用php cli.php
。当然,您可以定义尽可能多的命令。
在这里,命令是一个匿名类,以简化示例,但它可以是一个实现Command
的普通类。由于命令只需要实现一个接口,您可以完全控制可以注入到其中的依赖项。这意味着您的命令实例可以来自依赖注入容器。由于接口简单,另一个优点是您可以轻松地对命令进行单元测试。
Command
接口要求您实现两个方法:__invoke
和usage
。第一个方法是在它是期望调用的命令时被调用的。方法usage
是您定义命令结构的地方,即命令的名称、它的参数/选项列表、其简短描述和完整描述。
要定义您命令的所有属性,它将类似于以下内容
{command name} {optional list of arguments/options}
{short description on a single line}
{full description that can span multiple lines}
当您运行help
命令(该命令将列出所有可用命令)时,会显示命令名称和简短描述。只有当您使用额外选项--help
调用命令(或误用命令)时,才会显示参数/选项列表和完整描述。
要定义参数,您有3种模式可供选择:
- 使用
foo
,您请求一个必需的参数,可以通过这种方式访问:$console->arguments()->get('foo')
- 使用
[bar]
,您请求一个可选参数,在访问之前必须通过$console->arguments()->contains('bar')
来验证其存在。可选参数不能紧跟必需参数之后。 - 使用
...baz
,您请求所有额外参数都将作为一个名为baz
的列表重新分组,它将提供一个任何长度的Sequence<string>
。您只能有一个此类参数,并且必须放在最后,您通过$console->arguments()->pack()
来访问。
要定义选项,您有2种模式可供选择:
-f|--foo
这定义了一个可以通过-f
或--foo
调用的标志,如果您不希望有简短名称,只需定义--foo
即可。-f|--foo=
这定义了一个需要值的选项,如果您不希望有简短名称,只需定义--foo=
即可。它可以通过-f=value
、-f value
或--foo=value
来调用。