Skip to content

v4 create group

Inhere edited this page May 28, 2022 · 6 revisions

创建命令组

通过 Controller 形式可以简单快速的组织一组相关命令。在v4版本,命令组同样进行了增强,可以支持嵌入独立命令当做子命令

代码示例

先看一个代码示例片段,来自我的工具应用项目 inhere/kite

<?php declare(strict_types=1);

namespace Inhere\Kite\Console\Controller;

use Inhere\Console\Controller;
use Inhere\Console\Exception\PromptException;
use Inhere\Console\IO\Input;
use Inhere\Console\IO\Output;
use Inhere\Kite\Console\Component\Clipboard;
use Inhere\Kite\Common\Cmd;
use Inhere\Kite\Common\CmdRunner;
use Inhere\Kite\Helper\AppHelper;
use Inhere\Kite\Helper\GitUtil;
use PhpGit\Changelog\Filter\KeywordsFilter;
use PhpGit\Changelog\Formatter\GithubReleaseFormatter;
use PhpGit\Changelog\Formatter\SimpleFormatter;
use PhpGit\Changelog\GitChangeLog;
use PhpGit\Git;
use PhpGit\Info\TagsInfo;
use PhpGit\Repo;
use Throwable;
use Toolkit\PFlag\FlagsParser;
use Toolkit\Stdlib\Obj\ConfigObject;
use Toolkit\Stdlib\Str;

/**
 * Class GitController
 */
class GitController extends Controller
{
    protected static $name = 'git';

    protected static $description = 'Provide useful tool commands for quick use git';

    /**
     * @var ConfigObject
     */
    private $settings;

    public static function aliases(): array
    {
        return ['g'];
    }

    protected static function commandAliases(): array
    {
        return [
            'changelog'    => ['chlog', 'clog', 'cl'],
            'log'          => ['l', 'lg'],
        ];
    }

    /**
     * @return string[]
     */
    protected function options(): array
    {
        return [
            '--dry-run' => 'bool;Dry-run the workflow, dont real execute',
            '-y, --yes' => 'Direct execution without confirmation',
            // '-i, --interactive' => 'Run in an interactive environment[TODO]',
        ];
    }

    protected function beforeRun(): void
    {
        if ($this->app && !$this->settings) {
            $this->settings = ConfigObject::new($this->app->getArrayParam('git'));
        }
    }
    
    /**
     * display recently git commits information by `git log`
     *
     * @arguments
     *  maxCommit       int;Max display how many commits;;15
     *
     * @options
     *  --ac, --abbrev-commit     bool;Only display the abbrev commit ID
     *  --exclude                 Exclude contains given sub-string. multi by comma split.
     *  --file                    Export changelog message to file
     *  --format                  The git log option `--pretty` value.
     *                            can be one of oneline, short, medium, full, fuller, reference, email, raw, format:<string> and tformat:<string>.
     *  --mc, --max-commit        int;Max display how many commits
     *  --nc, --no-color          bool;Dont use color render git output
     *  --nm, --no-merges         bool;No contains merge request logs
     *
     * @param FlagsParser $fs
     * @param Output $output
     */
    public function logCommand(FlagsParser $fs, Output $output): void
    {
        $b = Git::new()->newCmd('log');

        $noColor = $fs->getOpt('no-color');
        $exclude = $fs->getOpt('exclude');

        $noMerges  = $fs->getOpt('no-merges');
        $abbrevID  = $fs->getOpt('abbrev-commit');
        $maxCommit = $fs->getOpt('max-commit', $fs->getArg('maxCommit'));

        // git log --color --graph --pretty=format:'%Cred%h%Creset:%C(ul yellow)%d%Creset %s (%Cgreen%cr%Creset, %C(bold blue)%an%Creset)' --abbrev-commit -10
        $b->add('--graph');
        $b->addIf('--color', !$noColor);
        $b->add('--pretty=format:"%Cred%h%Creset:%C(ul yellow)%d%Creset %s (%Cgreen%cr%Creset, %C(bold blue)%an%Creset)"');
        $b->addIf("--exclude=$exclude", $exclude);
        $b->addIf('--abbrev-commit', $abbrevID);
        $b->addIf('--no-merges', $noMerges);
        $b->add('-' . abs($maxCommit));

        $b->runAndPrint();

        $output->success('Complete');
    }
}

TIP: 创建好命令后需要注册到 Application 才能运行, 请看 注册命令 章节

编写命令组说明

  • 必须继承基础类 Inhere\Console\Controller
  • $name 命令组名称,必须且不能为空
  • $desc 命令组描述说明
  • 所有公开的且符合 {name}Command 格式的方法都是命令组的子命令

命令渲染效果 kite git -h

image

绑定选项参数

可以观察到上面示例的 logCommand 方法注释是有一定格式的。

跟独立命令一样,命令组里的子命令也可以通过方法注释快速绑定命令选项和参数,运行时console会自动解析并绑定到当前命令

  • @arguments 后面的即是命令参数
  • @options 后面的即是命令选项
    • 注意选项名和后面的设置描述需间隔一定距离
    • 规则以分号 ; 分割每个部分 (完整规则:type;desc;required;default;shorts)
    • 默认是 string 类型,可以忽略

选项参数解析使用的 php-toolkit/pflag 更多说明可以点击查看

查看帮助

我们可以使用 -h 选项查看添加选项后效果

执行 ./bin/myapp.php git log -h:

image

运行命令

运行 kite git log 即会调用 GitController::logCommand():

kite git log
# 添加选项和参数
kite git log 2
kite git log --abbrev-commit 5

注意运行命令应当遵循通用的Linux命令调用格式:ENTRY CMD --OPTIONS ARGUMENTS

运行效果:

image

设置命令组别名

跟独立命令类似,通过 aliases() 方法可以设置当前命令组的别名

    /**
     * @return string[]
     */
    public static function aliases(): array
    {
        return ['g'];
    }

设置别名后,通过别名 kite g 也可以访问执行命令组。

设置子命令的别名

命令组里还可以通过 commandAliases 给内部的子命令添加别名,方便使用。

如下所示,添加别名后 kite git l 就相当于执行 kite git log

    protected static function commandAliases(): array
    {
        return [
            'changelog'    => ['chlog', 'clog', 'cl'],
            'log'          => ['l', 'lg'],
        ];
    }

设置命令组的选项

在命令组里,我们还可以直接给命令组绑定选项设置。

    /**
     * @return string[]
     */
    protected function getOptions(): array
    {
        return [
            '--try,--dry-run' => 'bool;Dry-run the workflow, dont real execute',
            '-y, --yes'       => 'bool;Direct execution without confirmation',
            '-w, --workdir'   => 'The command work dir, default is current dir.',
        ];
    }

使用时注意,命令组的选项应当跟随命令组。例如

kite git --workdir another/dir log 2

默认是查看当前目录的git log, 加上命令组选项 --workdir another/dir 则会在 another/dir 执行 git log 命令

更多有用的方法

  • protected function annotationVars(): array 继承此方法可以添加自定义的帮助信息变量,可以在命令注释里使用
  • protected function beforeExecute(): bool 将会在每个子命令执行前调用
  • 更多请查看命令的父类 Inhere\Console\Handler\AbstractHandler 拥有的方法
Clone this wiki locally
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy