test:
@echo "Running tests ... "
- @phpunit tests
+ @php -dphar.readonly=0 `which phpunit` tests
clean:
rm bin/pharext*
/**
* Compile the original spec
- * @param array $spec
+ * @param array|Traversable $spec
*/
- public function __construct(array $spec = null) {
- $this->compile($spec);
+ public function __construct($spec = null) {
+ if (is_array($spec) || $spec instanceof Traversable) {
+ $this->compile($spec);
+ }
+
}
/**
* Compile the original spec
- * @param array $spec
+ * @param array|Traversable $spec
* @return pharext\CliArgs self
*/
- public function compile(array $spec = null) {
- $this->orig = array_merge($this->orig, (array) $spec);
- foreach ((array) $spec as $arg) {
+ public function compile($spec) {
+ foreach ($spec as $arg) {
if (isset($arg[0])) {
$this->spec["-".$arg[0]] = $arg;
}
$this->spec["--".$arg[1]] = $arg;
+ $this->orig[] = $arg;
}
return $this;
}
* @see \pharext\Command::error()
*/
public function error($fmt) {
- if (!$this->args->quiet) {
- if (!isset($fmt)) {
- $fmt = "%s\n";
- $arg = error_get_last()["message"];
- } else {
- $arg = array_slice(func_get_args(), 1);
- }
- vfprintf(STDERR, "ERROR: $fmt", $arg);
+ if (!isset($fmt)) {
+ $fmt = "%s\n";
+ $arg = error_get_last()["message"];
+ } else {
+ $arg = array_slice(func_get_args(), 1);
}
+ vfprintf(STDERR, "ERROR: $fmt", $arg);
}
/**
}
/**
- * rm -r
- * @param string $dir
+ * Verbosity
+ * @return boolean
*/
- private function rm($dir) {
- foreach (scandir($dir) as $entry) {
- if ($entry === "." || $entry === "..") {
- continue;
- } elseif (is_dir("$dir/$entry")) {
- $this->rm("$dir/$entry");
- } elseif (!unlink("$dir/$entry")) {
- $this->warn(null);
- }
- }
- if (!rmdir($dir)) {
- $this->warn(null);
+ public function verbosity() {
+ if ($this->args->verbose) {
+ return true;
+ } elseif ($this->args->quiet) {
+ return false;
+ } else {
+ return null;
}
}
}
/**
* Execute a program with escalated privileges handling interactive password prompt
* @param string $command
- * @param string $output
- * @param int $status
+ * @param bool $verbose
+ * @return int exit status
*/
- private function suExec($command, &$output, &$status) {
+ private function suExec($command, $verbose = null) {
if (!($proc = proc_open($command, [STDIN,["pipe","w"],["pipe","w"]], $pipes))) {
- $status = -1;
+ $this->status = -1;
throw new Exception("Failed to run {$command}");
}
+
$stdout = $pipes[1];
$passwd = 0;
+ $checks = 10;
+
while (!feof($stdout)) {
$R = [$stdout]; $W = []; $E = [];
if (!stream_select($R, $W, $E, null)) {
}
$data = fread($stdout, 0x1000);
/* only check a few times */
- if ($passwd++ < 10) {
+ if ($passwd < $checks) {
+ $passwd++;
if (stristr($data, "password")) {
+ $passwd = $checks + 1;
printf("\n%s", $data);
+ continue;
+ }
+ } elseif ($passwd > $checks) {
+ /* new line after pw entry */
+ printf("\n");
+ $passwd = $checks;
+ }
+
+ if ($verbose === null) {
+ print $this->progress($data, 0);
+ } else {
+ if ($verbose) {
+ printf("%s\n", $data);
}
+ $this->output .= $data;
}
- $output .= $data;
}
- $status = proc_close($proc);
+ if ($verbose === null) {
+ $this->progress("", PHP_OUTPUT_HANDLER_FINAL);
+ }
+ return $this->status = proc_close($proc);
+ }
+
+ /**
+ * Output handler that displays some progress while soaking output
+ * @param string $string
+ * @param int $flags
+ * @return string
+ */
+ private function progress($string, $flags) {
+ static $c = 0;
+ static $s = ["\\","|","/","-"];
+
+ $this->output .= $string;
+
+ return $flags & PHP_OUTPUT_HANDLER_FINAL
+ ? " \r"
+ : sprintf(" %s\r", $s[$c++ % count($s)]);
}
/**
}
if ($this->sudo) {
- $this->suExec(sprintf($this->sudo." 2>&1", $exec), $this->output, $this->status);
+ $this->suExec(sprintf($this->sudo." 2>&1", $exec), $this->verbose);
} elseif ($this->verbose) {
ob_start(function($s) {
$this->output .= $s;
}, 1);
passthru($exec, $this->status);
ob_end_flush();
+ } elseif ($this->verbose !== false /* !quiet */) {
+ ob_start([$this, "progress"], 1);
+ passthru($exec . " 2>&1", $this->status);
+ ob_end_flush();
} else {
exec($exec ." 2>&1", $output, $this->status);
$this->output = implode("\n", $output);
private function extract(Phar $phar) {
$this->debug("Extracting %s ...\n", basename($phar->getPath()));
- return (new Task\Extract($phar))->run($this->args->verbose);
+ return (new Task\Extract($phar))->run($this->verbosity());
}
-
+
private function hooks(SplObjectStorage $phars) {
- $hooks = [];
+ $hook = [];
foreach ($phars as $phar) {
- if (isset($phar["pharext_install.php"])) {
- $callable = include $phar["pharext_install.php"];
- if (is_callable($callable)) {
- $hooks[] = $callable($this);
+ if (isset($phar["pharext_package.php"])) {
+ $sdir = include $phar["pharext_package.php"];
+ if ($sdir instanceof SourceDir) {
+ $this->args->compile($sdir->getArgs());
+ $hook[] = $sdir;
}
}
}
- return $hooks;
+ return $hook;
+ }
+
+ private function load() {
+ $list = new SplObjectStorage();
+ $phar = new Phar(Phar::running(false));
+ $temp = $this->extract($phar);
+
+ foreach ($phar as $entry) {
+ $dep_file = $entry->getBaseName();
+ if (fnmatch("*.ext.phar*", $dep_file)) {
+ $dep_phar = new Phar("$temp/$dep_file");
+ $list[$dep_phar] = $this->extract($dep_phar);
+ }
+ }
+
+ /* the actual ext.phar at last */
+ $list[$phar] = $temp;
+ return $list;
}
/**
*/
public function run($argc, array $argv) {
try {
- $list = new SplObjectStorage();
- $phar = new Phar(Phar::running(false));
- $temp = $this->extract($phar);
-
- foreach ($phar as $entry) {
- $dep_file = $entry->getBaseName();
- if (fnmatch("*.ext.phar*", $dep_file)) {
- $dep_phar = new Phar("$temp/$dep_file");
- $list[$dep_phar] = $this->extract($dep_phar);
- }
- }
- /* the actual ext.phar at last */
- $list[$phar] = $temp;
-
+ /* load the phar(s) */
+ $list = $this->load();
/* installer hooks */
$hook = $this->hooks($list);
} catch (\Exception $e) {
try {
/* post process hooks */
- foreach ($hook as $callback) {
- if (is_callable($callback)) {
- $callback($this);
- }
+ foreach ($hook as $sdir) {
+ $sdir->setArgs($this->args);
}
} catch (\Exception $e) {
$this->error("%s\n", $e->getMessage());
// phpize
$this->info("Running phpize ...\n");
$phpize = new Task\Phpize($temp, $this->args->prefix, $this->args->{"common-name"});
- $phpize->run($this->args->verbose);
+ $phpize->run($this->verbosity());
// configure
$this->info("Running configure ...\n");
$configure = new Task\Configure($temp, $this->args->configure, $this->args->prefix, $this->args{"common-name"});
- $configure->run($this->args->verbose);
+ $configure->run($this->verbosity());
// make
$this->info("Running make ...\n");
$make = new Task\Make($temp);
- $make->run($this->args->verbose);
+ $make->run($this->verbosity());
// install
$this->info("Running make install ...\n");
$sudo = isset($this->args->sudo) ? $this->args->sudo : null;
$install = new Task\Make($temp, ["install"], $sudo);
- $install->run($this->args->verbose);
+ $install->run($this->verbosity());
}
private function cleanup($temp) {
- if (is_dir($temp)) {
- $this->rm($temp);
- } elseif (file_exists($temp)) {
- unlink($temp);
- }
+ (new Task\Cleanup($temp))->run();
}
private function activate($temp) {
$this->info("Running INI activation ...\n");
$activate = new Task\Activate($temp, $files, $type, $this->args->prefix, $this->args{"common-name"}, $sudo);
- if (!$activate->run($this->args->verbose)) {
+ if (!$activate->run($this->verbosity())) {
$this->info("Extension already activated ...\n");
}
}
use Phar;
use pharext\Cli\Args as CliArgs;
use pharext\Cli\Command as CliCommand;
+use pharext\Exception;
/**
* The extension packaging command executed by bin/pharext
*/
function __destruct() {
foreach ($this->cleanup as $cleanup) {
- if (is_dir($cleanup)) {
- $this->rm($cleanup);
- } elseif (file_exists($cleanup)) {
- unlink($cleanup);
- }
+ $cleanup->run();
}
}
* so e.g. name and version can be overriden and CliArgs
* does not complain about missing arguments
*/
- if ($this->args["source"]) {
- $source = $this->localize($this->args["source"]);
- if ($this->args["pecl"]) {
- $this->source = new SourceDir\Pecl($this, $source);
- } elseif ($this->args["git"]) {
- $this->source = new SourceDir\Git($this, $source);
- } else {
- $this->source = new SourceDir\Pharext($this, $source);
- }
- }
+ $this->loadSource();
} catch (\Exception $e) {
$errs[] = $e->getMessage();
}
$task = new Task\GitClone($source);
} else {
$task = new Task\StreamFetch($source, function($bytes_pct) {
- $this->debug(" %3d%% [%s>%s] \r",
+ $this->info(" %3d%% [%s>%s] \r%s",
floor($bytes_pct*100),
str_repeat("=", round(50*$bytes_pct)),
- str_repeat(" ", round(50*(1-$bytes_pct)))
+ str_repeat(" ", round(50*(1-$bytes_pct))),
+ $bytes_pct == 1 ? "\n":""
);
});
}
- $local = $task->run($this->args->verbose);
- $this->debug("\n");
+ $local = $task->run($this->verbosity());
- $this->cleanup[] = $local;
+ $this->cleanup[] = new Task\Cleanup($local);
return $local;
}
$this->debug("Extracting %s ...\n", $source);
$task = new Task\Extract($source);
- $dest = $task->run($this->args->verbose);
+ $dest = $task->run($this->verbosity());
- $this->cleanup[] = $dest;
+ $this->cleanup[] = new Task\Cleanup($dest);
return $dest;
}
private function localize($source) {
if (!stream_is_local($source)) {
$source = $this->download($source);
- $this->cleanup[] = $source;
+ $this->cleanup[] = new Task\Cleanup($source);
}
$source = realpath($source);
if (!is_dir($source)) {
$source = $this->extract($source);
- $this->cleanup[] = $source;
+ $this->cleanup[] = new Task\Cleanup($source);
if ($this->args->pecl) {
$this->debug("Sanitizing PECL dir ...\n");
- $source = (new Task\PeclFixup($source))->run($this->args->verbose);
+ $source = (new Task\PeclFixup($source))->run($this->verbosity());
}
}
return $source;
}
+ /**
+ * Load the source dir
+ * @throws \pharext\Exception
+ */
+ private function loadSource(){
+ if ($this->args["source"]) {
+ $source = $this->localize($this->args["source"]);
+
+ if ($this->args["pecl"]) {
+ $this->source = new SourceDir\Pecl($source);
+ } elseif ($this->args["git"]) {
+ $this->source = new SourceDir\Git($source);
+ } elseif (is_file("$source/parext_package.php")) {
+ $this->source = include "$source/pharext_package.php";
+ }
+
+ if (!$this->source instanceof SourceDir) {
+ throw new Exception("Unknown source dir $source");
+ }
+
+ foreach ($this->source->getPackageInfo() as $key => $val) {
+ $this->args->$key = $val;
+ }
+ }
+ }
+
/**
* Creates the extension phar
*/
try {
if ($this->args->sign) {
$this->info("Using private key to sign phar ...\n");
- $pass = (new Task\Askpass)->run($this->args->verbose);
+ $pass = (new Task\Askpass)->run($this->verbosity());
$sign = new Task\PharSign($file, $this->args->sign, $pass);
- $pkey = $sign->run($this->args->verbose);
+ $pkey = $sign->run($this->verbosity());
}
} catch (\Exception $e) {
try {
$gzip = (new Task\PharCompress($file, Phar::GZ))->run();
$move = new Task\PharRename($gzip, $this->args->dest, $this->args->name ."-". $this->args->release);
- $name = $move->run($this->args->verbose);
+ $name = $move->run($this->verbosity());
$this->info("Created gzipped phar %s\n", $name);
if ($this->args->sign) {
$sign = new Task\PharSign($name, $this->args->sign, $pass);
- $sign->run($this->args->verbose)->exportPublicKey($name.".pubkey");
+ $sign->run($this->verbosity())->exportPublicKey($name.".pubkey");
}
} catch (\Exception $e) {
try {
$bzip = (new Task\PharCompress($file, Phar::BZ2))->run();
$move = new Task\PharRename($bzip, $this->args->dest, $this->args->name ."-". $this->args->release);
- $name = $move->run($this->args->verbose);
+ $name = $move->run($this->verbosity());
$this->info("Created bzipped phar %s\n", $name);
if ($this->args->sign) {
$sign = new Task\PharSign($name, $this->args->sign, $pass);
- $sign->run($this->args->verbose)->exportPublicKey($name.".pubkey");
+ $sign->run($this->verbosity())->exportPublicKey($name.".pubkey");
}
} catch (\Exception $e) {
try {
$move = new Task\PharRename($file, $this->args->dest, $this->args->name ."-". $this->args->release);
- $name = $move->run($this->args->verbose);
+ $name = $move->run($this->verbosity());
$this->info("Created executable phar %s\n", $name);
namespace pharext;
/**
- * Source directory interface
+ * Source directory interface, which should yield file names to package on traversal
*/
interface SourceDir extends \Traversable
{
- /**
- * Read the source directory
- *
- * Note: Best practices are for others, but if you want to follow them, do
- * not put constructors in interfaces. Keep your complaints, I warned you.
- *
- * @param Command $cmd
- * @param string $path
- */
- public function __construct(Command $cmd, $path);
-
/**
* Retrieve the base directory
* @return string
*/
public function getBaseDir();
+
+ /**
+ * Retrieve gathered package info
+ * @return array|Traversable
+ */
+ public function getPackageInfo();
+
+ /**
+ * Provide installer command line args
+ * @return array|Traversable
+ */
+ public function getArgs();
+
+ /**
+ * Process installer command line args
+ * @param \pharext\Cli\Args $args
+ */
+ public function setArgs(Cli\Args $args);
}
namespace pharext\SourceDir;
use pharext\Command;
+use pharext\Cli\Args;
use pharext\SourceDir;
/**
*/
class Git implements \IteratorAggregate, SourceDir
{
- /**
- * The Packager command
- * @var pharext\Command
- */
- private $cmd;
-
/**
* Base directory
* @var string
* @inheritdoc
* @see \pharext\SourceDir::__construct()
*/
- public function __construct(Command $cmd, $path) {
- $this->cmd = $cmd;
+ public function __construct($path) {
$this->path = $path;
}
public function getBaseDir() {
return $this->path;
}
-
+
+ /**
+ * @inheritdoc
+ * @return array
+ */
+ public function getPackageInfo() {
+ return [];
+ }
+
+ /**
+ * @inheritdoc
+ * @return array
+ */
+ public function getArgs() {
+ return [];
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function setArgs(Args $args) {
+ }
+
/**
* Generate a list of files by `git ls-files`
* @return Generator
$path = realpath($this->path);
while (!feof($pipe)) {
if (strlen($file = trim(fgets($pipe)))) {
- if ($this->cmd->getArgs()->verbose) {
- $this->cmd->info("Packaging %s\n", $file);
- }
/* there may be symlinks, so no realpath here */
- if (!file_exists("$path/$file")) {
- $this->cmd->warn("File %s does not exist in %s\n", $file, $path);
- }
yield "$path/$file";
}
}
}
chdir($pwd);
}
-
+
/**
* Implements IteratorAggregate
* @see IteratorAggregate::getIterator()
namespace pharext\SourceDir;
-use pharext\Command;
+use pharext\Cli\Args;
use pharext\Exception;
use pharext\SourceDir;
+use pharext\Tempfile;
/**
* A PECL extension source directory containing a v2 package.xml
*/
class Pecl implements \IteratorAggregate, SourceDir
{
- /**
- * The Packager command
- * @var pharext\Packager
- */
- private $cmd;
-
/**
* The package.xml
* @var SimpleXmlElement
* @var string
*/
private $path;
+
+ /**
+ * The package.xml
+ * @var string
+ */
+ private $file;
/**
* @inheritdoc
* @see \pharext\SourceDir::__construct()
*/
- public function __construct(Command $cmd, $path) {
- if (realpath("$path/package2.xml")) {
- $sxe = simplexml_load_file("$path/package2.xml");
- } elseif (realpath("$path/package.xml")) {
- $sxe = simplexml_load_file("$path/package.xml");
+ public function __construct($path) {
+ if (is_file("$path/package2.xml")) {
+ $sxe = simplexml_load_file($this->file = "$path/package2.xml");
+ } elseif (is_file("$path/package.xml")) {
+ $sxe = simplexml_load_file($this->file = "$path/package.xml");
} else {
throw new Exception("Missing package.xml in $path");
}
- $sxe->registerXPathNamespace("pecl", $sxe->getDocNamespaces()[""]);
-
- $args = $cmd->getArgs();
- if (!isset($args->name)) {
- $name = (string) $sxe->xpath("/pecl:package/pecl:name")[0];
- foreach ($args->parse(2, ["--name", $name]) as $error) {
- $cmd->warn("%s\n", $error);
- }
- }
- if (!isset($args->release)) {
- $release = (string) $sxe->xpath("/pecl:package/pecl:version/pecl:release")[0];
- foreach ($args->parse(2, ["--release", $release]) as $error) {
- $cmd->warn("%s\n", $error);
- }
- }
- if (!isset($args->zend)) {
- if ($sxe->xpath("/pecl:package/pecl:zendextsrcrelease")) {
- foreach ($args->parse(1, ["--zend"]) as $error) {
- $cmd->warn("%s\n", $error);
- }
- }
- }
+ $sxe->registerXPathNamespace("pecl", $sxe->getDocNamespaces()[""]);
- $this->cmd = $cmd;
$this->sxe = $sxe;
$this->path = $path;
}
public function getBaseDir() {
return $this->path;
}
+
+ /**
+ * Retrieve gathered package info
+ * @return Generator
+ */
+ public function getPackageInfo() {
+ if (($name = $this->sxe->xpath("/pecl:package/pecl:name"))) {
+ yield "name" => (string) $name[0];
+ }
+ if (($release = $this->sxe->xpath("/pecl:package/pecl:version/pecl:release"))) {
+ yield "release" => (string) $release[0];
+ }
+ if ($this->sxe->xpath("/pecl:package/pecl:zendextsrcrelease")) {
+ yield "zend" => true;
+ }
+ }
+
+ /**
+ * @inheritdoc
+ * @see \pharext\SourceDir::getArgs()
+ */
+ public function getArgs() {
+ $configure = $this->sxe->xpath("/pecl:package/pecl:extsrcrelease/pecl:configureoption");
+ foreach ($configure as $cfg) {
+ yield [null, $cfg["name"], ucfirst($cfg["prompt"]), Args::OPTARG,
+ strlen($cfg["default"]) ? $cfg["default"] : null];
+ }
+ $configure = $this->sxe->xpath("/pecl:package/pecl:zendextsrcrelease/pecl:configureoption");
+ foreach ($configure as $cfg) {
+ yield [null, $cfg["name"], ucfirst($cfg["prompt"]), Args::OPTARG,
+ strlen($cfg["default"]) ? $cfg["default"] : null];
+ }
+ }
+
+ /**
+ * @inheritdoc
+ * @see \pharext\SourceDir::setArgs()
+ */
+ public function setArgs(Args $args) {
+ $configure = $this->sxe->xpath("/pecl:package/pecl:extsrcrelease/pecl:configureoption");
+ foreach ($configure as $cfg) {
+ if (isset($args[$cfg["name"]])) {
+ $args->configure = "--{$cfg["name"]}={$args[$cfg["name"]]}";
+ }
+ }
+ $configure = $this->sxe->xpath("/pecl:package/pecl:zendextsrcrelease/pecl:configureoption");
+ foreach ($configure as $cfg) {
+ if (isset($args[$cfg["name"]])) {
+ $args->configure = "--{$cfg["name"]}={$args[$cfg["name"]]}";
+ }
+ }
+ }
/**
* Compute the path of a file by parent dir nodes
}
/**
- * Render installer hook
- * @param array $configure
- * @return string
+ * Generate a list of files from the package.xml
+ * @return Generator
*/
- private static function loadHook($configure, $dependencies) {
- require_once "pharext/Version.php";
- return include __DIR__."/../../pharext_install.tpl.php";
- }
+ private function generateFiles() {
+ /* hook */
+ $temp = tmpfile();
+ fprintf($temp, "<?php\nreturn new %s(__DIR__);\n", get_class($this));
+ rewind($temp);
+ yield "pharext_package.php" => $temp;
- /**
- * Create installer hook
- * @return \Generator
- */
- private function generateHooks() {
+ /* deps */
$dependencies = $this->sxe->xpath("/pecl:package/pecl:dependencies/pecl:required/pecl:package");
foreach ($dependencies as $key => $dep) {
if (($glob = glob("{$this->path}/{$dep->name}-*.ext.phar*"))) {
);
});
yield end($glob);
- } else {
- unset($dependencies[$key]);
- }
- }
- $configure = $this->sxe->xpath("/pecl:package/pecl:extsrcrelease/pecl:configureoption");
- if ($configure) {
- $fd = tmpfile();
- ob_start(function($s) use($fd){
- fwrite($fd, $s);
- return null;
- });
- self::loadHook($configure, $dependencies);
- ob_end_flush();
- rewind($fd);
- yield "pharext_install.php" => $fd;
- }
- }
-
- /**
- * Generate a list of files from the package.xml
- * @return Generator
- */
- private function generateFiles() {
- foreach ($this->generateHooks() as $file => $hook) {
- if ($this->cmd->getArgs()->verbose) {
- $this->cmd->info("Packaging %s\n", is_scalar($hook) ? $hook : $file);
}
- yield $file => $hook;
}
+
+ /* files */
+ yield $this->file;
foreach ($this->sxe->xpath("//pecl:file") as $file) {
- $path = $this->path ."/". $this->dirOf($file) ."/". $file["name"];
- if ($this->cmd->getArgs()->verbose) {
- $this->cmd->info("Packaging %s\n", substr($path, strlen($this->path)));
- }
- if (!($realpath = realpath($path))) {
- $this->cmd->warn("File %s does not exist", $path);
- }
- yield $realpath;
+ yield realpath($this->path ."/". $this->dirOf($file) ."/". $file["name"]);
}
}
+++ /dev/null
-<?php
-
-namespace pharext\SourceDir;
-
-use pharext\Command;
-use pharext\Exception;
-use pharext\SourceDir;
-
-/**
- * A source directory containing pharext_package.php and eventually pharext_install.php
- */
-class Pharext implements \IteratorAggregate, SourceDir
-{
- /**
- * @var pharext\Command
- */
- private $cmd;
-
- /**
- * @var string
- */
- private $path;
-
- /**
- * @var callable
- */
- private $iter;
-
- /**
- * @inheritdoc
- * @see \pharext\SourceDir::__construct()
- */
- 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);
- }
-
- /**
- * @inheritdoc
- * @see \pharext\SourceDir::getBaseDir()
- */
- public function getBaseDir() {
- return $this->path;
- }
-
- /**
- * Implements IteratorAggregate
- * @see IteratorAggregate::getIterator()
- */
- public function getIterator() {
- if (!is_callable($this->iter)) {
- return new Git($this->cmd, $this->path);
- }
- return call_user_func($this->iter, $this->cmd, $this->path);
- }
-}
--- /dev/null
+<?php
+
+namespace pharext\Task;
+
+use pharext\Task;
+
+use FilesystemIterator;
+use RecursiveDirectoryIterator;
+use RecursiveIteratorIterator;
+
+/**
+ * Recursively cleanup FS entries
+ */
+class Cleanup implements Task
+{
+ /**
+ * @var string
+ */
+ private $rm;
+
+ public function __construct($rm) {
+ $this->rm = $rm;
+ }
+
+ /**
+ * @param bool $verbose
+ */
+ public function run($verbose = false) {
+ if (is_dir($this->rm)) {
+ $rdi = new RecursiveDirectoryIterator($this->rm,
+ FilesystemIterator::CURRENT_AS_PATHNAME |
+ FilesystemIterator::SKIP_DOTS);
+ $rii = new RecursiveIteratorIterator($rdi,
+ RecursiveIteratorIterator::CHILD_FIRST);
+ foreach ($rii as $path) {
+ if ($rii->isDir()) {
+ rmdir($path);
+ } else {
+ unlink($path);
+ }
+ }
+ rmdir($this->rm);
+ } else {
+ @unlink($this->rm);
+ }
+ }
+}
+++ /dev/null
-<?='<?php'?>
-
-/**
- * Generated by pharext v<?=pharext\VERSION?> at <?=date("Y-m-d H:i:s T")?>.
- */
-namespace pharext;
-
-use pharext\Cli\Args as CliArgs;
-
-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; ?>
-
- };
-};
protected $source;
protected function setUp() {
- $this->source = new SourceDir\Git(new Cmd, ".");
+ $this->source = new SourceDir\Git(".");
}
public function testGetBaseDir() {
--- /dev/null
+<?php
+
+namespace pharext;
+
+require_once __DIR__."/../../autoload.php";
+
+use pharext\Task;
+
+class TaskTest extends \PHPUnit_Framework_TestCase
+{
+ function testGitClone() {
+ $cmd = new Task\GitClone("https://git.php.net/repository/pecl/http/apfd.git");
+ $dir = $cmd->run();
+
+ $this->assertTrue(is_dir("$dir/.git"), "is_dir($dir/.git)");
+
+ (new Task\Cleanup($dir))->run();
+ $this->assertFalse(is_dir($dir), "is_dir($dir)");
+ }
+
+ function testPecl() {
+ $cmd = new Task\StreamFetch("http://pecl.php.net/get/pecl_http", function($pct) use(&$log) {
+ $log[] = $pct;
+ });
+ $tmp = $cmd->run();
+
+ $this->assertTrue(is_file($tmp), "is_file($tmp)");
+ $this->assertGreaterThan(1, count($log), "1 < count(\$log)");
+ $this->assertContains(0, $log, "in_array(0, \$log)");
+ $this->assertContains(1, $log, "in_array(1, \$log)");
+
+ $cmd = new Task\Extract($tmp);
+ $dir = $cmd->run();
+
+ $this->assertTrue(is_dir($dir), "is_dir($dir)");
+ $this->assertTrue(is_file("$dir/package.xml"), "is_file($dir/package.xml");
+
+ $cmd = new Task\PeclFixup($dir);
+ $new = $cmd->run();
+
+ $this->assertTrue(is_dir($new), "is_dir($new)");
+ $this->assertFalse(is_file("$dir/package.xml"), "is_file($dir/package.xml");
+ $this->assertTrue(is_file("$new/package.xml"), "is_file($new/package.xml");
+
+ (new Task\Cleanup($dir))->run();
+ $this->assertFalse(is_dir($dir), "is_dir($dir)");
+ $this->assertFalse(is_dir($new), "is_dir($new)");
+ }
+
+ function testPackage() {
+ $tmp = (new Task\StreamFetch("http://pecl.php.net/get/json_post/1.0.0", function(){}))->run();
+ $dir = (new Task\Extract($tmp))->run();
+ $new = (new Task\PeclFixup($dir))->run();
+ $src = new SourceDir\Pecl($new);
+ $inf = [
+ "date" => date("Y-m-d"),
+ "name" => "json_post",
+ "release" => "1.0.0",
+ "license" => file_get_contents($src->getBaseDir()."/LICENSE"),
+ "stub" => "pharext_installer.php",
+ "type" => "extension",
+ ];
+ $pkg = (new Task\PharBuild($src, $inf))->run();
+ $gzp = (new Task\PharCompress($pkg, \Phar::GZ))->run();
+ $pkg = (new Task\PharRename($pkg, ".", "json_post-1.0.0"))->run();
+ $gzp = (new Task\PharRename($gzp, ".", "json_post-1.0.0"))->run();
+
+ $this->assertTrue(is_file($pkg), "is_file($pkg)");
+ $this->assertTrue(is_file($gzp), "is_file($gzp)");
+ }
+}