Development

Changeset 19056

You must first sign up to be able to contribute.

Changeset 19056

Show
Ignore:
Timestamp:
06/09/09 12:41:14 (1 year ago)
Author:
fabien
Message:

[1.3] added sfFilesystem::execute() and made project:deploy output real-time feedback

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • branches/1.3/UPGRADE_TO_1_3

    r18909 r19056  
    7575    `checkResponseElement()`: These methods have been deprecated since 1.2, 
    7676    and replaced with the tester classes. 
     77 
     78  * `sfFilesystem::sh()`: You can replace all occurrences of this method by 
     79    calls to the new `sfFilesystem::execute()` method. Be warned that the 
     80    returned value of this method is an array composed of the `stdout` output 
     81    and the `stderr` output. 
    7782 
    7883The following methods and functions have been removed in symfony 1.3: 
  • branches/1.3/WHATS_NEW

    r18926 r19056  
    229229equivalent `php data/bin/symfony symfony:test` command. 
    230230 
     231### `project:deploy` 
     232 
     233The `project:deploy` task has been slightly improved. It now displays the 
     234progress of the files transfer in real-time, but only if the `-t` option is 
     235passed. If not, the task is silent, except for errors of course. Speaking of 
     236errors, if one occurs, the output is on a red background to easy problem 
     237identification. 
     238 
     239### `sfFileSystem::execute()` 
     240 
     241The `sfFileSystem::execute()` methods replaces the `sfFileSystem::sh()` method 
     242with more powerful features. It takes callbacks for real-time processing of 
     243the `stdout` and `stderr` outputs. It also returns both outputs as an array. 
     244You can find one example of its usage in the `sfProjectDeployTask` class. 
     245 
    231246Exceptions 
    232247---------- 
  • branches/1.3/lib/task/project/sfProjectDeployTask.class.php

    r10956 r19056  
    1919class sfProjectDeployTask extends sfBaseTask 
    2020{ 
     21  protected 
     22    $outputBuffer = '', 
     23    $errorBuffer = ''; 
     24 
    2125  /** 
    2226   * @see sfTask 
     
    3135      new sfCommandOption('go', null, sfCommandOption::PARAMETER_NONE, 'Do the deployment'), 
    3236      new sfCommandOption('rsync-dir', null, sfCommandOption::PARAMETER_REQUIRED, 'The directory where to look for rsync*.txt files', 'config'), 
    33       new sfCommandOption('rsync-options', null, sfCommandOption::PARAMETER_OPTIONAL, 'To options to pass to the rsync executable', '-azC --force --delete'), 
     37      new sfCommandOption('rsync-options', null, sfCommandOption::PARAMETER_OPTIONAL, 'To options to pass to the rsync executable', '-azC --force --delete --progress'), 
    3438    )); 
    3539 
     
    157161 
    158162    $dryRun = $options['go'] ? '' : '--dry-run'; 
    159  
    160     $this->log($this->getFilesystem()->sh("rsync --progress $dryRun $parameters -e $ssh ./ $user$host:$dir")); 
     163    $command = "rsync $dryRun $parameters -e $ssh ./ $user$host:$dir"; 
     164 
     165    $this->getFilesystem()->execute($command, $options['trace'] ? array($this, 'logOutput') : null, array($this, 'logErrors')); 
     166 
     167    $this->clearBuffers(); 
     168  } 
     169 
     170  public function logOutput($output, $color = null) 
     171  { 
     172    if (false !== $pos = strpos($output, "\n")) 
     173    { 
     174      $this->outputBuffer .= substr($output, 0, $pos); 
     175      $this->log($this->outputBuffer); 
     176      $this->outputBuffer = substr($output, $pos + 1); 
     177    } 
     178    else 
     179    { 
     180      $this->outputBuffer .= $output; 
     181    } 
     182  } 
     183 
     184  public function logErrors($output) 
     185  { 
     186    if (false !== $pos = strpos($output, "\n")) 
     187    { 
     188      $this->errorBuffer .= substr($output, 0, $pos); 
     189      $this->log($this->formatter->format($this->errorBuffer, 'ERROR')); 
     190      $this->errorBuffer = substr($output, $pos + 1); 
     191    } 
     192    else 
     193    { 
     194      $this->errorBuffer .= $output; 
     195    } 
     196  } 
     197 
     198  protected function clearBuffers() 
     199  { 
     200    if ($this->outputBuffer) 
     201    { 
     202      $this->log($this->outputBuffer); 
     203      $this->outputBuffer = ''; 
     204    } 
     205 
     206    if ($this->errorBuffer) 
     207    { 
     208      $this->log($this->formatter->format($this->errorBuffer, 'ERROR')); 
     209      $this->errorBuffer = ''; 
     210    } 
    161211  } 
    162212} 
  • branches/1.3/lib/task/sfFilesystem.class.php

    r14523 r19056  
    274274 
    275275  /** 
    276    * Executes a shell command. 
     276   * DEPRECATED: Executes a shell command. 
     277   * 
     278   * This method is deprecated. Use the more powerful execute() method instead. 
    277279   * 
    278280   * @param string $cmd  The command to execute on the shell 
     
    293295 
    294296    return $content; 
     297  } 
     298 
     299  /** 
     300   * Executes a shell command. 
     301   * 
     302   * @param string $cmd            The command to execute on the shell 
     303   * @param array  $stdoutCallback A callback for stdout output 
     304   * @param array  $stderrCallback A callback for stderr output 
     305   * 
     306   * @return array An array composed of the content output and the error output 
     307   */ 
     308  public function execute($cmd, $stdoutCallback = null, $stderrCallback = null) 
     309  { 
     310    $this->logSection('exec ', $cmd); 
     311 
     312    $descriptorspec = array( 
     313      1 => array('pipe', 'w'), // stdout 
     314      2 => array('pipe', 'w'), // stderr 
     315    ); 
     316 
     317    $process = proc_open($cmd, $descriptorspec, $pipes); 
     318    if (!is_resource($process)) 
     319    { 
     320      throw new RuntimeException('Unable to execute the command.'); 
     321    } 
     322 
     323    stream_set_blocking($pipes[1], false); 
     324    stream_set_blocking($pipes[2], false); 
     325 
     326    $output = ''; 
     327    $err = ''; 
     328    while (!feof($pipes[1])) 
     329    { 
     330      foreach ($pipes as $key => $pipe) 
     331      { 
     332        if (!$line = fread($pipe, 128)) 
     333        { 
     334          continue; 
     335        } 
     336 
     337        if (1 == $key) 
     338        { 
     339          // stdout 
     340          $output .= $line; 
     341          if ($stdoutCallback) 
     342          { 
     343            call_user_func($stdoutCallback, $line); 
     344          } 
     345        } 
     346        else 
     347        { 
     348          // stderr 
     349          $err .= $line; 
     350          if ($stderrCallback) 
     351          { 
     352            call_user_func($stderrCallback, $line); 
     353          } 
     354        } 
     355      } 
     356 
     357      sleep(0.1); 
     358    } 
     359 
     360    fclose($pipes[1]); 
     361    fclose($pipes[2]); 
     362 
     363    if (($return = proc_close($process)) > 0) 
     364    { 
     365      throw new RuntimeException('Problem executing command.', $return); 
     366    } 
     367 
     368    return array($output, $err); 
    295369  } 
    296370 

The Sensio Labs Network

Since 1998, Sensio Labs has been promoting the Open-Source software movement by providing quality web application development, training, consulting.
Sensio Labs also supports several large Open-Source projects.