214 lines
5.3 KiB
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;
|
|
}
|
|
|
|
}
|
|
|
|
?>
|