Skip to content

Commit

Permalink
AL-1737: Pass callback through to LocalMachineHelper::exec (#1947)
Browse files Browse the repository at this point in the history
* Pass callback through to LocalMachineHelper::exec

* Move interactivity checks from 'execute()' command to 'execInteractive()' command.

* Code style

* Add --progress option to 'terminus wp' and 'terminus drush'. Do not allow progress bars on these commands unless --progress is selected.

* Fix syntax error

* Move stderr() method to Robo::IO. Add annotations / usage for --progress

* Make separate @Usage annotations with and without --progress
  • Loading branch information
greg-1-anderson authored Feb 14, 2019
1 parent 041b75c commit 48587c1
Show file tree
Hide file tree
Showing 8 changed files with 149 additions and 157 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ All notable changes to this project will be documented in this file. This projec
- Added `is_owner` field to the output of `site:team:list` in order to indicate which user is the site owner. (#1949)
- Added boolean `is_owner` field to the output of `SiteUserMemberships::serialize()` in order to indicate which user is the site owner. (#1949)
- Added `SiteUserMemberships::isOwner()` function in order to ascertain whether the user is the site's owner. (#1949)
- A `--progress` option has been added to `remote:drush` and `remote:wp` to enable progress for remote commands. (#1947)

### Changed
- `org:site:list` now displays a `Plan`/`plan_name` field to replace `Service Level`/`service_level`. (#1901)
Expand Down
4 changes: 2 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@
"keywords": [ "cli", "pantheon", "terminus", "drupal", "wordpress" ],
"homepage": "https://pantheon.io",
"license": "MIT",
"minimum-stability": "dev",
"minimum-stability": "stable",
"prefer-stable": true,
"require": {
"php": ">=5.5.38",
"composer/semver": "^1.4",
"consolidation/output-formatters": "^3.2",
"consolidation/robo": "^1.1.0",
"consolidation/robo": "^1.4.4",
"guzzlehttp/guzzle": "^6.2",
"psy/psysh": "^0.8",
"symfony/console": "^3.3",
Expand Down
177 changes: 90 additions & 87 deletions composer.lock

Large diffs are not rendered by default.

6 changes: 5 additions & 1 deletion src/Commands/Remote/DrushCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,17 @@ class DrushCommand extends SSHBaseCommand
*
* @param string $site_env Site & environment in the format `site-name.env`
* @param array $drush_command Drush command
* @param array $options Commandline options
* @option progress Allow progress bar to be used (tty mode only)
* @return string Command output
*
* @usage <site>.<env> -- <command> Runs the Drush command <command> remotely on <site>'s <env> environment.
* @usage <site>.<env> --progress -- <command> Runs a Drush command with a progress bar
*/
public function drushCommand($site_env, array $drush_command)
public function drushCommand($site_env, array $drush_command, array $options = ['progress' => false])
{
$this->prepareEnvironment($site_env);
$this->setProgressAllowed($options['progress']);
return $this->executeCommand($drush_command);
}
}
35 changes: 31 additions & 4 deletions src/Commands/Remote/SSHBaseCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@
namespace Pantheon\Terminus\Commands\Remote;

use Pantheon\Terminus\Commands\TerminusCommand;
use Pantheon\Terminus\Exceptions\TerminusProcessException;
use Pantheon\Terminus\Helpers\LocalMachineHelper;
use Pantheon\Terminus\Models\Environment;
use Pantheon\Terminus\Models\Site;
use Pantheon\Terminus\Site\SiteAwareInterface;
use Pantheon\Terminus\Site\SiteAwareTrait;
use Pantheon\Terminus\Exceptions\TerminusProcessException;
use Symfony\Component\Console\Output\ConsoleOutputInterface;
use Symfony\Component\Process\Process;
use Symfony\Component\Process\ProcessUtils;

/**
Expand All @@ -32,6 +34,10 @@ abstract class SSHBaseCommand extends TerminusCommand implements SiteAwareInterf
* @var Site
*/
private $site;
/**
* @var bool
*/
protected $progressAllowed;

/**
* Define the environment and site properties
Expand All @@ -43,6 +49,20 @@ protected function prepareEnvironment($site_env_id)
list($this->site, $this->environment) = $this->getSiteEnv($site_env_id);
}

/**
* progressAllowed sets the field that controls whether a progress bar
* may be displayed when a program is executed. If allowed, a progress
* bar will be used in tty mode.
*
* @param type|bool $allowed
* @return $this
*/
protected function setProgressAllowed($allowed = true)
{
$this->progressAllowed = $allowed;
return $this;
}

/**
* Execute the command remotely
*
Expand Down Expand Up @@ -84,7 +104,8 @@ protected function sendCommandViaSsh($command)
}
return $this->getContainer()->get(LocalMachineHelper::class)->execute(
$ssh_command,
$this->getOutputCallback()
$this->getOutputCallback(),
$this->progressAllowed
);
}

Expand Down Expand Up @@ -196,8 +217,14 @@ private function getOutputCallback()
{
if ($this->getContainer()->get(LocalMachineHelper::class)->useTty() === false) {
$output = $this->output();
return function ($type, $buffer) use ($output) {
$output->write($buffer);
$stderr = $this->stderr();

return function ($type, $buffer) use ($output, $stderr) {
if (Process::ERR === $type) {
$stderr->write($buffer);
} else {
$output->write($buffer);
}
};
}
return function ($type, $buffer) {
Expand Down
6 changes: 5 additions & 1 deletion src/Commands/Remote/WPCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,17 @@ class WPCommand extends SSHBaseCommand
*
* @param string $site_env Site & environment in the format `site-name.env`
* @param array $wp_command WP-CLI command
* @param array $options Commandline options
* @option progress Allow progress bar to be used (tty mode only)
* @return string Command output
*
* @usage <site>.<env> -- <command> Runs the WP-CLI command <command> remotely on <site>'s <env> environment.
* @usage <site>.<env> --progress -- <command> Runs a WP-CLI command with a progress bar
*/
public function wpCommand($site_env, array $wp_command)
public function wpCommand($site_env, array $wp_command, array $options = ['progress' => false])
{
$this->prepareEnvironment($site_env);
$this->setProgressAllowed($options['progress']);
return $this->executeCommand($wp_command);
}
}
31 changes: 12 additions & 19 deletions src/Helpers/LocalMachineHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
use Robo\Common\IO;
use Robo\Contract\ConfigAwareInterface;
use Robo\Contract\IOAwareInterface;
use Symfony\Component\Console\Output\ConsoleOutputInterface;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\Finder\Finder;
use Symfony\Component\Process\Process;
Expand All @@ -35,36 +36,22 @@ class LocalMachineHelper implements ConfigAwareInterface, ContainerAwareInterfac
* @param string $cmd The command to execute
* @return array The command output and exit_code
*/
public function exec($cmd)
public function exec($cmd, $callback = null)
{
$process = $this->getProcess($cmd);
$process->run();
$process->run($callback);
return ['output' => $process->getOutput(), 'exit_code' => $process->getExitCode(),];
}

/**
* Executes the given command on the local machine either interactively or not based on config.
*
* @param string $cmd The command to execute
* @param callable $callback A function to run while waiting for the process to complete
* @return array The command output and exit_code
*/
public function execute($cmd, $callback = null)
{
if ($this->input()->isInteractive()) {
return $this->execInteractive($cmd, $callback);
}
return $this->exec($cmd);
}

/**
* Executes a buffered command.
*
* @param string $cmd The command to execute
* @param callable $callback A function to run while waiting for the process to complete
* @param bool $progressIndicatorAllowed Allow the progress bar to be used (if in tty mode only)
* @return array The command output and exit_code
*/
public function execInteractive($cmd, $callback = null)
public function execute($cmd, $callback = null, $progressIndicatorAllowed = false)
{
$process = $this->getProcess($cmd);
$useTty = $this->useTty();
Expand All @@ -78,7 +65,13 @@ public function execInteractive($cmd, $callback = null)
}
}
$process->setTty($useTty);
$this->getProgressBar($process)->cycle($callback);
// Use '$useTty' as a sort of 'isInteractive' indicator.
if ($useTty && $progressIndicatorAllowed) {
$this->getProgressBar($process)->cycle($callback);
} else {
$process->start();
$process->wait($callback);
}
return ['output' => $process->getOutput(), 'exit_code' => $process->getExitCode(),];
}

Expand Down
46 changes: 3 additions & 43 deletions tests/unit_tests/Helpers/LocalMachineHelperTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -70,51 +70,11 @@ public function testExec()
}

/**
* Tests the LocalMachineHelper::execute($command, $callback) function when interactive
* Tests the LocalMachineHelper::execute($command, $callback, $progress) function
*/
public function testExecuteWhenInteractive()
public function testExecute()
{
$command = 'ls';
$callback = function () {
return null;
};

$this->input->method('isInteractive')->willReturn(true);
$this->config->expects($this->once())
->method('get')
->with('timeout')
->willReturn(55);

$output = $this->local_machine->execute($command, $callback);
$this->assertEquals(0, $output['exit_code']);
}

/**
* Tests the LocalMachineHelper::execute($command, $callback) function when not interactive
*/
public function testExecuteWhenNotInteractive()
{
$command = 'ls';
$callback = function () {
return null;
};

$this->input->method('isInteractive')->willReturn(false);
$this->config->expects($this->once())
->method('get')
->with('timeout')
->willReturn(55);

$output = $this->local_machine->execute($command, $callback);
$this->assertEquals(0, $output['exit_code']);
}

/**
* Tests the LocalMachineHelper::execInteractive($command, $callback) function
*/
public function testExecInteractive()
{
$out = $this->local_machine->execInteractive('ls');
$out = $this->local_machine->execute('ls');
$this->assertEquals(0, $out['exit_code']);
}

Expand Down

0 comments on commit 48587c1

Please sign in to comment.