From e1c1b76f0a87c7573e30468763d47c0b97b11e8e Mon Sep 17 00:00:00 2001 From: Michael Wallner Date: Fri, 6 Mar 2015 09:11:02 +0100 Subject: [PATCH 1/1] Implement packager and installer hooks ==Packager hook If not --pecl nor --git are explicitely given, look for a pharext_install.php in --source. This script will be exectuted by the Packager. It must return a callable with the following signature: function(Packager $pkg, $path) : function(Packager $pkg, $path); So, the callback should return another callable. The primary callback is meant to set things like --name and --release, so you don't have to on the command line; build automation FTW. The secondary callback is meant to create the file iterator of the source dir, but if you're in a git clone, you might easily just return a new pharext\GitSourceDir and be done. ==Installer hook The packager will look for a pharext_install.php file within the root of the source dir. This script will be executed by the Installer; it must return a callable with the following signature: function(Installer $installer) : function(Installer $installer); So, again, the callback should return another callable. The primary callback is meant to add your own command line arguments to the CliArgs parser, and the secnodary callback is meant to proccess those args. For --pecl source dirs a pharext_install.php script is automatically generated from the package.xml. ==Examples for pecl_http pharext_package.php ---8<--- getArgs(); $args->name = "pecl_http"; $args->release = current(preg_filter("/^.*PHP_PECL_HTTP_VERSION\s+\"(.*)\".*$/s", "\$1", file("../http.git/php_http.h"))); return function (Packager $packager, $path) { return new GitSourceDir($packager, $path); }; }; ?> --->8--- pharext_install.php ---8<--- getArgs()->compile([ [null, "with-http-zlib-dir", "Where to find zlib", CliArgs::OPTARG], [null, "with-http-libcurl-dir", "Where to find libcurl", CliArgs::OPTARG], [null, "with-http-libevent-dir", "Where to find libev{,ent{,2}}", CliArgs::OPTARG], [null, "with-http-libidn-dir", "Where to find libidn", CliArgs::OPTARG], ]); return function(Installer $installer) { $opts = [ "with-http-zlib-dir", "with-http-libcurl-dir", "with-http-libevent-dir", "with-http-libidn-dir", ]; $args = $installer->getArgs(); foreach ($opts as $opt) { if (isset($args[$opt])) { $args->configure = "--$opt=".$args[$opt]; } } }; }; ?> --->8--- --- Makefile | 2 -- bin/pharext | Bin 31323 -> 34135 bytes src/pharext/CliArgs.php | 23 +++++++++++------ src/pharext/CliCommand.php | 28 +++++++++++++++++---- src/pharext/Installer.php | 11 ++++++++ src/pharext/Packager.php | 2 ++ src/pharext/PeclSourceDir.php | 22 ++++++++++++++++ src/pharext/PharextSourceDir.php | 32 ++++++++++++++++++++++++ src/pharext_install.tpl.php | 36 +++++++++++++++++++++++++++ tests/src/pharext/CliCommandTest.php | 1 - 10 files changed, 141 insertions(+), 16 deletions(-) create mode 100644 src/pharext/PharextSourceDir.php create mode 100644 src/pharext_install.tpl.php diff --git a/Makefile b/Makefile index 6b3dc1f..1027186 100644 --- a/Makefile +++ b/Makefile @@ -7,8 +7,6 @@ all: bin/pharext 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 $@ diff --git a/bin/pharext b/bin/pharext index e79c0424b80e5f8c3e43e6359021f4c032fd54f4..641f4f50627e67bb5c63ae6ddc712d610d833bbb 100755 GIT binary patch delta 3144 zcma)8Piz!b7;hH~*;TL=1k$edb=bn}w%ZEDg8j2?fzp=nr!EB{%VwF*zU_|8&I~iN zZ3&jW7@{aK_~gKagb+QVW>F7bBrygPO*9@n7`&S3!5BUG=i>LhH#6OZLfFH;nfJc; zd%y4Z{dx1#UyVOr3Vk%y+H^0}(6EjjZr#~DwYi}oTl!}PM`f@w$=+?1n%`e7CUN|w z{fP?uvUSTUuwuWq_VaN|+jc&_(w1nx-Xe@~JgT0)%C5AL=Ia~0Nf_UL_3jyVr>%4H zYD7%pcpiZeBj%qTCXWA}l|Ey~qn#Y@LNtkE z^;Yy=sEG`dOt$(~`|ZYd#kQ4mxe~SKs2p>Pnv+bKwl>#IVva@CI6Ki1->emgtT_&K z<(Oj6WnRd}4*2GN509e+(b5mq65)Q{q9p2fkt(zJL+3g)$ zDm5TriU?o@cH&IHbuv;CQKW1p3rMkfgb6RGf7igz63zhz~huS3QO}=rN9| z-t6lNv2R{{y_)Wy2(1BCRCM#h{*4vxW=UCucleh*B^67S9M{&VA$1cmrG=`v@5hk*!1Ua>6%3PvGa90KH=YzfPyq0eYZx&ZZVsTyPxef|^Mo zzsCircl9MYy!^$a=A!xH>=2%{%g3hDN#ykS%VNc6QT^eiKi2bXmSaWJJOj~( z^Qck+9*(KcQz%JQFXw5_Qrw~}-Cw9sq!Ofna5bhv?JBc61r%=^;ix=dB9(K#jT~6V zlRnXyP1SkW94v_gPu$pBX?q@JHwL>#D}#-Al^$ zNWH#SmZF|f<|wuvDb5Zk&o%KzSN%@8xOUx?=uOlnC=@FVlO}u^WY^UMv+O6?==g!^ z*XB^D1l2+fz6a(aFBin}VbR@D{9A>I|mQbvC-RN%bgQb?;(9*l!m z%!%4}kj{p8cE#MyE{!KDVE_(Nu_mXb817s#Ymf{22^G3hrh7iSMcZ5;23;Vh#urt} zgD*?dBKvrHk-U~aKn&9*UeFZc7mg@htOQR3q+MS$;3vc#Nn(V-l(k6DvZwdUtZ!c8 z)n3m}WEy`}&u9OAOgvouETQ}?yv@n(Z z`-gAM(}GggU8#a!O@dd=!Tu_q9boW}8PD|av4aPf7mU1C805Zzb6I|`i({d8c!G%K zh@U@!+?9vwEmV4h;GS!bp*Yq*DzN;u2w!zVfxdE z!RoNEgJ5y5tOQV68jLIrRzFz0))-xLEOz&ecVfT)ee2#AAOC#!#OBfTD10h6Ozb(d F=YJvnyxRZ( delta 655 zcmccK#dP}%;|5PD)*>bb2A;`&QYHc)#TghPvVVktXqk$QYbQ^VQWEHAg$RP^f`kcHQAbrlT)Q6BePi7 z4#ZWkRfvwAd`?kwvXGL>W@{xO!O0Vh6((OY(cp=W1xl)vfi!SVW;NBA%xEGGlHfuW z-kfft#WZ=cSrb!C-eysAcc#gUQpG0Mn@j2z6lLa>q-iKA0D-P*ag8pJP*5#a(oq1r zB-$Vr#xji6nS8)pQp7RHT~oncLCGeuDBVs$K}o?%L1XekbI~;afDo8mG*~hgBnLJb zXtZ11Zcq>d zTCboHyN^d-zDANtRASrxVbjSMrg9075irYR3F~SAKZ#J z`xe_UZN64k!?bx*r7+WEgF^PrGwYa{*vky{4D?KtHZN?R#VFI!&C`FExih-9^7{M< T9$eK4Sz4vQw8!A?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; @@ -296,12 +297,18 @@ class CliArgs implements \ArrayAccess 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) { diff --git a/src/pharext/CliCommand.php b/src/pharext/CliCommand.php index 1299a0e..f4f29b6 100644 --- a/src/pharext/CliCommand.php +++ b/src/pharext/CliCommand.php @@ -16,7 +16,7 @@ trait CliCommand * Output pharext vX.Y.Z header */ function header() { - printf("pharext v%s (c) Michael Wallner \n", VERSION); + printf("pharext v%s (c) Michael Wallner \n\n", VERSION); } /** @@ -24,7 +24,7 @@ trait CliCommand * @param string $prog */ public function help($prog) { - printf("\nUsage:\n\n \$ %s", $prog); + printf("Usage:\n\n \$ %s", $prog); $flags = []; $required = []; @@ -51,9 +51,27 @@ trait CliCommand printf(" [-%s ]", 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) ? " " : (($spec[3] & CliArgs::OPTARG) ? "[]" : " ")); - 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(" "); + } elseif ($spec[3] & CliArgs::OPTARG) { + printf("[]"); + } 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]); } diff --git a/src/pharext/Installer.php b/src/pharext/Installer.php index f6c7807..626cfa6 100644 --- a/src/pharext/Installer.php +++ b/src/pharext/Installer.php @@ -40,6 +40,13 @@ class Installer implements Command * @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) { @@ -69,6 +76,10 @@ class Installer implements Command exit(1); } + if (isset($recv)) { + $recv($this); + } + $this->installPackage(); } diff --git a/src/pharext/Packager.php b/src/pharext/Packager.php index b6b05e1..5401b4c 100644 --- a/src/pharext/Packager.php +++ b/src/pharext/Packager.php @@ -70,6 +70,8 @@ class Packager implements Command $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"]); } diff --git a/src/pharext/PeclSourceDir.php b/src/pharext/PeclSourceDir.php index ab71746..ca065ad 100644 --- a/src/pharext/PeclSourceDir.php +++ b/src/pharext/PeclSourceDir.php @@ -25,6 +25,12 @@ class PeclSourceDir implements \IteratorAggregate, SourceDir */ private $path; + /** + * Installer hook + * @var string + */ + private $hook; + /** * @inheritdoc * @see \pharext\SourceDir::__construct() @@ -48,6 +54,18 @@ class PeclSourceDir implements \IteratorAggregate, SourceDir } } + 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; @@ -79,6 +97,10 @@ class PeclSourceDir implements \IteratorAggregate, SourceDir * @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) { diff --git a/src/pharext/PharextSourceDir.php b/src/pharext/PharextSourceDir.php new file mode 100644 index 0000000..e0d9a2a --- /dev/null +++ b/src/pharext/PharextSourceDir.php @@ -0,0 +1,32 @@ +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 diff --git a/src/pharext_install.tpl.php b/src/pharext_install.tpl.php new file mode 100644 index 0000000..9bf8271 --- /dev/null +++ b/src/pharext_install.tpl.php @@ -0,0 +1,36 @@ + + +/** + * Generated by pharext v at . + */ +namespace pharext; + +return function(Installer $installer) { + $args = $installer->getArgs(); + + + $args->compile([[ + null, + "", + "", + CliArgs::OPTARG, + + "" + + NULL + + + ]]); + + + return function(Installer $installer) { + $args = $installer->getArgs(); + + + if (isset($args[""])) { + $args->configure = "--=".$args[""]; + } + + + }; +}; diff --git a/tests/src/pharext/CliCommandTest.php b/tests/src/pharext/CliCommandTest.php index a2bf3d9..7fd2448 100644 --- a/tests/src/pharext/CliCommandTest.php +++ b/tests/src/pharext/CliCommandTest.php @@ -35,7 +35,6 @@ class CliCommandTest extends \PHPUnit_Framework_TestCase public function testHelp() { $this->expectOutputString(<<] -- 2.30.2