Giter VIP home page Giter VIP logo

getoptionkit's Introduction

GetOptionKit

Code Quality

Build Status Coverage Status

Versions & Stats

Latest Stable Version Latest Unstable Version Total Downloads Monthly Downloads Daily Downloads License

A powerful option parser toolkit for PHP, supporting type constraints, flag, multiple flag, multiple values and required value checking.

GetOptionKit supports PHP5.3, with fine unit testing with PHPUnit testing framework.

GetOptionKit is object-oriented, it's flexible and extendable.

Powering PHPBrew https://github.com/phpbrew/phpbrew, CLIFramework https://github.com/c9s/CLIFramework and AssetKit https://github.com/c9s/AssetKit

Features

  • Simple format.
  • Type constrant.
  • Multiple value, requried value, optional value checking.
  • Auto-generated help text from defined options.
  • Support app/subcommand option parsing.
  • Option Value Validator
  • Option Suggestions
  • SPL library.
  • HHVM support.

Requirements

  • PHP 5.3+

Install From Composer

composer require corneltek/getoptionkit

Supported Option Formats

simple flags:

program.php -a -b -c
program.php -abc
program.php -vvv   # incremental flag v=3
program.php -a -bc

with multiple values:

program.php -a foo -a bar -a zoo -b -b -b

specify value with equal sign:

program.php -a=foo
program.php --long=foo

with normal arguments:

program.php -a=foo -b=bar arg1 arg2 arg3
program.php arg1 arg2 arg3 -a=foo -b=bar

Option SPEC

v|verbose    flag option (with boolean value true)
d|dir:       option require a value (MUST require)
d|dir+       option with multiple values.
d|dir?       option with optional value
dir:=string  option with type constraint of string
dir:=number  option with type constraint of number
dir:=file    option with type constraint of file
dir:=date    option with type constraint of date
dir:=boolean option with type constraint of boolean
d            single character only option
dir          long option name

Command Line Forms

app [app-opts] [app arguments]

app [app-opts] subcommand [subcommand-opts] [subcommand-args]

app [app-opts] subcmd1 [subcmd-opts1] subcmd2 [subcmd-opts] subcmd3 [subcmd-opts3] [subcommand arguments....]

Documentation

See more details in the documentation

Demo

Please check examples/demo.php.

Run:

% php examples/demo.php -f test -b 123 -b 333

Print:

* Available options:
      -f, --foo <value>    option requires a value.
     -b, --bar <value>+    option with multiple value.
    -z, --zoo [<value>]    option with optional value.
          -v, --verbose    verbose message.
            -d, --debug    debug message.
                 --long    long option name only.
                     -s    short option name only.
Enabled options: 
* key:foo      spec:-f, --foo <value>  desc:option requires a value.
    value => test

* key:bar      spec:-b, --bar <value>+  desc:option with multiple value.
    Array
    (
        [0] => 123
        [1] => 333
    )

Synopsis

use GetOptionKit\OptionCollection;
use GetOptionKit\OptionParser;
use GetOptionKit\OptionPrinter\ConsoleOptionPrinter;

$specs = new OptionCollection;
$specs->add('f|foo:', 'option requires a value.' )
    ->isa('String');

$specs->add('b|bar+', 'option with multiple value.' )
    ->isa('Number');

$specs->add('ip+', 'Ip constraint' )
    ->isa('Ip');

$specs->add('email+', 'Email address constraint' )
    ->isa('Email');

$specs->add('z|zoo?', 'option with optional value.' )
    ->isa('Boolean');

$specs->add('file:', 'option value should be a file.' )
    ->isa('File');

$specs->add('v|verbose', 'verbose message.' );
$specs->add('d|debug', 'debug message.' );
$specs->add('long', 'long option name only.' );
$specs->add('s', 'short option name only.' );

$printer = new ConsoleOptionPrinter();
echo $printer->render($specs);

$parser = new OptionParser($specs);

echo "Enabled options: \n";
try {
    $result = $parser->parse( $argv );
    foreach ($result->keys as $key => $spec) {
        print_r($spec);
    }

    $opt = $result->keys['foo']; // return the option object.
    $str = $result->keys['foo']->value; // return the option value
    
    print_r($opt);
    var_dump($str);
    
} catch( Exception $e ) {
    echo $e->getMessage();
}

Documentation

See https://github.com/c9s/GetOptionKit/wiki for more details.

Option Value Type

The option value type help you validate the input, the following list is the current supported types:

  • string
  • number
  • boolean
  • file
  • date
  • url
  • email
  • ip
  • ipv4
  • ipv6
  • regex

And here is the related sample code:

$opt->add( 'f|foo:' , 'with string type value' )
    ->isa('string');

$opt->add( 'b|bar+' , 'with number type value' )
    ->isa('number');

$opt->add( 'z|zoo?' , 'with boolean type value' )
    ->isa('boolean');

$opt->add( 'file:' , 'with file type value' )
    ->isa('file');

$opt->add( 'date:' , 'with date type value' )
    ->isa('date');

$opt->add( 'url:' , 'with url type value' )
    ->isa('url');

$opt->add( 'email:' , 'with email type value' )
    ->isa('email');

$opt->add( 'ip:' , 'with ip(v4/v6) type value' )
    ->isa('ip');

$opt->add( 'ipv4:' , 'with ipv4 type value' )
    ->isa('ipv4');

$opt->add( 'ipv6:' , 'with ipv6 type value' )
    ->isa('ipv6');

$specs->add('r|regex:', 'with custom regex type value')
      ->isa('Regex', '/^([a-z]+)$/');

Please note that currently only string, number, boolean types can be validated.

ContinuousOptionParser

$specs = new OptionCollection;
$spec_verbose = $specs->add('v|verbose');
$spec_color = $specs->add('c|color');
$spec_debug = $specs->add('d|debug');
$spec_verbose->description = 'verbose flag';

// ContinuousOptionParser
$parser = new ContinuousOptionParser( $specs );
$result = $parser->parse(explode(' ','program -v -d test -a -b -c subcommand -e -f -g subcommand2'));
$result2 = $parser->continueParse();

OptionPrinter

GetOptionKit\OptionPrinter can print options for you:

* Available options:
              -f, --foo   option requires a value.
              -b, --bar   option with multiple value.
              -z, --zoo   option with optional value.
          -v, --verbose   verbose message.
            -d, --debug   debug message.
                 --long   long option name only.
                     -s   short option name only.

Command-line app with subcommands

For application with subcommands is designed by following form:

[app name] [app opts] 
             [subcommand1] [subcommand-opts]
             [subcommand2] [subcommand-opts]
             [subcommand3] [subcommand-opts]
             [arguments]

You can check the tests/GetOptionKit/ContinuousOptionParserTest.php unit test file:

// subcommand stack
$subcommands = array('subcommand1','subcommand2','subcommand3');

// different command has its own options
$subcommandSpecs = array(
    'subcommand1' => $cmdspecs,
    'subcommand2' => $cmdspecs,
    'subcommand3' => $cmdspecs,
);

// for saved options
$subcommandOptions = array();

// command arguments
$arguments = array();

$argv = explode(' ','program -v -d -c subcommand1 -a -b -c subcommand2 -c subcommand3 arg1 arg2 arg3');

// parse application options first
$parser = new ContinuousOptionParser( $appspecs );
$app_options = $parser->parse( $argv );
while (! $parser->isEnd()) {
    if (@$subcommands[0] && $parser->getCurrentArgument() == $subcommands[0]) {
        $parser->advance();
        $subcommand = array_shift( $subcommands );
        $parser->setSpecs( $subcommandSpecs[$subcommand] );
        $subcommandOptions[ $subcommand ] = $parser->continueParse();
    } else {
        $arguments[] = $parser->advance();
    }
}

Todo

  • Option Spec group.
  • option valid value checking.
  • custom command mapping.

Command Line Utility Design Concept

  • main program name should be easy to type, easy to remember.
  • subcommand should be easy to type, easy to remember. length should be shorter than 7 characters.
  • options should always have long descriptive name
  • a program should be easy to check usage.

General command interface

To list usage of all subcommands or the program itself:

$ prog help

To list the subcommand usage

$ prog help subcommand subcommand2 subcommand3

Hacking

Fork this repository and clone it:

$ git clone git://github.com/c9s/GetOptionKit.git
$ cd GetOptionKit
$ composer install

Run PHPUnit to test:

$ phpunit 

License

This project is released under MIT License.

getoptionkit's People

Contributors

1franck avatar bitdeli-chef avatar c9s avatar davidcole1340 avatar dlussky avatar erikbooij avatar gasol avatar igorsantos07 avatar martyix avatar peter279k avatar robbertkl avatar soundasleep avatar sweetchuck avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

getoptionkit's Issues

Can not enter negative numbers

If number begins with -, it is treated as an option. Current workaround: use something like: -o " -1" because -o "-1" will not work.

unclear how to actually get value

Coming from a getopt I expect that calling this:

shell> php example.php -fvalue -h

and using parse() would give me something like:

array(2) {
  ["f"]=>
  string(5) "value"
  ["h"]=>
  bool(false)
}

However parse() responds with spec definitions strings:

$result = $parser->parse($argv);
echo 's is '.$result['f']."\n";

While it's handy for a demo, it's unclear how to actually get the value. My final working snippet looks like this:

$specs = new \GetOptionKit\OptionCollection;
$specs->add('f:', 'value of f' );
$parser = new \GetOptionKit\OptionParser($specs);
$result = $parser->parse($argv)->toArray();
echo 'f is '.$result['f']."\n";

but it took some poking in the code to arrive at this.

Short options not correctly parsed in ContinuousOptionParser

I have a ContinuousOptionParser with some short options (-a, -b and -c).

Whenever I call my script with the argument "-abc" instead of "-a -b -c", the remaining non-option arguments are removed (one argument for each additional short option to the first one).

Example:

$options = new OptionCollection;

$options->add("a");
$options->add("b");
$options->add("c");

$parser = new ContinuousOptionParser($options);

$result = $parser->parse($argv);

$arguments = array();

while (!$parser->isEnd())
{
        $arguments[] = $parser->getCurrentArgument();
        $parser->advance();
}

var_dump($arguments);

Example calls:

$ php test.php foo bar
array(2) {
  [0]=>
  string(3) "foo"
  [1]=>
  string(3) "bar"
}

$ php test.php -a foo bar
array(2) {
  [0]=>
  string(3) "foo"
  [1]=>
  string(3) "bar"
}

$ php test.php -a -b foo bar
array(2) {
  [0]=>
  string(3) "foo"
  [1]=>
  string(3) "bar"
}

$ php test.php -ab foo bar
PHP Notice:  Undefined offset: 4 in [...]/src/GetOptionKit/ContinuousOptionParser.php on line 120
PHP Notice:  Undefined offset: 4 in [...]/src/GetOptionKit/ContinuousOptionParser.php on line 114
array(2) {
  [0]=>
  string(3) "bar"
  [1]=>
  NULL
}

$ php test.php -abc foo bar
PHP Notice:  Undefined offset: 4 in [...]/src/GetOptionKit/ContinuousOptionParser.php on line 120
PHP Notice:  Undefined offset: 4 in [...]/src/GetOptionKit/ContinuousOptionParser.php on line 114
PHP Notice:  Undefined offset: 5 in [...]/src/GetOptionKit/ContinuousOptionParser.php on line 120
PHP Notice:  Undefined offset: 5 in [...]/src/GetOptionKit/ContinuousOptionParser.php on line 114
array(2) {
  [0]=>
  NULL
  [1]=>
  NULL
}

I'm using version 2.2.6.

Cannot install with composer: circular deprecation error

Firstly, after skipping over dozen of alternatives, i was very happy to find this project - seems like what i was looking for!

Unfortunately, i could not find a way to install it with composer:
composer require c9s/GetOptionKit

exits with the following error:

Package c9s/GetOptionKit is abandoned, you should avoid using it. Use corneltek/getoptionkit instead.

But trying to do that and typing

composer require corneltek/getoptionkit

results in the same message.
Moreover, it seems like there is no "getoptionkit" repo under https://github.com/corneltek/

So, i'd like to know whether is this project considered as completely abandoned and so the suggestion would be to not use it in new projects? Or are there any plans to publish a replacement for it or a successor?

Fatal error: Call to a member function isOption() on null

spec option with multiple values output fatal error when value(s) missing

...
$specs->add('b|bar+', 'option with multiple value.' )->isa('Number');
...

$ php script.php -f foo -b

Fatal error: Call to a member function isOption() on null in ...\vendor\corneltek\getoptionkit\src\GetOptionKit\OptionParser.php on line 187

$ php script.php -f foo -b 1 -b 2
Array
(
[0] => 1
[1] => 2
)

OptionParser.php temp fix

if($next) {
    if($next->isOption())
        $i++;
    $result->set($spec->getId(), $spec);
}

Fatal errors when not specifying values with := or ?

I'm working on a project using the CLIFramework and I'm running in the following issues:

First, using ":=s" in the end of an option gives a fatal error when you don't specify a value (it should throw an Exception instead?):

PHP Fatal error:  Call to a member function isEmpty() on a non-object in /home/igoru/dev/php/scripts/vendor/corneltek/getoptionkit/src/GetOptionKit/OptionParser.php on line 97
PHP Stack trace:
<<internal code ommited>>
PHP   4. GetOptionKit\ContinuousOptionParser->continueParse() /home/igoru/dev/php/scripts/vendor/corneltek/cliframework/src/CLIFramework/Application.php:168
PHP   5. GetOptionKit\ContinuousOptionParser->parse() /home/igoru/dev/php/scripts/vendor/corneltek/getoptionkit/src/GetOptionKit/ContinuousOptionParser.php:122
PHP   6. GetOptionKit\OptionParser->foundRequireValue() /home/igoru/dev/php/scripts/vendor/corneltek/getoptionkit/src/GetOptionKit/ContinuousOptionParser.php:171

Second, using "?" and not specifying a value as well gives another fatal (this should work, right?):

PHP Fatal error:  Call to a member function isOption() on a non-object in /home/igoru/dev/php/scripts/vendor/corneltek/getoptionkit/src/GetOptionKit/OptionParser.php on line 75
PHP Stack trace:
<<internal code ommited>>
PHP   4. GetOptionKit\ContinuousOptionParser->continueParse() /home/igoru/dev/php/scripts/vendor/corneltek/cliframework/src/CLIFramework/Application.php:168
PHP   5. GetOptionKit\ContinuousOptionParser->parse() /home/igoru/dev/php/scripts/vendor/corneltek/getoptionkit/src/GetOptionKit/ContinuousOptionParser.php:122
PHP   6. GetOptionKit\OptionParser->takeOptionValue() /home/igoru/dev/php/scripts/vendor/corneltek/getoptionkit/src/GetOptionKit/ContinuousOptionParser.php:188

Invalid Composer Version

Firstly thanks for this library.

The project's README specifies using ~1.2 as the library version, however the demo and examples provided require ~2 as OptionCollection does not seem to exist before version 2. Had me stumped for a while.

  • Kyle

Validator isn't triggered

Hi! I really like the library you've created for parsing CLI arguments, but I'm running into an issue. I'm probably just using it wrong, but maybe you can clarify.

I'm trying to add a validator to an option, to make sure the option is an existing and readable file. I was assuming it would work something like this:

$specs
    ->add('c|candidates:', 'Candidates file')
    ->validator(function($option) {
        return file_exists($option) && is_readable($option);
    });

But it doesn't. The validate function is used nowhere in the entire library (according to PHPStorm), so I figured I needed to trigger it myself, but doing this seems unnecessarily complicated:

$option->validate($option->value)

If it should actually automatically validate, I'll be more than happy to create a PR and change it, but I wanted to check first if this is not just the intended behaviour.

string is parsed as number

when option is set as $specs->add('s|serial=string,'my string value') and on command line it is invoked as say $php sript.php -s="0001", the parameter is treated as number 1 instead of a string '0001' and exception is thrown while invoking ->parse(argv)
$ Invalid value for -s, --serial. Requires a type String

Passing multiple short options is not working

If I have multiple short options in my command and I pass them like -mv I'll just get the first one as a passed option. Using -l -v works.

Also, using -vm4 does the same, while it should give me the v option as boolean, and m as 4. Doing -m4v gives me m without the value as well, and nothing else.

2 letter short options don't work as documented

I added the following to the the demo.php file.

opt->add( 'za|zooa?' , 'option with optional value. za' );

You can retrieve the value if I use the long option:

php demo.php -f 1 -z 1 --zooa 1

If you try and retrieve the value using the short form you get "Invalid option -a"

php demo.php -f 1 -z 1 -za 1

Throw more specific exceptions

Great library. Thanks for your work on this.

Instead of just throwing Exception when something goes wrong, it would be more useful to throw more meaningful exceptions so they can be caught and appropriately handled.

Some examples:

MissingValueException

Uncaught exception 'Exception' with message 'Option f require a value.'

InvalidOptionException

Uncaught exception 'Exception' with message 'Invalid option: -q'

I see that there is already NonNumericException. This would just be to flesh-out the support for more specific exceptions.

ContinuousOptionParser does not support incremental options

In the normal OptionParser you can define incremental options (e.g. -v or -vvv). The option value will then be set to the number of occurrences of the option (e.g. 1 or 3).

In case of the ContinuousOptionParser an incremental option always has a value of 1 even if it is given multiple times (e.g. -vv should set the value to 2).

Example:

$options = new OptionCollection;

//$options->add("v|verbose")->isa("number")->incremental();// Setting isa("number") will throw an InvalidOptionValue exception "Invalid value for -v, --verbose. Requires a type Number."
$options->add("v|verbose")->incremental();// This works but only sets the value to true even if specified multiple times

$parser = new ContinuousOptionParser($options);// Replace ContinuousOptionParser with OptionParser and everything works as expected

$result = $parser->parse($argv);

var_dump($result->keys["verbose"]->value);// Returns true (if the verbose option has been specified at least once)

Suport -- to separate paths from arguments.

When using git its often useful to prevent confusion by using -- to separate paths from revisions and arguments. An example of this for example would be:
git difftool 545988dae14a4361cb8ae795dd61fba83dd9444e -- server/cron/import.php

I would find this functionality very helpful to my work.

Changelog

Hi.
I just tried to update from 2.0.3 to 2.0.9 and noticed, that you removed a public method:

Call to undefined method GetOptionKit\OptionCollection::printOptions()

Could you please maintain a changelog for breaking changes like this?)
I see, that new behavior is reflected in example.php, and i like the new OptionPrinter, but it would be nice to have a brief changelog, at least a one line at release comment)

Quoted string arguments and spaces

The library doesn't appear to support arguments such as

command --option="foo bar baz"

This becomes

['"foo', 'bar', 'baz"']

...rather than

['foo bar baz']

Is this something that you are planning to/want to implement?

Arguments aren't consumed for "multiple" options

When defining a "single" option (e.g. foo:=string), that option's argument will be consumed and not returned with the remaining arguments from getArguments(), but a "multiple" option (e.g. bar+=string) does not consume its argument and leaves it with the rest of the arguments returned by getArguments().

$specs = new \GetOptionKit\OptionCollection();
$specs->add('test1+=string', 'Test 1');
$specs->add('test2:=string', 'Test 2');

$parser = new \GetOptionKit\OptionParser($specs);

$result = $parser->parse(explode(' ', '--test1 opt1 --test2 opt2 arg1 arg2'));

$result->getArguments(); // => ["opt1", "arg1", "arg2"]

Ideally, at least to the best of my knowledge, the arguments to a "multiple" option should be consumed and removed from the list returned by getArguments() so only ["arg1", "arg2"] would be returned in the above example.

isa('Number') is not worknig.

Documentation is inconsistent about 'number' vs 'Number': https://github.com/c9s/GetOptionKit/search?utf8=โœ“&q=isa

$specs->add('s|system', 'Select system by ID' )->isa('Number');

Orange-Dream:tools rw$ php importer.php -s 123
-s, --system=
Select system by ID

PHP Fatal error: Uncaught GetOptionKit\InvalidOptionValue: Invalid value for -s, --system. Requires a type Number. in /Users/rw/Sites/smbo/old/vendor/corneltek/getoptionkit/src/Option.php:264
Stack trace:
#0 /Users/rw/Sites/smbo/old/vendor/corneltek/getoptionkit/src/Option.php(297): GetOptionKit\Option->_preprocessValue(true)
#1 /Users/rw/Sites/smbo/old/vendor/corneltek/getoptionkit/src/OptionParser.php(48): GetOptionKit\Option->setValue(true)
#2 /Users/rw/Sites/smbo/old/vendor/corneltek/getoptionkit/src/OptionParser.php(172): GetOptionKit\OptionParser->consumeOptionToken(Object(GetOptionKit\Option), Object(GetOptionKit\Argument), Object(GetOptionKit\Argument))
#3 /Users/rw/Sites/smbo/old/tools/importer.php(32): GetOptionKit\OptionParser->parse(Array)
#4 {main}

thrown in /Users/rw/Sites/smbo/old/vendor/corneltek/getoptionkit/src/Option.php on line 264

Fatal error: Uncaught GetOptionKit\InvalidOptionValue: Invalid value for -s, --system. Requires a type Number. in /Users/rw/Sites/smbo/old/vendor/corneltek/getoptionkit/src/Option.php on line 264

GetOptionKit\InvalidOptionValue: Invalid value for -s, --system. Requires a type Number. in /Users/rw/Sites/smbo/old/vendor/corneltek/getoptionkit/src/Option.php on line 264

License unclear

Hello

what's the license of this code? The LICENSE file says it's GPL but the Readme says it's MIT.

Thanks

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.