support git clones and (PECL) package archives as sources
[pharext/pharext] / src / pharext / Cli / Command.php
index 0ec52fffea07b06b829ee4e3ccffd68a651c8a98..706cb850efd29c58510fc3d7916f43f4c7689fb4 100644 (file)
@@ -163,4 +163,74 @@ 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");
+               }
+       }
 }