testify/tools/cli.php

214 lines
5.3 KiB
PHP

<?php
class Cli {
private function __construct() {}
/**
* Parses command line arguments
*
* @param array $args
* @return array
*/
public static function parseArgs(array $args, CliSwitchCollection $switches) {
$parsed = array(
'switches' => array(),
'args' => array()
);
$last = null;
foreach ($args as $arg) {
if (strpos($arg, '-') === 0) {
$last = (substr($arg, 0, 2) === '--') ? substr($arg, 2) : substr($arg, 1);
$switch = $switches->getSwitch($last);
if ($switch !== null) {
$parsed['switches'][$switch->longName] = true;
}
} else if ($switch !== null) {
if ($switch->value !== null) {
$parsed['switches'][$switch->longName] = $arg;
} else {
$parsed['args'][] = $arg;
}
$switch = null;
} else {
$parsed['args'][] = $arg;
}
}
return $parsed;
}
}
class CliSwitch {
public $longName;
public $shortName;
public $required;
public $value;
public $description;
public function __construct($longName, $shortName = '', $required = true, $value = null, $description = '') {
$this->longName = $longName;
$this->shortName = $shortName;
$this->required = $required;
$this->value = $value;
$this->description = $description;
}
}
class CliSwitchCollection implements IteratorAggregate {
private $switches;
public function __construct() {
$this->switches = array();
}
public function addSwitch(CliSwitch $switch) {
$this->switches[] = $switch;
return $this;
}
public function getSwitch($longOrShortName) {
foreach ($this->switches as $switch) {
if ($switch->longName == $longOrShortName || $switch->shortName == $longOrShortName) {
return $switch;
}
}
return null;
}
public function segregateSwitches() {
$switches = array(
'required' => array(),
'optional' => array()
);
foreach ($this->switches as $switch) {
if ($switch->required) {
$switches['required'][] = $switch;
} else {
$switches['optional'][] = $switch;
}
}
return $switches;
}
public function getIterator() {
return new ArrayIterator($this->switches);
}
}
class Usage {
private $switches;
private $name;
private $script;
private $description;
private $copyright;
private $maxSwitchLength;
const LINE_LENGTH = 80;
public function __construct($name, $script, $description, $author = null, $date = null) {
$this->switches = array(array(), array());
$this->maxSwitchLength = 0;
$this->script = $script;
$this->name = $name;
$this->description = $description;
$this->copyright =
($date !== null)
? 'Copyright (c) ' . $date . (($author !== null) ? " $author" : '')
: (($author !== null) ? "by $author" : '');
}
public function __get($key) {
if ($key === 'switches') {
return $this->switches;
}
throw new InvalidArgumentException('Invalid property');
}
public function setSwitches(CliSwitchCollection $switches) {
$this->switches = $switches;
$this->maxSwitchLength = 0;
foreach ($switches->getIterator() as $switch) {
// + 2 for left padding
// + 2 for double-hyphen
$length = 2 + strlen($switch->longName) + 2;
// + 1 for left padding
// + 1 for hyphen
// + 1 for openening parenthesis
// + 1 for closing parenthesis
$length += (strlen($switch->shortName) > 0) ? 1 + 1 + 1 + strlen($switch->shortName) + 1 : 0;
//echo $length . "\n";
$this->maxSwitchLength = max($this->maxSwitchLength, $length);
}
//echo $this->maxSwitchLength; exit;
}
public function __toString() {
$this->maxSwitchLength += 2;
$usage = $this->name . "\n";
$usage .= (!empty($this->copyright)) ? ' ' . $this->copyright . "\n" : '';
$usage .= "\n";
$usage .= "USAGE\n";
$usageData = ' php ' . $this->script;
$switchData = "REQUIRED\n";
$switches = $this->switches->segregateSwitches();
foreach ($switches['required'] as $switch) {
$usageData .= ' --' . $switch->longName;
if ($switch->value !== null) {
$usageData .= ' ' . $switch->value;
}
$x = ' --' . $switch->longName;
if (!empty($switch->shortName)) {
$x .= str_repeat(' ', $this->maxSwitchLength - 5 - strlen($x)) . '(-' . $switch->shortName . ')';
}
$x .= str_repeat(' ' , $this->maxSwitchLength - strlen($x));
$x .= wordwrap($switch->description, self::LINE_LENGTH - strlen($x), "\n" . str_repeat(' ', strlen($x))) . "\n";
$switchData .= $x;
}
$switchData .= "\nOPTIONAL\n";
foreach ($switches['optional'] as $switch) {
$usageData .= ' [--' . $switch->longName;
if ($switch->value !== null) {
$usageData .= ' ' . $switch->value;
}
$usageData .= ']';
$x = ' --' . $switch->longName;
if (!empty($switch->shortName)) {
$x .= str_repeat(' ', $this->maxSwitchLength - 5 - strlen($x)) . '(-' . $switch->shortName . ')';
}
$x .= str_repeat(' ' , $this->maxSwitchLength - strlen($x));
$x .= wordwrap($switch->description, self::LINE_LENGTH - strlen($x), "\n" . str_repeat(' ', strlen($x))) . "\n";
$switchData .= $x;
}
$usage .= wordwrap($usageData, self::LINE_LENGTH - 2, "\n ");
$usage .= "\n\n" . $switchData . "\n";
return $usage;
}
}
?>