]> granicus.if.org Git - php/commitdiff
- Add phar.phar command input files
authorMarcus Boerger <helly@php.net>
Thu, 10 May 2007 20:55:28 +0000 (20:55 +0000)
committerMarcus Boerger <helly@php.net>
Thu, 10 May 2007 20:55:28 +0000 (20:55 +0000)
ext/phar/package.php
ext/phar/phar/clicommand.inc [new file with mode: 0755]
ext/phar/phar/directorygraphiterator.inc [new file with mode: 0755]
ext/phar/phar/directorytreeiterator.inc [new file with mode: 0755]
ext/phar/phar/phar.php [new file with mode: 0755]
ext/phar/phar/pharcommand.inc [new file with mode: 0755]

index 8620b693d7ea439ddaa45a446c04002d50653461..3fab369cfdf789d0cd8783e7e3bf7bb24e2fd950 100644 (file)
@@ -31,6 +31,7 @@ $options = array(
          'docs'         => 'doc',
          'examples'     => 'doc',
          'tests'        => 'test',
+         'phar'         => 'src',
     ),
     'exceptions'        => array(
          'CREDITS'            => 'doc',
diff --git a/ext/phar/phar/clicommand.inc b/ext/phar/phar/clicommand.inc
new file mode 100755 (executable)
index 0000000..cd0e292
--- /dev/null
@@ -0,0 +1,266 @@
+<?php
+
+/** @file clicommand.inc
+ * @ingroup Phar
+ * @brief class CLICommand
+ * @author  Marcus Boerger
+ * @date    2007 - 2007
+ *
+ * Phar Command
+ */
+
+/** @ingroup Phar
+ * @brief   Abstract base console command implementation
+ * @author  Marcus Boerger
+ * @version 1.0
+ */
+abstract class CLICommand
+{
+       protected $argc;
+       protected $argv;
+       protected $cmds = array();
+       protected $args = array();
+
+       function __construct($argc, array $argv)
+       {
+               $this->argc = $argc;
+               $this->argv = $argv;
+               $this->cmds = self::getCommands($this);
+               $this->types= self::getArgTypes($this);
+               
+               if ($argc < 2)
+               {
+                       echo "No command given, check ${argv[0]} help\n";
+                       exit(1);
+               }
+               elseif (!isset($this->cmds[$argv[1]]['run']))
+               {
+                       echo "Unknown command '${argv[1]}', check ${argv[0]} help\n";
+                       exit(1);
+               }
+               else
+               {
+                       $command = $argv[1];
+               }
+
+               if (isset($this->cmds[$command]['arg']))
+               {
+                       $this->args = call_user_func(array($this, $this->cmds[$command]['arg']));
+                       $i = 1;
+                       $missing = false;
+                       while (++$i < $argc)
+                       {
+                               if ($argv[$i][0] == '-')
+                               {
+                                       if (strlen($argv[$i]) == 2 && isset($this->args[$argv[$i][1]]))
+                                       {
+                                               $arg = $argv[$i][1];
+                                               if (++$i >= $argc)
+                                               {
+                                                       echo "Missing argument to parameter '$arg' of command '$command', check ${argv[0]} help\n";
+                                                       exit(1);
+                                               }
+                                               else
+                                               {
+                                                       $type = $this->args[$arg]['type'];
+
+                                                       if (isset($this->types[$type]['typ']))
+                                                       {
+                                                               $this->args[$arg]['val'] = call_user_func(array($this, $this->types[$type]['typ']), $argv[$i], $this->args[$arg]);
+                                                       }
+                                                       else
+                                                       {
+                                                               $this->args[$arg]['val'] = $argv[$i];
+                                                       }
+                                               }
+                                       }
+                                       else
+                                       {
+                                               echo "Unknown parameter '${argv[$i]}' to command $command, check ${argv[0]} help\n";
+                                               exit(1);
+                                       }
+                               }
+                               else
+                               {
+                                       break;
+                               }
+                       }
+                       if (isset($this->args['']))
+                       {
+                               if ($i >= $argc)
+                               {
+                                       if (isset($this->args['']['require']) && $this->args['']['require'])
+                                       {
+                                               echo "Missing default trailing arguments to command $command, check ${argv[0]} help\n";
+                                               $missing = true;
+                                       }
+                               }
+                               else
+                               {
+                                       $this->args['']['val'] = array();
+                                       while($i < $argc)
+                                       {
+                                               $this->args['']['val'][] = $argv[$i++];
+                                       }
+                               }
+                       }
+                       else if ($i < $argc)
+                       {
+                               echo "Unexpected default arguments to command $command, check ${argv[0]} help\n";
+                               exit(1);
+                       }
+                       foreach($this->args as $arg => $inf)
+                       {
+                               if (strlen($arg) && !isset($inf['val']) && isset($inf['required']) && $inf['required'])
+                               {
+                                       echo "Missing parameter '-$arg' to command $command, check ${argv[0]} help\n";
+                                       $missing = true;
+                               }
+                       }
+                       if ($missing)
+                       {
+                               exit(1);
+                       }
+               }
+               
+               call_user_func(array($this, $this->cmds[$command]['run']));
+       }
+
+       static function getSubFuncs(CLICommand $cmdclass, $prefix, array $subs)
+       {
+               $a = array();
+               $r = new ReflectionClass($cmdclass);
+               $l = strlen($prefix);
+               
+               foreach($r->getMethods() as $m)
+               {
+                       if (substr($m->name, 0, $l) == $prefix)
+                       {
+                               foreach($subs as $sub)
+                               {
+                                       $what = substr($m->name, $l+strlen($sub)+1);
+                                       $func = $prefix . $sub . '_' . $what;
+                                       if ($r->hasMethod($func))
+                                       {
+                                               if (!isset($a[$what]))
+                                               {
+                                                       $a[$what] = array();
+                                               }
+                                               $a[$what][$sub] = /*$m->class . '::' .*/ $func;
+                                       }
+                               }
+                       }
+               }
+               return $a;
+       }
+
+       static function getCommands(CLICommand $cmdclass)
+       {
+               return self::getSubFuncs($cmdclass, 'cli_cmd_', array('arg','inf','run'));
+       }
+       
+       static function getArgTypes(CLICommand $cmdclass)
+       {
+               return self::getSubFuncs($cmdclass, 'cli_arg_', array('typ'));
+       }
+
+       static function cli_arg_typ_bool($arg)
+       {
+               return (bool)$arg;
+       }
+
+       static function cli_arg_typ_select($arg, $cfg)
+       {
+               if (!in_array($arg, array_keys($cfg['select'])))
+               {
+                       echo "Parameter value '$arg' not one of '" . join("', '", array_keys($cfg['select'])) . "'.\n";
+                       exit(1);
+               }
+               return $arg;
+       }
+
+       static function cli_arg_typ_file($arg)
+       {
+               if (!file_exists($arg))
+               {
+                       echo "Requested file '$arg' does not exist.\n";
+                       exit(1);
+               }
+               return $arg;
+       }
+
+       static function cli_arg_typ_filecont($arg)
+       {
+               return file_get_contents(self::cli_arg_typ_file($arg));
+       }
+
+       function cli_get_SP2($l1, $l2, $arg_inf)
+       {
+               return str_repeat(' ', $l1 + 2 + 8);
+       }
+
+       static function cli_cmd_inf_help()
+       {
+               return "This help.";
+       }
+
+       function cli_cmd_run_help()
+       {
+               $argv = $this->argv;
+
+               echo "
+$argv[0] <command> [options]
+
+Commands:
+
+
+";
+               $l = 0;
+               foreach($this->cmds as $name => $funcs)
+               {
+                       $l = max($l, strlen($name));
+               }
+               $sp = str_repeat(' ', $l+2);
+               foreach($this->cmds as $name => $funcs)
+               {
+                       $inf = sprintf("%${l}s  ", $name);
+                       if (isset($funcs['inf']))
+                       {
+                               $inf .= call_user_func(array($this, $funcs['inf'])) . "\n";
+                               if (isset($funcs['arg']))
+                               {
+                                       $inf .= "\n";
+                                       foreach(call_user_func(array($this, $funcs['arg'])) as $arg => $conf)
+                                       {
+                                               if (strlen($arg))
+                                               {
+                                                       $arg = "-$arg  ";
+                                               }
+                                               else
+                                               {
+                                                       $arg = "... ";
+                                               }
+                                               $inf .= $sp . $arg . $conf['inf'] . "\n";
+                                               if ($conf['type'] == 'select')
+                                               {
+                                                       $l2 = 0;
+                                                       foreach($conf['select'] as $opt => $what)
+                                                       {
+                                                               $l2 = max($l2, strlen($opt));
+                                                       }
+                                                       $sp2 = $this->cli_get_SP2($l, $l2, $inf);
+                                                       foreach($conf['select'] as $opt => $what)
+                                                       {
+                                                               $inf .= $sp2 . sprintf("%-${l2}s  ", $opt) . $what . "\n";
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+                       echo "$inf\n\n";
+               }
+               exit(0);
+       }
+}
+
+?>
\ No newline at end of file
diff --git a/ext/phar/phar/directorygraphiterator.inc b/ext/phar/phar/directorygraphiterator.inc
new file mode 100755 (executable)
index 0000000..5808e3b
--- /dev/null
@@ -0,0 +1,34 @@
+<?php
+
+/** @file directorygraphiterator.inc
+ * @ingroup Examples
+ * @brief class DirectoryGraphIterator
+ * @author  Marcus Boerger
+ * @date    2003 - 2005
+ *
+ * SPL - Standard PHP Library
+ */
+
+/** @ingroup Examples
+ * @brief   A tree iterator that only shows directories.
+ * @author  Marcus Boerger
+ * @version 1.1
+ */
+class DirectoryGraphIterator extends DirectoryTreeIterator
+{
+       function __construct($path)
+       {
+               RecursiveIteratorIterator::__construct(
+                       new RecursiveCachingIterator(
+                               new ParentIterator(
+                                       new RecursiveDirectoryIterator($path, RecursiveDirectoryIterator::KEY_AS_FILENAME
+                                       )
+                               ), 
+                               CachingIterator::CALL_TOSTRING|CachingIterator::CATCH_GET_CHILD
+                       ), 
+                       parent::SELF_FIRST
+               );
+       }
+}
+
+?>
\ No newline at end of file
diff --git a/ext/phar/phar/directorytreeiterator.inc b/ext/phar/phar/directorytreeiterator.inc
new file mode 100755 (executable)
index 0000000..8e65d0d
--- /dev/null
@@ -0,0 +1,54 @@
+<?php
+
+/** @file directorytreeiterator.inc
+ * @ingroup Examples
+ * @brief class DirectoryTreeIterator
+ * @author  Marcus Boerger
+ * @date    2003 - 2005
+ *
+ * SPL - Standard PHP Library
+ */
+
+/** @ingroup Examples
+ * @brief   DirectoryIterator to generate ASCII graphic directory trees
+ * @author  Marcus Boerger
+ * @version 1.1
+ */
+class DirectoryTreeIterator extends RecursiveIteratorIterator
+{
+       /** Construct from a path.
+        * @param $path directory to iterate
+        */
+       function __construct($path)
+       {
+               parent::__construct(
+                       new RecursiveCachingIterator(
+                               new RecursiveDirectoryIterator($path, RecursiveDirectoryIterator::KEY_AS_FILENAME
+                               ), 
+                               CachingIterator::CALL_TOSTRING|CachingIterator::CATCH_GET_CHILD
+                       ), 
+                       parent::SELF_FIRST
+               );
+       }
+
+       /** @return the current element prefixed with ASCII graphics
+        */     
+       function current()
+       {
+               $tree = '';
+               for ($l=0; $l < $this->getDepth(); $l++) {
+                       $tree .= $this->getSubIterator($l)->hasNext() ? '| ' : '  ';
+               }
+               return $tree . ($this->getSubIterator($l)->hasNext() ? '|-' : '\-') 
+                      . $this->getSubIterator($l)->__toString();
+       }
+
+       /** Aggregates the inner iterator
+        */     
+       function __call($func, $params)
+       {
+               return call_user_func_array(array($this->getSubIterator(), $func), $params);
+       }
+}
+
+?>
\ No newline at end of file
diff --git a/ext/phar/phar/phar.php b/ext/phar/phar/phar.php
new file mode 100755 (executable)
index 0000000..5df884d
--- /dev/null
@@ -0,0 +1,40 @@
+<?php
+
+/** @file phar.php
+ * @ingroup Phar
+ * @brief class CLICommand
+ * @author  Marcus Boerger
+ * @date    2007 - 2007
+ *
+ * Phar Command
+ */
+foreach(array("SPL", "Reflection", "Phar") as $ext)
+{
+       if (!extension_loaded($ext))
+       {
+               echo "$argv[0] requires PHP extension $ext.\n";
+               exit(1);
+       }
+}
+
+function command_include($file)
+{
+       $file = 'phar://' . __FILE__ . '/' . $file;
+       if (file_exists($file))
+       {
+               include($file);
+       }
+}
+
+function command_autoload($classname)
+{
+       command_include(strtolower($classname) . '.inc');
+}
+
+Phar::loadPhar(__FILE__);
+
+spl_autoload_register('command_autoload');
+
+new PharCommand($argc, $argv);
+
+__HALT_COMPILER();
\ No newline at end of file
diff --git a/ext/phar/phar/pharcommand.inc b/ext/phar/phar/pharcommand.inc
new file mode 100755 (executable)
index 0000000..5539d62
--- /dev/null
@@ -0,0 +1,213 @@
+<?php
+
+/** @file pharcommand.inc
+ * @ingroup Phar
+ * @brief class CLICommand
+ * @author  Marcus Boerger
+ * @date    2007 - 2007
+ *
+ * Phar Command
+ */
+
+/** @ingroup Phar
+ * @brief   Phar console command implementation
+ * @author  Marcus Boerger
+ * @version 1.0
+ */
+class PharCommand extends CLICommand
+{
+       function cli_get_SP2($l1, $l2, $arg_inf)
+       {
+               return str_repeat(' ', $l1 + 2 + 17);
+       }
+
+       static function cli_arg_typ_pharfile($arg)
+       {
+               try
+               {
+                       if (!file_exists($arg) && file_exists($ps = dirname(__FILE__).'/'.$arg))
+                       {
+                               $arg = $ps;
+                       }
+                       if (!Phar::loadPhar($arg))
+                       {
+                               "Unable to open phar '$phar'\n";
+                               exit(1);
+                       }
+                       return $arg;
+               }
+               catch(Exception $e)
+               {
+                       echo "Exception while opening phar '$arg':\n";
+                       echo $e->getMessage() . "\n";
+                       exit(1);
+               }
+       }
+
+       static function cli_arg_typ_pharurl($arg)
+       {
+               return 'phar://' . self::cli_arg_typ_pharfile($arg);
+       }
+
+       static function cli_arg_typ_phar($arg)
+       {
+               try
+               {
+                       return new Phar(self::cli_arg_typ_pharfile($arg));
+               }
+               catch(Exception $e)
+               {
+                       echo "Exception while opening phar '$argv':\n";
+                       echo $e->getMessage() . "\n";
+                       exit(1);
+               }
+       }
+
+       static function cli_cmd_inf_pack()
+       {
+               return "Pack files into a PHAR archive.";
+       }
+
+       static function cli_cmd_arg_pack()
+       {
+               return array(
+                       'f' => array('type'=>'pharnew', 'val'=>NULL,      'required'=>1, 'inf'=>'<file>   Specifies the phar file to work on.'),
+                       'a' => array('type'=>'alias',   'val'=>'newphar', 'required'=>1, 'inf'=>'<alias>  Provide an alias name for the phar file.'),
+                       's' => array('type'=>'file',    'val'=>NULL,                     'inf'=>'<stub>   Select the stub file (excluded from list of input files/dirs).'),
+                       'r' => array('type'=>'regex',   'val'=>NULL,                     'inf'=>'<regex>  Specifies a regular expression for input files.'),
+                       'c' => array('type'=>'select',  'val'=>NULL,                     'inf'=>'<algo>   Compression algorithmus.', 'select'=>array('gz'=>'GZip compression','gzip'=>'GZip compression','bzip2'=>'BZip2 compression','bz'=>'BZip2 compression','bz2'=>'BZip2 compression','0'=>'No compression','none'=>'No compression')),
+                       ''  => array('type'=>'any',     'val'=>NULL,      'required'=>1, 'inf'=>'         Any number of input files and directories.'),
+                       );
+       }
+
+       function cli_cmd_run_pack()
+       {
+               if (ini_get('phar.readonly'))
+               {
+                       echo "Creating phar files is disabled by ini setting 'phar.readonly'.\n";
+                       exit(1);
+               }
+               if (Phar::canWrite() == version_compare(phpversion('phar'), '1.2', '<'))
+               {
+                       echo "Creating phar files is disabled, Phar::canWrite() returned false.\n";
+                       exit(1);
+               }
+
+               $archive = $this->args['f']['val'];
+               $alias   = $this->args['a']['val'];
+               $stub    = $this->args['s']['val'];
+               $regex   = $this->args['r']['val'];
+               $input   = $this->args['']['val'];
+
+               $phar  = new Phar($archive, 0, $alias);
+
+               $phar->startBuffering();
+               
+               if (isset($stub))
+               {
+                       $phar->setStub(file_get_contents($stub));
+                       $stub = new SplFileInfo($stub);
+               }
+
+               if (!is_array($input))
+               {
+                       $this->phar_add($phar, $input, $regex, $stub);
+               }
+               else
+               {
+                       foreach($input as $i)
+                       {
+                               $this->phar_add($phar, $i, $regex, $stub);
+                       }
+               }
+
+               $phar->stopBuffering();
+
+               switch($this->args['c']['val'])
+               {
+               case 'gz':
+               case 'gzip':
+                       $phar->compressAllFilesGZ();
+                       break;
+               case 'bz2':
+               case 'bzip2':
+                       $phar->compressAllFilesBZIP2();         
+                       break;
+               default:
+                       break;
+               }
+               exit(0);
+       }
+
+       static function phar_add(Phar $phar, $input, $regex, SplFileInfo $stub)
+       {
+               $dir   = new RecursiveDirectoryIterator($input);
+               $dir   = new RecursiveIteratorIterator($dir);
+
+               if (isset($regex))
+               {
+                       $dir = new RegexIterator($dir, '/'. $regex . '/');
+               }
+
+               try
+               {
+                       foreach($dir as $file)
+                       {
+                               if (empty($stub) || $file->getRealPath() != $stub->getRealPath())
+                               {
+                                       $f = $dir->getSubPathName();
+                                       echo "$f\n";
+                                       $phar[$f] = file_get_contents($file);
+                               }
+                       }
+               }
+               catch(Excpetion $e)
+               {
+                       echo "Unable to complete operation on file '$file'\n";
+                       echo $e->getMessage() . "\n";
+                       exit(1);
+               }
+       }
+
+       static function cli_cmd_inf_list()
+       {
+               return "List contents of a PHAR archive.";
+       }
+
+       static function cli_cmd_arg_list()
+       {
+               return array(
+                       'f' => array('type'=>'pharurl', 'val'=>NULL, 'required'=>1, 'inf'=>'<file>   Specifies the phar file to work on.'),
+                       );
+       }
+
+       function cli_cmd_run_list()
+       {
+               foreach(new DirectoryTreeIterator($this->args['f']['val']) as $f)
+               {
+                       echo "$f\n";
+               }
+       }
+
+       static function cli_cmd_inf_tree()
+       {
+               return "Get a directory tree for a PHAR archive.";
+       }
+
+       static function cli_cmd_arg_tree()
+       {
+               return array(
+                       'f' => array('type'=>'pharurl', 'val'=>NULL, 'required'=>1, 'inf'=>'<file>   Specifies the phar file to work on.'),
+                       );
+       }
+
+       function cli_cmd_run_tree()
+       {
+               foreach(new DirectoryGraphIterator($this->args['f']['val']) as $f)
+               {
+                       echo "$f\n";
+               }
+       }
+}
+
+?>
\ No newline at end of file