diff --git a/CHANGELOG.md b/CHANGELOG.md index 839a8699e..5e3de19d9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ - ISPManager recipe and docs. - Symfony 5 recipe. - Command for checking if a deploy is unlocked. [#2150] [#2150] +- `runLocally` function now accepts string or a Closure as first parameter [#2170] ### Fixed - Normalize CRLF to LF new line endings. [#2111] @@ -17,6 +18,7 @@ - When symfony_env is set to dev, require-dev are not installed. [#2035] - Fixed exit status of rollback command when there are no releases to rollback to. [#2052] - When the second parameter $options passed to run() and runLocally(), use it to overwrite default env config. [#2165] +- Fixed `recipe/check_remote.php` calling `get('bin/php)` in remote host context twice [#2170] ## v6.8.0 @@ -582,7 +584,7 @@ - Fixed typo3 recipe. - Fixed remove of shared dir on first deploy. - +[#2170]: https://github.com/deployphp/deployer/issues/2170 [#2165]: https://github.com/deployphp/deployer/issues/2165 [#2150]: https://github.com/deployphp/deployer/issues/2150 [#2111]: https://github.com/deployphp/deployer/pull/2111 diff --git a/recipe/deploy/check_remote.php b/recipe/deploy/check_remote.php index 820e8865f..3528a1c95 100644 --- a/recipe/deploy/check_remote.php +++ b/recipe/deploy/check_remote.php @@ -39,7 +39,10 @@ $opt = '--heads'; } - $remoteLs = runLocally(sprintf("%s ls-remote $opt $repository $ref", get('bin/git'))); + $remoteLs = runLocally(function () use ($opt, $repository, $ref) { + $cmd = sprintf("%s ls-remote $opt $repository $ref", get('bin/git')); + return run($cmd); + }); if (strstr($remoteLs, "\n")) { throw new Exception("Could not determine target revision. '$ref' matched multiple commits."); } diff --git a/src/functions.php b/src/functions.php index de994a4ee..2cb014c21 100644 --- a/src/functions.php +++ b/src/functions.php @@ -7,6 +7,7 @@ namespace Deployer; +use Closure; use Deployer\Exception\Exception; use Deployer\Exception\GracefulShutdownException; use Deployer\Exception\RunException; @@ -339,24 +340,43 @@ function run($command, $options = []) /** * Execute commands on local machine * - * @param string $command Command to run locally. + * @param string|Closure $command Command to run locally, or a closure that will be executed in local machine context * @param array $options * @return string Output of command. */ function runLocally($command, $options = []) { - $process = Deployer::get()->processRunner; - $command = parse($command); + if ($command instanceof Closure) { + $input = Context::has() ? input() : null; + $output = Context::has() ? output() : null; - $env = array_merge_alternate(get('env', []), $options['env'] ?? []); - if (!empty($env)) { - $env = array_to_string($env); - $command = "export $env; $command"; - } + $localhostContext = new Context(new Localhost(), $input, $output); + Context::push($localhostContext); + try { + $output = $command(); + if (!is_string($output)) { + $output = ''; + } + } finally { + Context::pop(); + } + + $output = rtrim($output); + return $output; + } else { + $command = parse($command); + $env = array_merge_alternate(get('env', []), $options['env'] ?? []); - $output = $process->run(new Localhost(), $command, $options); + return runLocally(function () use ($command, $options, $env) { + if (!empty($env)) { + $env = array_to_string($env); + $command = "export $env; $command"; + } - return rtrim($output); + $output = run($command, $options); + return $output; + }); + } } /**