afeefa/cli-app

围绕symfony console的便捷包装

0.0.33 2023-12-21 09:16 UTC

README

使用最少配置创建一个 symfony/console PHP 命令行应用程序。

描述

有时,项目可能需要一个命令行工具来执行一些配置、安装或维护工作。让它运行起来不应该需要太多努力。此包是围绕PHP的symfony/console框架的一个便捷包装,旨在简化命令行应用程序的创建。它提供:

  • 创建(嵌套)命令的流畅接口
  • 可选的(子)命令和命令参数
  • 可重用的操作
  • 用于输入、输出和进程执行的辅助函数

安装

像往常一样使用composer安装。你很可能使用cli进行开发目的

composer require afeefa/cli-app --save-dev

文档

查看下面的示例以获得灵感,并前往文档页面

示例

  1. 基本工作流程
  2. 命令操作
  3. 命令参数
  4. 嵌套命令

示例 1:基本工作流程

最简单的示例显示了cli-app的工作流程。你创建一个或多个命令(通常在一个单独的文件中),并通过提供命令名称和描述将那些命令添加到应用程序实例中。

文件:pets.php

<?php

require_once __DIR__ . '/../../vendor/autoload.php';

use Afeefa\Component\Cli\Cli;
use Afeefa\Component\Cli\Command;

class Cats extends Command
{
    protected function executeCommand()
    {
        $this->printList(['Kitty', 'Tiger', 'Meow']);
    }
}

class Dogs extends Command
{
    protected function executeCommand()
    {
        $this->printList(['Laika', 'Lassie', 'Goofy']);
    }
}

(new Cli('Pets App'))
    ->command('cats', Cats::class, 'Show cats')
    ->command('dogs', Dogs::class, 'Show dogs')
    ->run();

运行示例

git clone git@github.com:afeefacode/cli-app.git
cd cli-app
composer install

examples/pets/pets
# examples/pets/pets cats

output

示例 2:命令操作

此示例显示了三件事

  • 一个操作,它是一种轻量级的命令,可以从任何命令或操作中调用
  • 一个提示,它允许用户从一系列选择中进行选择
  • 以及通过提供一个模式来重用命令的可能性
<?php
...
use Afeefa\Component\Cli\Action;

class Names extends Action
{
    protected function executeAction()
    {
        $pet = $this->getArgument('pet');
        $names = $pet === 'cat'
            ? ['Kitty', 'Tiger', 'Meow']
            : ['Laika', 'Lassie', 'Goofy'];
        return $this->printChoice("Select a $pet", $names); // prompt
    }
}

class Feed extends Command
{
    protected function executeCommand()
    {
        $pet = $this->getCommandMode();
        $name = $this->runAction(Names::class, ['pet' => $pet]);
        $this->printBullet("Feed <info>$name</info>");
    }
}

class Cuddle extends Command
{
    protected function executeCommand()
    {
        $name = $this->runAction(Names::class, ['pet' => 'cat']);
        $this->printBullet("Cuddle <info>$name</info>");
    }
}

(new Cli('Pets App'))
    ->command('feed-cat', [Feed::class, 'cat'], 'Feed a cat') // 'cat' = mode
    ->command('feed-dog', [Feed::class, 'dog'], 'Feed a dog')
    ->command('cuddle-cat', Cuddle::class, 'Cuddle a cat')
    ->run();

运行示例

git clone git@github.com:afeefacode/cli-app.git
cd cli-app
composer install

examples/feed/feed
# examples/feed/feed feed-dog
# examples/feed/feed cuddle-cat

output

示例 3:命令参数

命令参数是CLI的一个基本功能。如果你想通过提供一个列表的参数值供用户选择来帮助用户,你可以使用可选参数。示例显示

  • 使用和消耗可选参数
  • 设置默认命令
<?php
...
use Afeefa\Component\Cli\SelectableArgument;

class Walk extends Command
{
    protected function setArguments()
    {
        $this->addSelectableArgument( // selectable argument
            'pet', ['cat', 'dog'], 'The pet to walk with'
        );

        $this->addSelectableArgument( // dependent argument
            'name',
            function (SelectableArgument $argument) {
                $pet = $this->getArgument('pet');
                $argument->choices = $pet === 'cat'
                    ? ['Kitty', 'Tiger', 'Meow']
                    : ['Laika', 'Lassie', 'Goofy'];
                $argument->description = 'The name of the ' . $pet;
            }
        );
    }

    protected function executeCommand()
    {
        $pet = $this->getArgument('pet');
        $name = $this->getArgument('name');

        if ($pet === 'cat') {
            $this->printBullet("<info>$name</info> does not walk with you");
        } else {
            $this->printBullet("<info>$name</info> is happy to walk with you");
        }
    }
}

(new Cli('Pets App'))
    ->command('walk', Walk::class, 'Walk with a pet')
    ->default('walk')
    ->run();

运行示例

git clone git@github.com:afeefacode/cli-app.git
cd cli-app
composer install

examples/walk/walk
# examples/walk/walk
# examples/walk/walk walk dog
# examples/walk/walk walk dog Laika

output

示例 4:嵌套命令

此示例显示

  • 嵌套命令的配置
  • 检查命令或命令父级的名称的能力。
<?php
...
use Afeefa\Component\Cli\Definitions\GroupDefinition as Group;

class Play extends Command
{
    protected function executeCommand()
    {
        $action = $this->getLocalName();
        $pet = $this->getLocalParentName();
        if ($pet === 'cat') {
            $this->printBullet("<info>Cat</info> does not like <info>$action</info>");
        } else {
            $this->printBullet("<info>Dog</info> likes <info>$action</info>");
        }
    }
}

(new Cli('Pets App'))
    ->group('cat', 'Play with cat', function (Group $group) {
        $group->command('hide-seek', Play::class, 'Hide and seek');
    })
    ->group('dog', 'Play with dog', function (Group $group) {
        $group
            ->command('fetch', Play::class, 'Fetch the stick')
            ->command('cuddle', Play::class, 'Cuddle the dog');
    })
    ->run();

运行示例

git clone git@github.com:afeefacode/cli-app.git
cd cli-app
composer install

examples/play/play
# examples/play/play
# examples/play/play dog
# examples/play/play dog:fetch

output