Example #1
0
 /**
  * Runs the application, returning the status to exit with.
  * 
  * @return integer The exit status.
  * @access public
  */
 public function run()
 {
     $exit_status = 0;
     // Curator doesn't do anything without at least one argument, besides the curator command itself.
     if ($this->argc === 0) {
         Console::stdout('Use \'' . $this->cmd . ' --help\' for usage information.');
     } else {
         try {
             $parser = $this->buildCommandLineParser();
             $result = $parser->parse();
             // determine where our relevant directories are.
             if (!empty($result->options['proj_path'])) {
                 $project_dir = realpath($result->options['proj_path']);
             }
             if (empty($project_dir)) {
                 $project_dir = $_SERVER['PWD'];
             }
             $this->createDirectoryAtPath($project_dir);
             try {
                 $project = new Project($project_dir);
                 switch ($result->command_name) {
                     case 'new':
                         $project->install();
                         break;
                     case 'clean':
                         $project->clean();
                         break;
                     case 'build':
                         $project->build();
                         break;
                 }
             } catch (\Exception $e) {
                 Console::stderr('** Command \'' . $result->command_name . '\' has failed:');
                 Console::stderr('  ' . $e->getMessage());
             }
         } catch (\Exception $e) {
             $parser->displayError($e->getMessage());
             $exit_status = $e->getCode();
         }
     }
     return $exit_status;
 }
Example #2
0
 /**
  * Execute a Closure as another process in the background while showing a
  * status update. The status update can be an indefinite spinner or a string
  * periodically sent from the background process, depending on whether the
  * provided Closure object has a $socket parameter or not. Messaging to the
  * main process is done by socket_* functions. The return value is either
  * the return value of the background process, or false if the process fork
  * failed.
  *
  * @param callable $callable Closure object
  * @return bool|int
  * @throws \Exception
  */
 public static function work(\Closure $callable)
 {
     if (!extension_loaded('pcntl')) {
         throw new \Exception('pcntl extension required');
     }
     if (!extension_loaded('sockets')) {
         throw new \Exception('sockets extension required');
     }
     $spinner = array('|', '/', '-', '\\');
     $i = 0;
     $l = count($spinner);
     $delay = 100000;
     $func = new \ReflectionFunction($callable);
     $socket = (bool) $func->getNumberOfParameters();
     if ($socket) {
         $sockets = array();
         if (socket_create_pair(AF_UNIX, SOCK_STREAM, 0, $sockets) === false) {
             return false;
         }
     }
     $pid = pcntl_fork();
     if ($pid > 0) {
         $done = false;
         $retval = 0;
         pcntl_signal(SIGCHLD, function () use($pid, &$done, &$retval) {
             $child_pid = pcntl_waitpid($pid, $status);
             if (pcntl_wifexited($status)) {
                 $retval = pcntl_wexitstatus($status);
             }
             $done = true;
         });
         if ($socket) {
             $text = '';
             while (!$done) {
                 $r = array($sockets[1]);
                 $w = null;
                 $e = null;
                 if ($status = socket_select($r, $w, $e, 0)) {
                     $data = socket_read($sockets[1], 4096, PHP_NORMAL_READ);
                     if ($data === false) {
                         throw new \Exception(sprintf('socket write error %s', socket_strerror(socket_last_error($sockets[1]))));
                     }
                     echo str_repeat(chr(8), strlen($text));
                     $text = rtrim($data, "\n");
                     Console::stdout($text);
                 } else {
                     pcntl_signal_dispatch();
                 }
                 usleep($delay);
             }
             echo str_repeat(chr(8), strlen($text));
             socket_close($sockets[0]);
             socket_close($sockets[1]);
         } else {
             while (!$done) {
                 pcntl_signal_dispatch();
                 echo $spinner[$i];
                 usleep($delay);
                 echo chr(8);
                 $i = $i === $l - 1 ? 0 : $i + 1;
             }
         }
         return $retval;
     } elseif ($pid === 0) {
         if ($socket) {
             call_user_func($callable, $sockets[0]);
         } else {
             call_user_func($callable);
         }
         exit;
     } else {
         // Unable to fork process.
         return false;
     }
 }