From cb336a5416595efa321c024735e6452c9c7df106 Mon Sep 17 00:00:00 2001 From: Rob Bast Date: Fri, 6 Feb 2015 13:52:44 +0100 Subject: [PATCH] Implement writeError throughout Composer --- src/Composer/Autoload/ClassMapGenerator.php | 2 +- src/Composer/Cache.php | 10 ++-- src/Composer/Command/AboutCommand.php | 2 +- src/Composer/Command/ArchiveCommand.php | 16 ++--- src/Composer/Command/ClearCacheCommand.php | 8 +-- src/Composer/Command/ConfigCommand.php | 20 +++++-- src/Composer/Command/CreateProjectCommand.php | 10 ++-- src/Composer/Command/DependsCommand.php | 4 +- src/Composer/Command/DiagnoseCommand.php | 58 +++++++++---------- src/Composer/Command/DumpAutoloadCommand.php | 4 +- src/Composer/Command/GlobalCommand.php | 2 +- src/Composer/Command/HomeCommand.php | 8 +-- src/Composer/Command/InitCommand.php | 20 +++---- src/Composer/Command/InstallCommand.php | 6 +- src/Composer/Command/LicensesCommand.php | 10 ++-- src/Composer/Command/RemoveCommand.php | 6 +- src/Composer/Command/RequireCommand.php | 12 ++-- src/Composer/Command/RunScriptCommand.php | 8 +-- src/Composer/Command/SearchCommand.php | 4 +- src/Composer/Command/SelfUpdateCommand.php | 22 +++---- src/Composer/Command/ShowCommand.php | 56 +++++++++--------- src/Composer/Command/StatusCommand.php | 12 ++-- src/Composer/Command/UpdateCommand.php | 4 +- src/Composer/Command/ValidateCommand.php | 20 +++---- src/Composer/Console/Application.php | 32 +++++----- src/Composer/Downloader/ArchiveDownloader.php | 6 +- src/Composer/Downloader/DownloadManager.php | 4 +- src/Composer/Downloader/FileDownloader.php | 20 +++---- src/Composer/Downloader/GitDownloader.php | 22 +++---- src/Composer/Downloader/HgDownloader.php | 4 +- .../Downloader/PerforceDownloader.php | 4 +- src/Composer/Downloader/SvnDownloader.php | 14 ++--- src/Composer/Downloader/VcsDownloader.php | 22 +++---- .../EventDispatcher/EventDispatcher.php | 8 +-- src/Composer/Factory.php | 10 ++-- src/Composer/IO/ConsoleIO.php | 22 +++++++ src/Composer/IO/IOInterface.php | 8 +++ src/Composer/IO/NullIO.php | 7 +++ src/Composer/Installer.php | 50 ++++++++-------- src/Composer/Installer/LibraryInstaller.php | 6 +- src/Composer/Installer/PearInstaller.php | 2 +- src/Composer/Plugin/PluginManager.php | 2 +- .../Repository/ArtifactRepository.php | 4 +- .../Repository/ComposerRepository.php | 6 +- src/Composer/Repository/PearRepository.php | 6 +- .../Repository/Vcs/GitBitbucketDriver.php | 2 +- src/Composer/Repository/Vcs/GitDriver.php | 2 +- src/Composer/Repository/Vcs/GitHubDriver.php | 8 +-- .../Repository/Vcs/HgBitbucketDriver.php | 2 +- src/Composer/Repository/Vcs/HgDriver.php | 2 +- src/Composer/Repository/VcsRepository.php | 30 +++++----- src/Composer/Util/Git.php | 2 +- src/Composer/Util/GitHub.php | 22 +++---- src/Composer/Util/ProcessExecutor.php | 2 +- src/Composer/Util/RemoteFilesystem.php | 4 +- src/Composer/Util/Svn.php | 4 +- tests/Composer/Test/ApplicationTest.php | 2 +- .../Test/Autoload/ClassMapGeneratorTest.php | 2 +- .../Downloader/PerforceDownloaderTest.php | 4 +- .../EventDispatcher/EventDispatcherTest.php | 4 +- .../functional/create-project-command.test | 2 +- ...ject-shows-full-hash-for-dev-packages.test | 2 +- tests/Composer/Test/IO/ConsoleIOTest.php | 16 +++++ tests/Composer/Test/InstallerTest.php | 15 ++--- tests/Composer/Test/Util/GitHubTest.php | 2 +- 65 files changed, 390 insertions(+), 322 deletions(-) diff --git a/src/Composer/Autoload/ClassMapGenerator.php b/src/Composer/Autoload/ClassMapGenerator.php index 0f289bcbd..f8f18fc28 100644 --- a/src/Composer/Autoload/ClassMapGenerator.php +++ b/src/Composer/Autoload/ClassMapGenerator.php @@ -92,7 +92,7 @@ class ClassMapGenerator if (!isset($map[$class])) { $map[$class] = $filePath; } elseif ($io && $map[$class] !== $filePath && !preg_match('{/(test|fixture|example)s?/}i', strtr($map[$class].' '.$filePath, '\\', '/'))) { - $io->write( + $io->writeError( 'Warning: Ambiguous class resolution, "'.$class.'"'. ' was found in both "'.$map[$class].'" and "'.$filePath.'", the first will be used.' ); diff --git a/src/Composer/Cache.php b/src/Composer/Cache.php index 7341f61c2..4fae9be33 100644 --- a/src/Composer/Cache.php +++ b/src/Composer/Cache.php @@ -65,7 +65,7 @@ class Cache $file = preg_replace('{[^'.$this->whitelist.']}i', '-', $file); if ($this->enabled && file_exists($this->root . $file)) { if ($this->io->isDebug()) { - $this->io->write('Reading '.$this->root . $file.' from cache'); + $this->io->writeError('Reading '.$this->root . $file.' from cache'); } return file_get_contents($this->root . $file); @@ -80,7 +80,7 @@ class Cache $file = preg_replace('{[^'.$this->whitelist.']}i', '-', $file); if ($this->io->isDebug()) { - $this->io->write('Writing '.$this->root . $file.' into cache'); + $this->io->writeError('Writing '.$this->root . $file.' into cache'); } try { @@ -98,7 +98,7 @@ class Cache @disk_free_space($this->root . dirname($file)) ); - $this->io->write($message); + $this->io->writeError($message); return false; } @@ -120,7 +120,7 @@ class Cache $this->filesystem->ensureDirectoryExists(dirname($this->root . $file)); if ($this->io->isDebug()) { - $this->io->write('Writing '.$this->root . $file.' into cache'); + $this->io->writeError('Writing '.$this->root . $file.' into cache'); } return copy($source, $this->root . $file); @@ -139,7 +139,7 @@ class Cache touch($this->root . $file); if ($this->io->isDebug()) { - $this->io->write('Reading '.$this->root . $file.' from cache'); + $this->io->writeError('Reading '.$this->root . $file.' from cache'); } return copy($this->root . $file, $target); diff --git a/src/Composer/Command/AboutCommand.php b/src/Composer/Command/AboutCommand.php index ead7604df..5c79c65a0 100644 --- a/src/Composer/Command/AboutCommand.php +++ b/src/Composer/Command/AboutCommand.php @@ -34,7 +34,7 @@ EOT protected function execute(InputInterface $input, OutputInterface $output) { - $output->writeln(<<getIO()->write(<<Composer - Package Management for PHP Composer is a dependency manager tracking local dependencies of your projects and libraries. See http://getcomposer.org/ for more information. diff --git a/src/Composer/Command/ArchiveCommand.php b/src/Composer/Command/ArchiveCommand.php index 913a56a42..17157a82f 100644 --- a/src/Composer/Command/ArchiveCommand.php +++ b/src/Composer/Command/ArchiveCommand.php @@ -97,7 +97,7 @@ EOT $package = $this->getComposer()->getPackage(); } - $io->write('Creating the archive.'); + $io->writeError('Creating the archive.'); $archiveManager->archive($package, $format, $dest); return 0; @@ -105,14 +105,14 @@ EOT protected function selectPackage(IOInterface $io, $packageName, $version = null) { - $io->write('Searching for the specified package.'); + $io->writeError('Searching for the specified package.'); if ($composer = $this->getComposer(false)) { $localRepo = $composer->getRepositoryManager()->getLocalRepository(); $repos = new CompositeRepository(array_merge(array($localRepo), $composer->getRepositoryManager()->getRepositories())); } else { $defaultRepos = Factory::createDefaultRepositories($this->getIO()); - $io->write('No composer.json found in the current directory, searching packages from ' . implode(', ', array_keys($defaultRepos))); + $io->writeError('No composer.json found in the current directory, searching packages from ' . implode(', ', array_keys($defaultRepos))); $repos = new CompositeRepository($defaultRepos); } @@ -125,14 +125,14 @@ EOT if (count($packages) > 1) { $package = reset($packages); - $io->write('Found multiple matches, selected '.$package->getPrettyString().'.'); - $io->write('Alternatives were '.implode(', ', array_map(function ($p) { return $p->getPrettyString(); }, $packages)).'.'); - $io->write('Please use a more specific constraint to pick a different package.'); + $io->writeError('Found multiple matches, selected '.$package->getPrettyString().'.'); + $io->writeError('Alternatives were '.implode(', ', array_map(function ($p) { return $p->getPrettyString(); }, $packages)).'.'); + $io->writeError('Please use a more specific constraint to pick a different package.'); } elseif ($packages) { $package = reset($packages); - $io->write('Found an exact match '.$package->getPrettyString().'.'); + $io->writeError('Found an exact match '.$package->getPrettyString().'.'); } else { - $io->write('Could not find a package matching '.$packageName.'.'); + $io->writeError('Could not find a package matching '.$packageName.'.'); return false; } diff --git a/src/Composer/Command/ClearCacheCommand.php b/src/Composer/Command/ClearCacheCommand.php index b1b9ecd9a..9512ba416 100644 --- a/src/Composer/Command/ClearCacheCommand.php +++ b/src/Composer/Command/ClearCacheCommand.php @@ -51,21 +51,21 @@ EOT foreach ($cachePaths as $key => $cachePath) { $cachePath = realpath($cachePath); if (!$cachePath) { - $io->write("Cache directory does not exist ($key): $cachePath"); + $io->writeError("Cache directory does not exist ($key): $cachePath"); return; } $cache = new Cache($io, $cachePath); if (!$cache->isEnabled()) { - $io->write("Cache is not enabled ($key): $cachePath"); + $io->writeError("Cache is not enabled ($key): $cachePath"); return; } - $io->write("Clearing cache ($key): $cachePath"); + $io->writeError("Clearing cache ($key): $cachePath"); $cache->gc(0, 0); } - $io->write('All caches cleared.'); + $io->writeError('All caches cleared.'); } } diff --git a/src/Composer/Command/ConfigCommand.php b/src/Composer/Command/ConfigCommand.php index 1fd5750df..f170c9327 100644 --- a/src/Composer/Command/ConfigCommand.php +++ b/src/Composer/Command/ConfigCommand.php @@ -33,15 +33,25 @@ class ConfigCommand extends Command protected $config; /** - * @var Composer\Json\JsonFile + * @var JsonFile */ protected $configFile; /** - * @var Composer\Config\JsonConfigSource + * @var JsonConfigSource */ protected $configSource; + /** + * @var JsonFile + */ + protected $authConfigFile; + + /** + * @var JsonConfigSource + */ + protected $authConfigSource; + /** * {@inheritDoc} */ @@ -247,7 +257,7 @@ EOT $value = json_encode($value); } - $output->writeln($value); + $this->getIO()->write($value); return 0; } @@ -474,9 +484,9 @@ EOT } if (is_string($rawVal) && $rawVal != $value) { - $output->writeln('[' . $k . $key . '] ' . $rawVal . ' (' . $value . ')'); + $this->getIO()->write('[' . $k . $key . '] ' . $rawVal . ' (' . $value . ')'); } else { - $output->writeln('[' . $k . $key . '] ' . $value . ''); + $this->getIO()->write('[' . $k . $key . '] ' . $value . ''); } } } diff --git a/src/Composer/Command/CreateProjectCommand.php b/src/Composer/Command/CreateProjectCommand.php index 7bf3fed15..e7186fec8 100644 --- a/src/Composer/Command/CreateProjectCommand.php +++ b/src/Composer/Command/CreateProjectCommand.php @@ -106,7 +106,7 @@ EOT $this->updatePreferredOptions($config, $input, $preferSource, $preferDist); if ($input->getOption('no-custom-installers')) { - $output->writeln('You are using the deprecated option "no-custom-installers". Use "no-plugins" instead.'); + $this->getIO()->writeError('You are using the deprecated option "no-custom-installers". Use "no-plugins" instead.'); $input->setOption('no-plugins', true); } @@ -196,7 +196,7 @@ EOT } } } catch (\Exception $e) { - $io->write('An error occurred while removing the VCS metadata: '.$e->getMessage().''); + $io->writeError('An error occurred while removing the VCS metadata: '.$e->getMessage().''); } $hasVcs = false; @@ -288,10 +288,10 @@ EOT $directory = getcwd() . DIRECTORY_SEPARATOR . array_pop($parts); } - $io->write('Installing ' . $package->getName() . ' (' . VersionParser::formatVersion($package, false) . ')'); + $io->writeError('Installing ' . $package->getName() . ' (' . VersionParser::formatVersion($package, false) . ')'); if ($disablePlugins) { - $io->write('Plugins have been disabled.'); + $io->writeError('Plugins have been disabled.'); } if (0 === strpos($package->getPrettyVersion(), 'dev-') && in_array($package->getSourceType(), array('git', 'hg'))) { @@ -311,7 +311,7 @@ EOT $installedFromVcs = 'source' === $package->getInstallationSource(); - $io->write('Created project in ' . $directory . ''); + $io->writeError('Created project in ' . $directory . ''); chdir($directory); putenv('COMPOSER_ROOT_VERSION='.$package->getPrettyVersion()); diff --git a/src/Composer/Command/DependsCommand.php b/src/Composer/Command/DependsCommand.php index 755b40b90..97b9d0f39 100644 --- a/src/Composer/Command/DependsCommand.php +++ b/src/Composer/Command/DependsCommand.php @@ -96,9 +96,9 @@ EOT if ($messages) { sort($messages); - $output->writeln($messages); + $this->getIO()->write($messages); } else { - $output->writeln('There is no installed package depending on "'.$needle.'".'); + $this->getIO()->writeError('There is no installed package depending on "'.$needle.'".'); } } } diff --git a/src/Composer/Command/DiagnoseCommand.php b/src/Composer/Command/DiagnoseCommand.php index b1fcc8dbe..d6c6ec968 100644 --- a/src/Composer/Command/DiagnoseCommand.php +++ b/src/Composer/Command/DiagnoseCommand.php @@ -59,8 +59,8 @@ EOT $commandEvent = new CommandEvent(PluginEvents::COMMAND, 'diagnose', $input, $output); $composer->getEventDispatcher()->dispatch($commandEvent->getName(), $commandEvent); - $output->write('Checking composer.json: '); - $this->outputResult($output, $this->checkComposerSchema()); + $this->getIO()->write('Checking composer.json: ', false); + $this->outputResult($this->checkComposerSchema()); } if ($composer) { @@ -72,37 +72,37 @@ EOT $this->rfs = new RemoteFilesystem($this->getIO(), $config); $this->process = new ProcessExecutor($this->getIO()); - $output->write('Checking platform settings: '); - $this->outputResult($output, $this->checkPlatform()); + $this->getIO()->write('Checking platform settings: ', false); + $this->outputResult($this->checkPlatform()); - $output->write('Checking git settings: '); - $this->outputResult($output, $this->checkGit()); + $this->getIO()->write('Checking git settings: ', false); + $this->outputResult($this->checkGit()); - $output->write('Checking http connectivity: '); - $this->outputResult($output, $this->checkHttp()); + $this->getIO()->write('Checking http connectivity: ', false); + $this->outputResult($this->checkHttp()); $opts = stream_context_get_options(StreamContextFactory::getContext('http://example.org')); if (!empty($opts['http']['proxy'])) { - $output->write('Checking HTTP proxy: '); - $this->outputResult($output, $this->checkHttpProxy()); - $output->write('Checking HTTP proxy support for request_fulluri: '); - $this->outputResult($output, $this->checkHttpProxyFullUriRequestParam()); - $output->write('Checking HTTPS proxy support for request_fulluri: '); - $this->outputResult($output, $this->checkHttpsProxyFullUriRequestParam()); + $this->getIO()->write('Checking HTTP proxy: ', false); + $this->outputResult($this->checkHttpProxy()); + $this->getIO()->write('Checking HTTP proxy support for request_fulluri: ', false); + $this->outputResult($this->checkHttpProxyFullUriRequestParam()); + $this->getIO()->write('Checking HTTPS proxy support for request_fulluri: ', false); + $this->outputResult($this->checkHttpsProxyFullUriRequestParam()); } if ($oauth = $config->get('github-oauth')) { foreach ($oauth as $domain => $token) { - $output->write('Checking '.$domain.' oauth access: '); - $this->outputResult($output, $this->checkGithubOauth($domain, $token)); + $this->getIO()->write('Checking '.$domain.' oauth access: ', false); + $this->outputResult($this->checkGithubOauth($domain, $token)); } } else { - $output->write('Checking github.com rate limit: '); + $this->getIO()->write('Checking github.com rate limit: ', false); $rate = $this->getGithubRateLimit('github.com'); if (10 > $rate['remaining']) { - $output->writeln('WARNING'); - $output->writeln(sprintf( + $this->getIO()->write('WARNING'); + $this->getIO()->write(sprintf( 'Github has a rate limit on their API. ' . 'You currently have %u ' . 'out of %u requests left.' . PHP_EOL @@ -112,15 +112,15 @@ EOT $rate['limit'] )); } else { - $output->writeln('OK'); + $this->getIO()->write('OK'); } } - $output->write('Checking disk free space: '); - $this->outputResult($output, $this->checkDiskSpace($config)); + $this->getIO()->write('Checking disk free space: ', false); + $this->outputResult($this->checkDiskSpace($config)); - $output->write('Checking composer version: '); - $this->outputResult($output, $this->checkVersion()); + $this->getIO()->write('Checking composer version: ', false); + $this->outputResult($this->checkVersion()); return $this->failures; } @@ -308,17 +308,17 @@ EOT return true; } - private function outputResult(OutputInterface $output, $result) + private function outputResult($result) { if (true === $result) { - $output->writeln('OK'); + $this->getIO()->write('OK'); } else { $this->failures++; - $output->writeln('FAIL'); + $this->getIO()->write('FAIL'); if ($result instanceof \Exception) { - $output->writeln('['.get_class($result).'] '.$result->getMessage()); + $this->getIO()->write('['.get_class($result).'] '.$result->getMessage()); } elseif ($result) { - $output->writeln(trim($result)); + $this->getIO()->write(trim($result)); } } } diff --git a/src/Composer/Command/DumpAutoloadCommand.php b/src/Composer/Command/DumpAutoloadCommand.php index adcc7adfd..f560953b8 100644 --- a/src/Composer/Command/DumpAutoloadCommand.php +++ b/src/Composer/Command/DumpAutoloadCommand.php @@ -55,9 +55,9 @@ EOT $optimize = $input->getOption('optimize') || $config->get('optimize-autoloader') || $config->get('classmap-authoritative'); if ($optimize) { - $output->writeln('Generating optimized autoload files'); + $this->getIO()->writeError('Generating optimized autoload files'); } else { - $output->writeln('Generating autoload files'); + $this->getIO()->writeError('Generating autoload files'); } $generator = $composer->getAutoloadGenerator(); diff --git a/src/Composer/Command/GlobalCommand.php b/src/Composer/Command/GlobalCommand.php index 15f1fff08..502ce5e8a 100644 --- a/src/Composer/Command/GlobalCommand.php +++ b/src/Composer/Command/GlobalCommand.php @@ -72,7 +72,7 @@ EOT // change to global dir $config = Factory::createConfig(); chdir($config->get('home')); - $output->writeln('Changed current directory to '.$config->get('home').''); + $this->getIO()->writeError('Changed current directory to '.$config->get('home').''); // create new input without "global" command prefix $input = new StringInput(preg_replace('{\bg(?:l(?:o(?:b(?:a(?:l)?)?)?)?)?\b}', '', $input->__toString(), 1)); diff --git a/src/Composer/Command/HomeCommand.php b/src/Composer/Command/HomeCommand.php index 5ea193d5c..51a135c68 100644 --- a/src/Composer/Command/HomeCommand.php +++ b/src/Composer/Command/HomeCommand.php @@ -71,7 +71,7 @@ EOT if (!$package instanceof CompletePackageInterface) { $return = 1; - $output->writeln('Package '.$packageName.' not found'); + $this->getIO()->writeError('Package '.$packageName.' not found'); continue; } @@ -84,13 +84,13 @@ EOT if (!filter_var($url, FILTER_VALIDATE_URL)) { $return = 1; - $output->writeln(''.($input->getOption('homepage') ? 'Invalid or missing homepage' : 'Invalid or missing repository URL').' for '.$packageName.''); + $this->getIO()->writeError(''.($input->getOption('homepage') ? 'Invalid or missing homepage' : 'Invalid or missing repository URL').' for '.$packageName.''); continue; } if ($input->getOption('show')) { - $output->writeln(sprintf('%s', $url)); + $this->getIO()->write(sprintf('%s', $url)); } else { $this->openBrowser($url); } @@ -145,7 +145,7 @@ EOT } elseif (0 === $osx) { passthru('open ' . $url); } else { - $this->getIO()->write('no suitable browser opening command found, open yourself: ' . $url); + $this->getIO()->writeError('no suitable browser opening command found, open yourself: ' . $url); } } diff --git a/src/Composer/Command/InitCommand.php b/src/Composer/Command/InitCommand.php index 38dc2c4a5..7f146c2e5 100644 --- a/src/Composer/Command/InitCommand.php +++ b/src/Composer/Command/InitCommand.php @@ -117,13 +117,13 @@ EOT $json = $file->encode($options); if ($input->isInteractive()) { - $output->writeln(array( + $this->getIO()->writeError(array( '', $json, '' )); if (!$dialog->askConfirmation($output, $dialog->getQuestion('Do you confirm generation', 'yes', '?'), true)) { - $output->writeln('Command aborted'); + $this->getIO()->writeError('Command aborted'); return 1; } @@ -154,14 +154,14 @@ EOT $dialog = $this->getHelperSet()->get('dialog'); $formatter = $this->getHelperSet()->get('formatter'); - $output->writeln(array( + $this->getIO()->writeError(array( '', $formatter->formatBlock('Welcome to the Composer config generator', 'bg=blue;fg=white', true), '' )); // namespace - $output->writeln(array( + $this->getIO()->writeError(array( '', 'This command will guide you through creating your composer.json config.', '', @@ -266,7 +266,7 @@ EOT ); $input->setOption('license', $license); - $output->writeln(array( + $this->getIO()->writeError(array( '', 'Define your dependencies.', '' @@ -316,7 +316,7 @@ EOT $version = $this->findBestVersionForPackage($input, $requirement['name']); $requirement['version'] = $version; - $output->writeln(sprintf( + $this->getIO()->writeError(sprintf( 'Using version %s for %s', $requirement['version'], $requirement['name'] @@ -345,14 +345,14 @@ EOT // no match, prompt which to pick if (!$exactMatch) { - $output->writeln(array( + $this->getIO()->writeError(array( '', sprintf('Found %s packages matching %s', count($matches), $package), '' )); - $output->writeln($choices); - $output->writeln(''); + $this->getIO()->writeError($choices); + $this->getIO()->writeError(''); $validator = function ($selection) use ($matches) { if ('' === $selection) { @@ -392,7 +392,7 @@ EOT if (false === $constraint) { $constraint = $this->findBestVersionForPackage($input, $package); - $output->writeln(sprintf( + $this->getIO()->writeError(sprintf( 'Using version %s for %s', $constraint, $package diff --git a/src/Composer/Command/InstallCommand.php b/src/Composer/Command/InstallCommand.php index 115e1d6af..e548b8d69 100644 --- a/src/Composer/Command/InstallCommand.php +++ b/src/Composer/Command/InstallCommand.php @@ -65,18 +65,18 @@ EOT protected function execute(InputInterface $input, OutputInterface $output) { if ($args = $input->getArgument('packages')) { - $output->writeln('Invalid argument '.implode(' ', $args).'. Use "composer require '.implode(' ', $args).'" instead to add packages to your composer.json.'); + $this->getIO()->writeError('Invalid argument '.implode(' ', $args).'. Use "composer require '.implode(' ', $args).'" instead to add packages to your composer.json.'); return 1; } if ($input->getOption('no-custom-installers')) { - $output->writeln('You are using the deprecated option "no-custom-installers". Use "no-plugins" instead.'); + $this->getIO()->writeError('You are using the deprecated option "no-custom-installers". Use "no-plugins" instead.'); $input->setOption('no-plugins', true); } if ($input->getOption('dev')) { - $output->writeln('You are using the deprecated option "dev". Dev packages are installed by default now.'); + $this->getIO()->writeError('You are using the deprecated option "dev". Dev packages are installed by default now.'); } $composer = $this->getComposer(true, $input->getOption('no-plugins')); diff --git a/src/Composer/Command/LicensesCommand.php b/src/Composer/Command/LicensesCommand.php index 757de6d87..07b7b548b 100644 --- a/src/Composer/Command/LicensesCommand.php +++ b/src/Composer/Command/LicensesCommand.php @@ -68,10 +68,10 @@ EOT switch ($format = $input->getOption('format')) { case 'text': - $output->writeln('Name: '.$root->getPrettyName().''); - $output->writeln('Version: '.$versionParser->formatVersion($root).''); - $output->writeln('Licenses: '.(implode(', ', $root->getLicense()) ?: 'none').''); - $output->writeln('Dependencies:'); + $this->getIO()->write('Name: '.$root->getPrettyName().''); + $this->getIO()->write('Version: '.$versionParser->formatVersion($root).''); + $this->getIO()->write('Licenses: '.(implode(', ', $root->getLicense()) ?: 'none').''); + $this->getIO()->write('Dependencies:'); $table = new Table($output); $table->setStyle('borderless'); @@ -94,7 +94,7 @@ EOT ); } - $output->writeln(JsonFile::encode(array( + $this->getIO()->write(JsonFile::encode(array( 'name' => $root->getPrettyName(), 'version' => $versionParser->formatVersion($root), 'license' => $root->getLicense(), diff --git a/src/Composer/Command/RemoveCommand.php b/src/Composer/Command/RemoveCommand.php index c292a2812..8821bd991 100644 --- a/src/Composer/Command/RemoveCommand.php +++ b/src/Composer/Command/RemoveCommand.php @@ -73,7 +73,7 @@ EOT if (isset($composer[$type][$package])) { $json->removeLink($type, $package); } elseif (isset($composer[$altType][$package])) { - $output->writeln(''.$package.' could not be found in '.$type.' but it is present in '.$altType.''); + $this->getIO()->writeError(''.$package.' could not be found in '.$type.' but it is present in '.$altType.''); $dialog = $this->getHelperSet()->get('dialog'); if ($this->getIO()->isInteractive()) { if ($dialog->askConfirmation($output, $dialog->getQuestion('Do you want to remove it from '.$altType, 'yes', '?'), true)) { @@ -81,7 +81,7 @@ EOT } } } else { - $output->writeln(''.$package.' is not required in your composer.json and has not been removed'); + $this->getIO()->writeError(''.$package.' is not required in your composer.json and has not been removed'); } } @@ -111,7 +111,7 @@ EOT $status = $install->run(); if ($status !== 0) { - $output->writeln("\n".'Removal failed, reverting '.$file.' to its original content.'); + $this->getIO()->writeError("\n".'Removal failed, reverting '.$file.' to its original content.'); file_put_contents($jsonFile->getPath(), $composerBackup); } diff --git a/src/Composer/Command/RequireCommand.php b/src/Composer/Command/RequireCommand.php index ea972aaf0..4391f1d05 100644 --- a/src/Composer/Command/RequireCommand.php +++ b/src/Composer/Command/RequireCommand.php @@ -67,17 +67,17 @@ EOT $newlyCreated = !file_exists($file); if (!file_exists($file) && !file_put_contents($file, "{\n}\n")) { - $output->writeln(''.$file.' could not be created.'); + $this->getIO()->writeError(''.$file.' could not be created.'); return 1; } if (!is_readable($file)) { - $output->writeln(''.$file.' is not readable.'); + $this->getIO()->writeError(''.$file.' is not readable.'); return 1; } if (!is_writable($file)) { - $output->writeln(''.$file.' is not writable.'); + $this->getIO()->writeError(''.$file.' is not writable.'); return 1; } @@ -122,7 +122,7 @@ EOT $json->write($composerDefinition); } - $output->writeln(''.$file.' has been '.($newlyCreated ? 'created' : 'updated').''); + $this->getIO()->writeError(''.$file.' has been '.($newlyCreated ? 'created' : 'updated').''); if ($input->getOption('no-update')) { return 0; @@ -154,10 +154,10 @@ EOT $status = $install->run(); if ($status !== 0) { if ($newlyCreated) { - $output->writeln("\n".'Installation failed, deleting '.$file.'.'); + $this->getIO()->writeError("\n".'Installation failed, deleting '.$file.'.'); unlink($json->getPath()); } else { - $output->writeln("\n".'Installation failed, reverting '.$file.' to its original content.'); + $this->getIO()->writeError("\n".'Installation failed, reverting '.$file.' to its original content.'); file_put_contents($json->getPath(), $composerBackup); } } diff --git a/src/Composer/Command/RunScriptCommand.php b/src/Composer/Command/RunScriptCommand.php index 7e9fe6845..979f86a02 100644 --- a/src/Composer/Command/RunScriptCommand.php +++ b/src/Composer/Command/RunScriptCommand.php @@ -66,7 +66,7 @@ EOT protected function execute(InputInterface $input, OutputInterface $output) { if ($input->getOption('list')) { - return $this->listScripts($input, $output); + return $this->listScripts(); } elseif (!$input->getArgument('script')) { throw new \RunTimeException('Missing required argument "script"'); } @@ -95,7 +95,7 @@ EOT return $composer->getEventDispatcher()->dispatchScript($script, $input->getOption('dev') || !$input->getOption('no-dev'), $args); } - protected function listScripts(InputInterface $input, OutputInterface $output) + protected function listScripts() { $scripts = $this->getComposer()->getPackage()->getScripts(); @@ -103,9 +103,9 @@ EOT return 0; } - $output->writeln('scripts:'); + $this->getIO()->writeError('scripts:'); foreach ($scripts as $name => $script) { - $output->writeln(' ' . $name); + $this->getIO()->write(' ' . $name); } return 0; diff --git a/src/Composer/Command/SearchCommand.php b/src/Composer/Command/SearchCommand.php index b9aaa8d74..54990f30d 100644 --- a/src/Composer/Command/SearchCommand.php +++ b/src/Composer/Command/SearchCommand.php @@ -62,7 +62,7 @@ EOT $repos = new CompositeRepository(array_merge(array($installedRepo), $composer->getRepositoryManager()->getRepositories())); } else { $defaultRepos = Factory::createDefaultRepositories($this->getIO()); - $output->writeln('No composer.json found in the current directory, showing packages from ' . implode(', ', array_keys($defaultRepos))); + $this->getIO()->writeError('No composer.json found in the current directory, showing packages from ' . implode(', ', array_keys($defaultRepos))); $installedRepo = $platformRepo; $repos = new CompositeRepository(array_merge(array($installedRepo), $defaultRepos)); } @@ -78,7 +78,7 @@ EOT $results = $repos->search(implode(' ', $input->getArgument('tokens')), $flags); foreach ($results as $result) { - $output->writeln($result['name'] . (isset($result['description']) ? ' '. $result['description'] : '')); + $this->getIO()->write($result['name'] . (isset($result['description']) ? ' '. $result['description'] : '')); } } } diff --git a/src/Composer/Command/SelfUpdateCommand.php b/src/Composer/Command/SelfUpdateCommand.php index eb0de083e..e4e96e8f4 100644 --- a/src/Composer/Command/SelfUpdateCommand.php +++ b/src/Composer/Command/SelfUpdateCommand.php @@ -84,13 +84,13 @@ EOT $updateVersion = $input->getArgument('version') ?: $latestVersion; if (preg_match('{^[0-9a-f]{40}$}', $updateVersion) && $updateVersion !== $latestVersion) { - $output->writeln('You can not update to a specific SHA-1 as those phars are not available for download'); + $this->getIO()->writeError('You can not update to a specific SHA-1 as those phars are not available for download'); return 1; } if (Composer::VERSION === $updateVersion) { - $output->writeln('You are already using composer version '.$updateVersion.'.'); + $this->getIO()->writeError('You are already using composer version '.$updateVersion.'.'); return 0; } @@ -104,11 +104,11 @@ EOT self::OLD_INSTALL_EXT ); - $output->writeln(sprintf("Updating to version %s.", $updateVersion)); + $this->getIO()->writeError(sprintf("Updating to version %s.", $updateVersion)); $remoteFilename = $baseUrl . (preg_match('{^[0-9a-f]{40}$}', $updateVersion) ? '/composer.phar' : "/download/{$updateVersion}/composer.phar"); $remoteFilesystem->copy(self::HOMEPAGE, $remoteFilename, $tempFilename, !$input->getOption('no-progress')); if (!file_exists($tempFilename)) { - $output->writeln('The download of the new composer version failed for an unexpected reason'); + $this->getIO()->writeError('The download of the new composer version failed for an unexpected reason'); return 1; } @@ -120,22 +120,22 @@ EOT $fs = new Filesystem; foreach ($finder as $file) { $file = (string) $file; - $output->writeln('Removing: '.$file.''); + $this->getIO()->writeError('Removing: '.$file.''); $fs->remove($file); } } if ($err = $this->setLocalPhar($localFilename, $tempFilename, $backupFile)) { - $output->writeln('The file is corrupted ('.$err->getMessage().').'); - $output->writeln('Please re-run the self-update command to try again.'); + $this->getIO()->writeError('The file is corrupted ('.$err->getMessage().').'); + $this->getIO()->writeError('Please re-run the self-update command to try again.'); return 1; } if (file_exists($backupFile)) { - $output->writeln('Use composer self-update --rollback to return to version '.Composer::VERSION); + $this->getIO()->writeError('Use composer self-update --rollback to return to version '.Composer::VERSION); } else { - $output->writeln('A backup of the current version could not be written to '.$backupFile.', no rollback possible'); + $this->getIO()->writeError('A backup of the current version could not be written to '.$backupFile.', no rollback possible'); } } @@ -160,9 +160,9 @@ EOT } $oldFile = $rollbackDir . "/{$rollbackVersion}" . self::OLD_INSTALL_EXT; - $output->writeln(sprintf("Rolling back to version %s.", $rollbackVersion)); + $this->getIO()->writeError(sprintf("Rolling back to version %s.", $rollbackVersion)); if ($err = $this->setLocalPhar($localFilename, $oldFile)) { - $output->writeln('The backup file was corrupted ('.$err->getMessage().') and has been removed.'); + $this->getIO()->writeError('The backup file was corrupted ('.$err->getMessage().') and has been removed.'); return 1; } diff --git a/src/Composer/Command/ShowCommand.php b/src/Composer/Command/ShowCommand.php index 907e99f90..6f2a1dab6 100644 --- a/src/Composer/Command/ShowCommand.php +++ b/src/Composer/Command/ShowCommand.php @@ -84,7 +84,7 @@ EOT } else { $defaultRepos = Factory::createDefaultRepositories($this->getIO()); $repos = new CompositeRepository($defaultRepos); - $output->writeln('No composer.json found in the current directory, showing available packages from ' . implode(', ', array_keys($defaultRepos))); + $this->getIO()->writeError('No composer.json found in the current directory, showing available packages from ' . implode(', ', array_keys($defaultRepos))); } } elseif ($composer) { $localRepo = $composer->getRepositoryManager()->getLocalRepository(); @@ -92,7 +92,7 @@ EOT $repos = new CompositeRepository(array_merge(array($installedRepo), $composer->getRepositoryManager()->getRepositories())); } else { $defaultRepos = Factory::createDefaultRepositories($this->getIO()); - $output->writeln('No composer.json found in the current directory, showing available packages from ' . implode(', ', array_keys($defaultRepos))); + $this->getIO()->writeError('No composer.json found in the current directory, showing available packages from ' . implode(', ', array_keys($defaultRepos))); $installedRepo = $platformRepo; $repos = new CompositeRepository(array_merge(array($installedRepo), $defaultRepos)); } @@ -119,9 +119,9 @@ EOT $this->printLinks($input, $output, $package, 'requires'); $this->printLinks($input, $output, $package, 'devRequires', 'requires (dev)'); if ($package->getSuggests()) { - $output->writeln("\nsuggests"); + $this->getIO()->write("\nsuggests"); foreach ($package->getSuggests() as $suggested => $reason) { - $output->writeln($suggested . ' ' . $reason . ''); + $this->getIO()->write($suggested . ' ' . $reason . ''); } } $this->printLinks($input, $output, $package, 'provides'); @@ -172,7 +172,7 @@ EOT foreach (array('platform:' => true, 'available:' => false, 'installed:' => true) as $type => $showVersion) { if (isset($packages[$type])) { if ($tree) { - $output->writeln($type); + $this->getIO()->write($type); } ksort($packages[$type]); @@ -222,10 +222,10 @@ EOT } else { $output->write($indent . $package); } - $output->writeln(''); + $this->getIO()->write(''); } if ($tree) { - $output->writeln(''); + $this->getIO()->write(''); } } } @@ -285,53 +285,53 @@ EOT */ protected function printMeta(InputInterface $input, OutputInterface $output, CompletePackageInterface $package, array $versions, RepositoryInterface $installedRepo, RepositoryInterface $repos) { - $output->writeln('name : ' . $package->getPrettyName()); - $output->writeln('descrip. : ' . $package->getDescription()); - $output->writeln('keywords : ' . join(', ', $package->getKeywords() ?: array())); + $this->getIO()->write('name : ' . $package->getPrettyName()); + $this->getIO()->write('descrip. : ' . $package->getDescription()); + $this->getIO()->write('keywords : ' . join(', ', $package->getKeywords() ?: array())); $this->printVersions($input, $output, $package, $versions, $installedRepo, $repos); - $output->writeln('type : ' . $package->getType()); - $output->writeln('license : ' . implode(', ', $package->getLicense())); - $output->writeln('source : ' . sprintf('[%s] %s %s', $package->getSourceType(), $package->getSourceUrl(), $package->getSourceReference())); - $output->writeln('dist : ' . sprintf('[%s] %s %s', $package->getDistType(), $package->getDistUrl(), $package->getDistReference())); - $output->writeln('names : ' . implode(', ', $package->getNames())); + $this->getIO()->write('type : ' . $package->getType()); + $this->getIO()->write('license : ' . implode(', ', $package->getLicense())); + $this->getIO()->write('source : ' . sprintf('[%s] %s %s', $package->getSourceType(), $package->getSourceUrl(), $package->getSourceReference())); + $this->getIO()->write('dist : ' . sprintf('[%s] %s %s', $package->getDistType(), $package->getDistUrl(), $package->getDistReference())); + $this->getIO()->write('names : ' . implode(', ', $package->getNames())); if ($package->isAbandoned()) { $replacement = ($package->getReplacementPackage() !== null) ? ' The author suggests using the ' . $package->getReplacementPackage(). ' package instead.' : null; - $output->writeln( + $this->getIO()->writeError( sprintf('Attention: This package is abandoned and no longer maintained.%s', $replacement) ); } if ($package->getSupport()) { - $output->writeln("\nsupport"); + $this->getIO()->write("\nsupport"); foreach ($package->getSupport() as $type => $value) { - $output->writeln('' . $type . ' : '.$value); + $this->getIO()->write('' . $type . ' : '.$value); } } if ($package->getAutoload()) { - $output->writeln("\nautoload"); + $this->getIO()->write("\nautoload"); foreach ($package->getAutoload() as $type => $autoloads) { - $output->writeln('' . $type . ''); + $this->getIO()->write('' . $type . ''); if ($type === 'psr-0') { foreach ($autoloads as $name => $path) { - $output->writeln(($name ?: '*') . ' => ' . (is_array($path) ? implode(', ', $path) : ($path ?: '.'))); + $this->getIO()->write(($name ?: '*') . ' => ' . (is_array($path) ? implode(', ', $path) : ($path ?: '.'))); } } elseif ($type === 'psr-4') { foreach ($autoloads as $name => $path) { - $output->writeln(($name ?: '*') . ' => ' . (is_array($path) ? implode(', ', $path) : ($path ?: '.'))); + $this->getIO()->write(($name ?: '*') . ' => ' . (is_array($path) ? implode(', ', $path) : ($path ?: '.'))); } } elseif ($type === 'classmap') { - $output->writeln(implode(', ', $autoloads)); + $this->getIO()->write(implode(', ', $autoloads)); } } if ($package->getIncludePaths()) { - $output->writeln('include-path'); - $output->writeln(implode(', ', $package->getIncludePaths())); + $this->getIO()->write('include-path'); + $this->getIO()->write(implode(', ', $package->getIncludePaths())); } } } @@ -355,7 +355,7 @@ EOT $versions = implode(', ', $versions); - $output->writeln('versions : ' . $versions); + $this->getIO()->write('versions : ' . $versions); } /** @@ -371,10 +371,10 @@ EOT { $title = $title ?: $linkType; if ($links = $package->{'get'.ucfirst($linkType)}()) { - $output->writeln("\n" . $title . ""); + $this->getIO()->write("\n" . $title . ""); foreach ($links as $link) { - $output->writeln($link->getTarget() . ' ' . $link->getPrettyConstraint() . ''); + $this->getIO()->write($link->getTarget() . ' ' . $link->getPrettyConstraint() . ''); } } } diff --git a/src/Composer/Command/StatusCommand.php b/src/Composer/Command/StatusCommand.php index e458c8fb9..220327cb6 100644 --- a/src/Composer/Command/StatusCommand.php +++ b/src/Composer/Command/StatusCommand.php @@ -76,9 +76,9 @@ EOT // output errors/warnings if (!$errors) { - $output->writeln('No local changes'); + $this->getIO()->writeError('No local changes'); } else { - $output->writeln('You have changes in the following dependencies:'); + $this->getIO()->writeError('You have changes in the following dependencies:'); } foreach ($errors as $path => $changes) { @@ -86,15 +86,15 @@ EOT $indentedChanges = implode("\n", array_map(function ($line) { return ' ' . ltrim($line); }, explode("\n", $changes))); - $output->writeln(''.$path.':'); - $output->writeln($indentedChanges); + $this->getIO()->write(''.$path.':'); + $this->getIO()->write($indentedChanges); } else { - $output->writeln($path); + $this->getIO()->write($path); } } if ($errors && !$input->getOption('verbose')) { - $output->writeln('Use --verbose (-v) to see modified files'); + $this->getIO()->writeError('Use --verbose (-v) to see modified files'); } // Dispatch post-status-command diff --git a/src/Composer/Command/UpdateCommand.php b/src/Composer/Command/UpdateCommand.php index 460075f0f..579236143 100644 --- a/src/Composer/Command/UpdateCommand.php +++ b/src/Composer/Command/UpdateCommand.php @@ -75,12 +75,12 @@ EOT protected function execute(InputInterface $input, OutputInterface $output) { if ($input->getOption('no-custom-installers')) { - $output->writeln('You are using the deprecated option "no-custom-installers". Use "no-plugins" instead.'); + $this->getIO()->writeError('You are using the deprecated option "no-custom-installers". Use "no-plugins" instead.'); $input->setOption('no-plugins', true); } if ($input->getOption('dev')) { - $output->writeln('You are using the deprecated option "dev". Dev packages are installed by default now.'); + $this->getIO()->writeError('You are using the deprecated option "dev". Dev packages are installed by default now.'); } $composer = $this->getComposer(true, $input->getOption('no-plugins')); diff --git a/src/Composer/Command/ValidateCommand.php b/src/Composer/Command/ValidateCommand.php index e7e0860e1..08aaef209 100644 --- a/src/Composer/Command/ValidateCommand.php +++ b/src/Composer/Command/ValidateCommand.php @@ -57,12 +57,12 @@ EOT $file = $input->getArgument('file'); if (!file_exists($file)) { - $output->writeln('' . $file . ' not found.'); + $this->getIO()->writeError('' . $file . ' not found.'); return 1; } if (!is_readable($file)) { - $output->writeln('' . $file . ' is not readable.'); + $this->getIO()->writeError('' . $file . ' is not readable.'); return 1; } @@ -73,16 +73,16 @@ EOT // output errors/warnings if (!$errors && !$publishErrors && !$warnings) { - $output->writeln('' . $file . ' is valid'); + $this->getIO()->write('' . $file . ' is valid'); } elseif (!$errors && !$publishErrors) { - $output->writeln('' . $file . ' is valid, but with a few warnings'); - $output->writeln('See http://getcomposer.org/doc/04-schema.md for details on the schema'); + $this->getIO()->writeError('' . $file . ' is valid, but with a few warnings'); + $this->getIO()->writeError('See http://getcomposer.org/doc/04-schema.md for details on the schema'); } elseif (!$errors) { - $output->writeln('' . $file . ' is valid for simple usage with composer but has'); - $output->writeln('strict errors that make it unable to be published as a package:'); - $output->writeln('See http://getcomposer.org/doc/04-schema.md for details on the schema'); + $this->getIO()->writeError('' . $file . ' is valid for simple usage with composer but has'); + $this->getIO()->writeError('strict errors that make it unable to be published as a package:'); + $this->getIO()->writeError('See http://getcomposer.org/doc/04-schema.md for details on the schema'); } else { - $output->writeln('' . $file . ' is invalid, the following errors/warnings were found:'); + $this->getIO()->writeError('' . $file . ' is invalid, the following errors/warnings were found:'); } $messages = array( @@ -92,7 +92,7 @@ EOT foreach ($messages as $style => $msgs) { foreach ($msgs as $msg) { - $output->writeln('<' . $style . '>' . $msg . ''); + $this->getIO()->writeError('<' . $style . '>' . $msg . ''); } } diff --git a/src/Composer/Console/Application.php b/src/Composer/Console/Application.php index 1c8246f88..f318832bc 100644 --- a/src/Composer/Console/Application.php +++ b/src/Composer/Console/Application.php @@ -15,6 +15,7 @@ namespace Composer\Console; use Symfony\Component\Console\Application as BaseApplication; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; +use Symfony\Component\Console\Output\ConsoleOutputInterface; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Output\ConsoleOutput; use Symfony\Component\Console\Formatter\OutputFormatter; @@ -91,7 +92,7 @@ class Application extends BaseApplication $this->io = new ConsoleIO($input, $output, $this->getHelperSet()); if (version_compare(PHP_VERSION, '5.3.2', '<')) { - $output->writeln('Composer only officially supports PHP 5.3.2 and above, you will most likely encounter problems with your PHP '.PHP_VERSION.', upgrading is strongly recommended.'); + $this->getIO()->writeError('Composer only officially supports PHP 5.3.2 and above, you will most likely encounter problems with your PHP '.PHP_VERSION.', upgrading is strongly recommended.'); } if (defined('COMPOSER_DEV_WARNING_TIME')) { @@ -104,7 +105,7 @@ class Application extends BaseApplication } if ($commandName !== 'self-update' && $commandName !== 'selfupdate') { if (time() > COMPOSER_DEV_WARNING_TIME) { - $output->writeln(sprintf('Warning: This development build of composer is over 30 days old. It is recommended to update it by running "%s self-update" to get the latest version.', $_SERVER['PHP_SELF'])); + $this->getIO()->writeError(sprintf('Warning: This development build of composer is over 30 days old. It is recommended to update it by running "%s self-update" to get the latest version.', $_SERVER['PHP_SELF'])); } } } @@ -117,8 +118,8 @@ class Application extends BaseApplication if ($newWorkDir = $this->getNewWorkingDir($input)) { $oldWorkingDir = getcwd(); chdir($newWorkDir); - if ($output->getVerbosity() >= 4) { - $output->writeln('Changed CWD to ' . getcwd()); + if ($this->getIO()->isDebug() >= 4) { + $this->getIO()->writeError('Changed CWD to ' . getcwd()); } } @@ -129,7 +130,7 @@ class Application extends BaseApplication foreach ($composer['scripts'] as $script => $dummy) { if (!defined('Composer\Script\ScriptEvents::'.str_replace('-', '_', strtoupper($script)))) { if ($this->has($script)) { - $output->writeln('A script named '.$script.' would override a native Composer function and has been skipped'); + $this->getIO()->writeError('A script named '.$script.' would override a native Composer function and has been skipped'); } else { $this->add(new Command\ScriptAliasCommand($script)); } @@ -150,7 +151,7 @@ class Application extends BaseApplication } if (isset($startTime)) { - $output->writeln('Memory usage: '.round(memory_get_usage() / 1024 / 1024, 2).'MB (peak: '.round(memory_get_peak_usage() / 1024 / 1024, 2).'MB), time: '.round(microtime(true) - $startTime, 2).'s'); + $this->getIO->writeError('Memory usage: '.round(memory_get_usage() / 1024 / 1024, 2).'MB (peak: '.round(memory_get_peak_usage() / 1024 / 1024, 2).'MB), time: '.round(microtime(true) - $startTime, 2).'s'); } return $result; @@ -186,23 +187,27 @@ 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) ) { - $output->writeln('The disk hosting '.$dir.' is full, this may be the cause of the following exception'); + $this->getIO()->writeError('The disk hosting '.$dir.' is full, this may be the cause of the following exception'); } } } catch (\Exception $e) { } if (defined('PHP_WINDOWS_VERSION_BUILD') && false !== strpos($exception->getMessage(), 'The system cannot find the path specified')) { - $output->writeln('The following exception may be caused by a stale entry in your cmd.exe AutoRun'); - $output->writeln('Check https://getcomposer.org/doc/articles/troubleshooting.md#-the-system-cannot-find-the-path-specified-windows- for details'); + $this->getIO()->writeError('The following exception may be caused by a stale entry in your cmd.exe AutoRun'); + $this->getIO()->writeError('Check https://getcomposer.org/doc/articles/troubleshooting.md#-the-system-cannot-find-the-path-specified-windows- for details'); } if (false !== strpos($exception->getMessage(), 'fork failed - Cannot allocate memory')) { - $output->writeln('The following exception is caused by a lack of memory and not having swap configured'); - $output->writeln('Check https://getcomposer.org/doc/articles/troubleshooting.md#proc-open-fork-failed-errors for details'); + $this->getIO()->writeError('The following exception is caused by a lack of memory and not having swap configured'); + $this->getIO()->writeError('Check https://getcomposer.org/doc/articles/troubleshooting.md#proc-open-fork-failed-errors for details'); } - return parent::renderException($exception, $output); + if ($output instanceof ConsoleOutputInterface) { + parent::renderException($exception, $output->getErrorOutput()); + } else { + parent::renderException($exception, $output); + } } /** @@ -218,7 +223,7 @@ class Application extends BaseApplication $this->composer = Factory::create($this->io, null, $disablePlugins); } catch (\InvalidArgumentException $e) { if ($required) { - $this->io->write($e->getMessage()); + $this->io->writeError($e->getMessage()); exit(1); } } catch (JsonValidationException $e) { @@ -323,7 +328,6 @@ class Application extends BaseApplication protected function getDefaultHelperSet() { $helperSet = parent::getDefaultHelperSet(); - $helperSet->set(new DialogHelper()); return $helperSet; diff --git a/src/Composer/Downloader/ArchiveDownloader.php b/src/Composer/Downloader/ArchiveDownloader.php index 204c09154..35dfe308a 100644 --- a/src/Composer/Downloader/ArchiveDownloader.php +++ b/src/Composer/Downloader/ArchiveDownloader.php @@ -35,7 +35,7 @@ abstract class ArchiveDownloader extends FileDownloader $fileName = parent::download($package, $path); if ($this->io->isVerbose()) { - $this->io->write(' Extracting archive'); + $this->io->writeError(' Extracting archive'); } try { @@ -77,7 +77,7 @@ abstract class ArchiveDownloader extends FileDownloader // retry downloading if we have an invalid zip file if ($retries && $e instanceof \UnexpectedValueException && class_exists('ZipArchive') && $e->getCode() === \ZipArchive::ER_NOZIP) { - $this->io->write(' Invalid zip file, retrying...'); + $this->io->writeError(' Invalid zip file, retrying...'); usleep(500000); continue; } @@ -88,7 +88,7 @@ abstract class ArchiveDownloader extends FileDownloader break; } - $this->io->write(''); + $this->io->writeError(''); } /** diff --git a/src/Composer/Downloader/DownloadManager.php b/src/Composer/Downloader/DownloadManager.php index 4bbbae5a9..5c0980725 100644 --- a/src/Composer/Downloader/DownloadManager.php +++ b/src/Composer/Downloader/DownloadManager.php @@ -192,7 +192,7 @@ class DownloadManager foreach ($sources as $i => $source) { if (isset($e)) { - $this->io->write(' Now trying to download from ' . $source . ''); + $this->io->writeError(' Now trying to download from ' . $source . ''); } $package->setInstallationSource($source); try { @@ -206,7 +206,7 @@ class DownloadManager throw $e; } - $this->io->write( + $this->io->writeError( ' Failed to download '. $package->getPrettyName(). ' from ' . $source . ': '. diff --git a/src/Composer/Downloader/FileDownloader.php b/src/Composer/Downloader/FileDownloader.php index 96bd57c06..04f8fc4b5 100644 --- a/src/Composer/Downloader/FileDownloader.php +++ b/src/Composer/Downloader/FileDownloader.php @@ -81,7 +81,7 @@ class FileDownloader implements DownloaderInterface throw new \InvalidArgumentException('The given package is missing url information'); } - $this->io->write(" - Installing " . $package->getName() . " (" . VersionParser::formatVersion($package) . ")"); + $this->io->writeError(" - Installing " . $package->getName() . " (" . VersionParser::formatVersion($package) . ")"); $urls = $package->getDistUrls(); while ($url = array_shift($urls)) { @@ -89,11 +89,11 @@ class FileDownloader implements DownloaderInterface return $this->doDownload($package, $path, $url); } catch (\Exception $e) { if ($this->io->isDebug()) { - $this->io->write(''); - $this->io->write('Failed: ['.get_class($e).'] '.$e->getCode().': '.$e->getMessage()); + $this->io->writeError(''); + $this->io->writeError('Failed: ['.get_class($e).'] '.$e->getCode().': '.$e->getMessage()); } elseif (count($urls)) { - $this->io->write(''); - $this->io->write(' Failed, trying the next URL ('.$e->getCode().': '.$e->getMessage().')'); + $this->io->writeError(''); + $this->io->writeError(' Failed, trying the next URL ('.$e->getCode().': '.$e->getMessage().')'); } if (!count($urls)) { @@ -102,7 +102,7 @@ class FileDownloader implements DownloaderInterface } } - $this->io->write(''); + $this->io->writeError(''); } protected function doDownload(PackageInterface $package, $path, $url) @@ -127,7 +127,7 @@ class FileDownloader implements DownloaderInterface // download if we don't have it in cache or the cache is invalidated if (!$this->cache || ($checksum && $checksum !== $this->cache->sha1($cacheKey)) || !$this->cache->copyTo($cacheKey, $fileName)) { if (!$this->outputProgress) { - $this->io->write(' Downloading'); + $this->io->writeError(' Downloading'); } // try to download 3 times then fail hard @@ -142,7 +142,7 @@ class FileDownloader implements DownloaderInterface throw $e; } if ($this->io->isVerbose()) { - $this->io->write(' Download failed, retrying...'); + $this->io->writeError(' Download failed, retrying...'); } usleep(500000); } @@ -152,7 +152,7 @@ class FileDownloader implements DownloaderInterface $this->cache->copyFrom($cacheKey, $fileName); } } else { - $this->io->write(' Loading from cache'); + $this->io->writeError(' Loading from cache'); } if (!file_exists($fileName)) { @@ -205,7 +205,7 @@ class FileDownloader implements DownloaderInterface */ public function remove(PackageInterface $package, $path) { - $this->io->write(" - Removing " . $package->getName() . " (" . VersionParser::formatVersion($package) . ")"); + $this->io->writeError(" - Removing " . $package->getName() . " (" . VersionParser::formatVersion($package) . ")"); if (!$this->filesystem->removeDirectory($path)) { throw new \RuntimeException('Could not completely delete '.$path.', aborting.'); } diff --git a/src/Composer/Downloader/GitDownloader.php b/src/Composer/Downloader/GitDownloader.php index bdebaf4cf..dd8086b84 100644 --- a/src/Composer/Downloader/GitDownloader.php +++ b/src/Composer/Downloader/GitDownloader.php @@ -45,7 +45,7 @@ class GitDownloader extends VcsDownloader $ref = $package->getSourceReference(); $flag = defined('PHP_WINDOWS_VERSION_MAJOR') ? '/D ' : ''; $command = 'git clone --no-checkout %s %s && cd '.$flag.'%2$s && git remote add composer %1$s && git fetch composer'; - $this->io->write(" Cloning ".$ref); + $this->io->writeError(" Cloning ".$ref); $commandCallable = function ($url) use ($ref, $path, $command) { return sprintf($command, ProcessExecutor::escape($url), ProcessExecutor::escape($path), ProcessExecutor::escape($ref)); @@ -78,7 +78,7 @@ class GitDownloader extends VcsDownloader } $ref = $target->getSourceReference(); - $this->io->write(" Checking out ".$ref); + $this->io->writeError(" Checking out ".$ref); $command = 'git remote set-url composer %s && git fetch composer && git fetch --tags composer'; $commandCallable = function ($url) use ($command) { @@ -143,10 +143,10 @@ class GitDownloader extends VcsDownloader $changes = array_map(function ($elem) { return ' '.$elem; }, preg_split('{\s*\r?\n\s*}', $changes)); - $this->io->write(' The package has modified files:'); - $this->io->write(array_slice($changes, 0, 10)); + $this->io->writeError(' The package has modified files:'); + $this->io->writeError(array_slice($changes, 0, 10)); if (count($changes) > 10) { - $this->io->write(' '.count($changes) - 10 . ' more files modified, choose "v" to view the full list'); + $this->io->writeError(' '.count($changes) - 10 . ' more files modified, choose "v" to view the full list'); } while (true) { @@ -167,21 +167,21 @@ class GitDownloader extends VcsDownloader throw new \RuntimeException('Update aborted'); case 'v': - $this->io->write($changes); + $this->io->writeError($changes); break; case '?': default: help: - $this->io->write(array( + $this->io->writeError(array( ' y - discard changes and apply the '.($update ? 'update' : 'uninstall'), ' n - abort the '.($update ? 'update' : 'uninstall').' and let you manually clean things up', ' v - view modified files', )); if ($update) { - $this->io->write(' s - stash changes and try to reapply them after the update'); + $this->io->writeError(' s - stash changes and try to reapply them after the update'); } - $this->io->write(' ? - print help'); + $this->io->writeError(' ? - print help'); break; } } @@ -195,7 +195,7 @@ class GitDownloader extends VcsDownloader $path = $this->normalizePath($path); if ($this->hasStashedChanges) { $this->hasStashedChanges = false; - $this->io->write(' Re-applying stashed changes'); + $this->io->writeError(' Re-applying stashed changes'); if (0 !== $this->process->execute('git stash pop', $output, $path)) { throw new \RuntimeException("Failed to apply stashed changes:\n\n".$this->process->getErrorOutput()); } @@ -261,7 +261,7 @@ class GitDownloader extends VcsDownloader // reference was not found (prints "fatal: reference is not a tree: $ref") if (false !== strpos($this->process->getErrorOutput(), $reference)) { - $this->io->write(' '.$reference.' is gone (history was rewritten?)'); + $this->io->writeError(' '.$reference.' is gone (history was rewritten?)'); } throw new \RuntimeException('Failed to execute ' . GitUtil::sanitizeUrl($command) . "\n\n" . $this->process->getErrorOutput()); diff --git a/src/Composer/Downloader/HgDownloader.php b/src/Composer/Downloader/HgDownloader.php index 3d5cc6209..117cc5a17 100644 --- a/src/Composer/Downloader/HgDownloader.php +++ b/src/Composer/Downloader/HgDownloader.php @@ -27,7 +27,7 @@ class HgDownloader extends VcsDownloader { $url = ProcessExecutor::escape($url); $ref = ProcessExecutor::escape($package->getSourceReference()); - $this->io->write(" Cloning ".$package->getSourceReference()); + $this->io->writeError(" Cloning ".$package->getSourceReference()); $command = sprintf('hg clone %s %s', $url, ProcessExecutor::escape($path)); if (0 !== $this->process->execute($command, $ignoredOutput)) { throw new \RuntimeException('Failed to execute ' . $command . "\n\n" . $this->process->getErrorOutput()); @@ -45,7 +45,7 @@ class HgDownloader extends VcsDownloader { $url = ProcessExecutor::escape($url); $ref = ProcessExecutor::escape($target->getSourceReference()); - $this->io->write(" Updating to ".$target->getSourceReference()); + $this->io->writeError(" Updating to ".$target->getSourceReference()); if (!is_dir($path.'/.hg')) { throw new \RuntimeException('The .hg directory is missing from '.$path.', see http://getcomposer.org/commit-deps for more information'); diff --git a/src/Composer/Downloader/PerforceDownloader.php b/src/Composer/Downloader/PerforceDownloader.php index 683ea9f34..ae2769999 100644 --- a/src/Composer/Downloader/PerforceDownloader.php +++ b/src/Composer/Downloader/PerforceDownloader.php @@ -31,7 +31,7 @@ class PerforceDownloader extends VcsDownloader $ref = $package->getSourceReference(); $label = $this->getLabelFromSourceReference($ref); - $this->io->write(' Cloning ' . $ref); + $this->io->writeError(' Cloning ' . $ref); $this->initPerforce($package, $path, $url); $this->perforce->setStream($ref); $this->perforce->p4Login($this->io); @@ -85,7 +85,7 @@ class PerforceDownloader extends VcsDownloader */ public function getLocalChanges(PackageInterface $package, $path) { - $this->io->write('Perforce driver does not check for local changes before overriding', true); + $this->io->writeError('Perforce driver does not check for local changes before overriding', true); return; } diff --git a/src/Composer/Downloader/SvnDownloader.php b/src/Composer/Downloader/SvnDownloader.php index 689781f6c..975780eb8 100644 --- a/src/Composer/Downloader/SvnDownloader.php +++ b/src/Composer/Downloader/SvnDownloader.php @@ -29,7 +29,7 @@ class SvnDownloader extends VcsDownloader SvnUtil::cleanEnv(); $ref = $package->getSourceReference(); - $this->io->write(" Checking out ".$package->getSourceReference()); + $this->io->writeError(" Checking out ".$package->getSourceReference()); $this->execute($url, "svn co", sprintf("%s/%s", $url, $ref), null, $path); } @@ -52,7 +52,7 @@ class SvnDownloader extends VcsDownloader } } - $this->io->write(" Checking out " . $ref); + $this->io->writeError(" Checking out " . $ref); $this->execute($url, "svn switch" . $flags, sprintf("%s/%s", $url, $ref), $path); } @@ -114,10 +114,10 @@ class SvnDownloader extends VcsDownloader $changes = array_map(function ($elem) { return ' '.$elem; }, preg_split('{\s*\r?\n\s*}', $changes)); - $this->io->write(' The package has modified files:'); - $this->io->write(array_slice($changes, 0, 10)); + $this->io->writeError(' The package has modified files:'); + $this->io->writeError(array_slice($changes, 0, 10)); if (count($changes) > 10) { - $this->io->write(' '.count($changes) - 10 . ' more files modified, choose "v" to view the full list'); + $this->io->writeError(' '.count($changes) - 10 . ' more files modified, choose "v" to view the full list'); } while (true) { @@ -130,12 +130,12 @@ class SvnDownloader extends VcsDownloader throw new \RuntimeException('Update aborted'); case 'v': - $this->io->write($changes); + $this->io->writeError($changes); break; case '?': default: - $this->io->write(array( + $this->io->writeError(array( ' y - discard changes and apply the '.($update ? 'update' : 'uninstall'), ' n - abort the '.($update ? 'update' : 'uninstall').' and let you manually clean things up', ' v - view modified files', diff --git a/src/Composer/Downloader/VcsDownloader.php b/src/Composer/Downloader/VcsDownloader.php index e653794ca..254f6143d 100644 --- a/src/Composer/Downloader/VcsDownloader.php +++ b/src/Composer/Downloader/VcsDownloader.php @@ -54,7 +54,7 @@ abstract class VcsDownloader implements DownloaderInterface, ChangeReportInterfa throw new \InvalidArgumentException('Package '.$package->getPrettyName().' is missing reference information'); } - $this->io->write(" - Installing " . $package->getName() . " (" . VersionParser::formatVersion($package) . ")"); + $this->io->writeError(" - Installing " . $package->getName() . " (" . VersionParser::formatVersion($package) . ")"); $this->filesystem->emptyDirectory($path); $urls = $package->getSourceUrls(); @@ -67,9 +67,9 @@ abstract class VcsDownloader implements DownloaderInterface, ChangeReportInterfa break; } catch (\Exception $e) { if ($this->io->isDebug()) { - $this->io->write('Failed: ['.get_class($e).'] '.$e->getMessage()); + $this->io->writeError('Failed: ['.get_class($e).'] '.$e->getMessage()); } elseif (count($urls)) { - $this->io->write(' Failed, trying the next URL'); + $this->io->writeError(' Failed, trying the next URL'); } if (!count($urls)) { throw $e; @@ -77,7 +77,7 @@ abstract class VcsDownloader implements DownloaderInterface, ChangeReportInterfa } } - $this->io->write(''); + $this->io->writeError(''); } /** @@ -104,7 +104,7 @@ abstract class VcsDownloader implements DownloaderInterface, ChangeReportInterfa $to = VersionParser::formatVersion($target); } - $this->io->write(" - Updating " . $name . " (" . $from . " => " . $to . ")"); + $this->io->writeError(" - Updating " . $name . " (" . $from . " => " . $to . ")"); $this->cleanChanges($initial, $path, true); $urls = $target->getSourceUrls(); @@ -117,9 +117,9 @@ abstract class VcsDownloader implements DownloaderInterface, ChangeReportInterfa break; } catch (\Exception $e) { if ($this->io->isDebug()) { - $this->io->write('Failed: ['.get_class($e).'] '.$e->getMessage()); + $this->io->writeError('Failed: ['.get_class($e).'] '.$e->getMessage()); } elseif (count($urls)) { - $this->io->write(' Failed, trying the next URL'); + $this->io->writeError(' Failed, trying the next URL'); } else { // in case of failed update, try to reapply the changes before aborting $this->reapplyChanges($path); @@ -146,12 +146,12 @@ abstract class VcsDownloader implements DownloaderInterface, ChangeReportInterfa return ' ' . $line; }, explode("\n", $logs))); - $this->io->write(' '.$message); - $this->io->write($logs); + $this->io->writeError(' '.$message); + $this->io->writeError($logs); } } - $this->io->write(''); + $this->io->writeError(''); } /** @@ -159,7 +159,7 @@ abstract class VcsDownloader implements DownloaderInterface, ChangeReportInterfa */ public function remove(PackageInterface $package, $path) { - $this->io->write(" - Removing " . $package->getName() . " (" . $package->getPrettyVersion() . ")"); + $this->io->writeError(" - Removing " . $package->getName() . " (" . $package->getPrettyVersion() . ")"); $this->cleanChanges($package, $path, false); if (!$this->filesystem->removeDirectory($path)) { throw new \RuntimeException('Could not completely delete '.$path.', aborting.'); diff --git a/src/Composer/EventDispatcher/EventDispatcher.php b/src/Composer/EventDispatcher/EventDispatcher.php index 71fa01a41..2fa837615 100644 --- a/src/Composer/EventDispatcher/EventDispatcher.php +++ b/src/Composer/EventDispatcher/EventDispatcher.php @@ -154,11 +154,11 @@ class EventDispatcher $methodName = substr($callable, strpos($callable, '::') + 2); if (!class_exists($className)) { - $this->io->write('Class '.$className.' is not autoloadable, can not call '.$event->getName().' script'); + $this->io->writeError('Class '.$className.' is not autoloadable, can not call '.$event->getName().' script'); continue; } if (!is_callable($callable)) { - $this->io->write('Method '.$callable.' is not callable, can not call '.$event->getName().' script'); + $this->io->writeError('Method '.$callable.' is not callable, can not call '.$event->getName().' script'); continue; } @@ -166,13 +166,13 @@ class EventDispatcher $return = false === $this->executeEventPhpScript($className, $methodName, $event) ? 1 : 0; } catch (\Exception $e) { $message = "Script %s handling the %s event terminated with an exception"; - $this->io->write(''.sprintf($message, $callable, $event->getName()).''); + $this->io->writeError(''.sprintf($message, $callable, $event->getName()).''); throw $e; } } else { $args = implode(' ', array_map(array('Composer\Util\ProcessExecutor','escape'), $event->getArguments())); if (0 !== ($exitCode = $this->process->execute($callable . ($args === '' ? '' : ' '.$args)))) { - $this->io->write(sprintf('Script %s handling the %s event returned with an error', $callable, $event->getName())); + $this->io->writeError(sprintf('Script %s handling the %s event returned with an error', $callable, $event->getName())); throw new \RuntimeException('Error Output: '.$this->process->getErrorOutput(), $exitCode); } diff --git a/src/Composer/Factory.php b/src/Composer/Factory.php index 3290b51dc..da0a9ef63 100644 --- a/src/Composer/Factory.php +++ b/src/Composer/Factory.php @@ -116,7 +116,7 @@ class Factory $file = new JsonFile($home.'/config.json'); if ($file->exists()) { if ($io && $io->isDebug()) { - $io->write('Loading config file ' . $file->getPath()); + $io->writeError('Loading config file ' . $file->getPath()); } $config->merge($file->read()); } @@ -126,7 +126,7 @@ class Factory $file = new JsonFile($config->get('home').'/auth.json'); if ($file->exists()) { if ($io && $io->isDebug()) { - $io->write('Loading config file ' . $file->getPath()); + $io->writeError('Loading config file ' . $file->getPath()); } $config->merge(array('config' => $file->read())); } @@ -227,12 +227,12 @@ class Factory $config->merge($localConfig); if (isset($composerFile)) { if ($io && $io->isDebug()) { - $io->write('Loading config file ' . $composerFile); + $io->writeError('Loading config file ' . $composerFile); } $localAuthFile = new JsonFile(dirname(realpath($composerFile)) . '/auth.json'); if ($localAuthFile->exists()) { if ($io && $io->isDebug()) { - $io->write('Loading config file ' . $localAuthFile->getPath()); + $io->writeError('Loading config file ' . $localAuthFile->getPath()); } $config->merge(array('config' => $localAuthFile->read())); $config->setAuthConfigSource(new JsonConfigSource($localAuthFile, true)); @@ -362,7 +362,7 @@ class Factory $composer = self::createComposer($io, $config->get('home') . '/composer.json', $disablePlugins, $config->get('home'), false); } catch (\Exception $e) { if ($io->isDebug()) { - $io->write('Failed to initialize global composer: '.$e->getMessage()); + $io->writeError('Failed to initialize global composer: '.$e->getMessage()); } } diff --git a/src/Composer/IO/ConsoleIO.php b/src/Composer/IO/ConsoleIO.php index 7df26eabf..7145c8da1 100644 --- a/src/Composer/IO/ConsoleIO.php +++ b/src/Composer/IO/ConsoleIO.php @@ -13,6 +13,7 @@ namespace Composer\IO; use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\ConsoleOutputInterface; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Helper\HelperSet; use Symfony\Component\Process\ExecutableFinder; @@ -29,6 +30,7 @@ class ConsoleIO extends BaseIO protected $output; protected $helperSet; protected $lastMessage; + protected $lastMessageErr; private $startTime; /** @@ -94,6 +96,19 @@ class ConsoleIO extends BaseIO * {@inheritDoc} */ public function write($messages, $newline = true) + { + $this->doWrite($messages, $newline, false); + } + + /** + * {@inheritDoc} + */ + public function writeError($messages, $newline = true) + { + $this->doWrite($messages, $newline, true); + } + + private function doWrite($messages, $newline, $stderr) { if (null !== $this->startTime) { $memoryUsage = memory_get_usage() / 1024 / 1024; @@ -102,6 +117,13 @@ class ConsoleIO extends BaseIO return sprintf('[%.1fMB/%.2fs] %s', $memoryUsage, $timeSpent, $message); }, (array) $messages); } + + if (true === $stderr && $this->output instanceof ConsoleOutputInterface) { + $this->output->getErrorOutput()->write($messages, $newline); + $this->lastMessageErr = join($newline ? "\n" : '', (array) $messages); + return; + } + $this->output->write($messages, $newline); $this->lastMessage = join($newline ? "\n" : '', (array) $messages); } diff --git a/src/Composer/IO/IOInterface.php b/src/Composer/IO/IOInterface.php index f117ce974..a4c4e4f65 100644 --- a/src/Composer/IO/IOInterface.php +++ b/src/Composer/IO/IOInterface.php @@ -64,6 +64,14 @@ interface IOInterface */ public function write($messages, $newline = true); + /** + * 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 + */ + public function writeError($messages, $newline = true); + /** * Overwrites a previous message to the output. * diff --git a/src/Composer/IO/NullIO.php b/src/Composer/IO/NullIO.php index f3ecde0cb..f7fbfc753 100644 --- a/src/Composer/IO/NullIO.php +++ b/src/Composer/IO/NullIO.php @@ -66,6 +66,13 @@ class NullIO extends BaseIO { } + /** + * {@inheritDoc} + */ + public function writeError($messages, $newline = true) + { + } + /** * {@inheritDoc} */ diff --git a/src/Composer/Installer.php b/src/Composer/Installer.php index 72ad6656d..89ecd0643 100644 --- a/src/Composer/Installer.php +++ b/src/Composer/Installer.php @@ -177,7 +177,7 @@ class Installer // purge old require-dev packages to avoid conflicts with the new way of handling dev requirements $devRepo = new InstalledFilesystemRepository(new JsonFile($this->config->get('vendor-dir').'/composer/installed_dev.json')); if ($devRepo->getPackages()) { - $this->io->write('BC Notice: Removing old dev packages to migrate to the new require-dev handling.'); + $this->io->writeError('BC Notice: Removing old dev packages to migrate to the new require-dev handling.'); foreach ($devRepo->getPackages() as $package) { if ($this->installationManager->isPackageInstalled($devRepo, $package)) { $this->installationManager->uninstall($devRepo, new UninstallOperation($package)); @@ -243,7 +243,7 @@ class Installer } } - $this->io->write($suggestion['source'].' suggests installing '.$suggestion['target'].' ('.$suggestion['reason'].')'); + $this->io->writeError($suggestion['source'].' suggests installing '.$suggestion['target'].' ('.$suggestion['reason'].')'); } } @@ -257,7 +257,7 @@ class Installer ? 'Use ' . $package->getReplacementPackage() . ' instead' : 'No replacement was suggested'; - $this->io->write( + $this->io->writeError( sprintf( "Package %s is abandoned, you should avoid using it. %s.", $package->getPrettyName(), @@ -314,16 +314,16 @@ class Installer $this->preferLowest ); if ($updatedLock) { - $this->io->write('Writing lock file'); + $this->io->writeError('Writing lock file'); } } if ($this->dumpAutoloader) { // write autoloader if ($this->optimizeAutoloader) { - $this->io->write('Generating optimized autoload files'); + $this->io->writeError('Generating optimized autoload files'); } else { - $this->io->write('Generating autoload files'); + $this->io->writeError('Generating autoload files'); } $this->autoloadGenerator->setDevMode($this->devMode); @@ -374,7 +374,7 @@ class Installer $this->package->getDevRequires() ); - $this->io->write('Loading composer repositories with package information'); + $this->io->writeError('Loading composer repositories with package information'); // creating repository pool $policy = $this->createPolicy(); @@ -409,7 +409,7 @@ class Installer } if ($this->update) { - $this->io->write('Updating dependencies'.($withDevReqs ? ' (including require-dev)' : '').''); + $this->io->writeError('Updating dependencies'.($withDevReqs ? ' (including require-dev)' : '').''); $request->updateAll(); @@ -460,10 +460,10 @@ class Installer } } } elseif ($installFromLock) { - $this->io->write('Installing dependencies'.($withDevReqs ? ' (including require-dev)' : '').' from lock file'); + $this->io->writeError('Installing dependencies'.($withDevReqs ? ' (including require-dev)' : '').' from lock file'); if (!$this->locker->isFresh()) { - $this->io->write('Warning: The lock file is not up to date with the latest changes in composer.json. You may be getting outdated dependencies. Run update to update them.'); + $this->io->writeError('Warning: The lock file is not up to date with the latest changes in composer.json. You may be getting outdated dependencies. Run update to update them.'); } foreach ($lockedRepository->getPackages() as $package) { @@ -480,7 +480,7 @@ class Installer $request->install($link->getTarget(), $link->getConstraint()); } } else { - $this->io->write('Installing dependencies'.($withDevReqs ? ' (including require-dev)' : '').''); + $this->io->writeError('Installing dependencies'.($withDevReqs ? ' (including require-dev)' : '').''); if ($withDevReqs) { $links = array_merge($this->package->getRequires(), $this->package->getDevRequires()); @@ -503,8 +503,8 @@ class Installer $operations = $solver->solve($request, $this->ignorePlatformReqs); $this->eventDispatcher->dispatchInstallerEvent(InstallerEvents::POST_DEPENDENCIES_SOLVING, $this->devMode, $policy, $pool, $installedRepo, $request, $operations); } catch (SolverProblemsException $e) { - $this->io->write('Your requirements could not be resolved to an installable set of packages.'); - $this->io->write($e->getMessage()); + $this->io->writeError('Your requirements could not be resolved to an installable set of packages.'); + $this->io->writeError($e->getMessage()); return max(1, $e->getCode()); } @@ -514,7 +514,7 @@ class Installer // execute operations if (!$operations) { - $this->io->write('Nothing to install or update'); + $this->io->writeError('Nothing to install or update'); } $operations = $this->movePluginsToFront($operations); @@ -553,8 +553,8 @@ class Installer && $operation->getTargetPackage()->getSourceReference() === $operation->getInitialPackage()->getSourceReference() ) { if ($this->io->isDebug()) { - $this->io->write(' - Skipping update of '. $operation->getTargetPackage()->getPrettyName().' to the same reference-locked version'); - $this->io->write(''); + $this->io->writeError(' - Skipping update of '. $operation->getTargetPackage()->getPrettyName().' to the same reference-locked version'); + $this->io->writeError(''); } continue; @@ -568,11 +568,11 @@ class Installer // output non-alias ops in dry run, output alias ops in debug verbosity if ($this->dryRun && false === strpos($operation->getJobType(), 'Alias')) { - $this->io->write(' - ' . $operation); - $this->io->write(''); + $this->io->writeError(' - ' . $operation); + $this->io->writeError(''); } elseif ($this->io->isDebug() && false !== strpos($operation->getJobType(), 'Alias')) { - $this->io->write(' - ' . $operation); - $this->io->write(''); + $this->io->writeError(' - ' . $operation); + $this->io->writeError(''); } $this->installationManager->execute($localRepo, $operation); @@ -583,12 +583,12 @@ class Installer if ($reason instanceof Rule) { switch ($reason->getReason()) { case Rule::RULE_JOB_INSTALL: - $this->io->write(' REASON: Required by root: '.$reason->getPrettyString($pool)); - $this->io->write(''); + $this->io->writeError(' REASON: Required by root: '.$reason->getPrettyString($pool)); + $this->io->writeError(''); break; case Rule::RULE_PACKAGE_REQUIRES: - $this->io->write(' REASON: '.$reason->getPrettyString($pool)); - $this->io->write(''); + $this->io->writeError(' REASON: '.$reason->getPrettyString($pool)); + $this->io->writeError(''); break; } } @@ -1001,7 +1001,7 @@ class Installer } if (count($depPackages) == 0 && !$nameMatchesRequiredPackage && !in_array($packageName, array('nothing', 'lock'))) { - $this->io->write('Package "' . $packageName . '" listed for update is not installed. Ignoring.'); + $this->io->writeError('Package "' . $packageName . '" listed for update is not installed. Ignoring.'); } foreach ($depPackages as $depPackage) { diff --git a/src/Composer/Installer/LibraryInstaller.php b/src/Composer/Installer/LibraryInstaller.php index 05cd420d7..5d6180bb0 100644 --- a/src/Composer/Installer/LibraryInstaller.php +++ b/src/Composer/Installer/LibraryInstaller.php @@ -197,7 +197,7 @@ class LibraryInstaller implements InstallerInterface foreach ($binaries as $bin) { $binPath = $this->getInstallPath($package).'/'.$bin; if (!file_exists($binPath)) { - $this->io->write(' Skipped installation of bin '.$bin.' for package '.$package->getName().': file not found in package'); + $this->io->writeError(' Skipped installation of bin '.$bin.' for package '.$package->getName().': file not found in package'); continue; } @@ -216,7 +216,7 @@ class LibraryInstaller implements InstallerInterface // is a fresh install of the vendor. @chmod($link, 0777 & ~umask()); } - $this->io->write(' Skipped installation of bin '.$bin.' for package '.$package->getName().': name conflicts with an existing file'); + $this->io->writeError(' Skipped installation of bin '.$bin.' for package '.$package->getName().': name conflicts with an existing file'); continue; } if (defined('PHP_WINDOWS_VERSION_BUILD')) { @@ -226,7 +226,7 @@ class LibraryInstaller implements InstallerInterface @chmod($link, 0777 & ~umask()); $link .= '.bat'; if (file_exists($link)) { - $this->io->write(' Skipped installation of bin '.$bin.'.bat proxy for package '.$package->getName().': a .bat proxy was already installed'); + $this->io->writeError(' Skipped installation of bin '.$bin.'.bat proxy for package '.$package->getName().': a .bat proxy was already installed'); } } if (!file_exists($link)) { diff --git a/src/Composer/Installer/PearInstaller.php b/src/Composer/Installer/PearInstaller.php index fd3bbd976..146e68b95 100644 --- a/src/Composer/Installer/PearInstaller.php +++ b/src/Composer/Installer/PearInstaller.php @@ -76,7 +76,7 @@ class PearInstaller extends LibraryInstaller $pearExtractor->extractTo($this->getInstallPath($package), array('php' => '/', 'script' => '/bin', 'data' => '/data'), $vars); if ($this->io->isVerbose()) { - $this->io->write(' Cleaning up'); + $this->io->writeError(' Cleaning up'); } $this->filesystem->unlink($packageArchive); } diff --git a/src/Composer/Plugin/PluginManager.php b/src/Composer/Plugin/PluginManager.php index 9e4c12391..96b743de1 100644 --- a/src/Composer/Plugin/PluginManager.php +++ b/src/Composer/Plugin/PluginManager.php @@ -127,7 +127,7 @@ class PluginManager } if (!$requiresComposer->matches(new VersionConstraint('==', $this->versionParser->normalize(PluginInterface::PLUGIN_API_VERSION)))) { - $this->io->write("The plugin ".$package->getName()." requires a version of composer-plugin-api that does not match your composer installation. You may need to run composer update with the '--no-plugins' option."); + $this->io->writeError("The plugin ".$package->getName()." requires a version of composer-plugin-api that does not match your composer installation. You may need to run composer update with the '--no-plugins' option."); } $this->registerPackage($package); diff --git a/src/Composer/Repository/ArtifactRepository.php b/src/Composer/Repository/ArtifactRepository.php index 38936e40a..2bb518b8f 100644 --- a/src/Composer/Repository/ArtifactRepository.php +++ b/src/Composer/Repository/ArtifactRepository.php @@ -60,14 +60,14 @@ class ArtifactRepository extends ArrayRepository $package = $this->getComposerInformation($file); if (!$package) { if ($io->isVerbose()) { - $io->write("File {$file->getBasename()} doesn't seem to hold a package"); + $io->writeError("File {$file->getBasename()} doesn't seem to hold a package"); } continue; } if ($io->isVerbose()) { $template = 'Found package %s (%s) in file %s'; - $io->write(sprintf($template, $package->getName(), $package->getPrettyVersion(), $file->getBasename())); + $io->writeError(sprintf($template, $package->getName(), $package->getPrettyVersion(), $file->getBasename())); } $this->addPackage($package); diff --git a/src/Composer/Repository/ComposerRepository.php b/src/Composer/Repository/ComposerRepository.php index ad3c9996b..bd84ae187 100644 --- a/src/Composer/Repository/ComposerRepository.php +++ b/src/Composer/Repository/ComposerRepository.php @@ -434,7 +434,7 @@ class ComposerRepository extends ArrayRepository } if (!empty($data['warning'])) { - $this->io->write('Warning from '.$this->url.': '.$data['warning'].''); + $this->io->writeError('Warning from '.$this->url.': '.$data['warning'].''); } if (!empty($data['providers-lazy-url'])) { @@ -613,8 +613,8 @@ class ComposerRepository extends ArrayRepository if ($cacheKey && ($contents = $this->cache->read($cacheKey))) { if (!$this->degradedMode) { - $this->io->write(''.$e->getMessage().''); - $this->io->write(''.$this->url.' could not be fully loaded, package information was loaded from the local cache and may be out of date'); + $this->io->writeError(''.$e->getMessage().''); + $this->io->writeError(''.$this->url.' could not be fully loaded, package information was loaded from the local cache and may be out of date'); } $this->degradedMode = true; $data = JsonFile::parseJson($contents, $this->cache->getRoot().$cacheKey); diff --git a/src/Composer/Repository/PearRepository.php b/src/Composer/Repository/PearRepository.php index 6086df1ed..1f882eb80 100644 --- a/src/Composer/Repository/PearRepository.php +++ b/src/Composer/Repository/PearRepository.php @@ -66,13 +66,13 @@ class PearRepository extends ArrayRepository { parent::initialize(); - $this->io->write('Initializing PEAR repository '.$this->url); + $this->io->writeError('Initializing PEAR repository '.$this->url); $reader = new ChannelReader($this->rfs); try { $channelInfo = $reader->read($this->url); } catch (\Exception $e) { - $this->io->write('PEAR repository from '.$this->url.' could not be loaded. '.$e->getMessage().''); + $this->io->writeError('PEAR repository from '.$this->url.' could not be loaded. '.$e->getMessage().''); return; } @@ -98,7 +98,7 @@ class PearRepository extends ArrayRepository $normalizedVersion = $versionParser->normalize($version); } catch (\UnexpectedValueException $e) { if ($this->io->isVerbose()) { - $this->io->write('Could not load '.$packageDefinition->getPackageName().' '.$version.': '.$e->getMessage()); + $this->io->writeError('Could not load '.$packageDefinition->getPackageName().' '.$version.': '.$e->getMessage()); } continue; } diff --git a/src/Composer/Repository/Vcs/GitBitbucketDriver.php b/src/Composer/Repository/Vcs/GitBitbucketDriver.php index 68389dc33..199fc48c8 100644 --- a/src/Composer/Repository/Vcs/GitBitbucketDriver.php +++ b/src/Composer/Repository/Vcs/GitBitbucketDriver.php @@ -149,7 +149,7 @@ class GitBitbucketDriver extends VcsDriver implements VcsDriverInterface if (!extension_loaded('openssl')) { if ($io->isVerbose()) { - $io->write('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.'); } return false; diff --git a/src/Composer/Repository/Vcs/GitDriver.php b/src/Composer/Repository/Vcs/GitDriver.php index a859a6869..e9730412d 100644 --- a/src/Composer/Repository/Vcs/GitDriver.php +++ b/src/Composer/Repository/Vcs/GitDriver.php @@ -66,7 +66,7 @@ class GitDriver extends VcsDriver }; $gitUtil->runCommand($commandCallable, $this->url, $this->repoDir); } catch (\Exception $e) { - $this->io->write('Failed to update '.$this->url.', package information from this repository may be outdated ('.$e->getMessage().')'); + $this->io->writeError('Failed to update '.$this->url.', package information from this repository may be outdated ('.$e->getMessage().')'); } } else { // clean up directory and do a fresh clone into it diff --git a/src/Composer/Repository/Vcs/GitHubDriver.php b/src/Composer/Repository/Vcs/GitHubDriver.php index 9dbd21059..fd2e71545 100644 --- a/src/Composer/Repository/Vcs/GitHubDriver.php +++ b/src/Composer/Repository/Vcs/GitHubDriver.php @@ -266,7 +266,7 @@ class GitHubDriver extends VcsDriver if (!extension_loaded('openssl')) { if ($io->isVerbose()) { - $io->write('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.'); } return false; @@ -333,7 +333,7 @@ class GitHubDriver extends VcsDriver if (!$this->io->hasAuthentication($this->originUrl)) { if (!$this->io->isInteractive()) { - $this->io->write('GitHub API limit exhausted. Failed to get metadata for the '.$this->url.' repository, try running in interactive mode so that you can enter your GitHub credentials to increase the API limit'); + $this->io->writeError('GitHub API limit exhausted. Failed to get metadata for the '.$this->url.' repository, try running in interactive mode so that you can enter your GitHub credentials to increase the API limit'); throw $e; } @@ -344,7 +344,7 @@ class GitHubDriver extends VcsDriver if ($rateLimited) { $rateLimit = $this->getRateLimit($e->getHeaders()); - $this->io->write(sprintf( + $this->io->writeError(sprintf( 'GitHub API limit (%d calls/hr) is exhausted. You are already authorized so you have to wait until %s before doing more requests', $rateLimit['limit'], $rateLimit['reset'] @@ -435,7 +435,7 @@ class GitHubDriver extends VcsDriver } catch (\RuntimeException $e) { $this->gitDriver = null; - $this->io->write('Failed to clone the '.$this->generateSshUrl().' repository, try running in interactive mode so that you can enter your GitHub credentials'); + $this->io->writeError('Failed to clone the '.$this->generateSshUrl().' repository, try running in interactive mode so that you can enter your GitHub credentials'); throw $e; } } diff --git a/src/Composer/Repository/Vcs/HgBitbucketDriver.php b/src/Composer/Repository/Vcs/HgBitbucketDriver.php index cc2b386eb..569b83521 100644 --- a/src/Composer/Repository/Vcs/HgBitbucketDriver.php +++ b/src/Composer/Repository/Vcs/HgBitbucketDriver.php @@ -159,7 +159,7 @@ class HgBitbucketDriver extends VcsDriver if (!extension_loaded('openssl')) { if ($io->isVerbose()) { - $io->write('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.'); } return false; diff --git a/src/Composer/Repository/Vcs/HgDriver.php b/src/Composer/Repository/Vcs/HgDriver.php index ed8e927b9..06382f039 100644 --- a/src/Composer/Repository/Vcs/HgDriver.php +++ b/src/Composer/Repository/Vcs/HgDriver.php @@ -50,7 +50,7 @@ class HgDriver extends VcsDriver // update the repo if it is a valid hg repository if (is_dir($this->repoDir) && 0 === $this->process->execute('hg summary', $output, $this->repoDir)) { if (0 !== $this->process->execute('hg pull', $output, $this->repoDir)) { - $this->io->write('Failed to update '.$this->url.', package information from this repository may be outdated ('.$this->process->getErrorOutput().')'); + $this->io->writeError('Failed to update '.$this->url.', package information from this repository may be outdated ('.$this->process->getErrorOutput().')'); } } else { // clean up directory and do a fresh clone into it diff --git a/src/Composer/Repository/VcsRepository.php b/src/Composer/Repository/VcsRepository.php index 6c9dc5d4b..d876ae73e 100644 --- a/src/Composer/Repository/VcsRepository.php +++ b/src/Composer/Repository/VcsRepository.php @@ -127,14 +127,14 @@ class VcsRepository extends ArrayRepository } } catch (\Exception $e) { if ($verbose) { - $this->io->write('Skipped parsing '.$driver->getRootIdentifier().', '.$e->getMessage().''); + $this->io->writeError('Skipped parsing '.$driver->getRootIdentifier().', '.$e->getMessage().''); } } foreach ($driver->getTags() as $tag => $identifier) { $msg = 'Reading composer.json of ' . ($this->packageName ?: $this->url) . ' (' . $tag . ')'; if ($verbose) { - $this->io->write($msg); + $this->io->writeError($msg); } else { $this->io->overwrite($msg, false); } @@ -144,7 +144,7 @@ class VcsRepository extends ArrayRepository if (!$parsedTag = $this->validateTag($tag)) { if ($verbose) { - $this->io->write('Skipped tag '.$tag.', invalid tag name'); + $this->io->writeError('Skipped tag '.$tag.', invalid tag name'); } continue; } @@ -152,7 +152,7 @@ class VcsRepository extends ArrayRepository try { if (!$data = $driver->getComposerInformation($identifier)) { if ($verbose) { - $this->io->write('Skipped tag '.$tag.', no composer file'); + $this->io->writeError('Skipped tag '.$tag.', no composer file'); } continue; } @@ -173,19 +173,19 @@ class VcsRepository extends ArrayRepository // broken package, version doesn't match tag if ($data['version_normalized'] !== $parsedTag) { if ($verbose) { - $this->io->write('Skipped tag '.$tag.', tag ('.$parsedTag.') does not match version ('.$data['version_normalized'].') in composer.json'); + $this->io->writeError('Skipped tag '.$tag.', tag ('.$parsedTag.') does not match version ('.$data['version_normalized'].') in composer.json'); } continue; } if ($verbose) { - $this->io->write('Importing tag '.$tag.' ('.$data['version_normalized'].')'); + $this->io->writeError('Importing tag '.$tag.' ('.$data['version_normalized'].')'); } $this->addPackage($this->loader->load($this->preProcess($driver, $data, $identifier))); } catch (\Exception $e) { if ($verbose) { - $this->io->write('Skipped tag '.$tag.', '.($e instanceof TransportException ? 'no composer file was found' : $e->getMessage()).''); + $this->io->writeError('Skipped tag '.$tag.', '.($e instanceof TransportException ? 'no composer file was found' : $e->getMessage()).''); } continue; } @@ -198,14 +198,14 @@ class VcsRepository extends ArrayRepository foreach ($driver->getBranches() as $branch => $identifier) { $msg = 'Reading composer.json of ' . ($this->packageName ?: $this->url) . ' (' . $branch . ')'; if ($verbose) { - $this->io->write($msg); + $this->io->writeError($msg); } else { $this->io->overwrite($msg, false); } if (!$parsedBranch = $this->validateBranch($branch)) { if ($verbose) { - $this->io->write('Skipped branch '.$branch.', invalid name'); + $this->io->writeError('Skipped branch '.$branch.', invalid name'); } continue; } @@ -213,7 +213,7 @@ class VcsRepository extends ArrayRepository try { if (!$data = $driver->getComposerInformation($identifier)) { if ($verbose) { - $this->io->write('Skipped branch '.$branch.', no composer file'); + $this->io->writeError('Skipped branch '.$branch.', no composer file'); } continue; } @@ -230,7 +230,7 @@ class VcsRepository extends ArrayRepository } if ($verbose) { - $this->io->write('Importing branch '.$branch.' ('.$data['version'].')'); + $this->io->writeError('Importing branch '.$branch.' ('.$data['version'].')'); } $packageData = $this->preProcess($driver, $data, $identifier); @@ -241,16 +241,16 @@ class VcsRepository extends ArrayRepository $this->addPackage($package); } catch (TransportException $e) { if ($verbose) { - $this->io->write('Skipped branch '.$branch.', no composer file was found'); + $this->io->writeError('Skipped branch '.$branch.', no composer file was found'); } continue; } catch (\Exception $e) { if (!$verbose) { - $this->io->write(''); + $this->io->writeError(''); } $this->branchErrorOccurred = true; - $this->io->write('Skipped branch '.$branch.', '.$e->getMessage().''); - $this->io->write(''); + $this->io->writeError('Skipped branch '.$branch.', '.$e->getMessage().''); + $this->io->writeError(''); continue; } } diff --git a/src/Composer/Util/Git.php b/src/Composer/Util/Git.php index c3c5eb02c..f5c87487a 100644 --- a/src/Composer/Util/Git.php +++ b/src/Composer/Util/Git.php @@ -122,7 +122,7 @@ class Git } } - $this->io->write(' Authentication required ('.parse_url($url, PHP_URL_HOST).'):'); + $this->io->writeError(' Authentication required ('.parse_url($url, PHP_URL_HOST).'):'); $auth = array( 'username' => $this->io->ask(' Username: ', $defaultUsername), 'password' => $this->io->askAndHideAnswer(' Password: '), diff --git a/src/Composer/Util/GitHub.php b/src/Composer/Util/GitHub.php index 6008dc062..a994de97b 100644 --- a/src/Composer/Util/GitHub.php +++ b/src/Composer/Util/GitHub.php @@ -77,11 +77,11 @@ class GitHub public function authorizeOAuthInteractively($originUrl, $message = null) { if ($message) { - $this->io->write($message); + $this->io->writeError($message); } - $this->io->write(sprintf('A token will be created and stored in "%s", your password will never be stored', $this->config->getAuthConfigSource()->getName())); - $this->io->write('To revoke access to this token you can visit https://github.com/settings/applications'); + $this->io->writeError(sprintf('A token will be created and stored in "%s", your password will never be stored', $this->config->getAuthConfigSource()->getName())); + $this->io->writeError('To revoke access to this token you can visit https://github.com/settings/applications'); $otp = null; $attemptCounter = 0; @@ -105,13 +105,13 @@ class GitHub } if (401 === $e->getCode()) { - $this->io->write('Bad credentials.'); + $this->io->writeError('Bad credentials.'); } else { - $this->io->write('Maximum number of login attempts exceeded. Please try again later.'); + $this->io->writeError('Maximum number of login attempts exceeded. Please try again later.'); } - $this->io->write('You can also manually create a personal token at https://github.com/settings/applications'); - $this->io->write('Add it using "composer config github-oauth.github.com "'); + $this->io->writeError('You can also manually create a personal token at https://github.com/settings/applications'); + $this->io->writeError('Add it using "composer config github-oauth.github.com "'); continue; } @@ -166,7 +166,7 @@ class GitHub ) )); - $this->io->write('Token successfully created'); + $this->io->writeError('Token successfully created'); return JsonFile::parseJson($json); } @@ -184,14 +184,14 @@ class GitHub list($required, $method) = array_map('trim', explode(';', substr(strstr($headers[$key], ':'), 1))); if ('required' === $required) { - $this->io->write('Two-factor Authentication'); + $this->io->writeError('Two-factor Authentication'); if ('app' === $method) { - $this->io->write('Open the two-factor authentication app on your device to view your authentication code and verify your identity.'); + $this->io->writeError('Open the two-factor authentication app on your device to view your authentication code and verify your identity.'); } if ('sms' === $method) { - $this->io->write('You have been sent an SMS message with an authentication code to verify your identity.'); + $this->io->writeError('You have been sent an SMS message with an authentication code to verify your identity.'); } return $this->io->ask('Authentication Code: '); diff --git a/src/Composer/Util/ProcessExecutor.php b/src/Composer/Util/ProcessExecutor.php index 46dafb0ae..38f5bba00 100644 --- a/src/Composer/Util/ProcessExecutor.php +++ b/src/Composer/Util/ProcessExecutor.php @@ -45,7 +45,7 @@ class ProcessExecutor { if ($this->io && $this->io->isDebug()) { $safeCommand = preg_replace('{(://[^:/\s]+:)[^@\s/]+}i', '$1****', $command); - $this->io->write('Executing command ('.($cwd ?: 'CWD').'): '.$safeCommand); + $this->io->writeError('Executing command ('.($cwd ?: 'CWD').'): '.$safeCommand); } // make sure that null translate to the proper directory in case the dir is a symlink diff --git a/src/Composer/Util/RemoteFilesystem.php b/src/Composer/Util/RemoteFilesystem.php index 455bda92e..ae1938323 100644 --- a/src/Composer/Util/RemoteFilesystem.php +++ b/src/Composer/Util/RemoteFilesystem.php @@ -146,7 +146,7 @@ class RemoteFilesystem $options = $this->getOptionsForUrl($originUrl, $additionalOptions); if ($this->io->isDebug()) { - $this->io->write((substr($fileUrl, 0, 4) === 'http' ? 'Downloading ' : 'Reading ') . $fileUrl); + $this->io->writeError((substr($fileUrl, 0, 4) === 'http' ? 'Downloading ' : 'Reading ') . $fileUrl); } if (isset($options['github-token'])) { $fileUrl .= (false === strpos($fileUrl, '?') ? '?' : '&') . 'access_token='.$options['github-token']; @@ -158,7 +158,7 @@ class RemoteFilesystem $ctx = StreamContextFactory::getContext($fileUrl, $options, array('notification' => array($this, 'callbackGet'))); if ($this->progress) { - $this->io->write(" Downloading: connection...", false); + $this->io->writeError(" Downloading: connection...", false); } $errorMessage = ''; diff --git a/src/Composer/Util/Svn.php b/src/Composer/Util/Svn.php index 4949aa271..af7dc6cbd 100644 --- a/src/Composer/Util/Svn.php +++ b/src/Composer/Util/Svn.php @@ -111,7 +111,7 @@ class Svn } $output .= $buffer; if ($verbose) { - $io->write($buffer, false); + $io->writeError($buffer, false); } }; $status = $this->process->execute($svnCommand, $handler, $cwd); @@ -169,7 +169,7 @@ class Svn ); } - $this->io->write("The Subversion server ({$this->url}) requested credentials:"); + $this->io->writeError("The Subversion server ({$this->url}) requested credentials:"); $this->hasAuth = true; $this->credentials['username'] = $this->io->ask("Username: "); diff --git a/tests/Composer/Test/ApplicationTest.php b/tests/Composer/Test/ApplicationTest.php index c99022671..0f1a076b4 100644 --- a/tests/Composer/Test/ApplicationTest.php +++ b/tests/Composer/Test/ApplicationTest.php @@ -29,7 +29,7 @@ class ApplicationTest extends TestCase ->will($this->returnValue('list')); $outputMock->expects($this->once()) - ->method("writeln") + ->method("write") ->with($this->equalTo(sprintf('Warning: This development build of composer is over 30 days old. It is recommended to update it by running "%s self-update" to get the latest version.', $_SERVER['PHP_SELF']))); if (!defined('COMPOSER_DEV_WARNING_TIME')) { diff --git a/tests/Composer/Test/Autoload/ClassMapGeneratorTest.php b/tests/Composer/Test/Autoload/ClassMapGeneratorTest.php index 1ef68d459..81f99e57b 100644 --- a/tests/Composer/Test/Autoload/ClassMapGeneratorTest.php +++ b/tests/Composer/Test/Autoload/ClassMapGeneratorTest.php @@ -128,7 +128,7 @@ class ClassMapGeneratorTest extends \PHPUnit_Framework_TestCase $msg = ''; $io->expects($this->once()) - ->method('write') + ->method('writeError') ->will($this->returnCallback(function ($text) use (&$msg) { $msg = $text; })); diff --git a/tests/Composer/Test/Downloader/PerforceDownloaderTest.php b/tests/Composer/Test/Downloader/PerforceDownloaderTest.php index 3e2bce2b4..2c113b5ae 100644 --- a/tests/Composer/Test/Downloader/PerforceDownloaderTest.php +++ b/tests/Composer/Test/Downloader/PerforceDownloaderTest.php @@ -120,7 +120,7 @@ class PerforceDownloaderTest extends \PHPUnit_Framework_TestCase $ref = 'SOURCE_REF@123'; $label = 123; $this->package->expects($this->once())->method('getSourceReference')->will($this->returnValue($ref)); - $this->io->expects($this->once())->method('write')->with($this->stringContains('Cloning '.$ref)); + $this->io->expects($this->once())->method('writeError')->with($this->stringContains('Cloning '.$ref)); $perforceMethods = array('setStream', 'p4Login', 'writeP4ClientSpec', 'connectClient', 'syncCodeBase', 'cleanupClientSpec'); $perforce = $this->getMockBuilder('Composer\Util\Perforce', $perforceMethods)->disableOriginalConstructor()->getMock(); $perforce->expects($this->at(0))->method('initializePath')->with($this->equalTo($this->testPath)); @@ -143,7 +143,7 @@ class PerforceDownloaderTest extends \PHPUnit_Framework_TestCase $ref = 'SOURCE_REF'; $label = null; $this->package->expects($this->once())->method('getSourceReference')->will($this->returnValue($ref)); - $this->io->expects($this->once())->method('write')->with($this->stringContains('Cloning '.$ref)); + $this->io->expects($this->once())->method('writeError')->with($this->stringContains('Cloning '.$ref)); $perforceMethods = array('setStream', 'p4Login', 'writeP4ClientSpec', 'connectClient', 'syncCodeBase', 'cleanupClientSpec'); $perforce = $this->getMockBuilder('Composer\Util\Perforce', $perforceMethods)->disableOriginalConstructor()->getMock(); $perforce->expects($this->at(0))->method('initializePath')->with($this->equalTo($this->testPath)); diff --git a/tests/Composer/Test/EventDispatcher/EventDispatcherTest.php b/tests/Composer/Test/EventDispatcher/EventDispatcherTest.php index c750e82a9..06d9c652d 100644 --- a/tests/Composer/Test/EventDispatcher/EventDispatcherTest.php +++ b/tests/Composer/Test/EventDispatcher/EventDispatcherTest.php @@ -33,7 +33,7 @@ class EventDispatcherTest extends TestCase ), $io); $io->expects($this->once()) - ->method('write') + ->method('writeError') ->with('Script Composer\Test\EventDispatcher\EventDispatcherTest::call handling the post-install-cmd event terminated with an exception'); $dispatcher->dispatchScript(ScriptEvents::POST_INSTALL_CMD, false); @@ -189,7 +189,7 @@ class EventDispatcherTest extends TestCase ->will($this->returnValue($listener)); $io->expects($this->once()) - ->method('write') + ->method('writeError') ->with($this->equalTo('Script '.$code.' handling the post-install-cmd event returned with an error')); $this->setExpectedException('RuntimeException'); diff --git a/tests/Composer/Test/Fixtures/functional/create-project-command.test b/tests/Composer/Test/Fixtures/functional/create-project-command.test index 2e4b2762a..c59950274 100644 --- a/tests/Composer/Test/Fixtures/functional/create-project-command.test +++ b/tests/Composer/Test/Fixtures/functional/create-project-command.test @@ -1,6 +1,6 @@ --RUN-- create-project seld/jsonlint %testDir% 1.0.0 --prefer-source -n ---EXPECT-- +--EXPECT-ERROR-- Installing seld/jsonlint (1.0.0) - Installing seld/jsonlint (1.0.0) Cloning 3b4bc2a96ff5d3fe6866bfe9dd0c845246705791 diff --git a/tests/Composer/Test/Fixtures/functional/create-project-shows-full-hash-for-dev-packages.test b/tests/Composer/Test/Fixtures/functional/create-project-shows-full-hash-for-dev-packages.test index 0e5188e41..fa7ecbe32 100644 --- a/tests/Composer/Test/Fixtures/functional/create-project-shows-full-hash-for-dev-packages.test +++ b/tests/Composer/Test/Fixtures/functional/create-project-shows-full-hash-for-dev-packages.test @@ -1,4 +1,4 @@ --RUN-- create-project --repository-url=packages.json -v seld/jsonlint %testDir% dev-master ---EXPECT-REGEX-- +--EXPECT-ERROR-REGEX-- {^Installing seld/jsonlint \(dev-master [a-f0-9]{40}\)} diff --git a/tests/Composer/Test/IO/ConsoleIOTest.php b/tests/Composer/Test/IO/ConsoleIOTest.php index 417ff260c..0edd34d99 100644 --- a/tests/Composer/Test/IO/ConsoleIOTest.php +++ b/tests/Composer/Test/IO/ConsoleIOTest.php @@ -49,6 +49,22 @@ class ConsoleIOTest extends TestCase $consoleIO->write('some information about something', false); } + public function testWriteError() + { + $inputMock = $this->getMock('Symfony\Component\Console\Input\InputInterface'); + $outputMock = $this->getMock('Symfony\Component\Console\Output\ConsoleOutputInterface'); + $outputMock->expects($this->once()) + ->method('getErrorOutput') + ->willReturn($outputMock); + $outputMock->expects($this->once()) + ->method('write') + ->with($this->equalTo('some information about something'), $this->equalTo(false)); + $helperMock = $this->getMock('Symfony\Component\Console\Helper\HelperSet'); + + $consoleIO = new ConsoleIO($inputMock, $outputMock, $helperMock); + $consoleIO->writeError('some information about something', false); + } + public function testWriteWithMultipleLineStringWhenDebugging() { $inputMock = $this->getMock('Symfony\Component\Console\Input\InputInterface'); diff --git a/tests/Composer/Test/InstallerTest.php b/tests/Composer/Test/InstallerTest.php index 0ec1f5972..7fa85d76d 100644 --- a/tests/Composer/Test/InstallerTest.php +++ b/tests/Composer/Test/InstallerTest.php @@ -149,11 +149,15 @@ 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(function ($text, $newline) use (&$output) { - $output .= $text . ($newline ? "\n" : ""); - })); + ->will($this->returnCallback($callback)); + $io->expects($this->any()) + ->method('writeError') + ->will($this->returnCallback($callback)); $composer = FactoryMock::create($io, $composerConfig); @@ -195,10 +199,7 @@ class InstallerTest extends TestCase $composer->setAutoloadGenerator($autoloadGenerator); $composer->setEventDispatcher($eventDispatcher); - $installer = Installer::create( - $io, - $composer - ); + $installer = Installer::create($io, $composer); $application = new Application; $application->get('install')->setCode(function ($input, $output) use ($installer) { diff --git a/tests/Composer/Test/Util/GitHubTest.php b/tests/Composer/Test/Util/GitHubTest.php index 1f30c44a0..488507ec3 100644 --- a/tests/Composer/Test/Util/GitHubTest.php +++ b/tests/Composer/Test/Util/GitHubTest.php @@ -34,7 +34,7 @@ class GitHubTest extends \PHPUnit_Framework_TestCase $io = $this->getIOMock(); $io ->expects($this->at(0)) - ->method('write') + ->method('writeError') ->with($this->message) ; $io