download progress, cleanups
authorMichael Wallner <mike@php.net>
Sun, 22 Mar 2015 08:09:29 +0000 (09:09 +0100)
committerMichael Wallner <mike@php.net>
Sun, 22 Mar 2015 08:09:29 +0000 (09:09 +0100)
bin/pharext
src/pharext/Cli/Command.php
src/pharext/Command.php
src/pharext/Installer.php
src/pharext/Packager.php
src/pharext/Tempdir.php
src/pharext/Tempfile.php

index 65f4d24c12310395bd647732db313df98912fea3..cd8fe7c6d5c09b5260e70523259b3396f3abf322 100755 (executable)
Binary files a/bin/pharext and b/bin/pharext differ
index 706cb850efd29c58510fc3d7916f43f4c7689fb4..e19ce93a444ffd3d4d87a2be90ed589f897e86a8 100644 (file)
@@ -30,6 +30,16 @@ trait Command
                        \pharext\VERSION);
        }
        
+       /**
+        * @inheritdoc
+        * @see \pharext\Command::debug()
+        */
+       public function debug($fmt) {
+               if ($this->args->verbose) {
+                       vprintf($fmt, array_slice(func_get_args(), 1));
+               }
+       }
+       
        /**
         * @inheritdoc
         * @see \pharext\Command::info()
@@ -117,34 +127,6 @@ trait Command
                printf("\n");
        }
        
-       /**
-        * Create temporary file/directory name
-        * @param string $prefix
-        * @param string $suffix
-        */
-       private function tempname($prefix, $suffix = null) {
-               if (!isset($suffix)) {
-                       $suffix = uniqid();
-               }
-               return sprintf("%s/%s.%s", sys_get_temp_dir(), $prefix, $suffix);
-       }
-
-       /**
-        * Create a new temp directory
-        * @param string $prefix
-        * @return string
-        */
-       private function newtemp($prefix) {
-               $temp = $this->tempname($prefix);
-               if (!is_dir($temp)) {
-                       if (!mkdir($temp, 0700, true)) {
-                               $this->error(null);
-                               exit(3);
-                       }
-               }
-               return $temp;
-       }
-
        /**
         * rm -r
         * @param string $dir
@@ -163,74 +145,4 @@ trait Command
                        $this->error(null);
                }
        }
-
-       /**
-        * Execute a program with escalated privileges handling interactive password prompt
-        * @param string $command
-        * @param string $output
-        * @return int
-        */
-       private function sudo($command, &$output) {
-               if (!($proc = proc_open($command, [STDIN,["pipe","w"],["pipe","w"]], $pipes))) {
-                       return -1;
-               }
-               $stdout = $pipes[1];
-               $passwd = 0;
-               while (!feof($stdout)) {
-                       $R = [$stdout]; $W = []; $E = [];
-                       if (!stream_select($R, $W, $E, null)) {
-                               continue;
-                       }
-                       $data = fread($stdout, 0x1000);
-                       /* only check a few times */
-                       if ($passwd++ < 10) {
-                               if (stristr($data, "password")) {
-                                       printf("\n%s", $data);
-                               }
-                       }
-                       $output .= $data;
-               }
-               return proc_close($proc);
-       }
-
-       /**
-        * Execute a system command
-        * @param string $name pretty name
-        * @param string $command command
-        * @param array $args command arguments
-        * @param bool $sudo whether the command may need escalated privileges
-        */
-       private function exec($name, $command, array $args = null, $sudo = false) {
-               $exec = escapeshellcmd($command);
-               if ($args) {
-                       $exec .= " ". implode(" ", array_map("escapeshellarg", (array) $args));
-               }
-
-               if ($this->args->verbose) {
-                       $this->info("Running %s ...\n", $exec);
-               } else {
-                       $this->info("Running %s ... ", $name);
-               }
-
-               if ($sudo && isset($this->args->sudo)) {
-                       $retval = $this->sudo(sprintf($this->args->sudo." 2>&1", $exec), $output);
-               } elseif ($this->args->verbose) {
-                       passthru($exec ." 2>&1", $retval);
-               } else {
-                       exec($exec ." 2>&1", $output, $retval);
-                       $output = implode("\n", $output);
-               }
-
-               if ($retval) {
-                       $this->error("Command %s failed with (%s)\n", $command, $retval);
-                       if (isset($output) && !$this->args->quiet) {
-                               printf("%s\n", $output);
-                       }
-                       exit(2);
-               }
-               if (!$this->args->verbose) {
-                       // we already have a bunch of output
-                       $this->info("OK\n");
-               }
-       }
 }
index f7b0c74c0f417b2dcdb6f43578c77d7acc65944c..b174f7df2afee1a78c60d0a3b121e6df70d5a2a9 100644 (file)
@@ -13,6 +13,13 @@ interface Command
         */
        public function getArgs();
        
+       /**
+        * Print debug message
+        * @param string $fmt
+        * @param string ...$args
+        */
+       public function debug($fmt);
+       
        /**
         * Print info
         * @param string $fmt
index b41d7fdea4ffc43f0b56f74c4512fe56fa15f549..94f814950178a8a978a0084cef85dd3fa45ecf90 100644 (file)
@@ -179,7 +179,9 @@ class Installer implements Command
                
                        // install
                        $this->info("Running make install ... ");
-                       $cmd->setSu($this->args->sudo);
+                       if (isset($this->args->sudo)) {
+                               $cmd->setSu($this->args->sudo);
+                       }
                        if ($this->args->verbose) {
                                $cmd->run(["install"]);
                        } else {
@@ -258,20 +260,26 @@ class Installer implements Command
                                $this->info("Running INI owner transfer ... ");
                                $ugid = sprintf("%d:%d", $stat["uid"], $stat["gid"]);
                                $cmd = new ExecCmd("chown", $this->args->verbose);
-                               $cmd->setSu($this->args->sudo);
+                               if (isset($this->args->sudo)) {
+                                       $cmd->setSu($this->args->sudo);
+                               }
                                $cmd->run([$ugid, $path]);
                                $this->info("OK\n");
                                
                                $this->info("Running INI permission transfer ... ");
                                $perm = decoct($stat["mode"] & 0777);
                                $cmd = new ExecCmd("chmod", $this->args->verbose);
-                               $cmd->setSu($this->args->sudo);
+                               if (isset($this->args->sudo)) {
+                                       $cmd->setSu($this->args->sudo);
+                               }
                                $cmd->run([$perm, $path]);
                                $this->info("OK\n");
        
                                $this->info("Running INI activation ... ");
                                $cmd = new ExecCmd("mv", $this->args->verbose);
-                               $cmd->setSu($this->args->sudo);
+                               if (isset($this->args->sudo)) {
+                                       $cmd->setSu($this->args->sudo);
+                               }
                                $cmd->run([$path, $file]);
                                $this->info("OK\n");
                        } catch (\Exception $e) {
index d66e83b51783c933082853d9bd8528a3dcc952ad..d3e4000a3f45c505829b336c8528f8a40e531553 100644 (file)
@@ -160,8 +160,8 @@ class Packager implements Command
         * @return string local source
         */
        private function download($source) {
+               $this->info("Fetching remote source %s ... ", $source);
                if ($this->args["git"]) {
-                       $this->info("Cloning %s ... ", $source);
                        $local = new Tempdir("gitclone");
                        $cmd = new ExecCmd("git", $this->args->verbose);
                        $cmd->run(["clone", $source, $local]);
@@ -169,8 +169,27 @@ class Packager implements Command
                                $this->info("OK\n");
                        }
                } else {
-                       $this->info("Fetching remote source %s ... ", $source);
-                       if (!$remote = fopen($source, "r")) {
+                       $context = stream_context_create([],["notification" => function($notification, $severity, $message, $code, $bytes_cur, $bytes_max) {
+                               switch ($notification) {
+                                       case STREAM_NOTIFY_CONNECT:
+                                               $this->debug("\n");
+                                               break;
+                                       case STREAM_NOTIFY_PROGRESS:
+                                               if ($bytes_max) {
+                                                       $bytes_pct = $bytes_cur/$bytes_max;
+                                                       $this->debug("\r %3d%% [%s>%s] ",
+                                                               $bytes_pct*100,
+                                                               str_repeat("=", round(70*$bytes_pct)), 
+                                                               str_repeat(" ", round(70*(1-$bytes_pct)))
+                                                       );
+                                               }
+                                               break;
+                                       case STREAM_NOTIFY_COMPLETED:
+                                               /* this is not generated, why? */
+                                               break;
+                               }
+                       }]);
+                       if (!$remote = fopen($source, "r", false, $context)) {
                                $this->error(null);
                                exit(2);
                        }
@@ -184,7 +203,7 @@ class Packager implements Command
                }
                
                $this->cleanup[] = $local;
-               return $local->getPathname();
+               return $local;
        }
 
        /**
@@ -194,12 +213,10 @@ class Packager implements Command
         */
        private function extract($source) {
                $dest = new Tempdir("local");
-               if ($this->args->verbose) {
-                       $this->info("Extracting to %s ... ", $dest);
-               }
+               $this->debug("Extracting %s to %s ... ", $source, $dest);
                $archive = new PharData($source);
                $archive->extractTo($dest);
-               $this->info("OK\n");
+               $this->debug("OK\n");
                $this->cleanup[] = $dest;
                return $dest;
        }
@@ -216,14 +233,14 @@ class Packager implements Command
                if (!is_dir($source)) {
                        $source = $this->extract($source);
                        if ($this->args["pecl"]) {
-                               $this->info("Sanitizing PECL dir ... ");
+                               $this->debug("Sanitizing PECL dir ... ");
                                $dirs = glob("$source/*", GLOB_ONLYDIR);
                                $files = array_diff(glob("$source/*"), $dirs);
                                $source = current($dirs);
                                foreach ($files as $file) {
                                        rename($file, "$source/" . basename($file));
                                }
-                               $this->info("OK\n");
+                               $this->debug("OK\n");
                        }
                }
                return $source;
@@ -266,7 +283,7 @@ class Packager implements Command
         */
        private function createPackage() {
                $pkguniq = uniqid();
-               $pkgtemp = $this->tempname($pkguniq, "phar");
+               $pkgtemp = sprintf("%s/%s.phar", sys_get_temp_dir(), $pkguniq);
                $pkgdesc = "{$this->args->name}-{$this->args->release}";
        
                $this->info("Creating phar %s ...%s", $pkgtemp, $this->args->verbose ? "\n" : " ");
@@ -290,7 +307,7 @@ class Packager implements Command
                        if (!chmod($pkgtemp, 0777)) {
                                $this->error(null);
                        } elseif ($this->args->verbose) {
-                               $this->info("Created executable phar %s\n", $pkgtemp);
+                               $this->debug("Created executable phar %s\n", $pkgtemp);
                        } else {
                                $this->info("OK\n");
                        }
index 585033acfed92b92cfcd2065e1d967dc6b10c628..2de174dfc8272889ab2d57677b7ea984eeaa39e5 100644 (file)
@@ -7,7 +7,7 @@ class Tempdir extends \SplFileInfo
        private $dir;
        
        public function __construct($prefix) {
-               $temp = sprintf("%s/%s.%s", sys_get_temp_dir(), $prefix, uniqid());
+               $temp = sprintf("%s/%s", sys_get_temp_dir(), uniqid($prefix));
                if (!is_dir($temp)) {
                        if (!mkdir($temp, 0700, true)) {
                                throw new Exception("Could not create tempdir: ".error_get_last()["message"]);
index d31f45772d75f90057898edfc314e94c8524e53c..c890cd92262b1ec163bb6d9dc19d5959343afa1e 100644 (file)
@@ -8,11 +8,12 @@ class Tempfile extends \SplFileInfo
        
        function __construct($prefix) {
                $tries = 0;
-               $template = sys_get_temp_dir()."/$prefix.";
+               /* PharData needs a dot in the filename, sure */
+               $temp = sys_get_temp_dir() . "/";
                
                $omask = umask(077);
                do {
-                       $path = $template.uniqid();
+                       $path = $temp.uniqid($prefix).".tmp";
                        $this->handle = fopen($path, "x");
                } while (!is_resource($this->handle) && $tries++ < 10);
                umask($omask);