使用 symfony/process 执行 shell 命令的服务类,深受 laravel/valet 中的 CommandLine 类的启发。

1.1.0 2022-02-28 21:04 UTC

This package is auto-updated.

Last update: 2024-09-29 03:36:37 UTC


README

CLI 服务类接口和实现,用于使用 php 执行 shell 命令,使用 symfony/processsymfony/console,深受 laravel/valet 中的 CommandLine 类 的启发。

入门指南

要求

  • PHP ^8.0
  • Composer * (但推荐 2.2 或更高版本)

安装

composer require jascha030/cli

使用

该包内容主要包括一个简单的服务类,实现了一个接口。除此之外,还有一些这些类和接口的衍生品。

ShellInterface

主要接口是 Jascha030\CLI\Shell\ShellInterface,它要求一个类实现四个方法。

interface ShellInterface
{
    /**
     * Run a shell command.
     */
    public function run(string $command, ?string $cwd = null, ?callable $onError = null): string;

    /**
     * Run a shell command with sudo user capabilities.
     */
    public function runAsUser(string $command, ?string $cwd = null, ?callable $onError = null): string;

    /**
     * Run a shell command without writing output to the STDOUT or php.
     */
    public function quietly(string $command, ?string $cwd = null, ?callable $onError = null): void;

    /**
     * Run a shell command with sudo user capabilities,  without writing output to the STDOUT or php.
     */
    public function quietlyAsUser(string $command, ?string $cwd = null, ?callable $onError = null): void;
}

默认实现

此包还提供了一个类作为 Jascha030\CLI\Shell\ShellInterface 的最基本实现,即 Jascha030\CLI\Shell\Shell 类。此类实现了所有四个方法。

所有四个方法都使用 Shell::runCommand 方法,该方法也是直接可用的。

public function runCommand(string $command, ?string $cwd = null, ?callable $onError = null): string;

以下是一个使用该类的简单示例

<?php

use Jascha030\CLI\Shell\Shell;

/**
 * Include Composer's autoloader. 
 */
include __DIR__ . '/vendor/autoload.php';

$shell = new Shell();
// The console command's output is returned by the run method, as string.
echo $shell->run("`which php` -v");

上述代码输出以下内容

PHP 8.0.16 (cli) (built: Feb 18 2022 09:31:10) ( NTS )
Copyright (c) The PHP Group
Zend Engine v4.0.16, Copyright (c) Zend Technologies
    with Xdebug v3.1.2, Copyright (c) 2002-2021, by Derick Rethans
    with Zend OPcache v8.0.16, Copyright (c), by Zend Technologies

注意:此示例输出针对您的环境特定,具体的版本和扩展取决于您自己的环境。

静默执行命令

$shell->quietly($command);

以 sudo 用户身份执行命令

// This acts as if you run your command prepended by sudo.
$shell->runAsUser($command);

// Which also can be done silently.
$shell->quetlyAsUser($command);

上述所有方法都接受可选的 $cwd (字符串) 和 $onError (可调用) 参数。

$cwd 命令允许您从另一个目录执行命令。

// Runs the command two directories above the current script's directory.
$shell->run($command, dirname(__FILE__, 3));

$onError 是一个回调,可以传递以处理命令失败。

这两个参数都直接传递给 Process::fromShellCommandline() 方法,更多详细信息,请参阅 symfony 的 Process 组件文档

Shell 程序二进制文件

如果您正在编写围绕可执行二进制文件的 CLI,您可以实现 Jascha030\CLI\Shell\Binary\BinaryInterface。这些只是对 ShellInterface 的扩展,需要您提供名称、版本和二进制文件的路径。

interface BinaryInterface extends ShellInterface
{
    public function getName(): string;

    public function getPath(): string;

    public function getVersion(): ?string;
}

为了启动实现,各种特质和抽象类可用

  • Jascha030\CLI\Shell\Binary\BinaryAbstract 简单实现三个 BinaryInterface 方法,其值通过构造函数提供。
  • Jascha030\CLI\Shell\Binary\Traits\ShellDecoratorTrait 通过将命令委派给另一个实例的 ShellInterface(通过抽象的 ShellDecoratorTrait::getShell() 方法提供)来最简单实现 ShellInterface 所需的其余方法。
  • Jascha030\CLI\Shell\Binary\Traits\SelfResolvingPathTrait,当可以使用 which 命令(例如 which php)提供二进制文件的路径时使用。
  • Jascha030\CLI\Shell\Binary\Traits\SelfResolvingVersionTrait,当可以使用命令提供二进制文件的版本时使用。
    • 默认为 -v,但可以通过覆盖 SelfResolvingVersionTrait::getVersionCommand() 方法来覆盖。
    • 默认情况下,它将匹配提供的版本命令的输出与正则表达式模式(/\\d{1,2}\\.\\d{1,2}\\.\\d{1,2}/),这可以通过覆盖 SelfResolvingVersionTrait::getVersionRegex() 方法来覆盖。当此方法返回 null 时,将跳过正则表达式匹配,并使用命令的完整输出。

辅助函数

一组辅助函数包含在 includes/helper.php 中,位于 Jascha030\Cli\Helpers 命名空间下。

获取用户,或当可用时获取 sudo 用户。

类\Jascha030\CLI\Helpers\user(): ?string;

向控制台输出一条消息。

\Jascha030\CLI\Helpers\output(string $message, ?OutputInterface $output = null): void;

向控制台输出错误信息。

\Jascha030\CLI\Helpers\error(string $message, ?OutputInterface $output = null): void;

向控制台输出信息消息。

\Jascha030\CLI\Helpers\info(string $message, ?OutputInterface $output = null): void;

向控制台输出多行消息。

\Jascha030\CLI\Helpers\multilineOutput(array $message, ?OutputInterface $output = null): void;

向控制台输出多行错误信息。

\Jascha030\CLI\Helpers\multilineError(array $message, ?OutputInterface $output = null): void;

向控制台输出多行信息消息。

\Jascha030\CLI\Helpers\multilineInfo(array $message, ?OutputInterface $output = null): void;

开发

克隆此仓库,并在仓库内运行composer install

代码风格

.php-cs-fixer.dist.php中提供了代码风格的php-cs-fixer配置。为了方便执行,请使用提供的Composer脚本命令

composer run format

如果您已全局安装php-cs-fixer,请将其传递给fix命令的--config参数。

php-cs-fixer fix --config=.php-cs-fixer.dist.php

单元测试

phpunit.xml中提供了phpunit的配置。

为了方便执行,请使用提供的Composer脚本命令

composer run phpunit

如果您已全局安装phpunit并希望使用它,请将配置传递给--config参数。

phpunit --config phpunit.xml

位于laravel/valet包的CommandLine类中。

除此之外,它显然大量使用了各种Symfony组件,这使得作为PHP开发者,在许多情况下都可以更轻松地工作。首先,不需要重新发明轮子。其次,使用Symfony组件,几乎在所有情况下都保证了至少一定程度的与其他PHP框架、库以及当然还有composer的互操作性。

许可证

此Composer软件包是一个开源软件,受MIT许可证许可。