From 48587c166822c6af210d97312e9ba0f72ba58d08 Mon Sep 17 00:00:00 2001 From: Greg Anderson Date: Thu, 14 Feb 2019 14:27:00 -0800 Subject: [PATCH] AL-1737: Pass callback through to LocalMachineHelper::exec (#1947) * 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 --- CHANGELOG.md | 1 + composer.json | 4 +- composer.lock | 177 +++++++++--------- src/Commands/Remote/DrushCommand.php | 6 +- src/Commands/Remote/SSHBaseCommand.php | 35 +++- src/Commands/Remote/WPCommand.php | 6 +- src/Helpers/LocalMachineHelper.php | 31 ++- .../Helpers/LocalMachineHelperTest.php | 46 +---- 8 files changed, 149 insertions(+), 157 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cabc29cfc..c8be1b30b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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) diff --git a/composer.json b/composer.json index efc5f90cb..59417998b 100644 --- a/composer.json +++ b/composer.json @@ -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", diff --git a/composer.lock b/composer.lock index 2c82953be..e8aa9da34 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "9abdec3c6e76e467cb6eeeae736a1e1c", + "content-hash": "7b4820fdc26cdb129890a7052411cbd2", "packages": [ { "name": "composer/semver", @@ -70,21 +70,21 @@ }, { "name": "consolidation/annotated-command", - "version": "2.11.0", + "version": "2.11.2", "source": { "type": "git", "url": "https://github.com/consolidation/annotated-command.git", - "reference": "edea407f57104ed518cc3c3b47d5b84403ee267a" + "reference": "004af26391cd7d1cd04b0ac736dc1324d1b4f572" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/consolidation/annotated-command/zipball/edea407f57104ed518cc3c3b47d5b84403ee267a", - "reference": "edea407f57104ed518cc3c3b47d5b84403ee267a", + "url": "https://api.github.com/repos/consolidation/annotated-command/zipball/004af26391cd7d1cd04b0ac736dc1324d1b4f572", + "reference": "004af26391cd7d1cd04b0ac736dc1324d1b4f572", "shasum": "" }, "require": { "consolidation/output-formatters": "^3.4", - "php": ">=5.4.0", + "php": ">=5.4.5", "psr/log": "^1", "symfony/console": "^2.8|^3|^4", "symfony/event-dispatcher": "^2.5|^3|^4", @@ -162,7 +162,7 @@ } ], "description": "Initialize Symfony Console commands from annotated command class methods.", - "time": "2018-12-29T04:43:17+00:00" + "time": "2019-02-02T02:29:53+00:00" }, { "name": "consolidation/config", @@ -366,16 +366,16 @@ }, { "name": "consolidation/robo", - "version": "1.4.3", + "version": "1.4.4", "source": { "type": "git", "url": "https://github.com/consolidation/Robo.git", - "reference": "d0b6f516ec940add7abed4f1432d30cca5f8ae0c" + "reference": "8bec6a6ea54a7d03d56552a4250c49dec3b3083d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/consolidation/Robo/zipball/d0b6f516ec940add7abed4f1432d30cca5f8ae0c", - "reference": "d0b6f516ec940add7abed4f1432d30cca5f8ae0c", + "url": "https://api.github.com/repos/consolidation/Robo/zipball/8bec6a6ea54a7d03d56552a4250c49dec3b3083d", + "reference": "8bec6a6ea54a7d03d56552a4250c49dec3b3083d", "shasum": "" }, "require": { @@ -406,7 +406,7 @@ "natxet/cssmin": "3.0.4", "nikic/php-parser": "^3.1.5", "patchwork/jsqueeze": "~2", - "pear/archive_tar": "^1.4.2", + "pear/archive_tar": "^1.4.4", "php-coveralls/php-coveralls": "^1", "phpunit/php-code-coverage": "~2|~4", "squizlabs/php_codesniffer": "^2.8" @@ -470,7 +470,7 @@ } ], "description": "Modern task runner", - "time": "2019-01-02T21:33:28+00:00" + "time": "2019-02-08T20:59:23+00:00" }, { "name": "consolidation/self-update", @@ -1385,16 +1385,16 @@ }, { "name": "symfony/console", - "version": "v3.4.21", + "version": "v3.4.22", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "a700b874d3692bc8342199adfb6d3b99f62cc61a" + "reference": "069bf3f0e8f871a2169a06e43d9f3f03f355e9be" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/a700b874d3692bc8342199adfb6d3b99f62cc61a", - "reference": "a700b874d3692bc8342199adfb6d3b99f62cc61a", + "url": "https://api.github.com/repos/symfony/console/zipball/069bf3f0e8f871a2169a06e43d9f3f03f355e9be", + "reference": "069bf3f0e8f871a2169a06e43d9f3f03f355e9be", "shasum": "" }, "require": { @@ -1406,6 +1406,9 @@ "symfony/dependency-injection": "<3.4", "symfony/process": "<3.3" }, + "provide": { + "psr/log-implementation": "1.0" + }, "require-dev": { "psr/log": "~1.0", "symfony/config": "~3.3|~4.0", @@ -1415,7 +1418,7 @@ "symfony/process": "~3.3|~4.0" }, "suggest": { - "psr/log-implementation": "For using the console logger", + "psr/log": "For using the console logger", "symfony/event-dispatcher": "", "symfony/lock": "", "symfony/process": "" @@ -1450,20 +1453,20 @@ ], "description": "Symfony Console Component", "homepage": "https://symfony.com", - "time": "2019-01-04T04:42:43+00:00" + "time": "2019-01-25T10:42:12+00:00" }, { "name": "symfony/debug", - "version": "v3.4.21", + "version": "v3.4.22", "source": { "type": "git", "url": "https://github.com/symfony/debug.git", - "reference": "26d7f23b9bd0b93bee5583e4d6ca5cb1ab31b186" + "reference": "667a26c4dd6bc75c67f06bc9bcd015bdecc7cbb8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/debug/zipball/26d7f23b9bd0b93bee5583e4d6ca5cb1ab31b186", - "reference": "26d7f23b9bd0b93bee5583e4d6ca5cb1ab31b186", + "url": "https://api.github.com/repos/symfony/debug/zipball/667a26c4dd6bc75c67f06bc9bcd015bdecc7cbb8", + "reference": "667a26c4dd6bc75c67f06bc9bcd015bdecc7cbb8", "shasum": "" }, "require": { @@ -1506,20 +1509,20 @@ ], "description": "Symfony Debug Component", "homepage": "https://symfony.com", - "time": "2019-01-01T13:45:19+00:00" + "time": "2019-01-25T10:19:25+00:00" }, { "name": "symfony/event-dispatcher", - "version": "v3.4.21", + "version": "v3.4.22", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "d1cdd46c53c264a2bd42505bd0e8ce21423bd0e2" + "reference": "ed5be1663fa66623b3a7004d5d51a14c4045399b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/d1cdd46c53c264a2bd42505bd0e8ce21423bd0e2", - "reference": "d1cdd46c53c264a2bd42505bd0e8ce21423bd0e2", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/ed5be1663fa66623b3a7004d5d51a14c4045399b", + "reference": "ed5be1663fa66623b3a7004d5d51a14c4045399b", "shasum": "" }, "require": { @@ -1569,20 +1572,20 @@ ], "description": "Symfony EventDispatcher Component", "homepage": "https://symfony.com", - "time": "2019-01-01T18:08:36+00:00" + "time": "2019-01-16T13:27:11+00:00" }, { "name": "symfony/filesystem", - "version": "v3.4.21", + "version": "v3.4.22", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "c24ce3d18ccc9bb9d7e1d6ce9330fcc6061cafde" + "reference": "b52454ec66fe5082b7a66a491339d1f1da9a5a0d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/c24ce3d18ccc9bb9d7e1d6ce9330fcc6061cafde", - "reference": "c24ce3d18ccc9bb9d7e1d6ce9330fcc6061cafde", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/b52454ec66fe5082b7a66a491339d1f1da9a5a0d", + "reference": "b52454ec66fe5082b7a66a491339d1f1da9a5a0d", "shasum": "" }, "require": { @@ -1619,20 +1622,20 @@ ], "description": "Symfony Filesystem Component", "homepage": "https://symfony.com", - "time": "2019-01-01T13:45:19+00:00" + "time": "2019-01-16T13:27:11+00:00" }, { "name": "symfony/finder", - "version": "v3.4.21", + "version": "v3.4.22", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "3f2a2ab6315dd7682d4c16dcae1e7b95c8b8555e" + "reference": "7c0c627220308928e958a87c293108e5891cde1d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/3f2a2ab6315dd7682d4c16dcae1e7b95c8b8555e", - "reference": "3f2a2ab6315dd7682d4c16dcae1e7b95c8b8555e", + "url": "https://api.github.com/repos/symfony/finder/zipball/7c0c627220308928e958a87c293108e5891cde1d", + "reference": "7c0c627220308928e958a87c293108e5891cde1d", "shasum": "" }, "require": { @@ -1668,7 +1671,7 @@ ], "description": "Symfony Finder Component", "homepage": "https://symfony.com", - "time": "2019-01-01T13:45:19+00:00" + "time": "2019-01-16T13:43:35+00:00" }, { "name": "symfony/polyfill-ctype", @@ -1789,16 +1792,16 @@ }, { "name": "symfony/process", - "version": "v3.4.21", + "version": "v3.4.22", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "0d41dd7d95ed179aed6a13393b0f4f97bfa2d25c" + "reference": "009f8dda80930e89e8344a4e310b08f9ff07dd2e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/0d41dd7d95ed179aed6a13393b0f4f97bfa2d25c", - "reference": "0d41dd7d95ed179aed6a13393b0f4f97bfa2d25c", + "url": "https://api.github.com/repos/symfony/process/zipball/009f8dda80930e89e8344a4e310b08f9ff07dd2e", + "reference": "009f8dda80930e89e8344a4e310b08f9ff07dd2e", "shasum": "" }, "require": { @@ -1834,20 +1837,20 @@ ], "description": "Symfony Process Component", "homepage": "https://symfony.com", - "time": "2019-01-02T21:24:08+00:00" + "time": "2019-01-16T13:27:11+00:00" }, { "name": "symfony/var-dumper", - "version": "v3.4.21", + "version": "v3.4.22", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "a5f39641bb62e8b74e343467b145331273f615a2" + "reference": "2159335b452d929cbb9921fc4eb7d1bfed32d0be" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/a5f39641bb62e8b74e343467b145331273f615a2", - "reference": "a5f39641bb62e8b74e343467b145331273f615a2", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/2159335b452d929cbb9921fc4eb7d1bfed32d0be", + "reference": "2159335b452d929cbb9921fc4eb7d1bfed32d0be", "shasum": "" }, "require": { @@ -1903,20 +1906,20 @@ "debug", "dump" ], - "time": "2019-01-01T13:45:19+00:00" + "time": "2019-01-29T16:19:17+00:00" }, { "name": "symfony/yaml", - "version": "v3.4.21", + "version": "v3.4.22", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "554a59a1ccbaac238a89b19c8e551a556fd0e2ea" + "reference": "ba11776e9e6c15ad5759a07bffb15899bac75c2d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/554a59a1ccbaac238a89b19c8e551a556fd0e2ea", - "reference": "554a59a1ccbaac238a89b19c8e551a556fd0e2ea", + "url": "https://api.github.com/repos/symfony/yaml/zipball/ba11776e9e6c15ad5759a07bffb15899bac75c2d", + "reference": "ba11776e9e6c15ad5759a07bffb15899bac75c2d", "shasum": "" }, "require": { @@ -1962,7 +1965,7 @@ ], "description": "Symfony Yaml Component", "homepage": "https://symfony.com", - "time": "2019-01-01T13:45:19+00:00" + "time": "2019-01-16T10:59:17+00:00" } ], "packages-dev": [ @@ -2101,16 +2104,16 @@ }, { "name": "behat/gherkin", - "version": "v4.5.1", + "version": "v4.6.0", "source": { "type": "git", "url": "https://github.com/Behat/Gherkin.git", - "reference": "74ac03d52c5e23ad8abd5c5cce4ab0e8dc1b530a" + "reference": "ab0a02ea14893860bca00f225f5621d351a3ad07" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Behat/Gherkin/zipball/74ac03d52c5e23ad8abd5c5cce4ab0e8dc1b530a", - "reference": "74ac03d52c5e23ad8abd5c5cce4ab0e8dc1b530a", + "url": "https://api.github.com/repos/Behat/Gherkin/zipball/ab0a02ea14893860bca00f225f5621d351a3ad07", + "reference": "ab0a02ea14893860bca00f225f5621d351a3ad07", "shasum": "" }, "require": { @@ -2118,8 +2121,8 @@ }, "require-dev": { "phpunit/phpunit": "~4.5|~5", - "symfony/phpunit-bridge": "~2.7|~3", - "symfony/yaml": "~2.3|~3" + "symfony/phpunit-bridge": "~2.7|~3|~4", + "symfony/yaml": "~2.3|~3|~4" }, "suggest": { "symfony/yaml": "If you want to parse features, represented in YAML files" @@ -2156,7 +2159,7 @@ "gherkin", "parser" ], - "time": "2017-08-30T11:04:43+00:00" + "time": "2019-01-16T14:22:17+00:00" }, { "name": "behat/transliterator", @@ -3516,16 +3519,16 @@ }, { "name": "symfony/class-loader", - "version": "v3.4.21", + "version": "v3.4.22", "source": { "type": "git", "url": "https://github.com/symfony/class-loader.git", - "reference": "4513348012c25148f8cbc3a7761a1d1e60ca3e87" + "reference": "4459eef5298dedfb69f771186a580062b8516497" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/class-loader/zipball/4513348012c25148f8cbc3a7761a1d1e60ca3e87", - "reference": "4513348012c25148f8cbc3a7761a1d1e60ca3e87", + "url": "https://api.github.com/repos/symfony/class-loader/zipball/4459eef5298dedfb69f771186a580062b8516497", + "reference": "4459eef5298dedfb69f771186a580062b8516497", "shasum": "" }, "require": { @@ -3568,20 +3571,20 @@ ], "description": "Symfony ClassLoader Component", "homepage": "https://symfony.com", - "time": "2019-01-01T13:45:19+00:00" + "time": "2019-01-16T09:39:14+00:00" }, { "name": "symfony/config", - "version": "v3.4.21", + "version": "v3.4.22", "source": { "type": "git", "url": "https://github.com/symfony/config.git", - "reference": "17c5d8941eb75a03d19bc76a43757738632d87b3" + "reference": "c9bc510c217075d42d4a927e285917d0c2001cf4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/config/zipball/17c5d8941eb75a03d19bc76a43757738632d87b3", - "reference": "17c5d8941eb75a03d19bc76a43757738632d87b3", + "url": "https://api.github.com/repos/symfony/config/zipball/c9bc510c217075d42d4a927e285917d0c2001cf4", + "reference": "c9bc510c217075d42d4a927e285917d0c2001cf4", "shasum": "" }, "require": { @@ -3632,20 +3635,20 @@ ], "description": "Symfony Config Component", "homepage": "https://symfony.com", - "time": "2019-01-01T13:45:19+00:00" + "time": "2019-01-30T11:33:42+00:00" }, { "name": "symfony/dependency-injection", - "version": "v3.4.21", + "version": "v3.4.22", "source": { "type": "git", "url": "https://github.com/symfony/dependency-injection.git", - "reference": "928a38b18bd632d67acbca74d0b2eed09915e83e" + "reference": "b514f5b765cf3e4a56e9d8ebacf14b117f7a0ee1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/928a38b18bd632d67acbca74d0b2eed09915e83e", - "reference": "928a38b18bd632d67acbca74d0b2eed09915e83e", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/b514f5b765cf3e4a56e9d8ebacf14b117f7a0ee1", + "reference": "b514f5b765cf3e4a56e9d8ebacf14b117f7a0ee1", "shasum": "" }, "require": { @@ -3703,20 +3706,20 @@ ], "description": "Symfony DependencyInjection Component", "homepage": "https://symfony.com", - "time": "2019-01-05T12:26:58+00:00" + "time": "2019-01-30T17:48:51+00:00" }, { "name": "symfony/stopwatch", - "version": "v3.4.21", + "version": "v3.4.22", "source": { "type": "git", "url": "https://github.com/symfony/stopwatch.git", - "reference": "af55d31cb58c5452d2c160655fa1968b872a8084" + "reference": "2a651c2645c10bbedd21170771f122d935e0dd58" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/stopwatch/zipball/af55d31cb58c5452d2c160655fa1968b872a8084", - "reference": "af55d31cb58c5452d2c160655fa1968b872a8084", + "url": "https://api.github.com/repos/symfony/stopwatch/zipball/2a651c2645c10bbedd21170771f122d935e0dd58", + "reference": "2a651c2645c10bbedd21170771f122d935e0dd58", "shasum": "" }, "require": { @@ -3752,20 +3755,20 @@ ], "description": "Symfony Stopwatch Component", "homepage": "https://symfony.com", - "time": "2019-01-01T13:45:19+00:00" + "time": "2019-01-16T09:39:14+00:00" }, { "name": "symfony/translation", - "version": "v3.4.21", + "version": "v3.4.22", "source": { "type": "git", "url": "https://github.com/symfony/translation.git", - "reference": "5f357063f4907cef47e5cf82fa3187fbfb700456" + "reference": "81cfcd6935cb7505640153576c1f9155b2a179c1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation/zipball/5f357063f4907cef47e5cf82fa3187fbfb700456", - "reference": "5f357063f4907cef47e5cf82fa3187fbfb700456", + "url": "https://api.github.com/repos/symfony/translation/zipball/81cfcd6935cb7505640153576c1f9155b2a179c1", + "reference": "81cfcd6935cb7505640153576c1f9155b2a179c1", "shasum": "" }, "require": { @@ -3820,7 +3823,7 @@ ], "description": "Symfony Translation Component", "homepage": "https://symfony.com", - "time": "2019-01-01T13:45:19+00:00" + "time": "2019-01-25T10:00:44+00:00" }, { "name": "theseer/fdomdocument", @@ -3915,7 +3918,7 @@ } ], "aliases": [], - "minimum-stability": "dev", + "minimum-stability": "stable", "stability-flags": [], "prefer-stable": true, "prefer-lowest": false, diff --git a/src/Commands/Remote/DrushCommand.php b/src/Commands/Remote/DrushCommand.php index d1feab0d3..90cabed1c 100755 --- a/src/Commands/Remote/DrushCommand.php +++ b/src/Commands/Remote/DrushCommand.php @@ -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 . -- Runs the Drush command remotely on 's environment. + * @usage . --progress -- 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); } } diff --git a/src/Commands/Remote/SSHBaseCommand.php b/src/Commands/Remote/SSHBaseCommand.php index edd2fc588..0b08a037d 100755 --- a/src/Commands/Remote/SSHBaseCommand.php +++ b/src/Commands/Remote/SSHBaseCommand.php @@ -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; /** @@ -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 @@ -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 * @@ -84,7 +104,8 @@ protected function sendCommandViaSsh($command) } return $this->getContainer()->get(LocalMachineHelper::class)->execute( $ssh_command, - $this->getOutputCallback() + $this->getOutputCallback(), + $this->progressAllowed ); } @@ -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) { diff --git a/src/Commands/Remote/WPCommand.php b/src/Commands/Remote/WPCommand.php index 7a6102ede..0e95d348a 100755 --- a/src/Commands/Remote/WPCommand.php +++ b/src/Commands/Remote/WPCommand.php @@ -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 . -- Runs the WP-CLI command remotely on 's environment. + * @usage . --progress -- 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); } } diff --git a/src/Helpers/LocalMachineHelper.php b/src/Helpers/LocalMachineHelper.php index 853df4698..3f434ccb4 100644 --- a/src/Helpers/LocalMachineHelper.php +++ b/src/Helpers/LocalMachineHelper.php @@ -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; @@ -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(); @@ -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(),]; } diff --git a/tests/unit_tests/Helpers/LocalMachineHelperTest.php b/tests/unit_tests/Helpers/LocalMachineHelperTest.php index 67fe6caa4..71c02dfba 100644 --- a/tests/unit_tests/Helpers/LocalMachineHelperTest.php +++ b/tests/unit_tests/Helpers/LocalMachineHelperTest.php @@ -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']); }