corneltek/cliframework

PHP的命令行框架


README

Coverage Status Latest Stable Version Latest Unstable Version Total Downloads Monthly Downloads License

CLIFramework是一个命令行应用程序框架,用于构建灵活、简单的命令行应用程序。

命令和子命令可以从应用程序外部或插件中注册。

定义新命令很简单,只需声明一个继承自CLIFramework\Command类的类即可。

功能

  • 直观的命令类和选项规范

  • 支持命令选项,由GetOptionKit提供支持,包括长选项、短选项、必需|可选|默认值。

  • 分层命令。

  • 自动帮助页面生成。

  • 自动zsh完成生成器。

  • 自动bash完成生成器。

  • 当命令参数不足时显示友好的消息。

  • 可测试,CLIFramework为PHP中的命令提供PHPUnit测试用例。

  • 参数验证、建议、

  • 命令组

  • HHVM兼容

概要

class CommitCommand extends CLIFramework\Command {

    public function brief() { return 'brief of bar'; }

    public function options($opts) {
        $opts->add('C|reuse-message:','Take an existing commit object, and reuse the log message and the authorship information (including the timestamp) when creating the commit.')
            ->isa('string')
            ->valueName('commit hash')
            // ->validValues([ 'static-50768ab', 'static-c2efdc2', 'static-ed5ba6a', 'static-cf0b1eb'])
            ->validValues(function() {
                $output = array();
                exec("git rev-list --abbrev-commit HEAD -n 20", $output);
                return $output;
            })
            ;

        // Runtime completion by setting up a closure for completion
        $opts->add('c|reedit-message:','like -C, but with -c the editor is invoked, so that the user can further edit the commit message.')
            ->isa('string')
            ->valueName('commit hash')
            ->validValues(function() {
                // exec("git log -n 10 --pretty=format:%H:%s", $output);
                exec("git log -n 10 --pretty=format:%H:%s", $output);
                return array_map(function($line) {
                    list($key,$val) = explode(':',$line);
                    $val = preg_replace('/\W/',' ', $val);
                    return array($key, $val);
                }, $output);
            })
            ;

        $opts->add('author:', 'Override the commit author. Specify an explicit author using the standard A U Thor <author@example.com> format.')
            ->suggestions(array( 'c9s', 'foo' , 'bar' ))
            ->valueName('author name')
            ;

        $opts->add('output:', 'Output file')
            ->isa('file')
            ;
    }

    public function arguments($args) {
        $args->add('user')
            ->validValues(['c9s','bar','foo']);

        // Static completion result
        $args->add('repo')
            ->validValues(['CLIFramework','GetOptionKit']);

        // Add an argument info expecting multiple *.php files
        $args->add('file')
            ->isa('file')
            ->glob('*.php')
            ->multiple()
            ;
    }

    public function init() {

        $this->command('foo'); // register App\Command\FooCommand automatically

        $this->command('bar', 'WhatEver\MyCommand\BarCommand');

        $this->commandGroup('General Commands', ['foo', 'bar']);

        $this->commandGroup('Database Commands', ['create-db', 'drop-db']);

        $this->commandGroup('More Commands', [
            'foo' => 'WhatEver\MyCommand\FooCommand',
            'bar' => 'WhatEver\MyCommand\BarCommand'
        ]);
    }

    public function execute($user,$repo) {
        $this->logger->notice('executing bar command.');
        $this->logger->info('info message');
        $this->logger->debug('info message');
        $this->logger->write('just write');
        $this->logger->writeln('just drop a line');
        $this->logger->newline();

        return "Return result as an API"; // This can be integrated in your web application
    }
}

自动Zsh完成生成器

Imgur

带有懒加载完成值的Zsh完成

Imgur

Bash完成

Imgur

文档

请参阅我们的wiki上的文档https://github.com/c9s/CLIFramework/wiki

命令形式

CLIFramework支持许多命令行形式,例如

$ app [app-opts] [subcommand1] [subcommand1-opts] [subcommand2] [subcommand2-opts] .... [arguments] 

如果未定义子命令,您仍然可以使用简单形式

$ app [app-opts] [arguments]

例如,

$ app db schema --clean dbname
$ app gen controller --opt1 --opt2 ControllerName 

子命令层次结构

命令具有如prepareexecutefinish等阶段的方法,对于以下命令

$ app foo_cmd bar_cmd arg1 arg2 arg3

调用图如下

app->run
- app->prepare
  - foo_cmd->prepare
    - bar_cmd->prepare
    - bar_cmd->execute
    - bar_cmd->finish
  - foo_cmd->finish
- app->finish

基本要求

  • PHP 5.3

安装

从composer安装

{
    "require": {
        "corneltek/cliframework": "*"
    }
}

Zsh完成生成器

example/demo zsh demo > _demo
source _demo
demo <TAB>

Imgur

Imgur

Imgur

Imgur

控制台提示(Readline)

简单提示

$input = $this->ask("Your name please");
$ php demo.php
Your name please: 

提示并接受有效值

$input = $this->ask("Your name please", array('John', 'Pedro'));

版本信息

CLIFrameword有一个内置的--version选项,要设置版本信息,您只需覆盖应用程序类中的一个常量来设置版本字符串即可

class ConsoleApp extends CLIFramework\Application
{
    const NAME = 'YourApp';
    const VERSION = '1.2.1';
}

这将显示

$ yourapp.php --version
YourApp - version 1.2.1

示例

请检查example/demo.php

$ php example/demo.php

ArgumentEditor

use CLIFramework\ArgumentEditor\ArgumentEditor;

$editor = new ArgumentEditor(array('./configure','--enable-debug'));
$editor->append('--enable-zip');
$editor->append('--with-sqlite','--with-postgres');

echo $editor;
# ./configure --enable-debug --enable-zip --with-sqlite --with-postgres

消息样式格式化器

$formatter = new CLIFramework\Formatter;
$formatter->format( 'message' , 'green' );

内置样式

'red'          => array('fg' => 'red'),
'green'        => array('fg' => 'green'),
'white'        => array('fg' => 'white'),
'yellow'       => array('fg' => 'yellow'),
'strong_red'   => array('fg' => 'red', 'bold'  => 1),
'strong_green' => array('fg' => 'green','bold' => 1),
'strong_white' => array('fg' => 'white','bold' => 1),

构建Phar存档文件

COMPOSER=tests/fixture/composer.json.phar-test composer install
php example/demo archive --working-dir /Users/c9s/work/php/CLIFramework \
        --composer tests/fixture/composer.json.phar-test \
        app.phar

选择器组件

$chooser = new CLIFramework\Chooser;
$value = $chooser->choose( "System Options" , array( 
    'use php-5.4.0' => '5.4.0',
    'use php-5.4.1' => '5.4.1',
    'use system' => '5.3.0',
));

调试工具

行指示器

use CLIFramework\Debug\LineIndicator;
$indicator = new LineIndicator;
echo PHP_EOL, $indicator->indicateFile(__FILE__, __LINE__);

ConsoleDebug类

use CLIFramework\Debug\ConsoleDebug;

ConsoleDebug::dumpRows($pdo->fetchAll());

ConsoleDebug::dumpException($e);

下一版本中的待办事项

  • 提供一个简单的方法来定义链式命令
  • 子命令的可继承选项。
  • 人类可读的异常渲染器。
  • 交互式工具

黑客攻击

设置

  1. https://github.com/phpbrew/Onion下载并安装Onion

  2. 使用Onion捆绑依赖关系

    $ onion bundle

  3. 运行测试,应该通过。

  4. 黑客黑客黑客。

  5. 运行测试。

  6. 发送拉取请求。

命令类注册的工作方式

  • CLIApplication继承自CommandBase。
  • 命令也继承自CommandBase。
  • 要注册子命令,我们使用addCommand方法来注册命令或子命令。
    • 命令类是可选的,如果省略命令类名,则addCommand方法将尝试猜测真实命令类,并尝试加载命令类。

Bitdeli Badge