bin/pharext: src/* src/pharext/*
@echo "Linting changed source files ... "
@for file in $?; do php -l $$file | sed -ne '/^No syntax errors/!p' && exit $${PIPESTATUS[0]}; done
- @echo "Running tests ... "
- @phpunit tests
@echo "Creating bin/pharext ... "
php -d phar.readonly=0 build/create-phar.php
chmod +x $@
* Original option spec
* @var array
*/
- private $orig;
+ private $orig = [];
/**
* Compiled spec
* @return pharext\CliArgs self
*/
public function compile(array $spec = null) {
- $this->orig = $spec;
- $this->spec = [];
+ $this->orig = array_merge($this->orig, $spec);
foreach ((array) $spec as $arg) {
- $this->spec["-".$arg[0]] = $arg;
+ if (isset($arg[0])) {
+ $this->spec["-".$arg[0]] = $arg;
+ }
$this->spec["--".$arg[1]] = $arg;
}
return $this;
return $this->offsetGet($o);
}
function offsetSet($o, $v) {
+ $osn = $this->optShortName($o);
+ $oln = $this->optLongName($o);
if ($this->optIsMulti($o)) {
- $this->args["-".$this->optShortName($o)][] = $v;
- $this->args["--".$this->optLongName($o)][] = $v;
+ if (isset($osn)) {
+ $this->args["-$osn"][] = $v;
+ }
+ $this->args["--$oln"][] = $v;
} else {
- $this->args["-".$this->optShortName($o)] = $v;
- $this->args["--".$this->optLongName($o)] = $v;
+ if (isset($osn)) {
+ $this->args["-$osn"] = $v;
+ }
+ $this->args["--$oln"] = $v;
}
}
function __set($o, $v) {
* Output pharext vX.Y.Z header
*/
function header() {
- printf("pharext v%s (c) Michael Wallner <mike@php.net>\n", VERSION);
+ printf("pharext v%s (c) Michael Wallner <mike@php.net>\n\n", VERSION);
}
/**
* @param string $prog
*/
public function help($prog) {
- printf("\nUsage:\n\n \$ %s", $prog);
+ printf("Usage:\n\n \$ %s", $prog);
$flags = [];
$required = [];
printf(" [-%s <arg>]", implode("|-", array_column($optional, 0)));
}
printf("\n\n");
- foreach ($this->args->getSpec() as $spec) {
- printf(" -%s|--%s %s", $spec[0], $spec[1], ($spec[3] & CliArgs::REQARG) ? "<arg> " : (($spec[3] & CliArgs::OPTARG) ? "[<arg>]" : " "));
- printf("%s%s%s", str_repeat(" ", 16-strlen($spec[1])), $spec[2], ($spec[3] & CliArgs::REQUIRED) ? " (REQUIRED)" : "");
+ $spc = $this->args->getSpec();
+ $max = max(array_map("strlen", array_column($spc, 1)));
+ $max += $max % 8 + 2;
+ foreach ($spc as $spec) {
+ if (isset($spec[0])) {
+ printf(" -%s|", $spec[0]);
+ } else {
+ printf(" ");
+ }
+ printf("--%s ", $spec[1]);
+ if ($spec[3] & CliArgs::REQARG) {
+ printf("<arg> ");
+ } elseif ($spec[3] & CliArgs::OPTARG) {
+ printf("[<arg>]");
+ } else {
+ printf(" ");
+ }
+ printf("%s%s", str_repeat(" ", $max-strlen($spec[1])+3*!isset($spec[0])), $spec[2]);
+ if ($spec[3] & CliArgs::REQUIRED) {
+ printf(" (REQUIRED)");
+ }
if (isset($spec[4])) {
printf(" [%s]", $spec[4]);
}
* @see \pharext\Command::run()
*/
public function run($argc, array $argv) {
+ if (($hook = stream_resolve_include_path("pharext_install.php"))) {
+ $callable = include $hook;
+ if (is_callable($callable)) {
+ $recv = $callable($this);
+ }
+ }
+
$errs = [];
$prog = array_shift($argv);
foreach ($this->args->parse(--$argc, $argv) as $error) {
exit(1);
}
+ if (isset($recv)) {
+ $recv($this);
+ }
+
$this->installPackage();
}
$this->source = new PeclSourceDir($this, $this->args["source"]);
} elseif ($this->args["git"]) {
$this->source = new GitSourceDir($this, $this->args["source"]);
+ } elseif (realpath($this->args["source"]."/pharext_package.php")) {
+ $this->source = new PharextSourceDir($this, $this->args["source"]);
} else {
$this->source = new FilteredSourceDir($this, $this->args["source"]);
}
*/
private $path;
+ /**
+ * Installer hook
+ * @var string
+ */
+ private $hook;
+
/**
* @inheritdoc
* @see \pharext\SourceDir::__construct()
}
}
+ if (($configure = $sxe->xpath("/pecl:package/pecl:extsrcrelease/pecl:configureoption"))) {
+ $this->hook = tmpfile();
+ ob_start(function($s) {
+ fwrite($this->hook, $s);
+ return null;
+ });
+ call_user_func(function() use ($configure) {
+ include __DIR__."/../pharext_install.tpl.php";
+ });
+ ob_end_flush();
+ }
+
$this->cmd = $cmd;
$this->sxe = $sxe;
$this->path = $path;
* @return Generator
*/
private function generateFiles() {
+ if ($this->hook) {
+ rewind($this->hook);
+ yield "pharext_install.php" => $this->hook;
+ }
foreach ($this->sxe->xpath("//pecl:file") as $file) {
$path = $this->path ."/". $this->dirOf($file) ."/". $file["name"];
if ($this->cmd->getArgs()->verbose) {
--- /dev/null
+<?php
+
+namespace pharext;
+
+class PharextSourceDir implements \IteratorAggregate, SourceDir
+{
+ private $cmd;
+ private $path;
+ private $iter;
+
+ public function __construct(Command $cmd, $path) {
+ $this->cmd = $cmd;
+ $this->path = $path;
+
+ $callable = include "$path/pharext_package.php";
+ if (!is_callable($callable)) {
+ throw new \Exception("Package hook did not return a callable");
+ }
+ $this->iter = $callable($cmd, $path);
+ }
+
+ public function getBaseDir() {
+ return $this->path;
+ }
+
+ public function getIterator() {
+ if (!is_callable($this->iter)) {
+ throw new \Exception("Package hook callback did not return a callable");
+ }
+ return call_user_func($this->iter, $this->cmd, $this->path);
+ }
+}
\ No newline at end of file
--- /dev/null
+<?='<?php'?>
+
+/**
+ * Generated by pharext v<?=pharext\VERSION?> at <?=date("Y-m-d H:i:i T")?>.
+ */
+namespace pharext;
+
+return function(Installer $installer) {
+ $args = $installer->getArgs();
+ <?php foreach ($configure as $cfg) : ?>
+
+ $args->compile([[
+ null,
+ "<?=$cfg["name"]?>",
+ "<?=ucfirst($cfg["prompt"])?>",
+ CliArgs::OPTARG,
+ <?php if (strlen($cfg["default"])) : ?>
+ "<?=$cfg["default"]?>"
+ <?php else : ?>
+ NULL
+ <?php endif; ?>
+
+ ]]);
+ <?php endforeach; ?>
+
+ return function(Installer $installer) {
+ $args = $installer->getArgs();
+ <?php foreach ($configure as $cfg) : ?>
+
+ if (isset($args["<?=$cfg["name"]?>"])) {
+ $args->configure = "--<?=$cfg["name"]?>=".$args["<?=$cfg["name"]?>"];
+ }
+ <?php endforeach; ?>
+
+ };
+};
public function testHelp() {
$this->expectOutputString(<<<EOF
-
Usage:
$ testprog [-hvqs] [-p|-n|-c <arg>]