diff --git a/CHANGELOG.md b/CHANGELOG.md index 65e7018f6..6700114fc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,7 +12,7 @@ * Added --strict to the `validate` command to treat any warning as an error that then returns a non-zero exit code * Added a dependency on composer/semver, which is the externalized lib for all the version constraints parsing and handling * Added support for classmap autoloading to load plugin classes and script handlers - * Added `bin-compat` config option that if set to `full` will create .bat proxy for binaries even if Compoesr runs in a linux VM + * Added `bin-compat` config option that if set to `full` will create .bat proxy for binaries even if Composer runs in a linux VM * Added SPDX 2.0 support, and externalized that in a composer/spdx-licenses lib * Added warnings when the classmap autoloader finds duplicate classes * Added --file to the `archive` command to choose the filename diff --git a/src/Composer/Cache.php b/src/Composer/Cache.php index 8c5bce4ee..7090a8a0d 100644 --- a/src/Composer/Cache.php +++ b/src/Composer/Cache.php @@ -67,9 +67,7 @@ class Cache { $file = preg_replace('{[^'.$this->whitelist.']}i', '-', $file); if ($this->enabled && file_exists($this->root . $file)) { - if ($this->io->isDebug()) { - $this->io->writeError('Reading '.$this->root . $file.' from cache'); - } + $this->io->writeError('Reading '.$this->root . $file.' from cache', true, IOInterface::DEBUG); return file_get_contents($this->root . $file); } @@ -82,16 +80,12 @@ class Cache if ($this->enabled) { $file = preg_replace('{[^'.$this->whitelist.']}i', '-', $file); - if ($this->io->isDebug()) { - $this->io->writeError('Writing '.$this->root . $file.' into cache'); - } + $this->io->writeError('Writing '.$this->root . $file.' into cache', true, IOInterface::DEBUG); try { return file_put_contents($this->root . $file, $contents); } catch (\ErrorException $e) { - if ($this->io->isDebug()) { - $this->io->writeError('Failed to write into cache: '.$e->getMessage().''); - } + $this->io->writeError('Failed to write into cache: '.$e->getMessage().'', true, IOInterface::DEBUG); if (preg_match('{^file_put_contents\(\): Only ([0-9]+) of ([0-9]+) bytes written}', $e->getMessage(), $m)) { // Remove partial file. unlink($this->root . $file); @@ -152,9 +146,7 @@ class Cache touch($this->root . $file); } - if ($this->io->isDebug()) { - $this->io->writeError('Reading '.$this->root . $file.' from cache'); - } + $this->io->writeError('Reading '.$this->root . $file.' from cache', true, IOInterface::DEBUG); return copy($this->root . $file, $target); } diff --git a/src/Composer/Command/ShowCommand.php b/src/Composer/Command/ShowCommand.php index 7f0c77537..e3e1ffd71 100644 --- a/src/Composer/Command/ShowCommand.php +++ b/src/Composer/Command/ShowCommand.php @@ -246,10 +246,10 @@ EOT $writeDescription = !$input->getOption('name-only') && !$input->getOption('path') && ($nameLength + ($showVersion ? $versionLength : 0) + 24 <= $width); foreach ($packages[$type] as $package) { if (is_object($package)) { - $output->write($indent . str_pad($package->getPrettyName(), $nameLength, ' '), false); + $io->write($indent . str_pad($package->getPrettyName(), $nameLength, ' '), false); if ($writeVersion) { - $output->write(' ' . str_pad($package->getFullPrettyVersion(), $versionLength, ' '), false); + $io->write(' ' . str_pad($package->getFullPrettyVersion(), $versionLength, ' '), false); } if ($writeDescription) { @@ -258,15 +258,15 @@ EOT if (strlen($description) > $remaining) { $description = substr($description, 0, $remaining - 3) . '...'; } - $output->write(' ' . $description); + $io->write(' ' . $description, false); } if ($writePath) { $path = strtok(realpath($composer->getInstallationManager()->getInstallPath($package)), "\r\n"); - $output->write(' ' . $path); + $io->write(' ' . $path, false); } } else { - $output->write($indent . $package); + $io->write($indent . $package, false); } $io->write(''); } @@ -489,10 +489,10 @@ EOT $packagesInTree = array(); $packagesInTree[] = $package; - $output->write(sprintf('%s', $package->getPrettyName())); - $output->write(' ' . $package->getPrettyVersion()); - $output->write(' ' . strtok($package->getDescription(), "\r\n")); - $output->writeln(''); + $io = $this->getIO(); + $io->write(sprintf('%s', $package->getPrettyName()), false); + $io->write(' ' . $package->getPrettyVersion(), false); + $io->write(' ' . strtok($package->getDescription(), "\r\n")); if (is_object($package)) { $requires = $package->getRequires(); diff --git a/src/Composer/Console/Application.php b/src/Composer/Console/Application.php index 632741586..f77876100 100644 --- a/src/Composer/Console/Application.php +++ b/src/Composer/Console/Application.php @@ -136,9 +136,7 @@ class Application extends BaseApplication if ($newWorkDir = $this->getNewWorkingDir($input)) { $oldWorkingDir = getcwd(); chdir($newWorkDir); - if ($io->isDebug() >= 4) { - $io->writeError('Changed CWD to ' . getcwd()); - } + $io->writeError('Changed CWD to ' . getcwd(), true, IOInterface::DEBUG); } // add non-standard scripts as own commands @@ -214,7 +212,7 @@ class Application extends BaseApplication || (($df = disk_free_space($dir = $config->get('vendor-dir'))) !== false && $df < $minSpaceFree) || (($df = disk_free_space($dir = sys_get_temp_dir())) !== false && $df < $minSpaceFree) ) { - $io->writeError('The disk hosting '.$dir.' is full, this may be the cause of the following exception'); + $io->writeError('The disk hosting '.$dir.' is full, this may be the cause of the following exception', true, IOInterface::QUIET); } } } catch (\Exception $e) { @@ -222,13 +220,13 @@ class Application extends BaseApplication Silencer::restore(); if (defined('PHP_WINDOWS_VERSION_BUILD') && false !== strpos($exception->getMessage(), 'The system cannot find the path specified')) { - $io->writeError('The following exception may be caused by a stale entry in your cmd.exe AutoRun'); - $io->writeError('Check https://getcomposer.org/doc/articles/troubleshooting.md#-the-system-cannot-find-the-path-specified-windows- for details'); + $io->writeError('The following exception may be caused by a stale entry in your cmd.exe AutoRun', true, IOInterface::QUIET); + $io->writeError('Check https://getcomposer.org/doc/articles/troubleshooting.md#-the-system-cannot-find-the-path-specified-windows- for details', true, IOInterface::QUIET); } if (false !== strpos($exception->getMessage(), 'fork failed - Cannot allocate memory')) { - $io->writeError('The following exception is caused by a lack of memory and not having swap configured'); - $io->writeError('Check https://getcomposer.org/doc/articles/troubleshooting.md#proc-open-fork-failed-errors for details'); + $io->writeError('The following exception is caused by a lack of memory and not having swap configured', true, IOInterface::QUIET); + $io->writeError('Check https://getcomposer.org/doc/articles/troubleshooting.md#proc-open-fork-failed-errors for details', true, IOInterface::QUIET); } } diff --git a/src/Composer/DependencyResolver/SolverProblemsException.php b/src/Composer/DependencyResolver/SolverProblemsException.php index a457c5c63..c6092c28c 100644 --- a/src/Composer/DependencyResolver/SolverProblemsException.php +++ b/src/Composer/DependencyResolver/SolverProblemsException.php @@ -41,7 +41,7 @@ class SolverProblemsException extends \RuntimeException } if (strpos($text, 'could not be found') || strpos($text, 'no matching package found')) { - $text .= "\nPotential causes:\n - A typo in the package name\n - The package is not available in a stable-enough version according to your minimum-stability setting\n see for more details.\n\nRead for further common problems."; + $text .= "\nPotential causes:\n - A typo in the package name\n - The package is not available in a stable-enough version according to your minimum-stability setting\n see for more details.\n\nRead for further common problems."; } if ($hasExtensionProblems) { diff --git a/src/Composer/Downloader/ArchiveDownloader.php b/src/Composer/Downloader/ArchiveDownloader.php index f42b82872..9fa6a3338 100644 --- a/src/Composer/Downloader/ArchiveDownloader.php +++ b/src/Composer/Downloader/ArchiveDownloader.php @@ -14,6 +14,7 @@ namespace Composer\Downloader; use Composer\Package\PackageInterface; use Symfony\Component\Finder\Finder; +use Composer\IO\IOInterface; /** * Base downloader for archives @@ -34,9 +35,7 @@ abstract class ArchiveDownloader extends FileDownloader while ($retries--) { $fileName = parent::download($package, $path); - if ($this->io->isVerbose()) { - $this->io->writeError(' Extracting archive'); - } + $this->io->writeError(' Extracting archive', true, IOInterface::VERBOSE); try { $this->filesystem->ensureDirectoryExists($temporaryDir); diff --git a/src/Composer/Downloader/FileDownloader.php b/src/Composer/Downloader/FileDownloader.php index d3a57500c..ece495dba 100644 --- a/src/Composer/Downloader/FileDownloader.php +++ b/src/Composer/Downloader/FileDownloader.php @@ -141,9 +141,7 @@ class FileDownloader implements DownloaderInterface if ((0 !== $e->getCode() && !in_array($e->getCode(), array(500, 502, 503, 504))) || !$retries) { throw $e; } - if ($this->io->isVerbose()) { - $this->io->writeError(' Download failed, retrying...'); - } + $this->io->writeError(' Download failed, retrying...', true, IOInterface::VERBOSE); usleep(500000); } } diff --git a/src/Composer/EventDispatcher/EventDispatcher.php b/src/Composer/EventDispatcher/EventDispatcher.php index c669b9dab..b9a879a01 100644 --- a/src/Composer/EventDispatcher/EventDispatcher.php +++ b/src/Composer/EventDispatcher/EventDispatcher.php @@ -155,9 +155,7 @@ class EventDispatcher $event = $this->checkListenerExpectedEvent($callable, $event); $return = false === call_user_func($callable, $event) ? 1 : 0; } elseif ($this->isComposerScript($callable)) { - if ($this->io->isVerbose()) { - $this->io->writeError(sprintf('> %s: %s', $event->getName(), $callable)); - } + $this->io->writeError(sprintf('> %s: %s', $event->getName(), $callable), true, IOInterface::VERBOSE); $scriptName = substr($callable, 1); $args = $event->getArguments(); $flags = $event->getFlags(); diff --git a/src/Composer/Factory.php b/src/Composer/Factory.php index e11677b56..058709275 100644 --- a/src/Composer/Factory.php +++ b/src/Composer/Factory.php @@ -190,6 +190,20 @@ class Factory } $config->setAuthConfigSource(new JsonConfigSource($file, true)); + // load COMPOSER_AUTH environment variable if set + if ($composerAuthEnv = getenv('COMPOSER_AUTH')) { + $authData = json_decode($composerAuthEnv, true); + + if (is_null($authData)) { + throw new \UnexpectedValueException('COMPOSER_AUTH environment variable is malformed, should be a valid JSON object'); + } + + if ($io && $io->isDebug()) { + $io->writeError('Loading auth config from COMPOSER_AUTH'); + } + $config->merge(array('config' => $authData)); + } + return $config; } @@ -293,14 +307,10 @@ class Factory $config = static::createConfig($io, $cwd); $config->merge($localConfig); if (isset($composerFile)) { - if ($io && $io->isDebug()) { - $io->writeError('Loading config file ' . $composerFile); - } + $io->writeError('Loading config file ' . $composerFile, true, IOInterface::DEBUG); $localAuthFile = new JsonFile(dirname(realpath($composerFile)) . '/auth.json'); if ($localAuthFile->exists()) { - if ($io && $io->isDebug()) { - $io->writeError('Loading config file ' . $localAuthFile->getPath()); - } + $io->writeError('Loading config file ' . $localAuthFile->getPath(), true, IOInterface::DEBUG); $config->merge(array('config' => $localAuthFile->read())); $config->setAuthConfigSource(new JsonConfigSource($localAuthFile, true)); } @@ -435,9 +445,7 @@ class Factory try { $composer = self::createComposer($io, $config->get('home') . '/composer.json', $disablePlugins, $config->get('home'), false); } catch (\Exception $e) { - if ($io->isDebug()) { - $io->writeError('Failed to initialize global composer: '.$e->getMessage()); - } + $io->writeError('Failed to initialize global composer: '.$e->getMessage(), true, IOInterface::DEBUG); } return $composer; diff --git a/src/Composer/IO/BaseIO.php b/src/Composer/IO/BaseIO.php index 3a5a1d701..ad7e32df4 100644 --- a/src/Composer/IO/BaseIO.php +++ b/src/Composer/IO/BaseIO.php @@ -60,50 +60,25 @@ abstract class BaseIO implements IOInterface */ public function loadConfiguration(Config $config) { - $githubOauth = $config->get('github-oauth'); - $gitlabOauth = $config->get('gitlab-oauth'); - $httpBasic = $config->get('http-basic'); - - // Use COMPOSER_AUTH environment variable if set - if ($composerAuthEnv = getenv('COMPOSER_AUTH')) { - $authData = json_decode($composerAuthEnv, true); - - if (is_null($authData)) { - throw new \UnexpectedValueException('COMPOSER_AUTH environment variable is malformed'); - } - - if (isset($authData['github-oauth'])) { - $githubOauth = array_merge($githubOauth, $authData['github-oauth']); - } - if (isset($authData['gitlab-oauth'])) { - $gitlabOauth = array_merge($gitlabOauth, $authData['gitlab-oauth']); - } - if (isset($authData['http-basic'])) { - $httpBasic = array_merge($httpBasic, $authData['http-basic']); - } - } + $githubOauth = $config->get('github-oauth') ?: array(); + $gitlabOauth = $config->get('gitlab-oauth') ?: array(); + $httpBasic = $config->get('http-basic') ?: array(); // reload oauth token from config if available - if ($githubOauth) { - foreach ($githubOauth as $domain => $token) { - if (!preg_match('{^[a-z0-9]+$}', $token)) { - throw new \UnexpectedValueException('Your github oauth token for '.$domain.' contains invalid characters: "'.$token.'"'); - } - $this->setAuthentication($domain, $token, 'x-oauth-basic'); + foreach ($githubOauth as $domain => $token) { + if (!preg_match('{^[a-z0-9]+$}', $token)) { + throw new \UnexpectedValueException('Your github oauth token for '.$domain.' contains invalid characters: "'.$token.'"'); } + $this->setAuthentication($domain, $token, 'x-oauth-basic'); } - if ($gitlabOauth) { - foreach ($gitlabOauth as $domain => $token) { - $this->setAuthentication($domain, $token, 'oauth2'); - } + foreach ($gitlabOauth as $domain => $token) { + $this->setAuthentication($domain, $token, 'oauth2'); } // reload http basic credentials from config if available - if ($httpBasic) { - foreach ($httpBasic as $domain => $cred) { - $this->setAuthentication($domain, $cred['username'], $cred['password']); - } + foreach ($httpBasic as $domain => $cred) { + $this->setAuthentication($domain, $cred['username'], $cred['password']); } // setup process timeout diff --git a/src/Composer/IO/BufferIO.php b/src/Composer/IO/BufferIO.php index db3fb634b..1069c0d9a 100644 --- a/src/Composer/IO/BufferIO.php +++ b/src/Composer/IO/BufferIO.php @@ -35,7 +35,7 @@ class BufferIO extends ConsoleIO $input = new StringInput($input); $input->setInteractive(false); - $output = new StreamOutput(fopen('php://memory', 'rw'), $verbosity, !empty($formatter), $formatter); + $output = new StreamOutput(fopen('php://memory', 'rw'), $verbosity, $formatter ? $formatter->isDecorated() : false, $formatter); parent::__construct($input, $output, new HelperSet(array())); } diff --git a/src/Composer/IO/ConsoleIO.php b/src/Composer/IO/ConsoleIO.php index 3867695f1..f97af2e8a 100644 --- a/src/Composer/IO/ConsoleIO.php +++ b/src/Composer/IO/ConsoleIO.php @@ -33,6 +33,7 @@ class ConsoleIO extends BaseIO protected $lastMessage; protected $lastMessageErr; private $startTime; + private $verbosityMap; /** * Constructor. @@ -46,6 +47,13 @@ class ConsoleIO extends BaseIO $this->input = $input; $this->output = $output; $this->helperSet = $helperSet; + $this->verbosityMap = array( + self::QUIET => OutputInterface::VERBOSITY_QUIET, + self::NORMAL => OutputInterface::VERBOSITY_NORMAL, + self::VERBOSE => OutputInterface::VERBOSITY_VERBOSE, + self::VERY_VERBOSE => OutputInterface::VERBOSITY_VERY_VERBOSE, + self::DEBUG => OutputInterface::VERBOSITY_DEBUG, + ); } public function enableDebugging($startTime) @@ -96,26 +104,32 @@ class ConsoleIO extends BaseIO /** * {@inheritDoc} */ - public function write($messages, $newline = true) + public function write($messages, $newline = true, $verbosity = self::NORMAL) { - $this->doWrite($messages, $newline, false); + $this->doWrite($messages, $newline, false, $verbosity); } /** * {@inheritDoc} */ - public function writeError($messages, $newline = true) + public function writeError($messages, $newline = true, $verbosity = self::NORMAL) { - $this->doWrite($messages, $newline, true); + $this->doWrite($messages, $newline, true, $verbosity); } /** * @param array|string $messages * @param bool $newline * @param bool $stderr + * @param int $verbosity */ - private function doWrite($messages, $newline, $stderr) + private function doWrite($messages, $newline, $stderr, $verbosity) { + $sfVerbosity = $this->verbosityMap[$verbosity]; + if ($sfVerbosity > $this->output->getVerbosity()) { + return; + } + if (null !== $this->startTime) { $memoryUsage = memory_get_usage() / 1024 / 1024; $timeSpent = microtime(true) - $this->startTime; @@ -125,30 +139,30 @@ class ConsoleIO extends BaseIO } if (true === $stderr && $this->output instanceof ConsoleOutputInterface) { - $this->output->getErrorOutput()->write($messages, $newline); + $this->output->getErrorOutput()->write($messages, $newline, $sfVerbosity); $this->lastMessageErr = join($newline ? "\n" : '', (array) $messages); return; } - $this->output->write($messages, $newline); + $this->output->write($messages, $newline, $sfVerbosity); $this->lastMessage = join($newline ? "\n" : '', (array) $messages); } /** * {@inheritDoc} */ - public function overwrite($messages, $newline = true, $size = null) + public function overwrite($messages, $newline = true, $size = null, $verbosity = self::NORMAL) { - $this->doOverwrite($messages, $newline, $size, false); + $this->doOverwrite($messages, $newline, $size, false, $verbosity); } /** * {@inheritDoc} */ - public function overwriteError($messages, $newline = true, $size = null) + public function overwriteError($messages, $newline = true, $size = null, $verbosity = self::NORMAL) { - $this->doOverwrite($messages, $newline, $size, true); + $this->doOverwrite($messages, $newline, $size, true, $verbosity); } /** @@ -156,8 +170,9 @@ class ConsoleIO extends BaseIO * @param bool $newline * @param int|null $size * @param bool $stderr + * @param int $verbosity */ - private function doOverwrite($messages, $newline, $size, $stderr) + private function doOverwrite($messages, $newline, $size, $stderr, $verbosity) { // messages can be an array, let's convert it to string anyway $messages = join($newline ? "\n" : '', (array) $messages); @@ -168,21 +183,21 @@ class ConsoleIO extends BaseIO $size = strlen(strip_tags($stderr ? $this->lastMessageErr : $this->lastMessage)); } // ...let's fill its length with backspaces - $this->doWrite(str_repeat("\x08", $size), false, $stderr); + $this->doWrite(str_repeat("\x08", $size), false, $stderr, $verbosity); // write the new message - $this->doWrite($messages, false, $stderr); + $this->doWrite($messages, false, $stderr, $verbosity); $fill = $size - strlen(strip_tags($messages)); if ($fill > 0) { // whitespace whatever has left - $this->doWrite(str_repeat(' ', $fill), false, $stderr); + $this->doWrite(str_repeat(' ', $fill), false, $stderr, $verbosity); // move the cursor back - $this->doWrite(str_repeat("\x08", $fill), false, $stderr); + $this->doWrite(str_repeat("\x08", $fill), false, $stderr, $verbosity); } if ($newline) { - $this->doWrite('', true, $stderr); + $this->doWrite('', true, $stderr, $verbosity); } if ($stderr) { diff --git a/src/Composer/IO/IOInterface.php b/src/Composer/IO/IOInterface.php index 3165b0d24..ff20a591d 100644 --- a/src/Composer/IO/IOInterface.php +++ b/src/Composer/IO/IOInterface.php @@ -21,6 +21,12 @@ use Composer\Config; */ interface IOInterface { + const QUIET = 1; + const NORMAL = 2; + const VERBOSE = 4; + const VERY_VERBOSE = 8; + const DEBUG = 16; + /** * Is this input means interactive? * @@ -59,36 +65,40 @@ interface IOInterface /** * Writes a message to the output. * - * @param string|array $messages The message as an array of lines or a single string - * @param bool $newline Whether to add a newline or not + * @param string|array $messages The message as an array of lines or a single string + * @param bool $newline Whether to add a newline or not + * @param int $verbosity Verbosity level from the VERBOSITY_* constants */ - public function write($messages, $newline = true); + public function write($messages, $newline = true, $verbosity = self::NORMAL); /** * Writes a message to the error output. * - * @param string|array $messages The message as an array of lines or a single string - * @param bool $newline Whether to add a newline or not + * @param string|array $messages The message as an array of lines or a single string + * @param bool $newline Whether to add a newline or not + * @param int $verbosity Verbosity level from the VERBOSITY_* constants */ - public function writeError($messages, $newline = true); + public function writeError($messages, $newline = true, $verbosity = self::NORMAL); /** * Overwrites a previous message to the output. * - * @param string|array $messages The message as an array of lines or a single string - * @param bool $newline Whether to add a newline or not - * @param int $size The size of line + * @param string|array $messages The message as an array of lines or a single string + * @param bool $newline Whether to add a newline or not + * @param int $size The size of line + * @param int $verbosity Verbosity level from the VERBOSITY_* constants */ - public function overwrite($messages, $newline = true, $size = null); + public function overwrite($messages, $newline = true, $size = null, $verbosity = self::NORMAL); /** * Overwrites a previous message to the error output. * - * @param string|array $messages The message as an array of lines or a single string - * @param bool $newline Whether to add a newline or not - * @param int $size The size of line + * @param string|array $messages The message as an array of lines or a single string + * @param bool $newline Whether to add a newline or not + * @param int $size The size of line + * @param int $verbosity Verbosity level from the VERBOSITY_* constants */ - public function overwriteError($messages, $newline = true, $size = null); + public function overwriteError($messages, $newline = true, $size = null, $verbosity = self::NORMAL); /** * Asks a question to the user. diff --git a/src/Composer/IO/NullIO.php b/src/Composer/IO/NullIO.php index 1a88395d3..587168677 100644 --- a/src/Composer/IO/NullIO.php +++ b/src/Composer/IO/NullIO.php @@ -62,28 +62,28 @@ class NullIO extends BaseIO /** * {@inheritDoc} */ - public function write($messages, $newline = true) + public function write($messages, $newline = true, $verbosity = self::NORMAL) { } /** * {@inheritDoc} */ - public function writeError($messages, $newline = true) + public function writeError($messages, $newline = true, $verbosity = self::NORMAL) { } /** * {@inheritDoc} */ - public function overwrite($messages, $newline = true, $size = 80) + public function overwrite($messages, $newline = true, $size = 80, $verbosity = self::NORMAL) { } /** * {@inheritDoc} */ - public function overwriteError($messages, $newline = true, $size = 80) + public function overwriteError($messages, $newline = true, $size = 80, $verbosity = self::NORMAL) { } diff --git a/src/Composer/Installer.php b/src/Composer/Installer.php index f59eac7d3..3172e596f 100644 --- a/src/Composer/Installer.php +++ b/src/Composer/Installer.php @@ -529,10 +529,8 @@ class Installer return max(1, $e->getCode()); } - if ($this->io->isVerbose()) { - $this->io->writeError("Analyzed ".count($pool)." packages to resolve dependencies"); - $this->io->writeError("Analyzed ".$solver->getRuleSetSize()." rules to resolve dependencies"); - } + $this->io->writeError("Analyzed ".count($pool)." packages to resolve dependencies", true, IOInterface::VERBOSE); + $this->io->writeError("Analyzed ".$solver->getRuleSetSize()." rules to resolve dependencies", true, IOInterface::VERBOSE); // force dev packages to be updated if we update or install from a (potentially new) lock $operations = $this->processDevPackages($localRepo, $pool, $policy, $repositories, $installedRepo, $lockedRepository, $installFromLock, $withDevReqs, 'force-updates', $operations); @@ -578,10 +576,8 @@ class Installer && (!$operation->getTargetPackage()->getSourceReference() || $operation->getTargetPackage()->getSourceReference() === $operation->getInitialPackage()->getSourceReference()) && (!$operation->getTargetPackage()->getDistReference() || $operation->getTargetPackage()->getDistReference() === $operation->getInitialPackage()->getDistReference()) ) { - if ($this->io->isDebug()) { - $this->io->writeError(' - Skipping update of '. $operation->getTargetPackage()->getPrettyName().' to the same reference-locked version'); - $this->io->writeError(''); - } + $this->io->writeError(' - Skipping update of '. $operation->getTargetPackage()->getPrettyName().' to the same reference-locked version', true, IOInterface::DEBUG); + $this->io->writeError('', true, IOInterface::DEBUG); continue; } diff --git a/src/Composer/Installer/PearInstaller.php b/src/Composer/Installer/PearInstaller.php index 146e68b95..35f7855de 100644 --- a/src/Composer/Installer/PearInstaller.php +++ b/src/Composer/Installer/PearInstaller.php @@ -75,9 +75,7 @@ class PearInstaller extends LibraryInstaller $pearExtractor = new PearPackageExtractor($packageArchive); $pearExtractor->extractTo($this->getInstallPath($package), array('php' => '/', 'script' => '/bin', 'data' => '/data'), $vars); - if ($this->io->isVerbose()) { - $this->io->writeError(' Cleaning up'); - } + $this->io->writeError(' Cleaning up', true, IOInterface::VERBOSE); $this->filesystem->unlink($packageArchive); } diff --git a/src/Composer/Plugin/PluginManager.php b/src/Composer/Plugin/PluginManager.php index bfb0d9427..175a5e05b 100644 --- a/src/Composer/Plugin/PluginManager.php +++ b/src/Composer/Plugin/PluginManager.php @@ -206,9 +206,7 @@ class PluginManager */ private function addPlugin(PluginInterface $plugin) { - if ($this->io->isDebug()) { - $this->io->writeError('Loading plugin '.get_class($plugin)); - } + $this->io->writeError('Loading plugin '.get_class($plugin), true, IOInterface::DEBUG); $this->plugins[] = $plugin; $plugin->activate($this->composer, $this->io); diff --git a/src/Composer/Repository/ArtifactRepository.php b/src/Composer/Repository/ArtifactRepository.php index 81335ef7e..ece78bb1c 100644 --- a/src/Composer/Repository/ArtifactRepository.php +++ b/src/Composer/Repository/ArtifactRepository.php @@ -67,16 +67,12 @@ class ArtifactRepository extends ArrayRepository implements ConfigurableReposito $package = $this->getComposerInformation($file); if (!$package) { - if ($io->isVerbose()) { - $io->writeError("File {$file->getBasename()} doesn't seem to hold a package"); - } + $io->writeError("File {$file->getBasename()} doesn't seem to hold a package", true, IOInterface::VERBOSE); continue; } - if ($io->isVerbose()) { - $template = 'Found package %s (%s) in file %s'; - $io->writeError(sprintf($template, $package->getName(), $package->getPrettyVersion(), $file->getBasename())); - } + $template = 'Found package %s (%s) in file %s'; + $io->writeError(sprintf($template, $package->getName(), $package->getPrettyVersion(), $file->getBasename()), true, IOInterface::VERBOSE); $this->addPackage($package); } diff --git a/src/Composer/Repository/PearRepository.php b/src/Composer/Repository/PearRepository.php index 1d6d4710a..2c3e64bbe 100644 --- a/src/Composer/Repository/PearRepository.php +++ b/src/Composer/Repository/PearRepository.php @@ -105,9 +105,7 @@ class PearRepository extends ArrayRepository implements ConfigurableRepositoryIn try { $normalizedVersion = $versionParser->normalize($version); } catch (\UnexpectedValueException $e) { - if ($this->io->isVerbose()) { - $this->io->writeError('Could not load '.$packageDefinition->getPackageName().' '.$version.': '.$e->getMessage()); - } + $this->io->writeError('Could not load '.$packageDefinition->getPackageName().' '.$version.': '.$e->getMessage(), true, IOInterface::VERBOSE); continue; } diff --git a/src/Composer/Repository/Vcs/GitBitbucketDriver.php b/src/Composer/Repository/Vcs/GitBitbucketDriver.php index 0f0a57c47..7a2781ecb 100644 --- a/src/Composer/Repository/Vcs/GitBitbucketDriver.php +++ b/src/Composer/Repository/Vcs/GitBitbucketDriver.php @@ -160,9 +160,7 @@ class GitBitbucketDriver extends VcsDriver implements VcsDriverInterface } if (!extension_loaded('openssl')) { - if ($io->isVerbose()) { - $io->writeError('Skipping Bitbucket git driver for '.$url.' because the OpenSSL PHP extension is missing.'); - } + $io->writeError('Skipping Bitbucket git driver for '.$url.' because the OpenSSL PHP extension is missing.', true, IOInterface::VERBOSE); return false; } diff --git a/src/Composer/Repository/Vcs/GitHubDriver.php b/src/Composer/Repository/Vcs/GitHubDriver.php index cdd9df89f..4a4e1fcea 100644 --- a/src/Composer/Repository/Vcs/GitHubDriver.php +++ b/src/Composer/Repository/Vcs/GitHubDriver.php @@ -268,9 +268,7 @@ class GitHubDriver extends VcsDriver } if (!extension_loaded('openssl')) { - if ($io->isVerbose()) { - $io->writeError('Skipping GitHub driver for '.$url.' because the OpenSSL PHP extension is missing.'); - } + $io->writeError('Skipping GitHub driver for '.$url.' because the OpenSSL PHP extension is missing.', true, IOInterface::VERBOSE); return false; } diff --git a/src/Composer/Repository/Vcs/GitLabDriver.php b/src/Composer/Repository/Vcs/GitLabDriver.php index fa13f952c..8642c2d42 100644 --- a/src/Composer/Repository/Vcs/GitLabDriver.php +++ b/src/Composer/Repository/Vcs/GitLabDriver.php @@ -367,9 +367,7 @@ class GitLabDriver extends VcsDriver } if ('https' === $scheme && !extension_loaded('openssl')) { - if ($io->isVerbose()) { - $io->write('Skipping GitLab driver for '.$url.' because the OpenSSL PHP extension is missing.'); - } + $io->writeError('Skipping GitLab driver for '.$url.' because the OpenSSL PHP extension is missing.', true, IOInterface::VERBOSE); return false; } diff --git a/src/Composer/Repository/Vcs/HgBitbucketDriver.php b/src/Composer/Repository/Vcs/HgBitbucketDriver.php index 3beeee440..eb6808601 100644 --- a/src/Composer/Repository/Vcs/HgBitbucketDriver.php +++ b/src/Composer/Repository/Vcs/HgBitbucketDriver.php @@ -170,9 +170,7 @@ class HgBitbucketDriver extends VcsDriver } if (!extension_loaded('openssl')) { - if ($io->isVerbose()) { - $io->writeError('Skipping Bitbucket hg driver for '.$url.' because the OpenSSL PHP extension is missing.'); - } + $io->writeError('Skipping Bitbucket hg driver for '.$url.' because the OpenSSL PHP extension is missing.', true, IOInterface::VERBOSE); return false; } diff --git a/src/Composer/Util/RemoteFilesystem.php b/src/Composer/Util/RemoteFilesystem.php index 2d94e5909..f4c5f3150 100644 --- a/src/Composer/Util/RemoteFilesystem.php +++ b/src/Composer/Util/RemoteFilesystem.php @@ -227,9 +227,7 @@ class RemoteFilesystem unset($tempAdditionalOptions); $userlandFollow = isset($options['http']['follow_location']) && !$options['http']['follow_location']; - if ($this->io->isDebug()) { - $this->io->writeError((substr($fileUrl, 0, 4) === 'http' ? 'Downloading ' : 'Reading ') . $fileUrl); - } + $this->io->writeError((substr($fileUrl, 0, 4) === 'http' ? 'Downloading ' : 'Reading ') . $fileUrl, true, IOInterface::DEBUG); if (isset($options['github-token'])) { $fileUrl .= (false === strpos($fileUrl, '?') ? '?' : '&') . 'access_token='.$options['github-token']; @@ -609,13 +607,11 @@ class RemoteFilesystem // Handle subjectAltName on lesser PHP's. $certMap = $this->peerCertificateMap[$urlAuthority]; - if ($this->io->isDebug()) { - $this->io->writeError(sprintf( - 'Using %s as CN for subjectAltName enabled host %s', - $certMap['cn'], - $urlAuthority - )); - } + $this->io->writeError(sprintf( + 'Using %s as CN for subjectAltName enabled host %s', + $certMap['cn'], + $urlAuthority + ), true, IOInterface::DEBUG); $tlsOptions['ssl']['CN_match'] = $certMap['cn']; $tlsOptions['ssl']['peer_fingerprint'] = $certMap['fp']; @@ -689,9 +685,7 @@ class RemoteFilesystem if (!empty($targetUrl)) { $this->redirects++; - if ($this->io->isDebug()) { - $this->io->writeError(sprintf('Following redirect (%u) %s', $this->redirects, $targetUrl)); - } + $this->io->writeError(sprintf('Following redirect (%u) %s', $this->redirects, $targetUrl), true, IOInterface::DEBUG); $additionalOptions['redirects'] = $this->redirects; @@ -914,9 +908,7 @@ class RemoteFilesystem return $files[$filename]; } - if ($this->io->isDebug()) { - $this->io->writeError('Checking CA file '.realpath($filename)); - } + $this->io->writeError('Checking CA file '.realpath($filename), true, IOInterface::DEBUG); $contents = file_get_contents($filename); // assume the CA is valid if php is vulnerable to diff --git a/tests/Composer/Test/ApplicationTest.php b/tests/Composer/Test/ApplicationTest.php index 68d17d3f6..e7ab59c78 100644 --- a/tests/Composer/Test/ApplicationTest.php +++ b/tests/Composer/Test/ApplicationTest.php @@ -14,6 +14,7 @@ namespace Composer\Test; use Composer\Console\Application; use Composer\TestCase; +use Symfony\Component\Console\Output\OutputInterface; class ApplicationTest extends TestCase { @@ -30,11 +31,19 @@ class ApplicationTest extends TestCase $index = 0; if (extension_loaded('xdebug')) { + $outputMock->expects($this->at($index++)) + ->method("getVerbosity") + ->willReturn(OutputInterface::VERBOSITY_NORMAL); + $outputMock->expects($this->at($index++)) ->method("write") ->with($this->equalTo('You are running composer with xdebug enabled. This has a major impact on runtime performance. See https://getcomposer.org/xdebug')); } + $outputMock->expects($this->at($index++)) + ->method("getVerbosity") + ->willReturn(OutputInterface::VERBOSITY_NORMAL); + $outputMock->expects($this->at($index++)) ->method("write") ->with($this->equalTo(sprintf('Warning: This development build of composer is over 60 days old. It is recommended to update it by running "%s self-update" to get the latest version.', $_SERVER['PHP_SELF']))); diff --git a/tests/Composer/Test/DependencyResolver/SolverTest.php b/tests/Composer/Test/DependencyResolver/SolverTest.php index ed62e3d79..63de2973f 100644 --- a/tests/Composer/Test/DependencyResolver/SolverTest.php +++ b/tests/Composer/Test/DependencyResolver/SolverTest.php @@ -709,7 +709,7 @@ class SolverTest extends TestCase $msg .= "Potential causes:\n"; $msg .= " - A typo in the package name\n"; $msg .= " - The package is not available in a stable-enough version according to your minimum-stability setting\n"; - $msg .= " see for more details.\n\n"; + $msg .= " see for more details.\n\n"; $msg .= "Read for further common problems."; $this->assertEquals($msg, $e->getMessage()); } diff --git a/tests/Composer/Test/EventDispatcher/EventDispatcherTest.php b/tests/Composer/Test/EventDispatcher/EventDispatcherTest.php index 2dd9f8a4a..e0c1fa45e 100644 --- a/tests/Composer/Test/EventDispatcher/EventDispatcherTest.php +++ b/tests/Composer/Test/EventDispatcher/EventDispatcherTest.php @@ -15,9 +15,11 @@ namespace Composer\Test\EventDispatcher; use Composer\EventDispatcher\Event; use Composer\Installer\InstallerEvents; use Composer\TestCase; +use Composer\IO\BufferIO; use Composer\Script\ScriptEvents; use Composer\Script\CommandEvent; use Composer\Util\ProcessExecutor; +use Symfony\Component\Console\Output\OutputInterface; class EventDispatcherTest extends TestCase { @@ -101,7 +103,7 @@ class EventDispatcherTest extends TestCase $dispatcher = $this->getMockBuilder('Composer\EventDispatcher\EventDispatcher') ->setConstructorArgs(array( $this->getMock('Composer\Composer'), - $io = $this->getMock('Composer\IO\IOInterface'), + $io = new BufferIO('', OutputInterface::VERBOSITY_VERBOSE), $process, )) ->setMethods(array( @@ -123,23 +125,12 @@ class EventDispatcherTest extends TestCase ->method('getListeners') ->will($this->returnValue($listeners)); - $io->expects($this->any()) - ->method('isVerbose') - ->willReturn(1); - - $io->expects($this->at(1)) - ->method('writeError') - ->with($this->equalTo('> post-install-cmd: echo -n foo')); - - $io->expects($this->at(3)) - ->method('writeError') - ->with($this->equalTo('> post-install-cmd: Composer\Test\EventDispatcher\EventDispatcherTest::someMethod')); - - $io->expects($this->at(5)) - ->method('writeError') - ->with($this->equalTo('> post-install-cmd: echo -n bar')); - $dispatcher->dispatchScript(ScriptEvents::POST_INSTALL_CMD, false); + + $expected = '> post-install-cmd: echo -n foo'.PHP_EOL. + '> post-install-cmd: Composer\Test\EventDispatcher\EventDispatcherTest::someMethod'.PHP_EOL. + '> post-install-cmd: echo -n bar'.PHP_EOL; + $this->assertEquals($expected, $io->getOutput()); } public function testDispatcherCanExecuteComposerScriptGroups() @@ -148,7 +139,7 @@ class EventDispatcherTest extends TestCase $dispatcher = $this->getMockBuilder('Composer\EventDispatcher\EventDispatcher') ->setConstructorArgs(array( $composer = $this->getMock('Composer\Composer'), - $io = $this->getMock('Composer\IO\IOInterface'), + $io = new BufferIO('', OutputInterface::VERBOSITY_VERBOSE), $process, )) ->setMethods(array( @@ -174,31 +165,13 @@ class EventDispatcherTest extends TestCase return array(); })); - $io->expects($this->any()) - ->method('isVerbose') - ->willReturn(1); - - $io->expects($this->at(1)) - ->method('writeError') - ->with($this->equalTo('> root: @group')); - - $io->expects($this->at(3)) - ->method('writeError') - ->with($this->equalTo('> group: echo -n foo')); - - $io->expects($this->at(5)) - ->method('writeError') - ->with($this->equalTo('> group: @subgroup')); - - $io->expects($this->at(7)) - ->method('writeError') - ->with($this->equalTo('> subgroup: echo -n baz')); - - $io->expects($this->at(9)) - ->method('writeError') - ->with($this->equalTo('> group: echo -n bar')); - $dispatcher->dispatch('root', new CommandEvent('root', $composer, $io)); + $expected = '> root: @group'.PHP_EOL. + '> group: echo -n foo'.PHP_EOL. + '> group: @subgroup'.PHP_EOL. + '> subgroup: echo -n baz'.PHP_EOL. + '> group: echo -n bar'.PHP_EOL; + $this->assertEquals($expected, $io->getOutput()); } /** diff --git a/tests/Composer/Test/Fixtures/installer/abandoned-listed.test b/tests/Composer/Test/Fixtures/installer/abandoned-listed.test index 26861b1c6..1e0b9ff2c 100644 --- a/tests/Composer/Test/Fixtures/installer/abandoned-listed.test +++ b/tests/Composer/Test/Fixtures/installer/abandoned-listed.test @@ -24,12 +24,12 @@ Abandoned packages are flagged --RUN-- install --EXPECT-OUTPUT-- -Loading composer repositories with package information -Installing dependencies (including require-dev) +Loading composer repositories with package information +Installing dependencies (including require-dev) Package a/a is abandoned, you should avoid using it. No replacement was suggested. Package c/c is abandoned, you should avoid using it. Use b/b instead. -Writing lock file -Generating autoload files +Writing lock file +Generating autoload files --EXPECT-- Installing a/a (1.0.0) diff --git a/tests/Composer/Test/Fixtures/installer/broken-deps-do-not-replace.test b/tests/Composer/Test/Fixtures/installer/broken-deps-do-not-replace.test index 19bd8f914..e7c6cd984 100644 --- a/tests/Composer/Test/Fixtures/installer/broken-deps-do-not-replace.test +++ b/tests/Composer/Test/Fixtures/installer/broken-deps-do-not-replace.test @@ -21,9 +21,9 @@ Broken dependencies should not lead to a replacer being installed which is not m --RUN-- install --EXPECT-OUTPUT-- -Loading composer repositories with package information -Installing dependencies (including require-dev) -Your requirements could not be resolved to an installable set of packages. +Loading composer repositories with package information +Installing dependencies (including require-dev) +Your requirements could not be resolved to an installable set of packages. Problem 1 - c/c 1.0.0 requires x/x 1.0 -> no matching package found. @@ -33,7 +33,7 @@ install Potential causes: - A typo in the package name - The package is not available in a stable-enough version according to your minimum-stability setting - see for more details. + see for more details. Read for further common problems. diff --git a/tests/Composer/Test/Fixtures/installer/suggest-installed.test b/tests/Composer/Test/Fixtures/installer/suggest-installed.test index 94f6c2016..4929f972e 100644 --- a/tests/Composer/Test/Fixtures/installer/suggest-installed.test +++ b/tests/Composer/Test/Fixtures/installer/suggest-installed.test @@ -19,10 +19,10 @@ Suggestions are not displayed for installed packages --RUN-- install --EXPECT-OUTPUT-- -Loading composer repositories with package information -Installing dependencies (including require-dev) -Writing lock file -Generating autoload files +Loading composer repositories with package information +Installing dependencies (including require-dev) +Writing lock file +Generating autoload files --EXPECT-- Installing a/a (1.0.0) diff --git a/tests/Composer/Test/Fixtures/installer/suggest-prod.test b/tests/Composer/Test/Fixtures/installer/suggest-prod.test index 290ccf4bb..c89bb0c20 100644 --- a/tests/Composer/Test/Fixtures/installer/suggest-prod.test +++ b/tests/Composer/Test/Fixtures/installer/suggest-prod.test @@ -17,10 +17,10 @@ Suggestions are not displayed in non-dev mode --RUN-- install --no-dev --EXPECT-OUTPUT-- -Loading composer repositories with package information -Installing dependencies -Writing lock file -Generating autoload files +Loading composer repositories with package information +Installing dependencies +Writing lock file +Generating autoload files --EXPECT-- Installing a/a (1.0.0) diff --git a/tests/Composer/Test/Fixtures/installer/suggest-replaced.test b/tests/Composer/Test/Fixtures/installer/suggest-replaced.test index 99d13a720..5d64d2176 100644 --- a/tests/Composer/Test/Fixtures/installer/suggest-replaced.test +++ b/tests/Composer/Test/Fixtures/installer/suggest-replaced.test @@ -19,10 +19,10 @@ Suggestions are not displayed for packages if they are replaced --RUN-- install --EXPECT-OUTPUT-- -Loading composer repositories with package information -Installing dependencies (including require-dev) -Writing lock file -Generating autoload files +Loading composer repositories with package information +Installing dependencies (including require-dev) +Writing lock file +Generating autoload files --EXPECT-- Installing c/c (1.0.0) diff --git a/tests/Composer/Test/Fixtures/installer/suggest-uninstalled.test b/tests/Composer/Test/Fixtures/installer/suggest-uninstalled.test index d7e026e98..d04b6c8d5 100644 --- a/tests/Composer/Test/Fixtures/installer/suggest-uninstalled.test +++ b/tests/Composer/Test/Fixtures/installer/suggest-uninstalled.test @@ -17,11 +17,11 @@ Suggestions are displayed --RUN-- install --EXPECT-OUTPUT-- -Loading composer repositories with package information -Installing dependencies (including require-dev) +Loading composer repositories with package information +Installing dependencies (including require-dev) a/a suggests installing b/b (an obscure reason) -Writing lock file -Generating autoload files +Writing lock file +Generating autoload files --EXPECT-- Installing a/a (1.0.0) diff --git a/tests/Composer/Test/IO/ConsoleIOTest.php b/tests/Composer/Test/IO/ConsoleIOTest.php index a300350b9..ca7d420c9 100644 --- a/tests/Composer/Test/IO/ConsoleIOTest.php +++ b/tests/Composer/Test/IO/ConsoleIOTest.php @@ -14,6 +14,7 @@ namespace Composer\Test\IO; use Composer\IO\ConsoleIO; use Composer\TestCase; +use Symfony\Component\Console\Output\OutputInterface; class ConsoleIOTest extends TestCase { @@ -40,6 +41,9 @@ class ConsoleIOTest extends TestCase { $inputMock = $this->getMock('Symfony\Component\Console\Input\InputInterface'); $outputMock = $this->getMock('Symfony\Component\Console\Output\OutputInterface'); + $outputMock->expects($this->once()) + ->method('getVerbosity') + ->willReturn(OutputInterface::VERBOSITY_NORMAL); $outputMock->expects($this->once()) ->method('write') ->with($this->equalTo('some information about something'), $this->equalTo(false)); @@ -53,6 +57,9 @@ class ConsoleIOTest extends TestCase { $inputMock = $this->getMock('Symfony\Component\Console\Input\InputInterface'); $outputMock = $this->getMock('Symfony\Component\Console\Output\ConsoleOutputInterface'); + $outputMock->expects($this->once()) + ->method('getVerbosity') + ->willReturn(OutputInterface::VERBOSITY_NORMAL); $outputMock->expects($this->once()) ->method('getErrorOutput') ->willReturn($outputMock); @@ -69,6 +76,9 @@ class ConsoleIOTest extends TestCase { $inputMock = $this->getMock('Symfony\Component\Console\Input\InputInterface'); $outputMock = $this->getMock('Symfony\Component\Console\Output\OutputInterface'); + $outputMock->expects($this->once()) + ->method('getVerbosity') + ->willReturn(OutputInterface::VERBOSITY_NORMAL); $outputMock->expects($this->once()) ->method('write') ->with( @@ -95,25 +105,28 @@ class ConsoleIOTest extends TestCase $inputMock = $this->getMock('Symfony\Component\Console\Input\InputInterface'); $outputMock = $this->getMock('Symfony\Component\Console\Output\OutputInterface'); - $outputMock->expects($this->at(0)) - ->method('write') - ->with($this->equalTo('something (strlen = 23)')); + $outputMock->expects($this->any()) + ->method('getVerbosity') + ->willReturn(OutputInterface::VERBOSITY_NORMAL); $outputMock->expects($this->at(1)) ->method('write') - ->with($this->equalTo(str_repeat("\x08", 23)), $this->equalTo(false)); - $outputMock->expects($this->at(2)) - ->method('write') - ->with($this->equalTo('shorter (12)'), $this->equalTo(false)); + ->with($this->equalTo('something (strlen = 23)')); $outputMock->expects($this->at(3)) ->method('write') - ->with($this->equalTo(str_repeat(' ', 11)), $this->equalTo(false)); - $outputMock->expects($this->at(4)) - ->method('write') - ->with($this->equalTo(str_repeat("\x08", 11)), $this->equalTo(false)); + ->with($this->equalTo(str_repeat("\x08", 23)), $this->equalTo(false)); $outputMock->expects($this->at(5)) + ->method('write') + ->with($this->equalTo('shorter (12)'), $this->equalTo(false)); + $outputMock->expects($this->at(7)) + ->method('write') + ->with($this->equalTo(str_repeat(' ', 11)), $this->equalTo(false)); + $outputMock->expects($this->at(9)) + ->method('write') + ->with($this->equalTo(str_repeat("\x08", 11)), $this->equalTo(false)); + $outputMock->expects($this->at(11)) ->method('write') ->with($this->equalTo(str_repeat("\x08", 12)), $this->equalTo(false)); - $outputMock->expects($this->at(6)) + $outputMock->expects($this->at(13)) ->method('write') ->with($this->equalTo('something longer than initial (34)')); diff --git a/tests/Composer/Test/InstallerTest.php b/tests/Composer/Test/InstallerTest.php index 5339b8ff3..b0a51fea7 100644 --- a/tests/Composer/Test/InstallerTest.php +++ b/tests/Composer/Test/InstallerTest.php @@ -26,7 +26,10 @@ use Composer\Test\Mock\InstalledFilesystemRepositoryMock; use Composer\Test\Mock\InstallationManagerMock; use Symfony\Component\Console\Input\StringInput; use Symfony\Component\Console\Output\StreamOutput; +use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Formatter\OutputFormatter; use Composer\TestCase; +use Composer\IO\BufferIO; class InstallerTest extends TestCase { @@ -146,18 +149,7 @@ class InstallerTest extends TestCase } } - $output = null; - $io = $this->getMock('Composer\IO\IOInterface'); - $callback = function ($text, $newline) use (&$output) { - $output .= $text . ($newline ? "\n" : ""); - }; - $io->expects($this->any()) - ->method('write') - ->will($this->returnCallback($callback)); - $io->expects($this->any()) - ->method('writeError') - ->will($this->returnCallback($callback)); - + $io = new BufferIO('', OutputInterface::VERBOSITY_NORMAL, new OutputFormatter(false)); $composer = FactoryMock::create($io, $composerConfig); $jsonMock = $this->getMockBuilder('Composer\Json\JsonFile')->disableOriginalConstructor()->getMock(); @@ -233,6 +225,7 @@ class InstallerTest extends TestCase $appOutput = fopen('php://memory', 'w+'); $result = $application->run(new StringInput($run), new StreamOutput($appOutput)); fseek($appOutput, 0); + $output = str_replace("\r", '', $io->getOutput()); $this->assertEquals($expectExitCode, $result, $output . stream_get_contents($appOutput)); if ($expectLock) {