diff --git a/src/Transport/KubectlTransport.php b/src/Transport/KubectlTransport.php index 988a12f..195d9da 100644 --- a/src/Transport/KubectlTransport.php +++ b/src/Transport/KubectlTransport.php @@ -4,6 +4,7 @@ use Consolidation\SiteProcess\SiteProcess; use Consolidation\SiteAlias\SiteAliasInterface; +use Consolidation\SiteProcess\Util\Escape; use Consolidation\SiteProcess\Util\Shell; /** @@ -15,6 +16,9 @@ class KubectlTransport implements TransportInterface /** @var bool */ protected $tty; + /** @var string */ + protected $cd_remote; + /** @var \Consolidation\SiteAlias\SiteAliasInterface */ protected $siteAlias; @@ -64,6 +68,21 @@ public function wrap($args) $transport = is_array($entrypoint) ? [...$transport, ...$entrypoint] : [...$transport, $entrypoint]; } + if ($this->cd_remote) { + // Wrap the command in a subshell, to be able to prepend a `cd`. + $args = [ + 'sh', + '-c', + // Escape each argument for the target system and then join. + implode(' ', Escape::argsForSite($this->siteAlias, [ + 'cd', + $this->cd_remote, + Shell::op('&&'), + ...$args + ])) + ]; + } + return array_merge($transport, $args); } @@ -72,13 +91,13 @@ public function wrap($args) */ public function addChdir($cd_remote, $args) { - return array_merge( - [ - 'cd', - $cd_remote, - Shell::op('&&'), - ], - $args - ); + // If the site alias specifies a root, and it matches the requested + // directory, there is no need to wrap the command in a subshell. + if ($cd_remote === $this->siteAlias->get('root') && $this->siteAlias->get('kubectl.cd_root') === false) { + return $args; + } + + $this->cd_remote = $cd_remote; + return $args; } } diff --git a/tests/Transport/KubectlTransportTest.php b/tests/Transport/KubectlTransportTest.php index 628acc5..0cbc5ba 100644 --- a/tests/Transport/KubectlTransportTest.php +++ b/tests/Transport/KubectlTransportTest.php @@ -100,6 +100,37 @@ public function wrapTestValues() ] ], ], + + // With root. + [ + "kubectl --namespace=vv exec --tty=false --stdin=false deploy/drupal -- sh -c 'cd /path/to/drupal && ls'", + ['ls'], + [ + 'root' => '/path/to/drupal', + 'kubectl' => [ + 'tty' => false, + 'interactive' => false, + 'namespace' => 'vv', + 'resource' => 'deploy/drupal', + ] + ], + ], + + // With root and cd_root set to false. + [ + 'kubectl --namespace=vv exec --tty=false --stdin=false deploy/drupal -- ls', + ['ls'], + [ + 'root' => '/path/to/drupal', + 'kubectl' => [ + 'tty' => false, + 'interactive' => false, + 'namespace' => 'vv', + 'resource' => 'deploy/drupal', + 'cd_root' => false, + ] + ], + ], ]; } @@ -110,6 +141,9 @@ public function testWrap($expected, $args, $siteAliasData) { $siteAlias = new SiteAlias($siteAliasData, '@alias.dev'); $dockerTransport = new KubectlTransport($siteAlias); + if (isset($siteAliasData['root'])) { + $dockerTransport->addChdir($siteAliasData['root']); + } $actual = $dockerTransport->wrap($args); $this->assertEquals($expected, implode(' ', $actual)); }