1
0
Fork 0

Convert static Process into an executor that can be injected

pull/219/merge
Jordi Boggiano 2012-01-18 08:56:35 +01:00
parent e4dbee2648
commit e218b811e0
9 changed files with 91 additions and 50 deletions

View File

@ -13,13 +13,20 @@
namespace Composer\Downloader; namespace Composer\Downloader;
use Composer\Package\PackageInterface; use Composer\Package\PackageInterface;
use Composer\Util\Process; use Composer\Util\ProcessExecutor;
/** /**
* @author Jordi Boggiano <j.boggiano@seld.be> * @author Jordi Boggiano <j.boggiano@seld.be>
*/ */
class GitDownloader implements DownloaderInterface class GitDownloader implements DownloaderInterface
{ {
protected $process;
public function __construct(ProcessExecutor $process = null)
{
$this->process = $process ?: new ProcessExecutor;
}
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@ -39,7 +46,7 @@ class GitDownloader implements DownloaderInterface
$url = escapeshellarg($package->getSourceUrl()); $url = escapeshellarg($package->getSourceUrl());
$ref = escapeshellarg($package->getSourceReference()); $ref = escapeshellarg($package->getSourceReference());
Process::execute(sprintf('git clone %s %s && cd %2$s && git checkout %3$s && git reset --hard %3$s', $url, $path, $ref)); $this->process->execute(sprintf('git clone %s %s && cd %2$s && git checkout %3$s && git reset --hard %3$s', $url, $path, $ref));
} }
/** /**
@ -52,7 +59,7 @@ class GitDownloader implements DownloaderInterface
} }
$this->enforceCleanDirectory($path); $this->enforceCleanDirectory($path);
Process::execute(sprintf('cd %s && git fetch && git checkout %2$s && git reset --hard %2$s', $path, $target->getSourceReference())); $this->process->execute(sprintf('cd %s && git fetch && git checkout %2$s && git reset --hard %2$s', $path, $target->getSourceReference()));
} }
/** /**
@ -67,7 +74,7 @@ class GitDownloader implements DownloaderInterface
private function enforceCleanDirectory($path) private function enforceCleanDirectory($path)
{ {
Process::execute(sprintf('cd %s && git status --porcelain', $path),$output); $this->process->execute(sprintf('cd %s && git status --porcelain', $path),$output);
if (implode('', $output)) { if (implode('', $output)) {
throw new \RuntimeException('Source directory has uncommitted changes'); throw new \RuntimeException('Source directory has uncommitted changes');
} }

View File

@ -13,13 +13,20 @@
namespace Composer\Downloader; namespace Composer\Downloader;
use Composer\Package\PackageInterface; use Composer\Package\PackageInterface;
use Composer\Util\Process; use Composer\Util\ProcessExecutor;
/** /**
* @author Per Bernhardt <plb@webfactory.de> * @author Per Bernhardt <plb@webfactory.de>
*/ */
class HgDownloader implements DownloaderInterface class HgDownloader implements DownloaderInterface
{ {
protected $process;
public function __construct(ProcessExecutor $process = null)
{
$this->process = $process ?: new ProcessExecutor;
}
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@ -39,7 +46,7 @@ class HgDownloader implements DownloaderInterface
$url = escapeshellarg($package->getSourceUrl()); $url = escapeshellarg($package->getSourceUrl());
$ref = escapeshellarg($package->getSourceReference()); $ref = escapeshellarg($package->getSourceReference());
Process::execute(sprintf('(hg clone %s %s 2> /dev/null) && cd %2$s && hg up %s', $url, $path, $ref)); $this->process->execute(sprintf('(hg clone %s %s 2> /dev/null) && cd %2$s && hg up %s', $url, $path, $ref));
} }
/** /**
@ -52,7 +59,7 @@ class HgDownloader implements DownloaderInterface
} }
$this->enforceCleanDirectory($path); $this->enforceCleanDirectory($path);
Process::execute(sprintf('cd %s && hg pull && hg up %s', $path, escapeshellarg($target->getSourceReference()))); $this->process->execute(sprintf('cd %s && hg pull && hg up %s', $path, escapeshellarg($target->getSourceReference())));
} }
/** /**
@ -67,7 +74,7 @@ class HgDownloader implements DownloaderInterface
private function enforceCleanDirectory($path) private function enforceCleanDirectory($path)
{ {
Process::execute(sprintf('cd %s && hg st', $path), $output); $this->process->execute(sprintf('cd %s && hg st', $path), $output);
if (implode('', $output)) { if (implode('', $output)) {
throw new \RuntimeException('Source directory has uncommitted changes'); throw new \RuntimeException('Source directory has uncommitted changes');
} }

View File

@ -1,15 +1,32 @@
<?php <?php
/*
* This file is part of Composer.
*
* (c) Nils Adermann <naderman@naderman.de>
* Jordi Boggiano <j.boggiano@seld.be>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Composer\Downloader; namespace Composer\Downloader;
use Composer\Package\PackageInterface; use Composer\Package\PackageInterface;
use Composer\Util\Process; use Composer\Util\ProcessExecutor;
/** /**
* @author Ben Bieker <mail@ben-bieker.de> * @author Ben Bieker <mail@ben-bieker.de>
*/ */
class SvnDownloader implements DownloaderInterface class SvnDownloader implements DownloaderInterface
{ {
protected $process;
public function __construct(ProcessExecutor $process = null)
{
$this->process = $process ?: new ProcessExecutor;
}
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@ -29,7 +46,7 @@ class SvnDownloader implements DownloaderInterface
$url = escapeshellarg($package->getSourceUrl()); $url = escapeshellarg($package->getSourceUrl());
$ref = escapeshellarg($package->getSourceReference()); $ref = escapeshellarg($package->getSourceReference());
Process::execute(sprintf('svn co %s/%s %s', $url, $ref, $path)); $this->process->execute(sprintf('svn co %s/%s %s', $url, $ref, $path));
} }
/** /**
@ -43,7 +60,7 @@ class SvnDownloader implements DownloaderInterface
$url = escapeshellarg($target->getSourceUrl()); $url = escapeshellarg($target->getSourceUrl());
$ref = escapeshellarg($target->getSourceReference()); $ref = escapeshellarg($target->getSourceReference());
Process::execute(sprintf('cd %s && svn switch %s/%s', $path, $url, $ref)); $this->process->execute(sprintf('cd %s && svn switch %s/%s', $path, $url, $ref));
} }
/** /**

View File

@ -12,7 +12,7 @@
namespace Composer\Downloader\Util; namespace Composer\Downloader\Util;
use Composer\Util\Process; use Composer\Util\ProcessExecutor;
/** /**
* @author Jordi Boggiano <j.boggiano@seld.be> * @author Jordi Boggiano <j.boggiano@seld.be>
@ -22,10 +22,12 @@ class Filesystem
public function removeDirectory($directory) public function removeDirectory($directory)
{ {
if (defined('PHP_WINDOWS_VERSION_BUILD')) { if (defined('PHP_WINDOWS_VERSION_BUILD')) {
Process::execute(sprintf('rmdir /S /Q %s', escapeshellarg(realpath($directory)))); $cmd = sprintf('rmdir /S /Q %s', escapeshellarg(realpath($directory)));
} else { } else {
Process::execute(sprintf('rm -rf %s', escapeshellarg($directory))); $cmd = sprintf('rm -rf %s', escapeshellarg($directory));
} }
return $this->getProcess()->execute($cmd) === 0;
} }
public function ensureDirectoryExists($directory) public function ensureDirectoryExists($directory)
@ -127,4 +129,9 @@ class Filesystem
{ {
return substr($path, 0, 1) === '/' || substr($path, 1, 1) === ':'; return substr($path, 0, 1) === '/' || substr($path, 1, 1) === ':';
} }
protected function getProcess()
{
return new ProcessExecutor;
}
} }

View File

@ -3,7 +3,7 @@
namespace Composer\Repository\Vcs; namespace Composer\Repository\Vcs;
use Composer\Json\JsonFile; use Composer\Json\JsonFile;
use Composer\Util\Process; use Composer\Util\ProcessExecutor;
use Composer\IO\IOInterface; use Composer\IO\IOInterface;
/** /**
@ -16,11 +16,11 @@ class GitDriver extends VcsDriver implements VcsDriverInterface
protected $rootIdentifier; protected $rootIdentifier;
protected $infoCache = array(); protected $infoCache = array();
public function __construct($url, IOInterface $io) public function __construct($url, IOInterface $io, ProcessExecutor $process = null)
{ {
$this->tmpDir = sys_get_temp_dir() . '/composer-' . preg_replace('{[^a-z0-9]}i', '-', $url) . '/'; $this->tmpDir = sys_get_temp_dir() . '/composer-' . preg_replace('{[^a-z0-9]}i', '-', $url) . '/';
parent::__construct($url, $io); parent::__construct($url, $io, $process);
} }
/** /**
@ -31,9 +31,9 @@ class GitDriver extends VcsDriver implements VcsDriverInterface
$url = escapeshellarg($this->url); $url = escapeshellarg($this->url);
$tmpDir = escapeshellarg($this->tmpDir); $tmpDir = escapeshellarg($this->tmpDir);
if (is_dir($this->tmpDir)) { if (is_dir($this->tmpDir)) {
Process::execute(sprintf('cd %s && git fetch origin', $tmpDir), $output); $this->process->execute(sprintf('cd %s && git fetch origin', $tmpDir), $output);
} else { } else {
Process::execute(sprintf('git clone %s %s', $url, $tmpDir), $output); $this->process->execute(sprintf('git clone %s %s', $url, $tmpDir), $output);
} }
$this->getTags(); $this->getTags();
@ -47,7 +47,7 @@ class GitDriver extends VcsDriver implements VcsDriverInterface
{ {
if (null === $this->rootIdentifier) { if (null === $this->rootIdentifier) {
$this->rootIdentifier = 'master'; $this->rootIdentifier = 'master';
Process::execute(sprintf('cd %s && git branch --no-color -r', escapeshellarg($this->tmpDir)), $output); $this->process->execute(sprintf('cd %s && git branch --no-color -r', escapeshellarg($this->tmpDir)), $output);
foreach ($output as $branch) { foreach ($output as $branch) {
if ($branch && preg_match('{/HEAD +-> +[^/]+/(\S+)}', $branch, $match)) { if ($branch && preg_match('{/HEAD +-> +[^/]+/(\S+)}', $branch, $match)) {
$this->rootIdentifier = $match[1]; $this->rootIdentifier = $match[1];
@ -91,7 +91,7 @@ class GitDriver extends VcsDriver implements VcsDriverInterface
public function getComposerInformation($identifier) public function getComposerInformation($identifier)
{ {
if (!isset($this->infoCache[$identifier])) { if (!isset($this->infoCache[$identifier])) {
Process::execute(sprintf('cd %s && git show %s:composer.json', escapeshellarg($this->tmpDir), escapeshellarg($identifier)), $output); $this->process->execute(sprintf('cd %s && git show %s:composer.json', escapeshellarg($this->tmpDir), escapeshellarg($identifier)), $output);
$composer = implode("\n", $output); $composer = implode("\n", $output);
unset($output); unset($output);
@ -102,7 +102,7 @@ class GitDriver extends VcsDriver implements VcsDriverInterface
$composer = JsonFile::parseJson($composer); $composer = JsonFile::parseJson($composer);
if (!isset($composer['time'])) { if (!isset($composer['time'])) {
Process::execute(sprintf('cd %s && git log -1 --format=%%at %s', escapeshellarg($this->tmpDir), escapeshellarg($identifier)), $output); $this->process->execute(sprintf('cd %s && git log -1 --format=%%at %s', escapeshellarg($this->tmpDir), escapeshellarg($identifier)), $output);
$date = new \DateTime('@'.$output[0]); $date = new \DateTime('@'.$output[0]);
$composer['time'] = $date->format('Y-m-d H:i:s'); $composer['time'] = $date->format('Y-m-d H:i:s');
} }
@ -118,7 +118,7 @@ class GitDriver extends VcsDriver implements VcsDriverInterface
public function getTags() public function getTags()
{ {
if (null === $this->tags) { if (null === $this->tags) {
Process::execute(sprintf('cd %s && git tag', escapeshellarg($this->tmpDir)), $output); $this->process->execute(sprintf('cd %s && git tag', escapeshellarg($this->tmpDir)), $output);
$this->tags = $output ? array_combine($output, $output) : array(); $this->tags = $output ? array_combine($output, $output) : array();
} }
@ -133,7 +133,7 @@ class GitDriver extends VcsDriver implements VcsDriverInterface
if (null === $this->branches) { if (null === $this->branches) {
$branches = array(); $branches = array();
Process::execute(sprintf('cd %s && git branch --no-color -rv', escapeshellarg($this->tmpDir)), $output); $this->process->execute(sprintf('cd %s && git branch --no-color -rv', escapeshellarg($this->tmpDir)), $output);
foreach ($output as $branch) { foreach ($output as $branch) {
if ($branch && !preg_match('{^ *[^/]+/HEAD }', $branch)) { if ($branch && !preg_match('{^ *[^/]+/HEAD }', $branch)) {
preg_match('{^ *[^/]+/(\S+) *([a-f0-9]+) .*$}', $branch, $match); preg_match('{^ *[^/]+/(\S+) *([a-f0-9]+) .*$}', $branch, $match);

View File

@ -13,7 +13,7 @@
namespace Composer\Repository\Vcs; namespace Composer\Repository\Vcs;
use Composer\Json\JsonFile; use Composer\Json\JsonFile;
use Composer\Util\Process; use Composer\Util\ProcessExecutor;
use Composer\IO\IOInterface; use Composer\IO\IOInterface;
/** /**
@ -26,11 +26,11 @@ class HgDriver extends VcsDriver implements VcsDriverInterface
protected $rootIdentifier; protected $rootIdentifier;
protected $infoCache = array(); protected $infoCache = array();
public function __construct($url, IOInterface $io) public function __construct($url, IOInterface $io, ProcessExecutor $process = null)
{ {
$this->tmpDir = sys_get_temp_dir() . '/composer-' . preg_replace('{[^a-z0-9]}i', '-', $url) . '/'; $this->tmpDir = sys_get_temp_dir() . '/composer-' . preg_replace('{[^a-z0-9]}i', '-', $url) . '/';
parent::__construct($url, $io); parent::__construct($url, $io, $process);
} }
/** /**
@ -41,9 +41,9 @@ class HgDriver extends VcsDriver implements VcsDriverInterface
$url = escapeshellarg($this->url); $url = escapeshellarg($this->url);
$tmpDir = escapeshellarg($this->tmpDir); $tmpDir = escapeshellarg($this->tmpDir);
if (is_dir($this->tmpDir)) { if (is_dir($this->tmpDir)) {
Process::execute(sprintf('cd %s && hg pull -u', $tmpDir), $output); $this->process->execute(sprintf('cd %s && hg pull -u', $tmpDir), $output);
} else { } else {
Process::execute(sprintf('cd %s && hg clone %s %s', escapeshellarg(sys_get_temp_dir()), $url, $tmpDir), $output); $this->process->execute(sprintf('cd %s && hg clone %s %s', escapeshellarg(sys_get_temp_dir()), $url, $tmpDir), $output);
} }
$this->getTags(); $this->getTags();
@ -57,7 +57,7 @@ class HgDriver extends VcsDriver implements VcsDriverInterface
{ {
$tmpDir = escapeshellarg($this->tmpDir); $tmpDir = escapeshellarg($this->tmpDir);
if (null === $this->rootIdentifier) { if (null === $this->rootIdentifier) {
Process::execute(sprintf('cd %s && hg tip --template "{node}"', $tmpDir), $output); $this->process->execute(sprintf('cd %s && hg tip --template "{node}"', $tmpDir), $output);
$this->rootIdentifier = $output[0]; $this->rootIdentifier = $output[0];
} }
@ -96,7 +96,7 @@ class HgDriver extends VcsDriver implements VcsDriverInterface
public function getComposerInformation($identifier) public function getComposerInformation($identifier)
{ {
if (!isset($this->infoCache[$identifier])) { if (!isset($this->infoCache[$identifier])) {
Process::execute(sprintf('cd %s && hg cat -r %s composer.json', escapeshellarg($this->tmpDir), escapeshellarg($identifier)), $output); $this->process->execute(sprintf('cd %s && hg cat -r %s composer.json', escapeshellarg($this->tmpDir), escapeshellarg($identifier)), $output);
$composer = implode("\n", $output); $composer = implode("\n", $output);
unset($output); unset($output);
@ -107,7 +107,7 @@ class HgDriver extends VcsDriver implements VcsDriverInterface
$composer = JsonFile::parseJson($composer); $composer = JsonFile::parseJson($composer);
if (!isset($composer['time'])) { if (!isset($composer['time'])) {
Process::execute(sprintf('cd %s && hg log --template "{date|rfc822date}" -r %s', escapeshellarg($this->tmpDir), escapeshellarg($identifier)), $output); $this->process->execute(sprintf('cd %s && hg log --template "{date|rfc822date}" -r %s', escapeshellarg($this->tmpDir), escapeshellarg($identifier)), $output);
$date = new \DateTime($output[0]); $date = new \DateTime($output[0]);
$composer['time'] = $date->format('Y-m-d H:i:s'); $composer['time'] = $date->format('Y-m-d H:i:s');
} }
@ -125,7 +125,7 @@ class HgDriver extends VcsDriver implements VcsDriverInterface
if (null === $this->tags) { if (null === $this->tags) {
$tags = array(); $tags = array();
Process::execute(sprintf('cd %s && hg tags', escapeshellarg($this->tmpDir)), $output); $this->process->execute(sprintf('cd %s && hg tags', escapeshellarg($this->tmpDir)), $output);
foreach ($output as $tag) { foreach ($output as $tag) {
if (preg_match('(^([^\s]+)\s+\d+:(.*)$)', $tag, $match)) if (preg_match('(^([^\s]+)\s+\d+:(.*)$)', $tag, $match))
$tags[$match[1]] = $match[2]; $tags[$match[1]] = $match[2];
@ -145,7 +145,7 @@ class HgDriver extends VcsDriver implements VcsDriverInterface
if (null === $this->branches) { if (null === $this->branches) {
$branches = array(); $branches = array();
Process::execute(sprintf('cd %s && hg branches', escapeshellarg($this->tmpDir)), $output); $this->process->execute(sprintf('cd %s && hg branches', escapeshellarg($this->tmpDir)), $output);
foreach ($output as $branch) { foreach ($output as $branch) {
if (preg_match('(^([^\s]+)\s+\d+:(.*)$)', $branch, $match)) if (preg_match('(^([^\s]+)\s+\d+:(.*)$)', $branch, $match))
$branches[$match[1]] = $match[2]; $branches[$match[1]] = $match[2];
@ -184,7 +184,7 @@ class HgDriver extends VcsDriver implements VcsDriverInterface
return false; return false;
} }
$exit = Process::execute(sprintf('cd %s && hg identify %s', escapeshellarg(sys_get_temp_dir()), escapeshellarg($url)), $ignored); $exit = $this->process->execute(sprintf('cd %s && hg identify %s', escapeshellarg(sys_get_temp_dir()), escapeshellarg($url)), $ignored);
return $exit === 0; return $exit === 0;
} }
} }

View File

@ -3,7 +3,7 @@
namespace Composer\Repository\Vcs; namespace Composer\Repository\Vcs;
use Composer\Json\JsonFile; use Composer\Json\JsonFile;
use Composer\Util\Process; use Composer\Util\ProcessExecutor;
use Composer\IO\IOInterface; use Composer\IO\IOInterface;
/** /**
@ -16,9 +16,9 @@ class SvnDriver extends VcsDriver implements VcsDriverInterface
protected $branches; protected $branches;
protected $infoCache = array(); protected $infoCache = array();
public function __construct($url, IOInterface $io) public function __construct($url, IOInterface $io, ProcessExecutor $process = null)
{ {
parent::__construct($this->baseUrl = rtrim($url, '/'), $io); parent::__construct($this->baseUrl = rtrim($url, '/'), $io, $process);
if (false !== ($pos = strrpos($url, '/trunk'))) { if (false !== ($pos = strrpos($url, '/trunk'))) {
$this->baseUrl = substr($url, 0, $pos); $this->baseUrl = substr($url, 0, $pos);
@ -80,7 +80,7 @@ class SvnDriver extends VcsDriver implements VcsDriverInterface
$rev = ''; $rev = '';
} }
Process::execute(sprintf('svn cat --non-interactive %s', escapeshellarg($this->baseUrl.$identifier.'composer.json'.$rev)),$output); $this->process->execute(sprintf('svn cat --non-interactive %s', escapeshellarg($this->baseUrl.$identifier.'composer.json'.$rev)),$output);
$composer = implode("\n", $output); $composer = implode("\n", $output);
unset($output); unset($output);
@ -91,7 +91,7 @@ class SvnDriver extends VcsDriver implements VcsDriverInterface
$composer = JsonFile::parseJson($composer); $composer = JsonFile::parseJson($composer);
if (!isset($composer['time'])) { if (!isset($composer['time'])) {
Process::execute(sprintf('svn info %s', escapeshellarg($this->baseUrl.$identifier.$rev)), $output); $this->process->execute(sprintf('svn info %s', escapeshellarg($this->baseUrl.$identifier.$rev)), $output);
foreach ($output as $line) { foreach ($output as $line) {
if (preg_match('{^Last Changed Date: ([^(]+)}', $line, $match)) { if (preg_match('{^Last Changed Date: ([^(]+)}', $line, $match)) {
$date = new \DateTime($match[1]); $date = new \DateTime($match[1]);
@ -112,7 +112,7 @@ class SvnDriver extends VcsDriver implements VcsDriverInterface
public function getTags() public function getTags()
{ {
if (null === $this->tags) { if (null === $this->tags) {
Process::execute(sprintf('svn ls --non-interactive %s', escapeshellarg($this->baseUrl.'/tags')), $output); $this->process->execute(sprintf('svn ls --non-interactive %s', escapeshellarg($this->baseUrl.'/tags')), $output);
$this->tags = array(); $this->tags = array();
foreach ($output as $tag) { foreach ($output as $tag) {
$this->tags[rtrim($tag, '/')] = '/tags/'.$tag; $this->tags[rtrim($tag, '/')] = '/tags/'.$tag;
@ -128,7 +128,7 @@ class SvnDriver extends VcsDriver implements VcsDriverInterface
public function getBranches() public function getBranches()
{ {
if (null === $this->branches) { if (null === $this->branches) {
Process::execute(sprintf('svn ls --verbose --non-interactive %s', escapeshellarg($this->baseUrl.'/')), $output); $this->process->execute(sprintf('svn ls --verbose --non-interactive %s', escapeshellarg($this->baseUrl.'/')), $output);
$this->branches = array(); $this->branches = array();
foreach ($output as $line) { foreach ($output as $line) {
@ -140,7 +140,7 @@ class SvnDriver extends VcsDriver implements VcsDriverInterface
} }
unset($output); unset($output);
Process::execute(sprintf('svn ls --verbose --non-interactive %s', escapeshellarg($this->baseUrl.'/branches')), $output); $this->process->execute(sprintf('svn ls --verbose --non-interactive %s', escapeshellarg($this->baseUrl.'/branches')), $output);
foreach ($output as $line) { foreach ($output as $line) {
preg_match('{^\s*(\S+).*?(\S+)\s*$}', $line, $match); preg_match('{^\s*(\S+).*?(\S+)\s*$}', $line, $match);
if ($match[2] === './') { if ($match[2] === './') {
@ -180,7 +180,7 @@ class SvnDriver extends VcsDriver implements VcsDriverInterface
return false; return false;
} }
$exit = Process::execute(sprintf('svn info --non-interactive %s 2>/dev/null', escapeshellarg($url)), $ignored); $exit = $this->process->execute(sprintf('svn info --non-interactive %s 2>/dev/null', escapeshellarg($url)), $ignored);
return $exit === 0; return $exit === 0;
} }
} }

View File

@ -13,6 +13,7 @@
namespace Composer\Repository\Vcs; namespace Composer\Repository\Vcs;
use Composer\IO\IOInterface; use Composer\IO\IOInterface;
use Composer\Util\ProcessExecutor;
/** /**
* A driver implementation for driver with authorization interaction. * A driver implementation for driver with authorization interaction.
@ -23,6 +24,7 @@ abstract class VcsDriver
{ {
protected $url; protected $url;
protected $io; protected $io;
protected $process;
private $firstCall; private $firstCall;
private $contentUrl; private $contentUrl;
private $content; private $content;
@ -32,11 +34,13 @@ abstract class VcsDriver
* *
* @param string $url The URL * @param string $url The URL
* @param IOInterface $io The IO instance * @param IOInterface $io The IO instance
* @param ProcessExecutor $process Process instance, injectable for mocking
*/ */
public function __construct($url, IOInterface $io) public function __construct($url, IOInterface $io, ProcessExecutor $process = null)
{ {
$this->url = $url; $this->url = $url;
$this->io = $io; $this->io = $io;
$this->process = $process ?: new ProcessExecutor;
$this->firstCall = true; $this->firstCall = true;
} }

View File

@ -12,24 +12,23 @@
namespace Composer\Util; namespace Composer\Util;
use Symfony\Component\Process\Process as BaseProcess; use Symfony\Component\Process\Process;
/** /**
* @author Robert Schönthal <seroscho@googlemail.com> * @author Robert Schönthal <seroscho@googlemail.com>
*/ */
class Process extends BaseProcess class ProcessExecutor
{ {
/** /**
* runs a process on the commandline * runs a process on the commandline
* *
* @static
* @param $command the command to execute * @param $command the command to execute
* @param null $output the output will be written into this var if passed * @param null $output the output will be written into this var if passed
* @return int statuscode * @return int statuscode
*/ */
public static function execute($command, &$output = null) public function execute($command, &$output = null)
{ {
$process = new static($command); $process = new Process($command);
$process->run(function($type, $buffer) use ($output) { $process->run(function($type, $buffer) use ($output) {
if (null === $output) { if (null === $output) {
return; return;