Files
icehrm/lib/composer/vendor/consolidation/robo/src/Common/ExecCommand.php
2017-09-03 20:39:22 +02:00

198 lines
4.6 KiB
PHP

<?php
namespace Robo\Common;
use Robo\Result;
use Symfony\Component\Process\ExecutableFinder;
use Symfony\Component\Process\Process;
/**
* This task is supposed to be executed as shell command.
* You can specify working directory and if output is printed.
*/
trait ExecCommand
{
/**
* @var bool
*/
protected $isPrinted = true;
/**
* @var string
*/
protected $workingDirectory;
/**
* @var \Robo\Common\TimeKeeper
*/
protected $execTimer;
/**
* @return \Robo\Common\TimeKeeper
*/
protected function getExecTimer()
{
if (!isset($this->execTimer)) {
$this->execTimer = new TimeKeeper();
}
return $this->execTimer;
}
/**
* Is command printing its output to screen
*
* @return bool
*/
public function getPrinted()
{
return $this->isPrinted;
}
/**
* Changes working directory of command
*
* @param string $dir
*
* @return $this
*/
public function dir($dir)
{
$this->workingDirectory = $dir;
return $this;
}
/**
* Should command output be printed
*
* @param bool $arg
*
* @return $this
*/
public function printed($arg)
{
if (is_bool($arg)) {
$this->isPrinted = $arg;
}
return $this;
}
/**
* Look for a "{$cmd}.phar" in the current working
* directory; return a string to exec it if it is
* found. Otherwise, look for an executable command
* of the same name via findExecutable.
*
* @param string $cmd
*
* @return bool|string
*/
protected function findExecutablePhar($cmd)
{
if (file_exists("{$cmd}.phar")) {
return "php {$cmd}.phar";
}
return $this->findExecutable($cmd);
}
/**
* Return the best path to the executable program
* with the provided name. Favor vendor/bin in the
* current project. If not found there, use
* whatever is on the $PATH.
*
* @param string $cmd
*
* @return bool|string
*/
protected function findExecutable($cmd)
{
$pathToCmd = $this->searchForExecutable($cmd);
if ($pathToCmd) {
return $this->useCallOnWindows($pathToCmd);
}
return false;
}
/**
* @param string $cmd
*
* @return string
*/
private function searchForExecutable($cmd)
{
$projectBin = $this->findProjectBin();
$localComposerInstallation = $projectBin . DIRECTORY_SEPARATOR . $cmd;
if (file_exists($localComposerInstallation)) {
return $localComposerInstallation;
}
$finder = new ExecutableFinder();
return $finder->find($cmd, null, []);
}
/**
* @return bool|string
*/
protected function findProjectBin()
{
$candidates = [ __DIR__ . '/../../vendor/bin', __DIR__ . '/../../bin' ];
// If this project is inside a vendor directory, give highest priority
// to that directory.
$vendorDirContainingUs = realpath(__DIR__ . '/../../../..');
if (is_dir($vendorDirContainingUs) && (basename($vendorDirContainingUs) == 'vendor')) {
array_unshift($candidates, $vendorDirContainingUs . '/bin');
}
foreach ($candidates as $dir) {
if (is_dir("$dir")) {
return realpath($dir);
}
}
return false;
}
/**
* Wrap Windows executables in 'call' per 7a88757d
*
* @param string $cmd
*
* @return string
*/
protected function useCallOnWindows($cmd)
{
if (defined('PHP_WINDOWS_VERSION_BUILD')) {
if (file_exists("{$cmd}.bat")) {
$cmd = "{$cmd}.bat";
}
return "call $cmd";
}
return $cmd;
}
/**
* @param string $command
*
* @return \Robo\Result
*/
protected function executeCommand($command)
{
$process = new Process($command);
$process->setTimeout(null);
if ($this->workingDirectory) {
$process->setWorkingDirectory($this->workingDirectory);
}
$this->getExecTimer()->start();
if ($this->isPrinted) {
$process->run(function ($type, $buffer) {
print $buffer;
});
} else {
$process->run();
}
$this->getExecTimer()->stop();
return new Result($this, $process->getExitCode(), $process->getOutput(), ['time' => $this->getExecTimer()->elapsed()]);
}
}