Permalink
Browse files

added more test coverage, bug fixes, examples and docs

  • Loading branch information...
nategood committed Aug 19, 2012
1 parent ac0a374 commit aa4a3b7c950188599392291623a7df45e53d3cb6
Showing with 551 additions and 73 deletions.
  1. +7 −0 LICENSE.txt
  2. +161 −0 README.md
  3. +7 −2 composer.json
  4. +12 −0 examples/basic
  5. +9 −0 examples/basic.php
  6. +45 −0 examples/greet.php
  7. +193 −65 src/Commando/Commando.php
  8. +39 −1 src/Commando/Option.php
  9. +78 −3 tests/Commando/CommandoTest.php
  10. +0 −2 tests/Commando/OptionTest.php
View
@@ -0,0 +1,7 @@
+Copyright (c) 2012 Nate Good <me@nategood.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
View
161 README.md
@@ -0,0 +1,161 @@
+# Commando
+## An Elegant PHP CLI Library
+
+Commando is a PHP command line interface library that beautifies and simplifies writing PHP scripts intended for command line use.
+
+## Why?
+
+PHP's `$argv` magic variable and global `$_SERVER['argv']` make me cringe, (`getopt`)[http://php.net/manual/en/function.getopt.php] isn't there yet, and most other PHP CLI libraries are far too OOP bloated. Commando gets down to business without a ton of overhead, removes the common boilerplate stuff when it comes to handling cli input, all while providing a clean and readable interface.
+
+# Example
+
+Here is a trivial example of a PHP Commando script packed with some of the cool stuff Commando supports. Let's say it is in a file called `hello.php`.
+
+``` php
+<?php
+
+$salutations = array('Mister' => 'Mr', 'Misses' => 'Mrs', 'Miss' => 'Ms', 'Doctor' => 'Dr');
+
+$hello_cmd = new Commando\Commando();
+$hello_cmd
+ // Define first option
+ ->option()
+ ->required()
+ ->describedAs('A person\'s name')
+ // Define a flag "-s" a.k.a. "--salutation"
+ ->option('s')
+ ->alias('salutation')
+ ->describedAs('When set, use this salutation to address the person')
+ ->must(function($salutation) {
+ return array_key_exists($salutation, $salutations) || in_array($salutation, $salutations);
+ })
+ ->map(function($salutation) {
+ if (array_key_exists($salutation, $salutations))
+ $salutation = $salutations[$salutation];
+ return "$salutation. ";
+ })
+ // Define a boolean flag "-c" aka "--capitalize"
+ ->option('c')
+ ->alias('capitalize')
+ ->describedAs('Always capitalize the words in a name')
+ ->boolean();
+
+$name = $hello_cmd[0];
+
+if ($hello_cmd['capitlize'])
+ $name = ucwords($hello_cmd[0]);
+
+echo "Hello, {$hello_cmd['salutation']}{$name}!";
+```
+
+Running it:
+
+ > php hello.php Nate
+ Hello, Nate!
+
+ > php hello.php --capitalize nate
+ Hello, Nate!
+
+ > php hello.php -c -s Mr 'nate good'
+ Hello, Mr. Nate Good!
+
+Things to note:
+
+ - Commando implements ArrayAccess so it acts much like an array when you want to retrieve values for it
+ - For "annonymous" (i.e. not a named flag) arguments, we access them based on their numeric index
+ - We can access option values in an array via a flags name OR it's alias
+ - We can use closures to perform validation and map operations right as part of our option definition
+
+## Option Definition Options
+
+### `option` (mixed name = null)
+
+Aliases: o
+
+Define a new option. When `name` is set, the option will be a named "flag" option and must only be a single char (e.g. `f` for option `-f`). When no `name` is defined, the option is an annonymous argument and is referenced in the future by it's position.
+
+### `alias` (string alias)
+
+Aliases: a, aka
+
+Add a long form (e.g. --example) alias for a named option. This method can be called multiple times to add multiple aliases.
+
+### `description` (string description)
+
+Aliases: d, describe, describedAs, h, help
+
+Text to describe this option. This text will be used to build the "help" page and as such, it is end user facing.
+
+### `require`
+
+Aliases: r, required
+
+Require that this flag is specified
+
+### `must` (Closure rule)
+
+Aliases: _N/A_
+
+Define a rule to validate input against. Takes function that accepts a string $value and returns a boolean as to whether or not $value is valid.
+
+### `map` (Closure map)
+
+Aliases: cast, castTo
+
+Perform a map operation on the value for this option. Takes function that accepts a string $value and return mixed (you can map to whatever you wish).
+
+## Installation
+
+Httpful is [PSR-0](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md) compliant and can be installed using [Composer](http://getcomposer.org/). Add `nategood/commando` to your `composer.json`
+
+ "require": {
+ "nategood/commando": "*"
+ }
+
+If you're new to Composer...
+
+ - [Download and build Composer](http://getcomposer.org/download/)
+ - Make it [globally accessible](http://getcomposer.org/doc/00-intro.md#globally)
+ - `cd` to your the directory where you'll be writing your Commando script and run `composer install`
+
+*Currently installing via Composer is the only option (phar build coming soon).*
+
+Notice
+
+ - Commando implements ArrayAccess so it acts much like an array when you want to retrieve values for it
+ - For "annonymous" (i.e. not a named flag) arguments, we access them based on their numeric index
+ - We can access option values in an array via a flags name OR it's alias
+
+## Baked in Help
+
+Commando has automatic `--help` support built in. Calling your script with this flag will print out a pretty help page based on your option definitions and Commando settings. If you define an option with the alias of 'help', it will override this built in support.
+
+## Trainwreck
+
+If you, [like Martin](http://www.amazon.com/gp/product/0132350882), are of the _train_ of thought that the chaining pattern is a "trainwreck", Commando also works fine without chaining. Commando reads much nicer with the chaining, however, chaining may require a bit more work when debugging and additional indentation diligence.
+
+```
+<?php
+// Commando without using chaining
+$cmd = new Commando();
+$option = $cmd->option('f');
+$option->alias('foo');
+$option2 = $cmd->option('g');
+```
+
+# Contributing
+
+Commando highly encourages sending in pull requests. When submitting a pull request please:
+
+ - All pull requests should target the `dev` branch (not `master`)
+ - Make sure your code follows the coding standards laid out in [PSR-1](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-1-basic-coding-standard.md) and [PSR-2](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md)
+ - Make sure you add appropriate test coverage for your changes
+ - Run all unit tests in the test directory via `phpunit ./tests`
+ - Include commenting where appropriate and add a descriptive pull request message
+
+## Inspiration
+
+ - [Commander](https://github.com/visionmedia/commander/)
+ - [Optimist](https://github.com/substack/node-optimist)
+
+Released under MIT license.
View
@@ -1,14 +1,19 @@
{
"name": "nategood/commando",
"description": "PHP CLI Commando Style",
+ "homepage": "http://github.com/nategood/commando",
+ "license": "MIT",
+ "keywords": ["cli", "command line", "command", "command line interface", "scripting", "automation"],
"authors": [
{
"name": "Nate Good",
"email": "me@nategood.com"
}
],
- "require": {},
- "version": "0.0.0",
+ "require": {
+ "php": ">=5.3"
+ },
+ "version": "0.0.1",
"autoload": {
"psr-0": {"Commando": "src/"}
}
View
@@ -0,0 +1,12 @@
+#! /usr/bin/env php
+<?php
+// Same as basic.php demoing that the library works fine as an executable as well
+// This example is Unix-ish specific
+// Usage
+// ./basic test
+
+require dirname(__DIR__) . '/vendor/autoload.php';
+
+$cmd = new Commando\Commando();
+
+echo "Argument #1: {$cmd[0]}";
View
@@ -0,0 +1,9 @@
+<?php
+// Usage
+// php basic.php test
+
+require dirname(__DIR__) . '/vendor/autoload.php';
+
+$cmd = new Commando\Commando();
+
+echo "Argument #1: {$cmd[0]}";
View
@@ -0,0 +1,45 @@
+<?php
+
+/**
+ * Example showing several of the option definition options in use, including
+ * map, must, required, alias (a.k.a. aka), desription (aka describedAs), and
+ * boolean.
+ */
+
+require dirname(__DIR__) . '/vendor/autoload.php';
+
+use Commando\Commando;
+
+$salutations = array('Mister' => 'Mr', 'Misses' => 'Mrs', 'Miss' => 'Ms', 'Doctor' => 'Dr');
+
+$hello_cmd = new Commando();
+$hello_cmd
+ // Define first option
+ ->option()
+ ->required()
+ ->describedAs('A person\'s name')
+ // Define a flag "-s" a.k.a. "--salutation"
+ ->option('s')
+ ->aka('salutation')
+ ->describedAs('When set, use this salutation to address the person')
+ ->must(function($salutation) {
+ return array_key_exists($salutation, $salutations) || in_array($salutation, $salutations);
+ })
+ ->map(function($salutation) {
+ if (array_key_exists($salutation, $salutations))
+ $salutation = $salutations[$salutation];
+ return "$salutation. ";
+ })
+ // Define a boolean flag "-c" aka "--capitalize"
+ ->option('c')
+ ->aka('capitalize')
+ ->aka('cap')
+ ->describedAs('Always capitalize the words in a name')
+ ->boolean();
+
+$name = $hello_cmd[0];
+
+if ($hello_cmd['capitlize'])
+ $name = ucwords($hello_cmd[0]);
+
+echo "Hello {$hello_cmd['salutation']}$name";
Oops, something went wrong.

0 comments on commit aa4a3b7

Please sign in to comment.