
| Current Path : /var/www/html/sirius-pallets/vendor/consolidation/site-process/src/ |
Linux ift1.ift-informatik.de 5.4.0-216-generic #236-Ubuntu SMP Fri Apr 11 19:53:21 UTC 2025 x86_64 |
| Current File : /var/www/html/sirius-pallets/vendor/consolidation/site-process/src/SiteProcess.php |
<?php
namespace Consolidation\SiteProcess;
use Consolidation\SiteAlias\SiteAliasInterface;
use Consolidation\SiteProcess\Transport\DockerComposeTransport;
use Consolidation\SiteProcess\Util\ArgumentProcessor;
use Consolidation\SiteProcess\Transport\LocalTransport;
use Consolidation\SiteProcess\Transport\SshTransport;
use Consolidation\SiteProcess\Transport\TransportInterface;
use Consolidation\Config\Util\Interpolator;
use Consolidation\SiteProcess\Util\Shell;
use Consolidation\SiteProcess\Util\ShellOperatorInterface;
use Consolidation\SiteProcess\Util\Escape;
use Symfony\Component\Process\Exception\ProcessFailedException;
use Symfony\Component\Process\Process;
/**
* A wrapper around Symfony Process that uses site aliases
* (https://github.com/consolidation/site-alias)
*
* - Interpolate arguments using values from the alias
* e.g. `$process = new SiteProcess($alias, ['git', '-C', '{{root}}']);`
* - Make remote calls via ssh as if they were local.
*/
class SiteProcess extends ProcessBase
{
/** @var SiteAliasInterface */
protected $siteAlias;
/** @var string[] */
protected $args;
/** @var string[] */
protected $options;
/** @var string[] */
protected $optionsPassedAsArgs;
/** @var string */
protected $cd_remote;
/** @var TransportInterface */
protected $transport;
/**
* Process arguments and options per the site alias and build the
* actual command to run.
*/
public function __construct(SiteAliasInterface $siteAlias, TransportInterface $transport, $args, $options = [], $optionsPassedAsArgs = [])
{
$this->siteAlias = $siteAlias;
$this->transport = $transport;
$this->args = $args;
$this->options = $options;
$this->optionsPassedAsArgs = $optionsPassedAsArgs;
parent::__construct([]);
}
/**
* Get a starting directory for the remote process.
*
* @return string|null
*/
public function getWorkingDirectory(): ?string
{
return $this->cd_remote;
}
/**
* Set a starting directory for the remote process.
*
* @param string $cd_remote
*
* @return \Consolidation\SiteProcess\SiteProcess
*/
public function setWorkingDirectory($cd_remote): static
{
$this->cd_remote = $cd_remote;
return $this;
}
/**
* Set a starting directory for the initial/local process.
*
* @param string $cd
*
* @return \Consolidation\SiteProcess\SiteProcess
*/
public function setWorkingDirectoryLocal($cd)
{
// Symfony 4 REQUIRES that there be a directory set, and defaults
// it to the cwd if it is not set. We will maintain that pattern here.
if (!$cd) {
$cd = getcwd();
}
return parent::setWorkingDirectory($cd);
}
/**
* Get the starting directory for the initial/local process.
*
* @return string|null;
*/
public function getWorkingDirectoryLocal()
{
return parent::getWorkingDirectory();
}
/**
*
* @param bool $shouldUseSiteRoot
* @return $this|\Symfony\Component\Process\Process
* @throws \Exception
*/
public function chdirToSiteRoot($shouldUseSiteRoot = true)
{
if (!$shouldUseSiteRoot || !$this->siteAlias->hasRoot()) {
return $this;
}
return $this->setWorkingDirectory($this->siteAlias->root());
}
/**
* Take all of our individual arguments and process them for use.
*/
protected function processArgs()
{
$transport = $this->getTransport($this->siteAlias);
$transport->configure($this);
$processor = new ArgumentProcessor();
$selectedArgs = $processor->selectArgs(
$this->siteAlias,
$this->args,
$this->options,
$this->optionsPassedAsArgs
);
// Set environment variables if needed.
if ($this->siteAlias->has('env-vars')) {
$selectedArgs = $this->addEnvVars($this->siteAlias->get('env-vars'), $selectedArgs);
}
// Ask the transport to drop in a 'cd' if needed.
if ($this->getWorkingDirectory()) {
$selectedArgs = $transport->addChdir($this->getWorkingDirectory(), $selectedArgs);
}
// Do any necessary interpolation on the selected arguments.
$processedArgs = $this->interpolate($selectedArgs);
// Wrap the command with 'ssh' or some other transport if this is
// a remote command; otherwise, leave it as-is.
return $transport->wrap($processedArgs);
}
/**
* Wrap the command/args in an env call.
* @todo Check if this needs to depend on linux/win.
* @todo Check if this needs to be delegated to transport.
*/
public function addEnvVars($envVars, $args)
{
$envArgs = ['env'];
foreach ($envVars as $key => $value) {
$envArgs[] = Escape::forSite($this->siteAlias, $key) . '='
. Escape::forSite($this->siteAlias, $value);
}
return array_merge($envArgs, $args);
}
public function setTransport($transport)
{
$this->transport = $transport;
}
/**
* Ask the transport manager for the correct transport for the
* provided alias.
*/
protected function getTransport(SiteAliasInterface $siteAlias)
{
return $this->transport;
}
/**
* @inheritDoc
*/
public function getCommandLine(): string
{
$commandLine = parent::getCommandLine();
if (empty($commandLine)) {
$processedArgs = $this->processArgs();
$commandLine = Escape::argsForSite($this->siteAlias, $processedArgs);
$commandLine = implode(' ', $commandLine);
$this->overrideCommandLine($commandLine);
}
return $commandLine;
}
/**
* @inheritDoc
*/
public function start(?callable $callback = null, array $env = []): void
{
$cmd = $this->getCommandLine();
parent::start($callback, $env);
}
public function mustRun(?callable $callback = null, array $env = []): static
{
if (0 !== $this->run($callback, $env)) {
// Be less verbose when there is nothing in stdout or stderr.
if (empty($this->getOutput()) && empty($this->getErrorOutput())) {
$this->disableOutput();
}
throw new ProcessFailedException($this);
}
return $this;
}
/**
* @inheritDoc
*/
public function wait(?callable $callback = null): int
{
$return = parent::wait($callback);
return $return;
}
/**
* interpolate examines each of the arguments in the provided argument list
* and replaces any token found therein with the value for that key as
* pulled from the given site alias.
*
* Example: "git -C {{root}} status"
*
* The token "{{root}}" will be converted to a value via $siteAlias->get('root').
* The result will replace the token.
*
* It is possible to use dot notation in the keys to access nested elements
* within the site alias record.
*
* @param SiteAliasInterface $siteAlias
* @param type $args
* @return type
*/
protected function interpolate($args)
{
$interpolator = new Interpolator();
return array_map(
function ($arg) use ($interpolator) {
if ($arg instanceof ShellOperatorInterface) {
return $arg;
}
return $interpolator->interpolate($this->siteAlias, $arg, false);
},
$args
);
}
/**
* Overrides the command line to be executed.
*
* @param string|array $commandline The command to execute
*
* @return $this
*
* @todo refactor library so this hack to get around changes in
* symfony/process 5 is unnecessary.
*/
private function overrideCommandLine($commandline)
{
$commandlineSetter = function ($commandline) {
$this->commandline = $commandline;
};
$commandlineSetter->bindTo($this, Process::class)($commandline);
return $this;
}
}