issue with offline sending through gearmanClient
[namibia] / composer.phar
1 #!/usr/bin/env php
2 <?php
3 /*
4  * This file is part of Composer.
5  *
6  * (c) Nils Adermann <naderman@naderman.de>
7  *     Jordi Boggiano <j.boggiano@seld.be>
8  *
9  * For the full copyright and license information, please view
10  * the license that is located at the bottom of this file.
11  */
12
13 // Avoid APC causing random fatal errors per https://github.com/composer/composer/issues/264
14 if (extension_loaded('apc') && ini_get('apc.enable_cli') && ini_get('apc.cache_by_default')) {
15     if (version_compare(phpversion('apc'), '3.0.12', '>=')) {
16         ini_set('apc.cache_by_default', 0);
17     } else {
18         fwrite(STDERR, 'Warning: APC <= 3.0.12 may cause fatal errors when running composer commands.'.PHP_EOL);
19         fwrite(STDERR, 'Update APC, or set apc.enable_cli or apc.cache_by_default to 0 in your php.ini.'.PHP_EOL);
20     }
21 }
22
23 Phar::mapPhar('composer.phar');
24 define('COMPOSER_DEV_WARNING_TIME', 1423113606);
25 require 'phar://composer.phar/bin/composer';
26
27 __HALT_COMPILER(); ?>\r
28 jr\0\0_\ 1\0\0\11\0\0\0\ 1\0\r\0\0\0composer.phar\0\0\0\0\11\0\0\0src/bootstrap.phpÅ\ 1\0\0\86p«TÅ\ 1\0\0¨¯2\90\ 1\0\0\0\0\0\0\1d\0\0\0src/Composer/IO/ConsoleIO.phpâ\ f\0\0\86p«Tâ\ f\0\0\ 4Ú N¶\ 1\0\0\0\0\0\0\1a\0\0\0src/Composer/IO/NullIO.php%\ 3\0\0\86p«T%\ 3\0\0~`\9f\ 4\ 1\0\0\0\0\0\0\1f\0\0\0src/Composer/IO/IOInterface.phpö\ 3\0\0\86p«Tö\ 3\0\0Gj¯:¶\ 1\0\0\0\0\0\0\1a\0\0\0src/Composer/IO/BaseIO.php\ 6\ 5\0\0\86p«T\ 6\ 5\0\0#\ e°.¶\ 1\0\0\0\0\0\0\1c\0\0\0src/Composer/IO/BufferIO.php+\ 4\0\0\86p«T+\ 4\0\0]\v\12í¶\ 1\0\0\0\0\0\0)\0\0\0src/Composer/Command/RunScriptCommand.phpg
29 \0\0\86p«Tg
30 \0\0|̲D¶\ 1\0\0\0\0\0\0(\0\0\0src/Composer/Command/DiagnoseCommand.phpÕ,\0\0\86p«TÕ,\0\0SÛD\r\ 1\0\0\0\0\0\0'\0\0\0src/Composer/Command/ArchiveCommand.phpà\10\0\0\86p«Tà\10\0\0\8c-zG¶\ 1\0\0\0\0\0\0*\0\0\0src/Composer/Command/ClearCacheCommand.phpB\ 5\0\0\86p«TB\ 5\0\0´\13Oã¶\ 1\0\0\0\0\0\0 \0\0\0src/Composer/Command/Command.php\89\ 6\0\0\86p«T\89\ 6\0\0µ\fvJ¶\ 1\0\0\0\0\0\0-\0\0\0src/Composer/Command/CreateProjectCommand.php+1\0\0\86p«T+1\0\0³\90~(¶\ 1\0\0\0\0\0\0%\0\0\0src/Composer/Command/AboutCommand.php¶\ 2\0\0\86p«T¶\ 2\0\0\89²E\8f\ 1\0\0\0\0\0\0+\0\0\0src/Composer/Command/ScriptAliasCommand.php\8d\ 5\0\0\86p«T\8d\ 5\0\0¢ò9J¶\ 1\0\0\0\0\0\0$\0\0\0src/Composer/Command/ShowCommand.php~/\0\0\86p«T~/\0\0\83\8f­J¶\ 1\0\0\0\0\0\0&\0\0\0src/Composer/Command/UpdateCommand.phpK\15\0\0\86p«TK\15\0\0x\v\91\1d\ 1\0\0\0\0\0\0&\0\0\0src/Composer/Command/ConfigCommand.phpõ0\0\0\86p«Tõ0\0\0ÈBÂk¶\ 1\0\0\0\0\0\0'\0\0\0src/Composer/Command/InstallCommand.php:\12\0\0\86p«T:\12\0\0]aI\94\ 1\0\0\0\0\0\0(\0\0\0src/Composer/Command/ValidateCommand.phpq    \0\0\86p«Tq \0\0>Ù:\99\ 1\0\0\0\0\0\0'\0\0\0src/Composer/Command/DependsCommand.phpu
31 \0\0\86p«Tu
32 \0\0¢\84°\99\ 1\0\0\0\0\0\0&\0\0\0src/Composer/Command/SearchCommand.php]       \0\0\86p«T] \0\0\8bÔke¶\ 1\0\0\0\0\0\0*\0\0\0src/Composer/Command/SelfUpdateCommand.php«\19\0\0\86p«T«\19\0\0Nºý'¶\ 1\0\0\0\0\0\0(\0\0\0src/Composer/Command/LicensesCommand.php&\ e\0\0\86p«T&\ e\0\0¾D橶\ 1\0\0\0\0\0\0$\0\0\0src/Composer/Command/HomeCommand.php2\f\0\0\86p«T2\f\0\0yT\1e\ 1\0\0\0\0\0\0'\0\0\0src/Composer/Command/RequireCommand.php§\17\0\0\86p«T§\17\0\0©ÿwÿ¶\ 1\0\0\0\0\0\0,\0\0\0src/Composer/Command/DumpAutoloadCommand.phpÁ\ 6\0\0\86p«TÁ\ 6\0\0\807µh¶\ 1\0\0\0\0\0\0&\0\0\0src/Composer/Command/GlobalCommand.php   \a\0\0\86p«T \a\0\0\16ƶ\ 1\0\0\0\0\0\0&\0\0\0src/Composer/Command/RemoveCommand.phpv\ e\0\0\86p«Tv\ e\0\0B  «É¶\ 1\0\0\0\0\0\0,\0\0\0src/Composer/Command/Helper/DialogHelper.php\9e\ 1\0\0\86p«T\9e\ 1\0\0\95\82\8c\ 1\0\0\0\0\0\0&\0\0\0src/Composer/Command/StatusCommand.phpN   \0\0\86p«TN \0\0\1d\97ö$¶\ 1\0\0\0\0\0\0$\0\0\0src/Composer/Command/InitCommand.php¥6\0\0\86p«T¥6\0\0szÌ@¶\ 1\0\0\0\0\0\0)\0\0\0src/Composer/Downloader/VcsDownloader.phpÀ\11\0\0\86p«TÀ\11\0\0bûíL¶\ 1\0\0\0\0\0\0)\0\0\0src/Composer/Downloader/RarDownloader.phpß\a\0\0\86p«Tß\a\0\0\15¾¼\7f\ 1\0\0\0\0\0\0*\0\0\0src/Composer/Downloader/FileDownloader.php7\15\0\0\86p«T7\15\0\0¼À\90þ¶\ 1\0\0\0\0\0\0)\0\0\0src/Composer/Downloader/SvnDownloader.php9\ f\0\0\86p«T9\ f\0\0]Òë\16\ 1\0\0\0\0\0\00\0\0\0src/Composer/Downloader/PearPackageExtractor.phpa\e\0\0\86p«Ta\e\0\0@ÔØ#¶\ 1\0\0\0\0\0\0+\0\0\0src/Composer/Downloader/DownloadManager.php\87\11\0\0\86p«T\87\11\0\0\7f=
33\ 1\0\0\0\0\0\0/\0\0\0src/Composer/Downloader/DownloaderInterface.phpÊ\ 1\0\0\86p«TÊ\ 1\0\0gs!l¶\ 1\0\0\0\0\0\0.\0\0\0src/Composer/Downloader/TransportException.php\96\ 1\0\0\86p«T\96\ 1\0\0h"Br¶\ 1\0\0\0\0\0\0*\0\0\0src/Composer/Downloader/PharDownloader.phpå\0\0\0\86p«Tå\0\0\0ÞÉ\1fç¶\ 1\0\0\0\0\0\0)\0\0\0src/Composer/Downloader/TarDownloader.phpã\0\0\0\86p«Tã\0\0\0Í\92X?¶\ 1\0\0\0\0\0\0(\0\0\0src/Composer/Downloader/HgDownloader.phpY\b\0\0\86p«TY\b\0\0\8bS¡Ù¶\ 1\0\0\0\0\0\01\0\0\0src/Composer/Downloader/ChangeReportInterface.phpÌ\0\0\0\86p«TÌ\0\0\0¯à¨¿¶\ 1\0\0\0\0\0\0-\0\0\0src/Composer/Downloader/ArchiveDownloader.php\91\r\0\0\86p«T\91\r\0\0H\1c\9cö¶\ 1\0\0\0\0\0\0/\0\0\0src/Composer/Downloader/FilesystemException.php\ f\ 1\0\0\86p«T\ f\ 1\0\0]T½\88\ 1\0\0\0\0\0\0.\0\0\0src/Composer/Downloader/PerforceDownloader.phpn\a\0\0\86p«Tn\a\0\0E¹:¾¶\ 1\0\0\0\0\0\0)\0\0\0src/Composer/Downloader/ZipDownloader.phpC\v\0\0\86p«TC\v\0\0\ 2]^+¶\ 1\0\0\0\0\0\0*\0\0\0src/Composer/Downloader/GzipDownloader.phpÈ\ 5\0\0\86p«TÈ\ 5\0\0­äßж\ 1\0\0\0\0\0\0)\0\0\0src/Composer/Downloader/GitDownloader.php/#\0\0\86p«T/#\0\0\rM(L¶\ 1\0\0\0\0\0\06\0\0\0src/Composer/Repository/InvalidRepositoryException.phpn\0\0\0\86p«Tn\0\0\0à\93ë\98\ 1\0\0\0\0\0\0+\0\0\0src/Composer/Repository/ArrayRepository.php\15\f\0\0\86p«T\15\f\0\0´¯Þ/¶\ 1\0\0\0\0\0\00\0\0\0src/Composer/Repository/FilesystemRepository.phpÀ\ 4\0\0\86p«TÀ\ 4\0\0&xb£¶\ 1\0\0\0\0\0\07\0\0\0src/Composer/Repository/WritableRepositoryInterface.php\89\ 1\0\0\86p«T\89\ 1\0\0\91/sï¶\ 1\0\0\0\0\0\0*\0\0\0src/Composer/Repository/PearRepository.php¡\15\0\0\86p«T¡\15\0\0O¬¶r¶\ 1\0\0\0\0\0\0-\0\0\0src/Composer/Repository/RepositoryManager.php³\a\0\0\86p«T³\a\0\033¸ï¶\ 1\0\0\0\0\0\03\0\0\0src/Composer/Repository/WritableArrayRepository.php\ f\ 3\0\0\86p«T\ f\ 3\0\0¾G\17\ 1\0\0\0\0\0\0,\0\0\0src/Composer/Repository/Vcs/GitHubDriver.php^'\0\0\86p«T^'\0\0k\º<¶\ 1\0\0\0\0\0\02\0\0\0src/Composer/Repository/Vcs/GitBitbucketDriver.phpå\f\0\0\86p«Tå\f\0\0ìQ,L¶\ 1\0\0\0\0\0\0)\0\0\0src/Composer/Repository/Vcs/GitDriver.phpg\15\0\0\86p«Tg\15\0\0×,»Ê¶\ 1\0\0\0\0\0\0.\0\0\0src/Composer/Repository/Vcs/PerforceDriver.php!
34 \0\0\86p«T!
35 \0\0\8d\80Ùk¶\ 1\0\0\0\0\0\0)\0\0\0src/Composer/Repository/Vcs/SvnDriver.php²\19\0\0\86p«T²\19\0\0Ë W¶\ 1\0\0\0\0\0\02\0\0\0src/Composer/Repository/Vcs/VcsDriverInterface.php\89\ 2\0\0\86p«T\89\ 2\0\0pO㤶\ 1\0\0\0\0\0\0(\0\0\0src/Composer/Repository/Vcs/HgDriver.phpÛ\12\0\0\86p«TÛ\12\0\0\1e\ 1\0\0\0\0\0\0)\0\0\0src/Composer/Repository/Vcs/VcsDriver.phpÑ\ 5\0\0\86p«TÑ\ 5\0\0å%\ 6\ 1\0\0\0\0\0\01\0\0\0src/Composer/Repository/Vcs/HgBitbucketDriver.phpí\r\0\0\86p«Tí\r\0\0Ü8)׶\ 1\0\0\0\0\0\04\0\0\0src/Composer/Repository/InstalledArrayRepository.php£\0\0\0\86p«T£\0\0\0/ö~>¶\ 1\0\0\0\0\0\07\0\0\0src/Composer/Repository/RepositorySecurityException.phpo\0\0\0\86p«To\0\0\0pÕ«ª¶\ 1\0\0\0\0\0\0)\0\0\0src/Composer/Repository/VcsRepository.phpá\1c\0\0\86p«Tá\1c\0\0\17à¶\ 1\0\0\0\0\0\0.\0\0\0src/Composer/Repository/PlatformRepository.php\9d\ e\0\0\86p«T\9d\ e\0\0µáÇض\ 1\0\0\0\0\0\09\0\0\0src/Composer/Repository/InstalledFilesystemRepository.php£\0\0\0\86p«T£\0\0\0V
36 \95\ 1\0\0\0\0\0\0/\0\0\0src/Composer/Repository/CompositeRepository.php\b  \0\0\86p«T\b \0\0\ 3\ 1\0\0\0\0\0\08\0\0\0src/Composer/Repository/InstalledRepositoryInterface.php\87\0\0\0\86p«T\87\0\0\0\18£9p¶\ 1\0\0\0\0\0\0.\0\0\0src/Composer/Repository/ComposerRepository.phpa>\0\0\86p«Ta>\0\0\1c_\93ï¶\ 1\0\0\0\0\0\0/\0\0\0src/Composer/Repository/Pear/DependencyInfo.phpq\ 1\0\0\86p«Tq\ 1\0\0fºTò¶\ 1\0\0\0\0\0\08\0\0\0src/Composer/Repository/Pear/PackageDependencyParser.php%\16\0\0\86p«T%\16\0\0\ 6j?\93\ 1\0\0\0\0\0\0,\0\0\0src/Composer/Repository/Pear/ChannelInfo.phpÄ\ 1\0\0\86p«TÄ\ 1\0\0:T*ɶ\ 1\0\0\0\0\0\0.\0\0\0src/Composer/Repository/Pear/ChannelReader.phpn\ 6\0\0\86p«Tn\ 6\0\0\1c\9a8\15\ 1\0\0\0\0\0\0,\0\0\0src/Composer/Repository/Pear/PackageInfo.php°\ 3\0\0\86p«T°\ 3\0\0\9f\r¸\f\ 1\0\0\0\0\0\05\0\0\0src/Composer/Repository/Pear/DependencyConstraint.phpq\ 2\0\0\86p«Tq\ 2\0\09\ e\17\ 1\0\0\0\0\0\04\0\0\0src/Composer/Repository/Pear/ChannelRest11Reader.php& \0\0\86p«T& \0\0òUb\b\ 1\0\0\0\0\0\0,\0\0\0src/Composer/Repository/Pear/ReleaseInfo.php\92\ 1\0\0\86p«T\92\ 1\0\0o\93\8aö\ 1\0\0\0\0\0\02\0\0\0src/Composer/Repository/Pear/BaseChannelReader.php6\ 5\0\0\86p«T6\ 5\0\0.fi!¶\ 1\0\0\0\0\0\04\0\0\0src/Composer/Repository/Pear/ChannelRest10Reader.phpÁ   \0\0\86p«TÁ \0\0\ 4O\80ë¶\ 1\0\0\0\0\0\0/\0\0\0src/Composer/Repository/RepositoryInterface.phpÔ\ 1\0\0\86p«TÔ\ 1\0\0ò\90\9fɶ\ 1\0\0\0\0\0\0.\0\0\0src/Composer/Repository/ArtifactRepository.phpá
37 \0\0\86p«Tá
38 \0\0xQoP¶\ 1\0\0\0\0\0\0-\0\0\0src/Composer/Repository/PackageRepository.phpG\ 3\0\0\86p«TG\ 3\0\0í\ 4:k¶\ 1\0\0\0\0\0\0(\0\0\0src/Composer/Package/CompletePackage.phpÿ\ 6\0\0\86p«Tÿ\ 6\0\0o+ã      ¶\ 1\0\0\0\0\0\0+\0\0\0src/Composer/Package/Dumper/ArrayDumper.phpì\v\0\0\86p«Tì\v\0\0ª\96\7fæ¶\ 1\0\0\0\0\0\07\0\0\0src/Composer/Package/Loader/InvalidPackageException.phpE\ 2\0\0\86p«TE\ 2\0\0xb\13¾¶\ 1\0\0\0\0\0\0*\0\0\0src/Composer/Package/Loader/JsonLoader.phpù\ 1\0\0\86p«Tù\ 1\0\0!~\88\ 1\0\0\0\0\0\0/\0\0\0src/Composer/Package/Loader/LoaderInterface.php²\0\0\0\86p«T²\0\0\0¦}úζ\ 1\0\0\0\0\0\0+\0\0\0src/Composer/Package/Loader/ArrayLoader.phpð\19\0\0\86p«Tð\19\0\0\9f\1cak¶\ 1\0\0\0\0\0\05\0\0\0src/Composer/Package/Loader/ValidatingArrayLoader.php\1f.\0\0\86p«T\1f.\0\0n\ 4{Z¶\ 1\0\0\0\0\0\01\0\0\0src/Composer/Package/Loader/RootPackageLoader.phpN!\0\0\86p«TN!\0\0\91-^À¶\ 1\0\0\0\0\0\0\1f\0\0\0src/Composer/Package/Locker.php¢\1c\0\0\86p«T¢\1c\0\0\8bÝ:â¶\ 1\0\0\0\0\0\0)\0\0\0src/Composer/Package/PackageInterface.php_\a\0\0\86p«T_\a\0\0æ\88¹\82\ 1\0\0\0\0\0\0$\0\0\0src/Composer/Package/BasePackage.phpM\v\0\0\86p«TM\v\0\0·\v%þ¶\ 1\0\0\0\0\0\00\0\0\0src/Composer/Package/Version/VersionSelector.phpü\b\0\0\86p«Tü\b\0\0í\aM¬¶\ 1\0\0\0\0\0\0.\0\0\0src/Composer/Package/Version/VersionParser.phpK-\0\0\86p«TK-\0\0·Ò\9a\ 1\0\0\0\0\0\01\0\0\0src/Composer/Package/CompletePackageInterface.phpõ\ 1\0\0\86p«Tõ\ 1\0\0¦Ê\81ò¶\ 1\0\0\0\0\0\0-\0\0\0src/Composer/Package/RootPackageInterface.php´\ 1\0\0\86p«T´\ 1\0\0êqKж\ 1\0\0\0\0\0\0$\0\0\0src/Composer/Package/RootPackage.phpn\ 4\0\0\86p«Tn\ 4\0\0áACO¶\ 1\0\0\0\0\0\03\0\0\0src/Composer/Package/Archiver/ArchiverInterface.phpï\0\0\0\86p«Tï\0\0\0\a<ʸ¶\ 1\0\0\0\0\0\07\0\0\0src/Composer/Package/Archiver/ComposerExcludeFilter.php\1f\ 1\0\0\86p«T\1f\ 1\0\0\8bSZ0¶\ 1\0\0\0\0\0\0.\0\0\0src/Composer/Package/Archiver/PharArchiver.php[\ 3\0\0\86p«T[\ 3\0\0Ê5Íø¶\ 1\0\0\0\0\0\03\0\0\0src/Composer/Package/Archiver/BaseExcludeFilter.php\91\ 6\0\0\86p«T\91\ 6\0\0\11\ 4Mù¶\ 1\0\0\0\0\0\02\0\0\0src/Composer/Package/Archiver/GitExcludeFilter.phpw\ 3\0\0\86p«Tw\ 3\0\0LgU»¶\ 1\0\0\0\0\0\07\0\0\0src/Composer/Package/Archiver/ArchivableFilesFinder.php¿\ 4\0\0\86p«T¿\ 4\0\0\8ecEl¶\ 1\0\0\0\0\0\00\0\0\0src/Composer/Package/Archiver/ArchiveManager.php'\f\0\0\86p«T'\f\0\0é\e\89ô¶\ 1\0\0\0\0\0\01\0\0\0src/Composer/Package/Archiver/HgExcludeFilter.php\13\ 5\0\0\86p«T\13\ 5\0\0~\94\ e¸¶\ 1\0\0\0\0\0\0)\0\0\0src/Composer/Package/RootAliasPackage.phpÞ\ 3\0\0\86p«TÞ\ 3\0\0Õ\12>\ 5\ 1\0\0\0\0\0\0 \0\0\0src/Composer/Package/Package.phpÄ\1a\0\0\86p«TÄ\1a\0\0\84ô\13\11\ 1\0\0\0\0\0\0%\0\0\0src/Composer/Package/AliasPackage.phpW\16\0\0\86p«TW\16\0\0T/YÁ¶\ 1\0\0\0\0\0\0\1d\0\0\0src/Composer/Package/Link.php*\ 5\0\0\86p«T*\ 5\0\0\1d_\92\85\ 1\0\0\0\0\0\07\0\0\0src/Composer/Package/LinkConstraint/EmptyConstraint.phpê\ 1\0\0\86p«Tê\ 1\0\0\0ì\e¾¶\ 1\0\0\0\0\0\07\0\0\0src/Composer/Package/LinkConstraint/MultiConstraint.phpg\ 4\0\0\86p«Tg\ 4\0\0s\153\ 6\ 1\0\0\0\0\0\09\0\0\0src/Composer/Package/LinkConstraint/VersionConstraint.phpÉ\b\0\0\86p«TÉ\b\0\0y?³Ø¶\ 1\0\0\0\0\0\0:\0\0\0src/Composer/Package/LinkConstraint/SpecificConstraint.phpp\ 2\0\0\86p«Tp\ 2\0\0_\84\88\ 1\0\0\0\0\0\0?\0\0\0src/Composer/Package/LinkConstraint/LinkConstraintInterface.php\15\ 1\0\0\86p«T\15\ 1\0\0åþ\87¢¶\ 1\0\0\0\0\0\0\16\0\0\0src/Composer/Cache.php\11\10\0\0\86p«T\11\10\0\0§û\99«¶\ 1\0\0\0\0\0\03\0\0\0src/Composer/DependencyResolver/PolicyInterface.php\91\ 1\0\0\86p«T\91\ 1\0\0B\18\9f¶¶\ 1\0\0\0\0\0\0+\0\0\0src/Composer/DependencyResolver/RuleSet.php%
39 \0\0\86p«T%
40 \0\09z    \ e\ 1\0\0\0\0\0\06\0\0\0src/Composer/DependencyResolver/SolverBugException.php\98\ 1\0\0\86p«T\98\ 1\0\0\7f"qN¶\ 1\0\0\0\0\0\01\0\0\0src/Composer/DependencyResolver/DefaultPolicy.php\e\17\0\0\86p«T\e\17\0\0\89\16&\97\ 1\0\0\0\0\0\0-\0\0\0src/Composer/DependencyResolver/Decisions.phpQ\ f\0\0\86p«TQ\ f\0\0?\98¬$¶\ 1\0\0\0\0\0\01\0\0\0src/Composer/DependencyResolver/RuleWatchNode.phpç\ 3\0\0\86p«Tç\ 3\0\0\97Þ\12ȶ\ 1\0\0\0\0\0\0;\0\0\0src/Composer/DependencyResolver/SolverProblemsException.php%\ 4\0\0\86p«T%\ 4\0\0T\1aíP¶\ 1\0\0\0\0\0\0/\0\0\0src/Composer/DependencyResolver/Transaction.phpÔ\13\0\0\86p«TÔ\13\0\0 3ô\e\ 1\0\0\0\0\0\0@\0\0\0src/Composer/DependencyResolver/Operation/UninstallOperation.phpI\ 2\0\0\86p«TI\ 2\0\0FûÂɶ\ 1\0\0\0\0\0\0=\0\0\0src/Composer/DependencyResolver/Operation/UpdateOperation.phph\ 3\0\0\86p«Th\ 3\0\0öSÕ]¶\ 1\0\0\0\0\0\0I\0\0\0src/Composer/DependencyResolver/Operation/MarkAliasInstalledOperation.phpÐ\ 2\0\0\86p«TÐ\ 2\0\0xUZa¶\ 1\0\0\0\0\0\0>\0\0\0src/Composer/DependencyResolver/Operation/InstallOperation.phpC\ 2\0\0\86p«TC\ 2\0\0´\õ*¶\ 1\0\0\0\0\0\0=\0\0\0src/Composer/DependencyResolver/Operation/SolverOperation.phpë\ 1\0\0\86p«Të\ 1\0\0ħÝ\94\ 1\0\0\0\0\0\0K\0\0\0src/Composer/DependencyResolver/Operation/MarkAliasUninstalledOperation.phpÖ\ 2\0\0\86p«TÖ\ 2\0\0_iÇ«¶\ 1\0\0\0\0\0\0@\0\0\0src/Composer/DependencyResolver/Operation/OperationInterface.phpÓ\0\0\0\86p«TÓ\0\0\0Ùâ&ä¶\ 1\0\0\0\0\0\0(\0\0\0src/Composer/DependencyResolver/Pool.php\85!\0\0\86p«T\85!\0\0~8ð6¶\ 1\0\0\0\0\0\0(\0\0\0src/Composer/DependencyResolver/Rule.php¡\14\0\0\86p«T¡\14\0\0z#¢Û¶\ 1\0\0\0\0\0\04\0\0\0src/Composer/DependencyResolver/RuleSetGenerator.php]\e\0\0\86p«T]\e\0\04\93Ñ9¶\ 1\0\0\0\0\0\0/\0\0\0src/Composer/DependencyResolver/DebugSolver.php\89\ 6\0\0\86p«T\89\ 6\0\0£Ò­\85\ 1\0\0\0\0\0\03\0\0\0src/Composer/DependencyResolver/RuleSetIterator.php\14\ 6\0\0\86p«T\14\ 6\0\0}õÇù¶\ 1\0\0\0\0\0\02\0\0\0src/Composer/DependencyResolver/RuleWatchChain.phpi\ 1\0\0\86p«Ti\ 1\0\0\9a\ 1\0\0\0\0\0\0*\0\0\0src/Composer/DependencyResolver/Solver.phpè6\0\0\86p«Tè6\0\0|£w0¶\ 1\0\0\0\0\0\0+\0\0\0src/Composer/DependencyResolver/Request.phpÌ\ 4\0\0\86p«TÌ\ 4\0\0\99¦òä¶\ 1\0\0\0\0\0\0+\0\0\0src/Composer/DependencyResolver/Problem.php\1c\12\0\0\86p«T\1c\12\0\0õüùÀ¶\ 1\0\0\0\0\0\02\0\0\0src/Composer/DependencyResolver/RuleWatchGraph.phpÜ\ 6\0\0\86p«TÜ\ 6\0\0\89\ 3\ f\ 1\0\0\0\0\0\0-\0\0\0src/Composer/Config/ConfigSourceInterface.php®\ 1\0\0\86p«T®\ 1\0\06J[ª¶\ 1\0\0\0\0\0\0(\0\0\0src/Composer/Config/JsonConfigSource.php}\f\0\0\86p«T}\f\0\0\ fèÇ ¶\ 1\0\0\0\0\0\0$\0\0\0src/Composer/Plugin/PluginEvents.php¤\0\0\0\86p«T¤\0\0\00ïÞX¶\ 1\0\0\0\0\0\0$\0\0\0src/Composer/Plugin/CommandEvent.phpâ\ 2\0\0\86p«Tâ\ 2\0\0³ÆÇW¶\ 1\0\0\0\0\0\0,\0\0\0src/Composer/Plugin/PreFileDownloadEvent.php`\ 2\0\0\86p«T`\ 2\0\0\09-ζ\ 1\0\0\0\0\0\0'\0\0\0src/Composer/Plugin/PluginInterface.phpô\0\0\0\86p«Tô\0\0\0\f1\89\ 1\0\0\0\0\0\0%\0\0\0src/Composer/Plugin/PluginManager.php\16\17\0\0\86p«T\16\17\0\0²$VU¶\ 1\0\0\0\0\0\0\18\0\0\0src/Composer/Factory.phpÔ,\0\0\86p«TÔ,\0\08ÈÍõ¶\ 1\0\0\0\0\0\0 \0\0\0src/Composer/Util/Filesystem.php4&\0\0\86p«T4&\0\0Rl\97\87\ 1\0\0\0\0\0\0\1c\0\0\0src/Composer/Util/GitHub.php*\11\0\0\86p«T*\11\0\0³\8f?ȶ\ 1\0\0\0\0\0\0$\0\0\0src/Composer/Util/ComposerMirror.php±\ 4\0\0\86p«T±\ 4\0\0­½øض\ 1\0\0\0\0\0\0\1e\0\0\0src/Composer/Util/Perforce.php\b3\0\0\86p«T\b3\0\0\82=e.¶\ 1\0\0\0\0\0\0%\0\0\0src/Composer/Util/ProcessExecutor.phpé\ 6\0\0\86p«Té\ 6\0\0{kßã¶\ 1\0\0\0\0\0\0\19\0\0\0src/Composer/Util/Git.phpM\16\0\0\86p«TM\16\0\0L¢äã¶\ 1\0\0\0\0\0\0&\0\0\0src/Composer/Util/RemoteFilesystem.phpA%\0\0\86p«TA%\0\0\10?\v¨¶\ 1\0\0\0\0\0\0*\0\0\0src/Composer/Util/StreamContextFactory.phpâ\f\0\0\86p«Tâ\f\0\0\eÐ\v\ 1\0\0\0\0\0\0%\0\0\0src/Composer/Util/ConfigValidator.php2\ e\0\0\86p«T2\ e\0\0ö\137.¶\ 1\0\0\0\0\0\0"\0\0\0src/Composer/Util/ErrorHandler.php\14\ 2\0\0\86p«T\14\ 2\0\0´@\85æ¶\ 1\0\0\0\0\0\0 \0\0\0src/Composer/Util/AuthHelper.phpÌ\ 3\0\0\86p«TÌ\ 3\0\0\9c¼\8dÀ¶\ 1\0\0\0\0\0\0+\0\0\0src/Composer/Util/SpdxLicenseIdentifier.php6
41 \0\0\86p«T6
42 \0\0Ä6»o¶\ 1\0\0\0\0\0\0$\0\0\0src/Composer/Util/NoProxyPattern.php¾\ 6\0\0\86p«T¾\ 6\0\0Z+°m¶\ 1\0\0\0\0\0\0\19\0\0\0src/Composer/Util/Svn.php\17\11\0\0\86p«T\17\11\0\0^îÕ\12\ 1\0\0\0\0\0\0\19\0\0\0src/Composer/Composer.php)       \0\0\86p«T) \0\0\1a\ 1\0\0\0\0\0\0%\0\0\0src/Composer/Json/JsonManipulator.php\12%\0\0\86p«T\12%\0\0\17¬¥ô¶\ 1\0\0\0\0\0\0\1e\0\0\0src/Composer/Json/JsonFile.phpy\10\0\0\86p«Ty\10\0\0¼è\7fî¶\ 1\0\0\0\0\0\0#\0\0\0src/Composer/Json/JsonFormatter.php\a\ 6\0\0\86p«T\a\ 6\0\0c\96]Y¶\ 1\0\0\0\0\0\0-\0\0\0src/Composer/Json/JsonValidationException.php]\ 1\0\0\86p«T]\ 1\0\0\10\91#\97\ 1\0\0\0\0\0\0\17\0\0\0src/Composer/Config.php\9a\17\0\0\86p«T\9a\17\0\0¡Ú\90¥¶\ 1\0\0\0\0\0\09\0\0\0src/Composer/EventDispatcher/EventSubscriberInterface.php©\0\0\0\86p«T©\0\0\0\ 1\ 1\0\0\0\0\0\0&\0\0\0src/Composer/EventDispatcher/Event.php \ 2\0\0\86p«T \ 2\0\0±\99jï¶\ 1\0\0\0\0\0\00\0\0\0src/Composer/EventDispatcher/EventDispatcher.php\93\19\0\0\86p«T\93\19\0\0ê®Ñ\93\ 1\0\0\0\0\0\0\1d\0\0\0src/Composer/Script/Event.phpµ\ 2\0\0\86p«Tµ\ 2\0\0lt¦M¶\ 1\0\0\0\0\0\0$\0\0\0src/Composer/Script/ScriptEvents.phpH\ 4\0\0\86p«TH\ 4\0\0¯ðܲ¶\ 1\0\0\0\0\0\0$\0\0\0src/Composer/Script/CommandEvent.phpW\0\0\0\86p«TW\0\0\0£VZt¶\ 1\0\0\0\0\0\0$\0\0\0src/Composer/Script/PackageEvent.php÷\ 1\0\0\86p«T÷\ 1\0\0a\16± ¶\ 1\0\0\0\0\0\0)\0\0\0src/Composer/Installer/InstallerEvent.php\97\ 5\0\0\86p«T\97\ 5\0\0üa\18\1f\ 1\0\0\0\0\0\0(\0\0\0src/Composer/Installer/NoopInstaller.php+\ 5\0\0\86p«T+\ 5\0\0À·M}¶\ 1\0\0\0\0\0\0/\0\0\0src/Composer/Installer/MetapackageInstaller.php\9c\ 4\0\0\86p«T\9c\ 4\0\0Æ\12Å!¶\ 1\0\0\0\0\0\0(\0\0\0src/Composer/Installer/PearInstaller.phpQ\11\0\0\86p«TQ\11\0\0@W\89\8a\ 1\0\0\0\0\0\0+\0\0\0src/Composer/Installer/ProjectInstaller.php\1d\ 6\0\0\86p«T\1d\ 6\0\0*0@P¶\ 1\0\0\0\0\0\0+\0\0\0src/Composer/Installer/LibraryInstaller.phpy\1c\0\0\86p«Ty\1c\0\0
43 M\r°¶\ 1\0\0\0\0\0\0.\0\0\0src/Composer/Installer/InstallationManager.php@\14\0\0\86p«T@\14\0\0\9bö«\ 3\ 1\0\0\0\0\0\0*\0\0\0src/Composer/Installer/InstallerEvents.phpÞ\0\0\0\86p«TÞ\0\0\0ì\9f@G¶\ 1\0\0\0\0\0\0*\0\0\0src/Composer/Installer/PluginInstaller.phpJ\ 6\0\0\86p«TJ\ 6\0\0«\10èV¶\ 1\0\0\0\0\0\0-\0\0\0src/Composer/Installer/InstallerInterface.phpÅ\ 2\0\0\86p«TÅ\ 2\0\0HS\93¡¶\ 1\0\0\0\0\0\0$\0\0\0src/Composer/Console/Application.phpü \0\0\86p«Tü \0\0Çd\13Û¶\ 1\0\0\0\0\0\0,\0\0\0src/Composer/Console/HtmlOutputFormatter.phpÐ\ 5\0\0\86p«TÐ\ 5\0\0ÝF×ê¶\ 1\0\0\0\0\0\0+\0\0\0src/Composer/Autoload/AutoloadGenerator.phpyC\0\0\86p«TyC\0\0Ln¿g¶\ 1\0\0\0\0\0\0+\0\0\0src/Composer/Autoload/ClassMapGenerator.phpE\ e\0\0\86p«TE\ e\0\0Dd\85\ 1\0\0\0\0\0\0\1a\0\0\0src/Composer/Installer.phpÕr\0\0\86p«TÕr\0\0\9a\89_µ¶\ 1\0\0\0\0\0\0%\0\0\0src/Composer/Autoload/ClassLoader.phpç-\0\0\86p«Tç-\0\0\ 5ï0Ú¶\ 1\0\0\0\0\0\0\18\0\0\0res/spdx-identifier.jsonD\10\0\0\86p«TD\10\0\0*Oiò¶\ 1\0\0\0\0\0\0\18\0\0\0res/composer-schema.json_O\0\0\86p«T_O\0\0\87}ÖT¶\ 1\0\0\0\0\0\0\1f\0\0\0src/Composer/IO/hiddeninput.exe\0$\0\0\86p«T\0$\0\0\95\8d¥v¶\ 1\0\0\0\0\0\0?\0\0\0vendor/symfony/process/Symfony/Component/Process/PhpProcess.php\ f\ 3\0\0\86p«T\ f\ 3\0\08ZÔ·¶\ 1\0\0\0\0\0\0E\0\0\0vendor/symfony/process/Symfony/Component/Process/ExecutableFinder.php\8e\ 4\0\0\86p«T\8e\ 4\0\0ëËXʶ\ 1\0\0\0\0\0\0<\0\0\0vendor/symfony/process/Symfony/Component/Process/Process.phpuN\0\0\86p«TuN\0\0@íÃ\81\ 1\0\0\0\0\0\0C\0\0\0vendor/symfony/process/Symfony/Component/Process/ProcessBuilder.php\ 3\v\0\0\86p«T\ 3\v\0\0\848<²¶\ 1\0\0\0\0\0\0A\0\0\0vendor/symfony/process/Symfony/Component/Process/ProcessUtils.php\94\ 5\0\0\86p«T\94\ 5\0\00]ä/¶\ 1\0\0\0\0\0\0W\0\0\0vendor/symfony/process/Symfony/Component/Process/Exception/ProcessTimedOutException.php\1f\ 4\0\0\86p«T\1f\ 4\0\0.      Ãá¶\ 1\0\0\0\0\0\0Q\0\0\0vendor/symfony/process/Symfony/Component/Process/Exception/ExceptionInterface.phpf\0\0\0\86p«Tf\0\0\0]ö>T¶\ 1\0\0\0\0\0\0O\0\0\0vendor/symfony/process/Symfony/Component/Process/Exception/RuntimeException.php\98\0\0\0\86p«T\98\0\0\0¢\eØ:¶\ 1\0\0\0\0\0\0M\0\0\0vendor/symfony/process/Symfony/Component/Process/Exception/LogicException.php\94\0\0\0\86p«T\94\0\0\0 ³ãñ¶\ 1\0\0\0\0\0\0U\0\0\0vendor/symfony/process/Symfony/Component/Process/Exception/ProcessFailedException.php<\ 3\0\0\86p«T<\ 3\0\0"wÛn¶\ 1\0\0\0\0\0\0W\0\0\0vendor/symfony/process/Symfony/Component/Process/Exception/InvalidArgumentException.php¨\0\0\0\86p«T¨\0\0\0ÐÀ+_¶\ 1\0\0\0\0\0\0H\0\0\0vendor/symfony/process/Symfony/Component/Process/PhpExecutableFinder.php\1c\ 4\0\0\86p«T\1c\ 4\0\0¦Fж\ 1\0\0\0\0\0\0I\0\0\0vendor/symfony/process/Symfony/Component/Process/Pipes/PipesInterface.phpD\ 1\0\0\86p«TD\ 1\0\0vØ\ 1\0\0\0\0\0\0H\0\0\0vendor/symfony/process/Symfony/Component/Process/Pipes/AbstractPipes.php\0\ 3\0\0\86p«T\0\ 3\0\0\98|¥¾¶\ 1\0\0\0\0\0\0G\0\0\0vendor/symfony/process/Symfony/Component/Process/Pipes/WindowsPipes.phpÄ\ e\0\0\86p«TÄ\ e\0\0{침¶\ 1\0\0\0\0\0\0D\0\0\0vendor/symfony/process/Symfony/Component/Process/Pipes/UnixPipes.php¬\v\0\0\86p«T¬\v\0\0i\14੶\ 1\0\0\0\0\0\0H\0\0\0vendor/symfony/console/Symfony/Component/Console/Command/HelpCommand.php1\a\0\0\86p«T1\a\0\0ý\1d\80\94\ 1\0\0\0\0\0\0D\0\0\0vendor/symfony/console/Symfony/Component/Console/Command/Command.phpë\e\0\0\86p«Të\e\0\0\ eض\ 1\0\0\0\0\0\0H\0\0\0vendor/symfony/console/Symfony/Component/Console/Command/ListCommand.php³\a\0\0\86p«T³\a\0\0V\ 3Óé¶\ 1\0\0\0\0\0\0M\0\0\0vendor/symfony/console/Symfony/Component/Console/Tester/ApplicationTester.phpÔ\ 5\0\0\86p«TÔ\ 5\0\0¬ì¤d¶\ 1\0\0\0\0\0\0I\0\0\0vendor/symfony/console/Symfony/Component/Console/Tester/CommandTester.php\90\ 6\0\0\86p«T\90\ 6\0\0H»â`¶\ 1\0\0\0\0\0\0X\0\0\0vendor/symfony/console/Symfony/Component/Console/Formatter/OutputFormatterStyleStack.php\b\ 5\0\0\86p«T\b\ 5\0\0y\bI'¶\ 1\0\0\0\0\0\0S\0\0\0vendor/symfony/console/Symfony/Component/Console/Formatter/OutputFormatterStyle.phpÅ\ f\0\0\86p«TÅ\ f\0\0ÂÚ³\15\ 1\0\0\0\0\0\0\\0\0\0vendor/symfony/console/Symfony/Component/Console/Formatter/OutputFormatterStyleInterface.php\8e\ 1\0\0\86p«T\8e\ 1\0\0öëÄ=¶\ 1\0\0\0\0\0\0N\0\0\0vendor/symfony/console/Symfony/Component/Console/Formatter/OutputFormatter.php\88\f\0\0\86p«T\88\f\0\0+ÂF5¶\ 1\0\0\0\0\0\0W\0\0\0vendor/symfony/console/Symfony/Component/Console/Formatter/OutputFormatterInterface.php\98\ 1\0\0\86p«T\98\ 1\0\03l~´¶\ 1\0\0\0\0\0\0@\0\0\0vendor/symfony/console/Symfony/Component/Console/Application.php{Q\0\0\86p«T{Q\0\0W\1f\võ¶\ 1\0\0\0\0\0\0H\0\0\0vendor/symfony/console/Symfony/Component/Console/Input/InputArgument.php\9e\ 5\0\0\86p«T\9e\ 5\0\0K]ìi¶\ 1\0\0\0\0\0\0@\0\0\0vendor/symfony/console/Symfony/Component/Console/Input/Input.php\12
44 \0\0\86p«T\12
45 \0\0ÇýT\ 5\ 1\0\0\0\0\0\0F\0\0\0vendor/symfony/console/Symfony/Component/Console/Input/StringInput.php\8b\ 5\0\0\86p«T\8b\ 5\0\0\86uný¶\ 1\0\0\0\0\0\0F\0\0\0vendor/symfony/console/Symfony/Component/Console/Input/InputOption.php«\v\0\0\86p«T«\v\0\0ê\86®½¶\ 1\0\0\0\0\0\0D\0\0\0vendor/symfony/console/Symfony/Component/Console/Input/ArgvInput.phpÄ\13\0\0\86p«TÄ\13\0\0ÌSGd¶\ 1\0\0\0\0\0\0I\0\0\0vendor/symfony/console/Symfony/Component/Console/Input/InputInterface.php \ 3\0\0\86p«T \ 3\0\09\94øǶ\ 1\0\0\0\0\0\0E\0\0\0vendor/symfony/console/Symfony/Component/Console/Input/ArrayInput.phpõ       \0\0\86p«Tõ \0\0É×\81\99\ 1\0\0\0\0\0\0N\0\0\0vendor/symfony/console/Symfony/Component/Console/Input/InputAwareInterface.php\9a\0\0\0\86p«T\9a\0\0\0\87jT\9f\ 1\0\0\0\0\0\0J\0\0\0vendor/symfony/console/Symfony/Component/Console/Input/InputDefinition.php\v\17\0\0\86p«T\v\17\0\0\98£JM¶\ 1\0\0\0\0\0\0:\0\0\0vendor/symfony/console/Symfony/Component/Console/Shell.php.\ f\0\0\86p«T.\ f\0\0þÉ\8e\87\ 1\0\0\0\0\0\0L\0\0\0vendor/symfony/console/Symfony/Component/Console/Question/ChoiceQuestion.phpZ\a\0\0\86p«TZ\a\0\0C8\17\ 1\0\0\0\0\0\0R\0\0\0vendor/symfony/console/Symfony/Component/Console/Question/ConfirmationQuestion.php@\ 2\0\0\86p«T@\ 2\0\0Y\93B;¶\ 1\0\0\0\0\0\0F\0\0\0vendor/symfony/console/Symfony/Component/Console/Question/Question.php®\b\0\0\86p«T®\b\0\0.e8Ö¶\ 1\0\0\0\0\0\0B\0\0\0vendor/symfony/console/Symfony/Component/Console/Output/Output.php§\b\0\0\86p«T§\b\0\0\1cÚ _¶\ 1\0\0\0\0\0\0F\0\0\0vendor/symfony/console/Symfony/Component/Console/Output/NullOutput.php¿\ 3\0\0\86p«T¿\ 3\0\0`5E˶\ 1\0\0\0\0\0\0R\0\0\0vendor/symfony/console/Symfony/Component/Console/Output/ConsoleOutputInterface.phpå\0\0\0\86p«Tå\0\0\0rNô\0\ 1\0\0\0\0\0\0H\0\0\0vendor/symfony/console/Symfony/Component/Console/Output/StreamOutput.php¢\ 4\0\0\86p«T¢\ 4\0\0\1a\ 6ü0¶\ 1\0\0\0\0\0\0J\0\0\0vendor/symfony/console/Symfony/Component/Console/Output/BufferedOutput.php_\ 1\0\0\86p«T_\ 1\0\0ûBÍ·¶\ 1\0\0\0\0\0\0K\0\0\0vendor/symfony/console/Symfony/Component/Console/Output/OutputInterface.phpI\ 3\0\0\86p«TI\ 3\0\0ÈâãB¶\ 1\0\0\0\0\0\0I\0\0\0vendor/symfony/console/Symfony/Component/Console/Output/ConsoleOutput.php\14\ 5\0\0\86p«T\14\ 5\0\0jå¬\ 6\ 1\0\0\0\0\0\0I\0\0\0vendor/symfony/console/Symfony/Component/Console/Logger/ConsoleLogger.php9  \0\0\86p«T9 \0\0ã\ 3\99ç¶\ 1\0\0\0\0\0\0S\0\0\0vendor/symfony/console/Symfony/Component/Console/Descriptor/DescriptorInterface.phpü\0\0\0\86p«Tü\0\0\0±Q\aµ¶\ 1\0\0\0\0\0\0N\0\0\0vendor/symfony/console/Symfony/Component/Console/Descriptor/TextDescriptor.php4\1a\0\0\86p«T4\1a\0\0Ô±\96\ 1\0\0\0\0\0\0M\0\0\0vendor/symfony/console/Symfony/Component/Console/Descriptor/XmlDescriptor.php\9e\1c\0\0\86p«T\9e\1c\0\0Ò\91¦j¶\ 1\0\0\0\0\0\0R\0\0\0vendor/symfony/console/Symfony/Component/Console/Descriptor/MarkdownDescriptor.php\16\ e\0\0\86p«T\16\ e\0\0ìC/\83\ 1\0\0\0\0\0\0V\0\0\0vendor/symfony/console/Symfony/Component/Console/Descriptor/ApplicationDescription.php÷\a\0\0\86p«T÷\a\0\0)Ißð¶\ 1\0\0\0\0\0\0J\0\0\0vendor/symfony/console/Symfony/Component/Console/Descriptor/Descriptor.phpZ\a\0\0\86p«TZ\a\0\0v;\83ö¶\ 1\0\0\0\0\0\0N\0\0\0vendor/symfony/console/Symfony/Component/Console/Descriptor/JsonDescriptor.php0\r\0\0\86p«T0\r\0\0\vFÄ`¶\ 1\0\0\0\0\0\0K\0\0\0vendor/symfony/console/Symfony/Component/Console/Helper/HelperInterface.phpï\0\0\0\86p«Tï\0\0\0=e\e\f\ 1\0\0\0\0\0\0G\0\0\0vendor/symfony/console/Symfony/Component/Console/Helper/TableHelper.phpß
46 \0\0\86p«Tß
47 \0\0\85kzζ\ 1\0\0\0\0\0\0A\0\0\0vendor/symfony/console/Symfony/Component/Console/Helper/Table.php\ 6\17\0\0\86p«T\ 6\17\0\0µlk\98\ 1\0\0\0\0\0\0G\0\0\0vendor/symfony/console/Symfony/Component/Console/Helper/ProgressBar.php\15$\0\0\86p«T\15$\0\02\8c5J¶\ 1\0\0\0\0\0\0L\0\0\0vendor/symfony/console/Symfony/Component/Console/Helper/DescriptorHelper.php9\ 5\0\0\86p«T9\ 5\0\0ûùäð¶\ 1\0\0\0\0\0\0K\0\0\0vendor/symfony/console/Symfony/Component/Console/Helper/FormatterHelper.php\1e\ 4\0\0\86p«T\1e\ 4\0\0\9eI\82\81\ 1\0\0\0\0\0\0P\0\0\0vendor/symfony/console/Symfony/Component/Console/Helper/DebugFormatterHelper.phpm\b\0\0\86p«Tm\b\0\0ò¯s>¶\ 1\0\0\0\0\0\0I\0\0\0vendor/symfony/console/Symfony/Component/Console/Helper/ProcessHelper.phpâ\b\0\0\86p«Tâ\b\0\0|\7f̼¶\ 1\0\0\0\0\0\0E\0\0\0vendor/symfony/console/Symfony/Component/Console/Helper/HelperSet.php/\ 4\0\0\86p«T/\ 4\0\0âw\0\ 1\0\0\0\0\0\0H\0\0\0vendor/symfony/console/Symfony/Component/Console/Helper/DialogHelper.phpÓ\e\0\0\86p«TÓ\e\0\0jWð\90\ 1\0\0\0\0\0\0J\0\0\0vendor/symfony/console/Symfony/Component/Console/Helper/QuestionHelper.phpp\18\0\0\86p«Tp\18\0\0¿7(ݶ\ 1\0\0\0\0\0\0J\0\0\0vendor/symfony/console/Symfony/Component/Console/Helper/TableSeparator.php[\0\0\0\86p«T[\0\0\0LV\16¡¶\ 1\0\0\0\0\0\0B\0\0\0vendor/symfony/console/Symfony/Component/Console/Helper/Helper.phpß\ 6\0\0\86p«Tß\ 6\0\0\ 1ã¶\ 1\0\0\0\0\0\0J\0\0\0vendor/symfony/console/Symfony/Component/Console/Helper/ProgressHelper.php\83\19\0\0\86p«T\83\19\0\0ê\ 5ëä¶\ 1\0\0\0\0\0\0L\0\0\0vendor/symfony/console/Symfony/Component/Console/Helper/InputAwareHelper.phpc\ 1\0\0\86p«Tc\ 1\0\0ñø\90\ 1\0\0\0\0\0\0F\0\0\0vendor/symfony/console/Symfony/Component/Console/Helper/TableStyle.phpÕ\b\0\0\86p«TÕ\b\0\0æ"ðù¶\ 1\0\0\0\0\0\0G\0\0\0vendor/symfony/console/Symfony/Component/Console/Event/ConsoleEvent.phpÅ\ 2\0\0\86p«TÅ\ 2\0\0ÒxÛ\¶\ 1\0\0\0\0\0\0P\0\0\0vendor/symfony/console/Symfony/Component/Console/Event/ConsoleTerminateEvent.phpz\ 2\0\0\86p«Tz\ 2\0\0³,îL¶\ 1\0\0\0\0\0\0P\0\0\0vendor/symfony/console/Symfony/Component/Console/Event/ConsoleExceptionEvent.php\12\ 3\0\0\86p«T\12\ 3\0\0á\162é¶\ 1\0\0\0\0\0\0N\0\0\0vendor/symfony/console/Symfony/Component/Console/Event/ConsoleCommandEvent.php²\ 1\0\0\86p«T²\ 1\0\0Zk\89\ 1\0\0\0\0\0\0B\0\0\0vendor/symfony/console/Symfony/Component/Console/ConsoleEvents.phpï\0\0\0\86p«Tï\0\0\0\rÕH¸¶\ 1\0\0\0\0\0\09\0\0\0vendor/symfony/finder/Symfony/Component/Finder/Finder.phpÍ \0\0\86p«TÍ \0\0ÿÛ¹1¶\ 1\0\0\0\0\0\0@\0\0\0vendor/symfony/finder/Symfony/Component/Finder/Shell/Command.php©
48 \0\0\86p«T©
49 \0\0V\82\84\ 1\0\0\0\0\0\0>\0\0\0vendor/symfony/finder/Symfony/Component/Finder/Shell/Shell.phpé\ 3\0\0\86p«Té\ 3\0\0¿ëÛ\95\ 1\0\0\0\0\0\0C\0\0\0vendor/symfony/finder/Symfony/Component/Finder/Expression/Regex.php\81\ e\0\0\86p«T\81\ e\0\0S7Pæ¶\ 1\0\0\0\0\0\0B\0\0\0vendor/symfony/finder/Symfony/Component/Finder/Expression/Glob.php¡\a\0\0\86p«T¡\a\0\0  V¿¶\ 1\0\0\0\0\0\0H\0\0\0vendor/symfony/finder/Symfony/Component/Finder/Expression/Expression.php}\ 5\0\0\86p«T}\ 5\0\0/·cð¶\ 1\0\0\0\0\0\0L\0\0\0vendor/symfony/finder/Symfony/Component/Finder/Expression/ValueInterface.php;\ 1\0\0\86p«T;\ 1\0\0\vîãÓ¶\ 1\0\0\0\0\0\0K\0\0\0vendor/symfony/finder/Symfony/Component/Finder/Adapter/AdapterInterface.php¯\ 3\0\0\86p«T¯\ 3\0\0\8b\béȶ\ 1\0\0\0\0\0\0I\0\0\0vendor/symfony/finder/Symfony/Component/Finder/Adapter/BsdFindAdapter.php{\ 6\0\0\86p«T{\ 6\0\0Q,D2¶\ 1\0\0\0\0\0\0I\0\0\0vendor/symfony/finder/Symfony/Component/Finder/Adapter/GnuFindAdapter.php^\ 6\0\0\86p«T^\ 6\0\0ßz\98\ 1\0\0\0\0\0\0J\0\0\0vendor/symfony/finder/Symfony/Component/Finder/Adapter/AbstractAdapter.php¤
50 \0\0\86p«T¤
51 \0\0¢)z9¶\ 1\0\0\0\0\0\0N\0\0\0vendor/symfony/finder/Symfony/Component/Finder/Adapter/AbstractFindAdapter.phpÛ\18\0\0\86p«TÛ\18\0\0SõT´¶\ 1\0\0\0\0\0\0E\0\0\0vendor/symfony/finder/Symfony/Component/Finder/Adapter/PhpAdapter.php+\a\0\0\86p«T+\a\0\0&\98îÒ¶\ 1\0\0\0\0\0\07\0\0\0vendor/symfony/finder/Symfony/Component/Finder/Glob.php\r\ 5\0\0\86p«T\r\ 5\0\0z\9dø
52\ 1\0\0\0\0\0\0T\0\0\0vendor/symfony/finder/Symfony/Component/Finder/Iterator/DepthRangeFilterIterator.phpð\ 1\0\0\86p«Tð\ 1\0\0ß0\99\ 4\ 1\0\0\0\0\0\0L\0\0\0vendor/symfony/finder/Symfony/Component/Finder/Iterator/SortableIterator.phpÞ\ 5\0\0\86p«TÞ\ 5\0\0ö³\ 6\ 1\0\0\0\0\0\0U\0\0\0vendor/symfony/finder/Symfony/Component/Finder/Iterator/FilecontentFilterIterator.php#\ 3\0\0\86p«T#\ 3\0\0Ú_VǶ\ 1\0\0\0\0\0\0M\0\0\0vendor/symfony/finder/Symfony/Component/Finder/Iterator/FilePathsIterator.php\8d\ 5\0\0\86p«T\8d\ 5\0\0ýòäQ¶\ 1\0\0\0\0\0\0S\0\0\0vendor/symfony/finder/Symfony/Component/Finder/Iterator/SizeRangeFilterIterator.phpg\ 2\0\0\86p«Tg\ 2\0\0\97é¶\ 1\0\0\0\0\0\0Z\0\0\0vendor/symfony/finder/Symfony/Component/Finder/Iterator/ExcludeDirectoryFilterIterator.php\94\ 2\0\0\86p«T\94\ 2\0\0"ÖóÁ¶\ 1\0\0\0\0\0\0J\0\0\0vendor/symfony/finder/Symfony/Component/Finder/Iterator/FilterIterator.php\86\ 2\0\0\86p«T\86\ 2\0\00£¾Ô¶\ 1\0\0\0\0\0\0V\0\0\0vendor/symfony/finder/Symfony/Component/Finder/Iterator/MultiplePcreFilterIterator.phpØ\ 2\0\0\86p«TØ\ 2\0\0\ 4Òù\93\ 1\0\0\0\0\0\0P\0\0\0vendor/symfony/finder/Symfony/Component/Finder/Iterator/CustomFilterIterator.php]\ 2\0\0\86p«T]\ 2\0\0tà±µ¶\ 1\0\0\0\0\0\0R\0\0\0vendor/symfony/finder/Symfony/Component/Finder/Iterator/FilenameFilterIterator.php\87\ 2\0\0\86p«T\87\ 2\0\0\92\v\ 1\0\0\0\0\0\0S\0\0\0vendor/symfony/finder/Symfony/Component/Finder/Iterator/DateRangeFilterIterator.phpz\ 2\0\0\86p«Tz\ 2\0\0\7f}\17¢¶\ 1\0\0\0\0\0\0R\0\0\0vendor/symfony/finder/Symfony/Component/Finder/Iterator/FileTypeFilterIterator.php\\ 2\0\0\86p«T\\ 2\0\0p\91'\98\ 1\0\0\0\0\0\0V\0\0\0vendor/symfony/finder/Symfony/Component/Finder/Iterator/RecursiveDirectoryIterator.phpY\ 6\0\0\86p«TY\ 6\0\0êÓÊܶ\ 1\0\0\0\0\0\0N\0\0\0vendor/symfony/finder/Symfony/Component/Finder/Iterator/PathFilterIterator.phpÀ\ 2\0\0\86p«TÀ\ 2\0\0Í"dÕ¶\ 1\0\0\0\0\0\0L\0\0\0vendor/symfony/finder/Symfony/Component/Finder/Comparator/DateComparator.php%\ 3\0\0\86p«T%\ 3\0\0L¿EǶ\ 1\0\0\0\0\0\0N\0\0\0vendor/symfony/finder/Symfony/Component/Finder/Comparator/NumberComparator.phpy\ 3\0\0\86p«Ty\ 3\0\0"`\14Û¶\ 1\0\0\0\0\0\0H\0\0\0vendor/symfony/finder/Symfony/Component/Finder/Comparator/Comparator.php\8c\ 3\0\0\86p«T\8c\ 3\0\0\16wþT¶\ 1\0\0\0\0\0\0R\0\0\0vendor/symfony/finder/Symfony/Component/Finder/Exception/AccessDeniedException.php\84\0\0\0\86p«T\84\0\0\0½¾s\9c\ 1\0\0\0\0\0\0O\0\0\0vendor/symfony/finder/Symfony/Component/Finder/Exception/ExceptionInterface.php\84\0\0\0\86p«T\84\0\0\0\1cGz-¶\ 1\0\0\0\0\0\0Z\0\0\0vendor/symfony/finder/Symfony/Component/Finder/Exception/OperationNotPermitedException.php\8a\0\0\0\86p«T\8a\0\0\0U\1288¶\ 1\0\0\0\0\0\0T\0\0\0vendor/symfony/finder/Symfony/Component/Finder/Exception/AdapterFailureException.php\16\ 2\0\0\86p«T\16\ 2\0\0m\8c_,¶\ 1\0\0\0\0\0\0Y\0\0\0vendor/symfony/finder/Symfony/Component/Finder/Exception/ShellCommandFailureException.php$\ 2\0\0\86p«T$\ 2\0\0C\94sÓ¶\ 1\0\0\0\0\0\0>\0\0\0vendor/symfony/finder/Symfony/Component/Finder/SplFileInfo.phpû\ 2\0\0\86p«Tû\ 2\0\0\91\ 5\86\ 1\0\0\0\0\0\04\0\0\0vendor/seld/jsonlint/src/Seld/JsonLint/Undefined.php>\0\0\0\86p«T>\0\0\0ÿq\9f\9f\ 1\0\0\0\0\0\05\0\0\0vendor/seld/jsonlint/src/Seld/JsonLint/JsonParser.php)1\0\0\86p«T)1\0\0?5R3¶\ 1\0\0\0\0\0\00\0\0\0vendor/seld/jsonlint/src/Seld/JsonLint/Lexer.php\ 4\ f\0\0\86p«T\ 4\ f\0\0ÒÅ~\97\ 1\0\0\0\0\0\0;\0\0\0vendor/seld/jsonlint/src/Seld/JsonLint/ParsingException.php\1e\ 1\0\0\86p«T\1e\ 1\0\0\89²\10ñ¶\ 1\0\0\0\0\0\0?\0\0\0vendor/justinrainbow/json-schema/src/JsonSchema/RefResolver.php|
53 \0\0\86p«T|
54 \0\0\99&\r\ 1\0\0\0\0\0\0I\0\0\0vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/Undefined.phpl\17\0\0\86p«Tl\17\0\0\83\rÎ\89\ 1\0\0\0\0\0\0D\0\0\0vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/Type.phph\b\0\0\86p«Th\b\0\0õ\1cd϶\ 1\0\0\0\0\0\0F\0\0\0vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/Schema.php\16\ 2\0\0\86p«T\16\ 2\0\0]\12ÜÙ¶\ 1\0\0\0\0\0\0F\0\0\0vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/Number.php«\b\0\0\86p«T«\b\0\0\9bçI)¶\ 1\0\0\0\0\0\0F\0\0\0vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/Object.php¾
55 \0\0\86p«T¾
56 \0\0|Ò\F¶\ 1\0\0\0\0\0\0S\0\0\0vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/ConstraintInterface.phpN\ 1\0\0\86p«TN\ 1\0\0øÆMy¶\ 1\0\0\0\0\0\0J\0\0\0vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/Constraint.php9\ e\0\0\86p«T9\ e\0\0éð°#¶\ 1\0\0\0\0\0\0J\0\0\0vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/Collection.phpý\b\0\0\86p«Tý\b\0\0Ç\f;ÿ¶\ 1\0\0\0\0\0\0D\0\0\0vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/Enum.phpè\ 1\0\0\86p«Tè\ 1\0\0ê\10vĶ\ 1\0\0\0\0\0\0F\0\0\0vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/Format.phpí\r\0\0\86p«Tí\r\0\0á\94\18\r\ 1\0\0\0\0\0\0F\0\0\0vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/String.php\9f\ 3\0\0\86p«T\9f\ 3\0\0\8d\88på¶\ 1\0\0\0\0\0\0R\0\0\0vendor/justinrainbow/json-schema/src/JsonSchema/Exception/UriResolverException.phpj\0\0\0\86p«Tj\0\0\0SÓdz¶\ 1\0\0\0\0\0\0W\0\0\0vendor/justinrainbow/json-schema/src/JsonSchema/Exception/ResourceNotFoundException.phpo\0\0\0\86p«To\0\0\0Æ$"Ŷ\ 1\0\0\0\0\0\0]\0\0\0vendor/justinrainbow/json-schema/src/JsonSchema/Exception/InvalidSchemaMediaTypeException.phpv\0\0\0\86p«Tv\0\0\0\ 2\8aCÓ¶\ 1\0\0\0\0\0\0W\0\0\0vendor/justinrainbow/json-schema/src/JsonSchema/Exception/InvalidSourceUriException.phpw\0\0\0\86p«Tw\0\0\0N-ò[¶\ 1\0\0\0\0\0\0S\0\0\0vendor/justinrainbow/json-schema/src/JsonSchema/Exception/JsonDecodingException.phpÞ\ 2\0\0\86p«TÞ\ 2\0\0\86¾©\91\ 1\0\0\0\0\0\0V\0\0\0vendor/justinrainbow/json-schema/src/JsonSchema/Exception/InvalidArgumentException.phpv\0\0\0\86p«Tv\0\0\0¬ «"¶\ 1\0\0\0\0\0\0C\0\0\0vendor/justinrainbow/json-schema/src/JsonSchema/Uri/UriResolver.php®     \0\0\86p«T® \0\0àP¾¡¶\ 1\0\0\0\0\0\0D\0\0\0vendor/justinrainbow/json-schema/src/JsonSchema/Uri/UriRetriever.php\96\13\0\0\86p«T\96\13\0\0ªÿ¨Ü¶\ 1\0\0\0\0\0\0T\0\0\0vendor/justinrainbow/json-schema/src/JsonSchema/Uri/Retrievers/AbstractRetriever.phpÜ\0\0\0\86p«TÜ\0\0\0\e]j\1c\ 1\0\0\0\0\0\0R\0\0\0vendor/justinrainbow/json-schema/src/JsonSchema/Uri/Retrievers/FileGetContents.phpÑ\ 4\0\0\86p«TÑ\ 4\0\0æ\87¨\12\ 1\0\0\0\0\0\0X\0\0\0vendor/justinrainbow/json-schema/src/JsonSchema/Uri/Retrievers/UriRetrieverInterface.php©\0\0\0\86p«T©\0\0\0\ 6\ 3CO¶\ 1\0\0\0\0\0\0G\0\0\0vendor/justinrainbow/json-schema/src/JsonSchema/Uri/Retrievers/Curl.phpt\ 4\0\0\86p«Tt\ 4\0\0I·ý\0\ 1\0\0\0\0\0\0R\0\0\0vendor/justinrainbow/json-schema/src/JsonSchema/Uri/Retrievers/PredefinedArray.php^\ 2\0\0\86p«T^\ 2\0\0"ß6o¶\ 1\0\0\0\0\0\0=\0\0\0vendor/justinrainbow/json-schema/src/JsonSchema/Validator.phps\ 2\0\0\86p«Ts\ 2\0\0ô\84\7f\ 1\0\0\0\0\0\0\13\0\0\0vendor/autoload.php\91\0\0\0\86p«T\91\0\0\0ï4\9f\8d\ 1\0\0\0\0\0\0'\0\0\0vendor/composer/autoload_namespaces.php±\ 1\0\0\86p«T±\ 1\0\0\13ã¶\ 1\0\0\0\0\0\0!\0\0\0vendor/composer/autoload_psr4.php²\0\0\0\86p«T²\0\0\0Ô\81¨Ð¶\ 1\0\0\0\0\0\0%\0\0\0vendor/composer/autoload_classmap.phpd\0\0\0\86p«Td\0\0\0Z¡¦H¶\ 1\0\0\0\0\0\0!\0\0\0vendor/composer/autoload_real.phpK\ 4\0\0\86p«TK\ 4\0\0J1·\12\ 1\0\0\0\0\0\0!\0\0\0vendor/composer/include_paths.php\9f\ 1\0\0\86p«T\9f\ 1\0\0§Åᢶ\ 1\0\0\0\0\0\0\1f\0\0\0vendor/composer/ClassLoader.php\97\13\0\0\86p«T\97\13\0\0\86\ 1\0\0\0\0\0\0\f\0\0\0bin/composern\ 4\0\0\86p«Tn\ 4\0\0\1f\96\85\ 1\0\0\0\0\0\0\a\0\0\0LICENSE3\ 4\0\0\86p«T3\ 4\0\0\v\812\v\ 1\0\0\0\0\0\0<?php
57
58
59
60
61
62
63
64
65
66
67
68 function includeIfExists($file)
69 {
70 return file_exists($file) ? include $file : false;
71 }
72
73 if ((!$loader = includeIfExists(__DIR__.'/../vendor/autoload.php')) && (!$loader = includeIfExists(__DIR__.'/../../../autoload.php'))) {
74 echo 'You must set up the project dependencies, run the following commands:'.PHP_EOL.
75 'curl -sS https://getcomposer.org/installer | php'.PHP_EOL.
76 'php composer.phar install'.PHP_EOL;
77 exit(1);
78 }
79
80 return $loader;
81 <?php
82
83
84
85
86
87
88
89
90
91
92
93 namespace Composer\IO;
94
95 use Symfony\Component\Console\Input\InputInterface;
96 use Symfony\Component\Console\Output\OutputInterface;
97 use Symfony\Component\Console\Helper\HelperSet;
98 use Symfony\Component\Process\ExecutableFinder;
99
100
101
102
103
104
105
106 class ConsoleIO extends BaseIO
107 {
108 protected $input;
109 protected $output;
110 protected $helperSet;
111 protected $lastMessage;
112 private $startTime;
113
114
115
116
117
118
119
120
121 public function __construct(InputInterface $input, OutputInterface $output, HelperSet $helperSet)
122 {
123 $this->input = $input;
124 $this->output = $output;
125 $this->helperSet = $helperSet;
126 }
127
128 public function enableDebugging($startTime)
129 {
130 $this->startTime = $startTime;
131 }
132
133
134
135
136 public function isInteractive()
137 {
138 return $this->input->isInteractive();
139 }
140
141
142
143
144 public function isDecorated()
145 {
146 return $this->output->isDecorated();
147 }
148
149
150
151
152 public function isVerbose()
153 {
154 return $this->output->getVerbosity() >= OutputInterface::VERBOSITY_VERBOSE;
155 }
156
157
158
159
160 public function isVeryVerbose()
161 {
162 return $this->output->getVerbosity() >= 3; 
163  }
164
165
166
167
168 public function isDebug()
169 {
170 return $this->output->getVerbosity() >= 4; 
171  }
172
173
174
175
176 public function write($messages, $newline = true)
177 {
178 if (null !== $this->startTime) {
179 $messages = (array) $messages;
180 $messages[0] = sprintf(
181 '[%.1fMB/%.2fs] %s',
182 memory_get_usage() / 1024 / 1024,
183 microtime(true) - $this->startTime,
184 $messages[0]
185 );
186 }
187 $this->output->write($messages, $newline);
188 $this->lastMessage = join($newline ? "\n" : '', (array) $messages);
189 }
190
191
192
193
194 public function overwrite($messages, $newline = true, $size = null)
195 {
196 if (!$this->output->isDecorated()) {
197 if (!$messages) {
198 return;
199 }
200
201 return $this->write($messages, count($messages) === 1 || $newline);
202 }
203
204
205  $messages = join($newline ? "\n" : '', (array) $messages);
206
207
208  if (!isset($size)) {
209
210  $size = strlen(strip_tags($this->lastMessage));
211 }
212
213  $this->write(str_repeat("\x08", $size), false);
214
215
216  $this->write($messages, false);
217
218 $fill = $size - strlen(strip_tags($messages));
219 if ($fill > 0) {
220
221  $this->write(str_repeat(' ', $fill), false);
222
223  $this->write(str_repeat("\x08", $fill), false);
224 }
225
226 if ($newline) {
227 $this->write('');
228 }
229 $this->lastMessage = $messages;
230 }
231
232
233
234
235 public function ask($question, $default = null)
236 {
237 return $this->helperSet->get('dialog')->ask($this->output, $question, $default);
238 }
239
240
241
242
243 public function askConfirmation($question, $default = true)
244 {
245 return $this->helperSet->get('dialog')->askConfirmation($this->output, $question, $default);
246 }
247
248
249
250
251 public function askAndValidate($question, $validator, $attempts = false, $default = null)
252 {
253 return $this->helperSet->get('dialog')->askAndValidate($this->output, $question, $validator, $attempts, $default);
254 }
255
256
257
258
259 public function askAndHideAnswer($question)
260 {
261
262  if (defined('PHP_WINDOWS_VERSION_BUILD')) {
263 $finder = new ExecutableFinder();
264
265
266  if ($finder->find('bash') && $finder->find('stty')) {
267 $this->write($question, false);
268 $value = rtrim(shell_exec('bash -c "stty -echo; read -n0 discard; read -r mypassword; stty echo; echo $mypassword"'));
269 $this->write('');
270
271 return $value;
272 }
273
274
275  $exe = __DIR__.'\\hiddeninput.exe';
276
277
278  if ('phar:' === substr(__FILE__, 0, 5)) {
279 $tmpExe = sys_get_temp_dir().'/hiddeninput.exe';
280
281
282  
283  $source = fopen(__DIR__.'\\hiddeninput.exe', 'r');
284 $target = fopen($tmpExe, 'w+');
285 stream_copy_to_stream($source, $target);
286 fclose($source);
287 fclose($target);
288 unset($source, $target);
289
290 $exe = $tmpExe;
291 }
292
293 $this->write($question, false);
294 $value = rtrim(shell_exec($exe));
295 $this->write('');
296
297
298  if (isset($tmpExe)) {
299 unlink($tmpExe);
300 }
301
302 return $value;
303 }
304
305 if (file_exists('/usr/bin/env')) {
306
307  $test = "/usr/bin/env %s -c 'echo OK' 2> /dev/null";
308 foreach (array('bash', 'zsh', 'ksh', 'csh') as $sh) {
309 if ('OK' === rtrim(shell_exec(sprintf($test, $sh)))) {
310 $shell = $sh;
311 break;
312 }
313 }
314 if (isset($shell)) {
315 $this->write($question, false);
316 $readCmd = ($shell === 'csh') ? 'set mypassword = $<' : 'read -r mypassword';
317 $command = sprintf("/usr/bin/env %s -c 'stty -echo; %s; stty echo; echo \$mypassword'", $shell, $readCmd);
318 $value = rtrim(shell_exec($command));
319 $this->write('');
320
321 return $value;
322 }
323 }
324
325
326  return $this->ask($question);
327 }
328 }
329 <?php
330
331
332
333
334
335
336
337
338
339
340
341 namespace Composer\IO;
342
343
344
345
346
347
348 class NullIO extends BaseIO
349 {
350
351
352
353 public function isInteractive()
354 {
355 return false;
356 }
357
358
359
360
361 public function isVerbose()
362 {
363 return false;
364 }
365
366
367
368
369 public function isVeryVerbose()
370 {
371 return false;
372 }
373
374
375
376
377 public function isDebug()
378 {
379 return false;
380 }
381
382
383
384
385 public function isDecorated()
386 {
387 return false;
388 }
389
390
391
392
393 public function write($messages, $newline = true)
394 {
395 }
396
397
398
399
400 public function overwrite($messages, $newline = true, $size = 80)
401 {
402 }
403
404
405
406
407 public function ask($question, $default = null)
408 {
409 return $default;
410 }
411
412
413
414
415 public function askConfirmation($question, $default = true)
416 {
417 return $default;
418 }
419
420
421
422
423 public function askAndValidate($question, $validator, $attempts = false, $default = null)
424 {
425 return $default;
426 }
427
428
429
430
431 public function askAndHideAnswer($question)
432 {
433 return null;
434 }
435 }
436 <?php
437
438
439
440
441
442
443
444
445
446
447
448 namespace Composer\IO;
449
450 use Composer\Config;
451
452
453
454
455
456
457 interface IOInterface
458 {
459
460
461
462
463
464 public function isInteractive();
465
466
467
468
469
470
471 public function isVerbose();
472
473
474
475
476
477
478 public function isVeryVerbose();
479
480
481
482
483
484
485 public function isDebug();
486
487
488
489
490
491
492 public function isDecorated();
493
494
495
496
497
498
499
500 public function write($messages, $newline = true);
501
502
503
504
505
506
507
508
509 public function overwrite($messages, $newline = true, $size = null);
510
511
512
513
514
515
516
517
518
519
520
521 public function ask($question, $default = null);
522
523
524
525
526
527
528
529
530
531
532
533 public function askConfirmation($question, $default = true);
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551 public function askAndValidate($question, $validator, $attempts = false, $default = null);
552
553
554
555
556
557
558
559
560 public function askAndHideAnswer($question);
561
562
563
564
565
566
567 public function getAuthentications();
568
569
570
571
572
573
574
575
576 public function hasAuthentication($repositoryName);
577
578
579
580
581
582
583
584
585 public function getAuthentication($repositoryName);
586
587
588
589
590
591
592
593
594 public function setAuthentication($repositoryName, $username, $password = null);
595
596
597
598
599
600
601 public function loadConfiguration(Config $config);
602 }
603 <?php
604
605
606
607
608
609
610
611
612
613
614
615 namespace Composer\IO;
616
617 use Composer\Config;
618
619 abstract class BaseIO implements IOInterface
620 {
621 protected $authentications = array();
622
623
624
625
626 public function getAuthentications()
627 {
628 return $this->authentications;
629 }
630
631
632
633
634 public function hasAuthentication($repositoryName)
635 {
636 return isset($this->authentications[$repositoryName]);
637 }
638
639
640
641
642 public function getAuthentication($repositoryName)
643 {
644 if (isset($this->authentications[$repositoryName])) {
645 return $this->authentications[$repositoryName];
646 }
647
648 return array('username' => null, 'password' => null);
649 }
650
651
652
653
654 public function setAuthentication($repositoryName, $username, $password = null)
655 {
656 $this->authentications[$repositoryName] = array('username' => $username, 'password' => $password);
657 }
658
659
660
661
662 public function loadConfiguration(Config $config)
663 {
664
665  if ($tokens = $config->get('github-oauth')) {
666 foreach ($tokens as $domain => $token) {
667 if (!preg_match('{^[a-z0-9]+$}', $token)) {
668 throw new \UnexpectedValueException('Your github oauth token for '.$domain.' contains invalid characters: "'.$token.'"');
669 }
670 $this->setAuthentication($domain, $token, 'x-oauth-basic');
671 }
672 }
673
674
675  if ($creds = $config->get('http-basic')) {
676 foreach ($creds as $domain => $cred) {
677 $this->setAuthentication($domain, $cred['username'], $cred['password']);
678 }
679 }
680 }
681 }
682 <?php
683
684
685
686
687
688
689
690
691
692
693
694 namespace Composer\IO;
695
696 use Symfony\Component\Console\Output\StreamOutput;
697 use Symfony\Component\Console\Formatter\OutputFormatterInterface;
698 use Symfony\Component\Console\Input\StringInput;
699 use Symfony\Component\Console\Helper\HelperSet;
700
701
702
703
704 class BufferIO extends ConsoleIO
705 {
706
707
708
709
710
711 public function __construct($input = '', $verbosity = null, OutputFormatterInterface $formatter = null)
712 {
713 $input = new StringInput($input);
714 $input->setInteractive(false);
715
716 $output = new StreamOutput(fopen('php://memory', 'rw'), $verbosity === null ? StreamOutput::VERBOSITY_NORMAL : $verbosity, !empty($formatter), $formatter);
717
718 parent::__construct($input, $output, new HelperSet(array()));
719 }
720
721 public function getOutput()
722 {
723 fseek($this->output->getStream(), 0);
724
725 $output = stream_get_contents($this->output->getStream());
726
727 $output = preg_replace_callback("{(?<=^|\n|\x08)(.+?)(\x08+)}", function ($matches) {
728 $pre = strip_tags($matches[1]);
729
730 if (strlen($pre) === strlen($matches[2])) {
731 return '';
732 }
733
734
735  return rtrim($matches[1])."\n";
736 }, $output);
737
738 return $output;
739 }
740 }
741 <?php
742
743
744
745
746
747
748
749
750
751
752
753 namespace Composer\Command;
754
755 use Composer\Script\CommandEvent;
756 use Composer\Script\ScriptEvents;
757 use Symfony\Component\Console\Input\InputInterface;
758 use Symfony\Component\Console\Input\InputOption;
759 use Symfony\Component\Console\Input\InputArgument;
760 use Symfony\Component\Console\Output\OutputInterface;
761
762
763
764
765 class RunScriptCommand extends Command
766 {
767
768
769
770 protected $commandEvents = array(
771 ScriptEvents::PRE_INSTALL_CMD,
772 ScriptEvents::POST_INSTALL_CMD,
773 ScriptEvents::PRE_UPDATE_CMD,
774 ScriptEvents::POST_UPDATE_CMD,
775 ScriptEvents::PRE_STATUS_CMD,
776 ScriptEvents::POST_STATUS_CMD,
777 ScriptEvents::POST_ROOT_PACKAGE_INSTALL,
778 ScriptEvents::POST_CREATE_PROJECT_CMD
779 );
780
781
782
783
784 protected $scriptEvents = array(
785 ScriptEvents::PRE_ARCHIVE_CMD,
786 ScriptEvents::POST_ARCHIVE_CMD,
787 ScriptEvents::PRE_AUTOLOAD_DUMP,
788 ScriptEvents::POST_AUTOLOAD_DUMP
789 );
790
791 protected function configure()
792 {
793 $this
794 ->setName('run-script')
795 ->setDescription('Run the scripts defined in composer.json.')
796 ->setDefinition(array(
797 new InputArgument('script', InputArgument::REQUIRED, 'Script name to run.'),
798 new InputArgument('args', InputArgument::IS_ARRAY | InputArgument::OPTIONAL, ''),
799 new InputOption('dev', null, InputOption::VALUE_NONE, 'Sets the dev mode.'),
800 new InputOption('no-dev', null, InputOption::VALUE_NONE, 'Disables the dev mode.'),
801 ))
802 ->setHelp(<<<EOT
803 The <info>run-script</info> command runs scripts defined in composer.json:
804
805 <info>php composer.phar run-script post-update-cmd</info>
806 EOT
807 )
808 ;
809 }
810
811 protected function execute(InputInterface $input, OutputInterface $output)
812 {
813 $script = $input->getArgument('script');
814 if (!in_array($script, $this->commandEvents) && !in_array($script, $this->scriptEvents)) {
815 if (defined('Composer\Script\ScriptEvents::'.str_replace('-', '_', strtoupper($script)))) {
816 throw new \InvalidArgumentException(sprintf('Script "%s" cannot be run with this command', $script));
817 }
818 }
819
820 $composer = $this->getComposer();
821 $hasListeners = $composer->getEventDispatcher()->hasEventListeners(new CommandEvent($script, $composer, $this->getIO()));
822 if (!$hasListeners) {
823 throw new \InvalidArgumentException(sprintf('Script "%s" is not defined in this package', $script));
824 }
825
826
827  $binDir = $composer->getConfig()->get('bin-dir');
828 if (is_dir($binDir)) {
829 putenv('PATH='.realpath($binDir).PATH_SEPARATOR.getenv('PATH'));
830 }
831
832 $args = $input->getArgument('args');
833
834 if (in_array($script, $this->commandEvents)) {
835 return $composer->getEventDispatcher()->dispatchCommandEvent($script, $input->getOption('dev') || !$input->getOption('no-dev'), $args);
836 }
837
838 return $composer->getEventDispatcher()->dispatchScript($script, $input->getOption('dev') || !$input->getOption('no-dev'), $args);
839 }
840 }
841 <?php
842
843
844
845
846
847
848
849
850
851
852
853 namespace Composer\Command;
854
855 use Composer\Composer;
856 use Composer\Factory;
857 use Composer\Downloader\TransportException;
858 use Composer\Plugin\CommandEvent;
859 use Composer\Plugin\PluginEvents;
860 use Composer\Util\ConfigValidator;
861 use Composer\Util\ProcessExecutor;
862 use Composer\Util\RemoteFilesystem;
863 use Composer\Util\StreamContextFactory;
864 use Symfony\Component\Console\Input\InputInterface;
865 use Symfony\Component\Console\Output\OutputInterface;
866
867
868
869
870 class DiagnoseCommand extends Command
871 {
872 protected $rfs;
873 protected $process;
874 protected $failures = 0;
875
876 protected function configure()
877 {
878 $this
879 ->setName('diagnose')
880 ->setDescription('Diagnoses the system to identify common errors.')
881 ->setHelp(<<<EOT
882 The <info>diagnose</info> command checks common errors to help debugging problems.
883
884 EOT
885 )
886 ;
887 }
888
889 protected function execute(InputInterface $input, OutputInterface $output)
890 {
891 $composer = $this->getComposer(false);
892 if ($composer) {
893 $commandEvent = new CommandEvent(PluginEvents::COMMAND, 'diagnose', $input, $output);
894 $composer->getEventDispatcher()->dispatch($commandEvent->getName(), $commandEvent);
895
896 $output->write('Checking composer.json: ');
897 $this->outputResult($output, $this->checkComposerSchema());
898 }
899
900 if ($composer) {
901 $config = $composer->getConfig();
902 } else {
903 $config = Factory::createConfig();
904 }
905
906 $this->rfs = new RemoteFilesystem($this->getIO(), $config);
907 $this->process = new ProcessExecutor($this->getIO());
908
909 $output->write('Checking platform settings: ');
910 $this->outputResult($output, $this->checkPlatform());
911
912 $output->write('Checking git settings: ');
913 $this->outputResult($output, $this->checkGit());
914
915 $output->write('Checking http connectivity: ');
916 $this->outputResult($output, $this->checkHttp());
917
918 $opts = stream_context_get_options(StreamContextFactory::getContext('http://example.org'));
919 if (!empty($opts['http']['proxy'])) {
920 $output->write('Checking HTTP proxy: ');
921 $this->outputResult($output, $this->checkHttpProxy());
922 $output->write('Checking HTTP proxy support for request_fulluri: ');
923 $this->outputResult($output, $this->checkHttpProxyFullUriRequestParam());
924 $output->write('Checking HTTPS proxy support for request_fulluri: ');
925 $this->outputResult($output, $this->checkHttpsProxyFullUriRequestParam());
926 }
927
928 if ($oauth = $config->get('github-oauth')) {
929 foreach ($oauth as $domain => $token) {
930 $output->write('Checking '.$domain.' oauth access: ');
931 $this->outputResult($output, $this->checkGithubOauth($domain, $token));
932 }
933 }
934
935 $output->write('Checking disk free space: ');
936 $this->outputResult($output, $this->checkDiskSpace($config));
937
938 $output->write('Checking composer version: ');
939 $this->outputResult($output, $this->checkVersion());
940
941 return $this->failures;
942 }
943
944 private function checkComposerSchema()
945 {
946 $validator = new ConfigValidator($this->getIO());
947 list($errors, $publishErrors, $warnings) = $validator->validate(Factory::getComposerFile());
948
949 if ($errors || $publishErrors || $warnings) {
950 $messages = array(
951 'error' => array_merge($errors, $publishErrors),
952 'warning' => $warnings,
953 );
954
955 $output = '';
956 foreach ($messages as $style => $msgs) {
957 foreach ($msgs as $msg) {
958 $output .= '<' . $style . '>' . $msg . '</' . $style . '>' . PHP_EOL;
959 }
960 }
961
962 return rtrim($output);
963 }
964
965 return true;
966 }
967
968 private function checkGit()
969 {
970 $this->process->execute('git config color.ui', $output);
971 if (strtolower(trim($output)) === 'always') {
972 return '<warning>Your git color.ui setting is set to always, this is known to create issues. Use "git config --global color.ui true" to set it correctly.</warning>';
973 }
974
975 return true;
976 }
977
978 private function checkHttp()
979 {
980 $protocol = extension_loaded('openssl') ? 'https' : 'http';
981 try {
982 $json = $this->rfs->getContents('packagist.org', $protocol . '://packagist.org/packages.json', false);
983 } catch (\Exception $e) {
984 return $e;
985 }
986
987 return true;
988 }
989
990 private function checkHttpProxy()
991 {
992 $protocol = extension_loaded('openssl') ? 'https' : 'http';
993 try {
994 $json = json_decode($this->rfs->getContents('packagist.org', $protocol . '://packagist.org/packages.json', false), true);
995 $hash = reset($json['provider-includes']);
996 $hash = $hash['sha256'];
997 $path = str_replace('%hash%', $hash, key($json['provider-includes']));
998 $provider = $this->rfs->getContents('packagist.org', $protocol . '://packagist.org/'.$path, false);
999
1000 if (hash('sha256', $provider) !== $hash) {
1001 return 'It seems that your proxy is modifying http traffic on the fly';
1002 }
1003 } catch (\Exception $e) {
1004 return $e;
1005 }
1006
1007 return true;
1008 }
1009
1010
1011
1012
1013
1014
1015
1016
1017 private function checkHttpProxyFullUriRequestParam()
1018 {
1019 $url = 'http://packagist.org/packages.json';
1020 try {
1021 $this->rfs->getContents('packagist.org', $url, false);
1022 } catch (TransportException $e) {
1023 try {
1024 $this->rfs->getContents('packagist.org', $url, false, array('http' => array('request_fulluri' => false)));
1025 } catch (TransportException $e) {
1026 return 'Unable to assess the situation, maybe packagist.org is down ('.$e->getMessage().')';
1027 }
1028
1029 return 'It seems there is a problem with your proxy server, try setting the "HTTP_PROXY_REQUEST_FULLURI" and "HTTPS_PROXY_REQUEST_FULLURI" environment variables to "false"';
1030 }
1031
1032 return true;
1033 }
1034
1035
1036
1037
1038
1039
1040
1041
1042 private function checkHttpsProxyFullUriRequestParam()
1043 {
1044 if (!extension_loaded('openssl')) {
1045 return 'You need the openssl extension installed for this check';
1046 }
1047
1048 $url = 'https://api.github.com/repos/Seldaek/jsonlint/zipball/1.0.0';
1049 try {
1050 $rfcResult = $this->rfs->getContents('github.com', $url, false);
1051 } catch (TransportException $e) {
1052 try {
1053 $this->rfs->getContents('github.com', $url, false, array('http' => array('request_fulluri' => false)));
1054 } catch (TransportException $e) {
1055 return 'Unable to assess the situation, maybe github is down ('.$e->getMessage().')';
1056 }
1057
1058 return 'It seems there is a problem with your proxy server, try setting the "HTTPS_PROXY_REQUEST_FULLURI" environment variable to "false"';
1059 }
1060
1061 return true;
1062 }
1063
1064 private function checkGithubOauth($domain, $token)
1065 {
1066 $this->getIO()->setAuthentication($domain, $token, 'x-oauth-basic');
1067 try {
1068 $url = $domain === 'github.com' ? 'https://api.'.$domain.'/user/repos' : 'https://'.$domain.'/api/v3/user/repos';
1069
1070 return $this->rfs->getContents($domain, $url, false) ? true : 'Unexpected error';
1071 } catch (\Exception $e) {
1072 if ($e instanceof TransportException && $e->getCode() === 401) {
1073 return '<warning>The oauth token for '.$domain.' seems invalid, run "composer config --global --unset github-oauth.'.$domain.'" to remove it</warning>';
1074 }
1075
1076 return $e;
1077 }
1078 }
1079
1080 private function checkDiskSpace($config)
1081 {
1082 $minSpaceFree = 1024*1024;
1083 if ((($df = @disk_free_space($dir = $config->get('home'))) !== false && $df < $minSpaceFree)
1084 || (($df = @disk_free_space($dir = $config->get('vendor-dir'))) !== false && $df < $minSpaceFree)
1085 ) {
1086 return '<error>The disk hosting '.$dir.' is full</error>';
1087 }
1088
1089 return true;
1090 }
1091
1092 private function checkVersion()
1093 {
1094 $protocol = extension_loaded('openssl') ? 'https' : 'http';
1095 $latest = trim($this->rfs->getContents('getcomposer.org', $protocol . '://getcomposer.org/version', false));
1096
1097 if (Composer::VERSION !== $latest && Composer::VERSION !== '@package_version@') {
1098 return '<warning>You are not running the latest version</warning>';
1099 }
1100
1101 return true;
1102 }
1103
1104 private function outputResult(OutputInterface $output, $result)
1105 {
1106 if (true === $result) {
1107 $output->writeln('<info>OK</info>');
1108 } else {
1109 $this->failures++;
1110 $output->writeln('<error>FAIL</error>');
1111 if ($result instanceof \Exception) {
1112 $output->writeln('['.get_class($result).'] '.$result->getMessage());
1113 } elseif ($result) {
1114 $output->writeln($result);
1115 }
1116 }
1117 }
1118
1119 private function checkPlatform()
1120 {
1121 $output = '';
1122 $out = function ($msg, $style) use (&$output) {
1123 $output .= '<'.$style.'>'.$msg.'</'.$style.'>';
1124 };
1125
1126
1127  $errors = array();
1128 $warnings = array();
1129
1130 $iniPath = php_ini_loaded_file();
1131 $displayIniMessage = false;
1132 if ($iniPath) {
1133 $iniMessage = PHP_EOL.PHP_EOL.'The php.ini used by your command-line PHP is: ' . $iniPath;
1134 } else {
1135 $iniMessage = PHP_EOL.PHP_EOL.'A php.ini file does not exist. You will have to create one.';
1136 }
1137 $iniMessage .= PHP_EOL.'If you can not modify the ini file, you can also run `php -d option=value` to modify ini values on the fly. You can use -d multiple times.';
1138
1139 if (!ini_get('allow_url_fopen')) {
1140 $errors['allow_url_fopen'] = true;
1141 }
1142
1143 if (version_compare(PHP_VERSION, '5.3.2', '<')) {
1144 $errors['php'] = PHP_VERSION;
1145 }
1146
1147 if (!isset($errors['php']) && version_compare(PHP_VERSION, '5.3.4', '<')) {
1148 $warnings['php'] = PHP_VERSION;
1149 }
1150
1151 if (!extension_loaded('openssl')) {
1152 $warnings['openssl'] = true;
1153 }
1154
1155 if (!defined('HHVM_VERSION') && !extension_loaded('apcu') && ini_get('apc.enable_cli')) {
1156 $warnings['apc_cli'] = true;
1157 }
1158
1159 if (ini_get('xdebug.profiler_enabled')) {
1160 $warnings['xdebug_profile'] = true;
1161 } elseif (extension_loaded('xdebug')) {
1162 $warnings['xdebug_loaded'] = true;
1163 }
1164
1165 ob_start();
1166 phpinfo(INFO_GENERAL);
1167 $phpinfo = ob_get_clean();
1168 if (preg_match('{Configure Command(?: *</td><td class="v">| *=> *)(.*?)(?:</td>|$)}m', $phpinfo, $match)) {
1169 $configure = $match[1];
1170
1171 if (false !== strpos($configure, '--enable-sigchild')) {
1172 $warnings['sigchild'] = true;
1173 }
1174
1175 if (false !== strpos($configure, '--with-curlwrappers')) {
1176 $warnings['curlwrappers'] = true;
1177 }
1178 }
1179
1180 if (!empty($errors)) {
1181 foreach ($errors as $error => $current) {
1182 switch ($error) {
1183 case 'php':
1184 $text = PHP_EOL."Your PHP ({$current}) is too old, you must upgrade to PHP 5.3.2 or higher.";
1185 break;
1186
1187 case 'allow_url_fopen':
1188 $text = PHP_EOL."The allow_url_fopen setting is incorrect.".PHP_EOL;
1189 $text .= "Add the following to the end of your `php.ini`:".PHP_EOL;
1190 $text .= "    allow_url_fopen = On";
1191 $displayIniMessage = true;
1192 break;
1193 }
1194 $out($text, 'error');
1195 }
1196
1197 $output .= PHP_EOL;
1198 }
1199
1200 if (!empty($warnings)) {
1201 foreach ($warnings as $warning => $current) {
1202 switch ($warning) {
1203 case 'apc_cli':
1204 $text = PHP_EOL."The apc.enable_cli setting is incorrect.".PHP_EOL;
1205 $text .= "Add the following to the end of your `php.ini`:".PHP_EOL;
1206 $text .= "    apc.enable_cli = Off";
1207 $displayIniMessage = true;
1208 break;
1209
1210 case 'sigchild':
1211 $text = PHP_EOL."PHP was compiled with --enable-sigchild which can cause issues on some platforms.".PHP_EOL;
1212 $text .= "Recompile it without this flag if possible, see also:".PHP_EOL;
1213 $text .= "    https://bugs.php.net/bug.php?id=22999";
1214 break;
1215
1216 case 'curlwrappers':
1217 $text = PHP_EOL."PHP was compiled with --with-curlwrappers which will cause issues with HTTP authentication and GitHub.".PHP_EOL;
1218 $text .= "Recompile it without this flag if possible";
1219 break;
1220
1221 case 'openssl':
1222 $text = PHP_EOL."The openssl extension is missing, which will reduce the security and stability of Composer.".PHP_EOL;
1223 $text .= "If possible you should enable it or recompile php with --with-openssl";
1224 break;
1225
1226 case 'php':
1227 $text = PHP_EOL."Your PHP ({$current}) is quite old, upgrading to PHP 5.3.4 or higher is recommended.".PHP_EOL;
1228 $text .= "Composer works with 5.3.2+ for most people, but there might be edge case issues.";
1229 break;
1230
1231 case 'xdebug_loaded':
1232 $text = PHP_EOL."The xdebug extension is loaded, this can slow down Composer a little.".PHP_EOL;
1233 $text .= "Disabling it when using Composer is recommended, but should not cause issues beyond slowness.";
1234 break;
1235
1236 case 'xdebug_profile':
1237 $text = PHP_EOL."The xdebug.profiler_enabled setting is enabled, this can slow down Composer a lot.".PHP_EOL;
1238 $text .= "Add the following to the end of your `php.ini` to disable it:".PHP_EOL;
1239 $text .= "    xdebug.profiler_enabled = 0";
1240 $displayIniMessage = true;
1241 break;
1242 }
1243 $out($text, 'warning');
1244 }
1245 }
1246
1247 if ($displayIniMessage) {
1248 $out($iniMessage, 'warning');
1249 }
1250
1251 return !$warnings && !$errors ? true : $output;
1252 }
1253 }
1254 <?php
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266 namespace Composer\Command;
1267
1268 use Composer\Factory;
1269 use Composer\IO\IOInterface;
1270 use Composer\DependencyResolver\Pool;
1271 use Composer\Repository\CompositeRepository;
1272 use Composer\Script\ScriptEvents;
1273 use Composer\Plugin\CommandEvent;
1274 use Composer\Plugin\PluginEvents;
1275 use Composer\Package\Version\VersionParser;
1276
1277 use Symfony\Component\Console\Input\InputArgument;
1278 use Symfony\Component\Console\Input\InputInterface;
1279 use Symfony\Component\Console\Input\InputOption;
1280 use Symfony\Component\Console\Output\OutputInterface;
1281
1282
1283
1284
1285
1286
1287 class ArchiveCommand extends Command
1288 {
1289 protected function configure()
1290 {
1291 $this
1292 ->setName('archive')
1293 ->setDescription('Create an archive of this composer package')
1294 ->setDefinition(array(
1295 new InputArgument('package', InputArgument::OPTIONAL, 'The package to archive instead of the current project'),
1296 new InputArgument('version', InputArgument::OPTIONAL, 'A version constraint to find the package to archive'),
1297 new InputOption('format', 'f', InputOption::VALUE_REQUIRED, 'Format of the resulting archive: tar or zip', 'tar'),
1298 new InputOption('dir', false, InputOption::VALUE_REQUIRED, 'Write the archive to this directory', '.'),
1299 ))
1300 ->setHelp(<<<EOT
1301 The <info>archive</info> command creates an archive of the specified format
1302 containing the files and directories of the Composer project or the specified
1303 package in the specified version and writes it to the specified directory.
1304
1305 <info>php composer.phar archive [--format=zip] [--dir=/foo] [package [version]]</info>
1306
1307 EOT
1308 )
1309 ;
1310 }
1311
1312 protected function execute(InputInterface $input, OutputInterface $output)
1313 {
1314 $composer = $this->getComposer(false);
1315 if ($composer) {
1316 $commandEvent = new CommandEvent(PluginEvents::COMMAND, 'archive', $input, $output);
1317 $composer->getEventDispatcher()->dispatch($commandEvent->getName(), $commandEvent);
1318 $composer->getEventDispatcher()->dispatchScript(ScriptEvents::PRE_ARCHIVE_CMD);
1319 }
1320
1321 $returnCode = $this->archive(
1322 $this->getIO(),
1323 $input->getArgument('package'),
1324 $input->getArgument('version'),
1325 $input->getOption('format'),
1326 $input->getOption('dir')
1327 );
1328
1329 if (0 === $returnCode && $composer) {
1330 $composer->getEventDispatcher()->dispatchScript(ScriptEvents::POST_ARCHIVE_CMD);
1331 }
1332
1333 return $returnCode;
1334 }
1335
1336 protected function archive(IOInterface $io, $packageName = null, $version = null, $format = 'tar', $dest = '.')
1337 {
1338 $config = Factory::createConfig();
1339 $factory = new Factory;
1340 $downloadManager = $factory->createDownloadManager($io, $config);
1341 $archiveManager = $factory->createArchiveManager($config, $downloadManager);
1342
1343 if ($packageName) {
1344 $package = $this->selectPackage($io, $packageName, $version);
1345
1346 if (!$package) {
1347 return 1;
1348 }
1349 } else {
1350 $package = $this->getComposer()->getPackage();
1351 }
1352
1353 $io->write('<info>Creating the archive.</info>');
1354 $archiveManager->archive($package, $format, $dest);
1355
1356 return 0;
1357 }
1358
1359 protected function selectPackage(IOInterface $io, $packageName, $version = null)
1360 {
1361 $io->write('<info>Searching for the specified package.</info>');
1362
1363 if ($composer = $this->getComposer(false)) {
1364 $localRepo = $composer->getRepositoryManager()->getLocalRepository();
1365 $repos = new CompositeRepository(array_merge(array($localRepo), $composer->getRepositoryManager()->getRepositories()));
1366 } else {
1367 $defaultRepos = Factory::createDefaultRepositories($this->getIO());
1368 $io->write('No composer.json found in the current directory, searching packages from ' . implode(', ', array_keys($defaultRepos)));
1369 $repos = new CompositeRepository($defaultRepos);
1370 }
1371
1372 $pool = new Pool();
1373 $pool->addRepository($repos);
1374
1375 $parser = new VersionParser();
1376 $constraint = ($version) ? $parser->parseConstraints($version) : null;
1377 $packages = $pool->whatProvides($packageName, $constraint, true);
1378
1379 if (count($packages) > 1) {
1380 $package = reset($packages);
1381 $io->write('<info>Found multiple matches, selected '.$package->getPrettyString().'.</info>');
1382 $io->write('Alternatives were '.implode(', ', array_map(function ($p) { return $p->getPrettyString(); }, $packages)).'.');
1383 $io->write('<comment>Please use a more specific constraint to pick a different package.</comment>');
1384 } elseif ($packages) {
1385 $package = reset($packages);
1386 $io->write('<info>Found an exact match '.$package->getPrettyString().'.</info>');
1387 } else {
1388 $io->write('<error>Could not find a package matching '.$packageName.'.</error>');
1389
1390 return false;
1391 }
1392
1393 return $package;
1394 }
1395 }
1396 <?php
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408 namespace Composer\Command;
1409
1410 use Composer\Cache;
1411 use Composer\Factory;
1412 use Symfony\Component\Console\Input\InputInterface;
1413 use Symfony\Component\Console\Output\OutputInterface;
1414
1415
1416
1417
1418 class ClearCacheCommand extends Command
1419 {
1420 protected function configure()
1421 {
1422 $this
1423 ->setName('clear-cache')
1424 ->setAliases(array('clearcache'))
1425 ->setDescription('Clears composer\'s internal package cache.')
1426 ->setHelp(<<<EOT
1427 The <info>clear-cache</info> deletes all cached packages from composer's
1428 cache directory.
1429 EOT
1430 )
1431 ;
1432 }
1433
1434 protected function execute(InputInterface $input, OutputInterface $output)
1435 {
1436 $config = Factory::createConfig();
1437 $io = $this->getIO();
1438
1439 $cachePaths = array(
1440 'cache-dir' => $config->get('cache-dir'),
1441 'cache-files-dir' => $config->get('cache-files-dir'),
1442 'cache-repo-dir' => $config->get('cache-repo-dir'),
1443 'cache-vcs-dir' => $config->get('cache-vcs-dir'),
1444 );
1445
1446 foreach ($cachePaths as $key => $cachePath) {
1447 $cachePath = realpath($cachePath);
1448 if (!$cachePath) {
1449 $io->write("<info>Cache directory does not exist ($key): $cachePath</info>");
1450
1451 return;
1452 }
1453 $cache = new Cache($io, $cachePath);
1454 if (!$cache->isEnabled()) {
1455 $io->write("<info>Cache is not enabled ($key): $cachePath</info>");
1456
1457 return;
1458 }
1459
1460 $io->write("<info>Clearing cache ($key): $cachePath</info>");
1461 $cache->gc(0, 0);
1462 }
1463
1464 $io->write('<info>All caches cleared.</info>');
1465 }
1466 }
1467 <?php
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479 namespace Composer\Command;
1480
1481 use Composer\Composer;
1482 use Composer\Console\Application;
1483 use Composer\IO\IOInterface;
1484 use Composer\IO\NullIO;
1485 use Symfony\Component\Console\Input\InputInterface;
1486 use Symfony\Component\Console\Output\OutputInterface;
1487 use Symfony\Component\Console\Command\Command as BaseCommand;
1488
1489
1490
1491
1492
1493
1494
1495 abstract class Command extends BaseCommand
1496 {
1497
1498
1499
1500 private $composer;
1501
1502
1503
1504
1505 private $io;
1506
1507
1508
1509
1510
1511
1512
1513 public function getComposer($required = true, $disablePlugins = false)
1514 {
1515 if (null === $this->composer) {
1516 $application = $this->getApplication();
1517 if ($application instanceof Application) {
1518
1519 $this->composer = $application->getComposer($required, $disablePlugins);
1520 } elseif ($required) {
1521 throw new \RuntimeException(
1522 'Could not create a Composer\Composer instance, you must inject '.
1523 'one if this command is not used with a Composer\Console\Application instance'
1524 );
1525 }
1526 }
1527
1528 return $this->composer;
1529 }
1530
1531
1532
1533
1534 public function setComposer(Composer $composer)
1535 {
1536 $this->composer = $composer;
1537 }
1538
1539
1540
1541
1542 public function resetComposer()
1543 {
1544 $this->composer = null;
1545 $this->getApplication()->resetComposer();
1546 }
1547
1548
1549
1550
1551 public function getIO()
1552 {
1553 if (null === $this->io) {
1554 $application = $this->getApplication();
1555 if ($application instanceof Application) {
1556
1557 $this->io = $application->getIO();
1558 } else {
1559 $this->io = new NullIO();
1560 }
1561 }
1562
1563 return $this->io;
1564 }
1565
1566
1567
1568
1569 public function setIO(IOInterface $io)
1570 {
1571 $this->io = $io;
1572 }
1573
1574
1575
1576
1577 protected function initialize(InputInterface $input, OutputInterface $output)
1578 {
1579 if (true === $input->hasParameterOption(array('--no-ansi')) && $input->hasOption('no-progress')) {
1580 $input->setOption('no-progress', true);
1581 }
1582
1583 parent::initialize($input, $output);
1584 }
1585 }
1586 <?php
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598 namespace Composer\Command;
1599
1600 use Composer\Config;
1601 use Composer\Factory;
1602 use Composer\Installer;
1603 use Composer\Installer\ProjectInstaller;
1604 use Composer\Installer\InstallationManager;
1605 use Composer\IO\IOInterface;
1606 use Composer\Package\BasePackage;
1607 use Composer\DependencyResolver\Pool;
1608 use Composer\DependencyResolver\Operation\InstallOperation;
1609 use Composer\Package\Version\VersionSelector;
1610 use Composer\Repository\ComposerRepository;
1611 use Composer\Repository\CompositeRepository;
1612 use Composer\Repository\FilesystemRepository;
1613 use Composer\Repository\InstalledFilesystemRepository;
1614 use Composer\Script\ScriptEvents;
1615 use Symfony\Component\Console\Input\InputArgument;
1616 use Symfony\Component\Console\Input\InputInterface;
1617 use Symfony\Component\Console\Input\InputOption;
1618 use Symfony\Component\Console\Output\OutputInterface;
1619 use Symfony\Component\Finder\Finder;
1620 use Composer\Json\JsonFile;
1621 use Composer\Config\JsonConfigSource;
1622 use Composer\Util\Filesystem;
1623 use Composer\Util\RemoteFilesystem;
1624 use Composer\Package\Version\VersionParser;
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634 class CreateProjectCommand extends Command
1635 {
1636 protected function configure()
1637 {
1638 $this
1639 ->setName('create-project')
1640 ->setDescription('Create new project from a package into given directory.')
1641 ->setDefinition(array(
1642 new InputArgument('package', InputArgument::OPTIONAL, 'Package name to be installed'),
1643 new InputArgument('directory', InputArgument::OPTIONAL, 'Directory where the files should be created'),
1644 new InputArgument('version', InputArgument::OPTIONAL, 'Version, will default to latest'),
1645 new InputOption('stability', 's', InputOption::VALUE_REQUIRED, 'Minimum-stability allowed (unless a version is specified).'),
1646 new InputOption('prefer-source', null, InputOption::VALUE_NONE, 'Forces installation from package sources when possible, including VCS information.'),
1647 new InputOption('prefer-dist', null, InputOption::VALUE_NONE, 'Forces installation from package dist even for dev versions.'),
1648 new InputOption('repository-url', null, InputOption::VALUE_REQUIRED, 'Pick a different repository url to look for the package.'),
1649 new InputOption('dev', null, InputOption::VALUE_NONE, 'Enables installation of require-dev packages (enabled by default, only present for BC).'),
1650 new InputOption('no-dev', null, InputOption::VALUE_NONE, 'Disables installation of require-dev packages.'),
1651 new InputOption('no-plugins', null, InputOption::VALUE_NONE, 'Whether to disable plugins.'),
1652 new InputOption('no-custom-installers', null, InputOption::VALUE_NONE, 'DEPRECATED: Use no-plugins instead.'),
1653 new InputOption('no-scripts', null, InputOption::VALUE_NONE, 'Whether to prevent execution of all defined scripts in the root package.'),
1654 new InputOption('no-progress', null, InputOption::VALUE_NONE, 'Do not output download progress.'),
1655 new InputOption('keep-vcs', null, InputOption::VALUE_NONE, 'Whether to prevent deletion vcs folder.'),
1656 new InputOption('no-install', null, InputOption::VALUE_NONE, 'Whether to skip installation of the package dependencies.'),
1657 new InputOption('ignore-platform-reqs', null, InputOption::VALUE_NONE, 'Ignore platform requirements (php & ext- packages).'),
1658 ))
1659 ->setHelp(<<<EOT
1660 The <info>create-project</info> command creates a new project from a given
1661 package into a new directory. If executed without params and in a directory
1662 with a composer.json file it installs the packages for the current project.
1663
1664 You can use this command to bootstrap new projects or setup a clean
1665 version-controlled installation for developers of your project.
1666
1667 <info>php composer.phar create-project vendor/project target-directory [version]</info>
1668
1669 You can also specify the version with the package name using = or : as separator.
1670
1671 To install unstable packages, either specify the version you want, or use the
1672 --stability=dev (where dev can be one of RC, beta, alpha or dev).
1673
1674 To setup a developer workable version you should create the project using the source
1675 controlled code by appending the <info>'--prefer-source'</info> flag.
1676
1677 To install a package from another repository than the default one you
1678 can pass the <info>'--repository-url=http://myrepository.org'</info> flag.
1679
1680 EOT
1681 )
1682 ;
1683 }
1684
1685 protected function execute(InputInterface $input, OutputInterface $output)
1686 {
1687 $config = Factory::createConfig();
1688
1689 $preferSource = false;
1690 $preferDist = false;
1691 $this->updatePreferredOptions($config, $input, $preferSource, $preferDist);
1692
1693 if ($input->getOption('no-custom-installers')) {
1694 $output->writeln('<warning>You are using the deprecated option "no-custom-installers". Use "no-plugins" instead.</warning>');
1695 $input->setOption('no-plugins', true);
1696 }
1697
1698 return $this->installProject(
1699 $this->getIO(),
1700 $config,
1701 $input->getArgument('package'),
1702 $input->getArgument('directory'),
1703 $input->getArgument('version'),
1704 $input->getOption('stability'),
1705 $preferSource,
1706 $preferDist,
1707 !$input->getOption('no-dev'),
1708 $input->getOption('repository-url'),
1709 $input->getOption('no-plugins'),
1710 $input->getOption('no-scripts'),
1711 $input->getOption('keep-vcs'),
1712 $input->getOption('no-progress'),
1713 $input->getOption('no-install'),
1714 $input->getOption('ignore-platform-reqs'),
1715 $input
1716 );
1717 }
1718
1719 public function installProject(IOInterface $io, Config $config, $packageName, $directory = null, $packageVersion = null, $stability = 'stable', $preferSource = false, $preferDist = false, $installDevPackages = false, $repositoryUrl = null, $disablePlugins = false, $noScripts = false, $keepVcs = false, $noProgress = false, $noInstall = false, $ignorePlatformReqs = false, InputInterface $input)
1720 {
1721 $oldCwd = getcwd();
1722
1723
1724  $io->loadConfiguration($config);
1725
1726 if ($packageName !== null) {
1727 $installedFromVcs = $this->installRootPackage($io, $config, $packageName, $directory, $packageVersion, $stability, $preferSource, $preferDist, $installDevPackages, $repositoryUrl, $disablePlugins, $noScripts, $keepVcs, $noProgress);
1728 } else {
1729 $installedFromVcs = false;
1730 }
1731
1732 $composer = Factory::create($io, null, $disablePlugins);
1733 $fs = new Filesystem();
1734
1735 if ($noScripts === false) {
1736
1737  $composer->getEventDispatcher()->dispatchCommandEvent(ScriptEvents::POST_ROOT_PACKAGE_INSTALL, $installDevPackages);
1738 }
1739
1740 $rootPackageConfig = $composer->getConfig();
1741 $this->updatePreferredOptions($rootPackageConfig, $input, $preferSource, $preferDist);
1742
1743
1744  if ($noInstall === false) {
1745 $installer = Installer::create($io, $composer);
1746 $installer->setPreferSource($preferSource)
1747 ->setPreferDist($preferDist)
1748 ->setDevMode($installDevPackages)
1749 ->setRunScripts(!$noScripts)
1750 ->setIgnorePlatformRequirements($ignorePlatformReqs);
1751
1752 if ($disablePlugins) {
1753 $installer->disablePlugins();
1754 }
1755
1756 $status = $installer->run();
1757 if (0 !== $status) {
1758 return $status;
1759 }
1760 }
1761
1762 $hasVcs = $installedFromVcs;
1763 if (!$keepVcs && $installedFromVcs
1764 && (
1765 !$io->isInteractive()
1766 || $io->askConfirmation('<info>Do you want to remove the existing VCS (.git, .svn..) history?</info> [<comment>Y,n</comment>]? ', true)
1767 )
1768 ) {
1769 $finder = new Finder();
1770 $finder->depth(0)->directories()->in(getcwd())->ignoreVCS(false)->ignoreDotFiles(false);
1771 foreach (array('.svn', '_svn', 'CVS', '_darcs', '.arch-params', '.monotone', '.bzr', '.git', '.hg') as $vcsName) {
1772 $finder->name($vcsName);
1773 }
1774
1775 try {
1776 $dirs = iterator_to_array($finder);
1777 unset($finder);
1778 foreach ($dirs as $dir) {
1779 if (!$fs->removeDirectory($dir)) {
1780 throw new \RuntimeException('Could not remove '.$dir);
1781 }
1782 }
1783 } catch (\Exception $e) {
1784 $io->write('<error>An error occurred while removing the VCS metadata: '.$e->getMessage().'</error>');
1785 }
1786
1787 $hasVcs = false;
1788 }
1789
1790
1791  if (!$hasVcs) {
1792 $package = $composer->getPackage();
1793 $configSource = new JsonConfigSource(new JsonFile('composer.json'));
1794 foreach (BasePackage::$supportedLinkTypes as $type => $meta) {
1795 foreach ($package->{'get'.$meta['method']}() as $link) {
1796 if ($link->getPrettyConstraint() === 'self.version') {
1797 $configSource->addLink($type, $link->getTarget(), $package->getPrettyVersion());
1798 }
1799 }
1800 }
1801 }
1802
1803 if ($noScripts === false) {
1804
1805  $composer->getEventDispatcher()->dispatchCommandEvent(ScriptEvents::POST_CREATE_PROJECT_CMD, $installDevPackages);
1806 }
1807
1808 chdir($oldCwd);
1809 $vendorComposerDir = $composer->getConfig()->get('vendor-dir').'/composer';
1810 if (is_dir($vendorComposerDir) && $fs->isDirEmpty($vendorComposerDir)) {
1811 @rmdir($vendorComposerDir);
1812 $vendorDir = $composer->getConfig()->get('vendor-dir');
1813 if (is_dir($vendorDir) && $fs->isDirEmpty($vendorDir)) {
1814 @rmdir($vendorDir);
1815 }
1816 }
1817
1818 return 0;
1819 }
1820
1821 protected function installRootPackage(IOInterface $io, Config $config, $packageName, $directory = null, $packageVersion = null, $stability = 'stable', $preferSource = false, $preferDist = false, $installDevPackages = false, $repositoryUrl = null, $disablePlugins = false, $noScripts = false, $keepVcs = false, $noProgress = false)
1822 {
1823 if (null === $repositoryUrl) {
1824 $sourceRepo = new CompositeRepository(Factory::createDefaultRepositories($io, $config));
1825 } elseif ("json" === pathinfo($repositoryUrl, PATHINFO_EXTENSION) && file_exists($repositoryUrl)) {
1826 $json = new JsonFile($repositoryUrl, new RemoteFilesystem($io, $config));
1827 $data = $json->read();
1828 if (!empty($data['packages']) || !empty($data['includes']) || !empty($data['provider-includes'])) {
1829 $sourceRepo = new ComposerRepository(array('url' => 'file://' . strtr(realpath($repositoryUrl), '\\', '/')), $io, $config);
1830 } else {
1831 $sourceRepo = new FilesystemRepository($json);
1832 }
1833 } elseif (0 === strpos($repositoryUrl, 'http')) {
1834 $sourceRepo = new ComposerRepository(array('url' => $repositoryUrl), $io, $config);
1835 } else {
1836 throw new \InvalidArgumentException("Invalid repository url given. Has to be a .json file or an http url.");
1837 }
1838
1839 $parser = new VersionParser();
1840 $requirements = $parser->parseNameVersionPairs(array($packageName));
1841 $name = strtolower($requirements[0]['name']);
1842 if (!$packageVersion && isset($requirements[0]['version'])) {
1843 $packageVersion = $requirements[0]['version'];
1844 }
1845
1846 if (null === $stability) {
1847 if (preg_match('{^[^,\s]*?@('.implode('|', array_keys(BasePackage::$stabilities)).')$}i', $packageVersion, $match)) {
1848 $stability = $match[1];
1849 } else {
1850 $stability = VersionParser::parseStability($packageVersion);
1851 }
1852 }
1853
1854 $stability = VersionParser::normalizeStability($stability);
1855
1856 if (!isset(BasePackage::$stabilities[$stability])) {
1857 throw new \InvalidArgumentException('Invalid stability provided ('.$stability.'), must be one of: '.implode(', ', array_keys(BasePackage::$stabilities)));
1858 }
1859
1860 $pool = new Pool($stability);
1861 $pool->addRepository($sourceRepo);
1862
1863
1864  $versionSelector = new VersionSelector($pool);
1865 $package = $versionSelector->findBestCandidate($name, $packageVersion);
1866
1867 if (!$package) {
1868 throw new \InvalidArgumentException("Could not find package $name" . ($packageVersion ? " with version $packageVersion." : " with stability $stability."));
1869 }
1870
1871 if (null === $directory) {
1872 $parts = explode("/", $name, 2);
1873 $directory = getcwd() . DIRECTORY_SEPARATOR . array_pop($parts);
1874 }
1875
1876 $io->write('<info>Installing ' . $package->getName() . ' (' . VersionParser::formatVersion($package, false) . ')</info>');
1877
1878 if ($disablePlugins) {
1879 $io->write('<info>Plugins have been disabled.</info>');
1880 }
1881
1882 if (0 === strpos($package->getPrettyVersion(), 'dev-') && in_array($package->getSourceType(), array('git', 'hg'))) {
1883 $package->setSourceReference(substr($package->getPrettyVersion(), 4));
1884 }
1885
1886 $dm = $this->createDownloadManager($io, $config);
1887 $dm->setPreferSource($preferSource)
1888 ->setPreferDist($preferDist)
1889 ->setOutputProgress(!$noProgress);
1890
1891 $projectInstaller = new ProjectInstaller($directory, $dm);
1892 $im = $this->createInstallationManager();
1893 $im->addInstaller($projectInstaller);
1894 $im->install(new InstalledFilesystemRepository(new JsonFile('php://memory')), new InstallOperation($package));
1895 $im->notifyInstalls();
1896
1897 $installedFromVcs = 'source' === $package->getInstallationSource();
1898
1899 $io->write('<info>Created project in ' . $directory . '</info>');
1900 chdir($directory);
1901
1902 putenv('COMPOSER_ROOT_VERSION='.$package->getPrettyVersion());
1903
1904 return $installedFromVcs;
1905 }
1906
1907 protected function createDownloadManager(IOInterface $io, Config $config)
1908 {
1909 $factory = new Factory();
1910
1911 return $factory->createDownloadManager($io, $config);
1912 }
1913
1914 protected function createInstallationManager()
1915 {
1916 return new InstallationManager();
1917 }
1918
1919
1920
1921
1922
1923
1924
1925
1926 protected function updatePreferredOptions(Config $config, InputInterface $input, &$preferSource, &$preferDist)
1927 {
1928 switch ($config->get('preferred-install')) {
1929 case 'source':
1930 $preferSource = true;
1931 $preferDist = false;
1932 break;
1933 case 'dist':
1934 $preferSource = false;
1935 $preferDist = true;
1936 break;
1937 case 'auto':
1938 default:
1939
1940  break;
1941 }
1942
1943 if ($input->getOption('prefer-source') || $input->getOption('prefer-dist')) {
1944 $preferSource = $input->getOption('prefer-source');
1945 $preferDist = $input->getOption('prefer-dist');
1946 }
1947 }
1948 }
1949 <?php
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961 namespace Composer\Command;
1962
1963 use Symfony\Component\Console\Input\InputInterface;
1964 use Symfony\Component\Console\Output\OutputInterface;
1965
1966
1967
1968
1969 class AboutCommand extends Command
1970 {
1971 protected function configure()
1972 {
1973 $this
1974 ->setName('about')
1975 ->setDescription('Short information about Composer')
1976 ->setHelp(<<<EOT
1977 <info>php composer.phar about</info>
1978 EOT
1979 )
1980 ;
1981 }
1982
1983 protected function execute(InputInterface $input, OutputInterface $output)
1984 {
1985 $output->writeln(<<<EOT
1986 <info>Composer - Package Management for PHP</info>
1987 <comment>Composer is a dependency manager tracking local dependencies of your projects and libraries.
1988 See http://getcomposer.org/ for more information.</comment>
1989 EOT
1990 );
1991 }
1992 }
1993 <?php
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005 namespace Composer\Command;
2006
2007 use Symfony\Component\Console\Input\InputInterface;
2008 use Symfony\Component\Console\Input\InputOption;
2009 use Symfony\Component\Console\Input\InputArgument;
2010 use Symfony\Component\Console\Output\OutputInterface;
2011
2012
2013
2014
2015 class ScriptAliasCommand extends Command
2016 {
2017 private $script;
2018
2019 public function __construct($script)
2020 {
2021 $this->script = $script;
2022
2023 parent::__construct();
2024 }
2025
2026 protected function configure()
2027 {
2028 $this
2029 ->setName($this->script)
2030 ->setDescription('Run the '.$this->script.' script as defined in composer.json.')
2031 ->setDefinition(array(
2032 new InputOption('dev', null, InputOption::VALUE_NONE, 'Sets the dev mode.'),
2033 new InputOption('no-dev', null, InputOption::VALUE_NONE, 'Disables the dev mode.'),
2034 new InputArgument('args', InputArgument::IS_ARRAY | InputArgument::OPTIONAL, ''),
2035 ))
2036 ->setHelp(<<<EOT
2037 The <info>run-script</info> command runs scripts defined in composer.json:
2038
2039 <info>php composer.phar run-script post-update-cmd</info>
2040 EOT
2041 )
2042 ;
2043 }
2044
2045 protected function execute(InputInterface $input, OutputInterface $output)
2046 {
2047 $composer = $this->getComposer();
2048
2049
2050  $binDir = $composer->getConfig()->get('bin-dir');
2051 if (is_dir($binDir)) {
2052 putenv('PATH='.realpath($binDir).PATH_SEPARATOR.getenv('PATH'));
2053 }
2054
2055 $args = $input->getArguments();
2056
2057 return $composer->getEventDispatcher()->dispatchScript($this->script, $input->getOption('dev') || !$input->getOption('no-dev'), $args['args']);
2058 }
2059 }
2060 <?php
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072 namespace Composer\Command;
2073
2074 use Composer\DependencyResolver\Pool;
2075 use Composer\DependencyResolver\DefaultPolicy;
2076 use Composer\Factory;
2077 use Composer\Package\CompletePackageInterface;
2078 use Composer\Package\Version\VersionParser;
2079 use Composer\Plugin\CommandEvent;
2080 use Composer\Plugin\PluginEvents;
2081 use Symfony\Component\Console\Input\InputInterface;
2082 use Symfony\Component\Console\Input\InputArgument;
2083 use Symfony\Component\Console\Input\InputOption;
2084 use Symfony\Component\Console\Output\OutputInterface;
2085 use Composer\Repository\ArrayRepository;
2086 use Composer\Repository\CompositeRepository;
2087 use Composer\Repository\ComposerRepository;
2088 use Composer\Repository\PlatformRepository;
2089 use Composer\Repository\RepositoryInterface;
2090
2091
2092
2093
2094
2095 class ShowCommand extends Command
2096 {
2097 protected $versionParser;
2098
2099 protected function configure()
2100 {
2101 $this
2102 ->setName('show')
2103 ->setDescription('Show information about packages')
2104 ->setDefinition(array(
2105 new InputArgument('package', InputArgument::OPTIONAL, 'Package to inspect'),
2106 new InputArgument('version', InputArgument::OPTIONAL, 'Version or version constraint to inspect'),
2107 new InputOption('installed', 'i', InputOption::VALUE_NONE, 'List installed packages only'),
2108 new InputOption('platform', 'p', InputOption::VALUE_NONE, 'List platform packages only'),
2109 new InputOption('available', 'a', InputOption::VALUE_NONE, 'List available packages only'),
2110 new InputOption('self', 's', InputOption::VALUE_NONE, 'Show the root package information'),
2111 new InputOption('name-only', 'N', InputOption::VALUE_NONE, 'List package names only'),
2112 new InputOption('path', 'P', InputOption::VALUE_NONE, 'Show package paths'),
2113 ))
2114 ->setHelp(<<<EOT
2115 The show command displays detailed information about a package, or
2116 lists all packages available.
2117
2118 EOT
2119 )
2120 ;
2121 }
2122
2123 protected function execute(InputInterface $input, OutputInterface $output)
2124 {
2125 $this->versionParser = new VersionParser;
2126
2127
2128  $platformRepo = new PlatformRepository;
2129
2130 $composer = $this->getComposer(false);
2131 if ($input->getOption('self')) {
2132 $package = $this->getComposer()->getPackage();
2133 $repos = $installedRepo = new ArrayRepository(array($package));
2134 } elseif ($input->getOption('platform')) {
2135 $repos = $installedRepo = $platformRepo;
2136 } elseif ($input->getOption('installed')) {
2137 $repos = $installedRepo = $this->getComposer()->getRepositoryManager()->getLocalRepository();
2138 } elseif ($input->getOption('available')) {
2139 $installedRepo = $platformRepo;
2140 if ($composer) {
2141 $repos = new CompositeRepository($composer->getRepositoryManager()->getRepositories());
2142 } else {
2143 $defaultRepos = Factory::createDefaultRepositories($this->getIO());
2144 $repos = new CompositeRepository($defaultRepos);
2145 $output->writeln('No composer.json found in the current directory, showing available packages from ' . implode(', ', array_keys($defaultRepos)));
2146 }
2147 } elseif ($composer) {
2148 $localRepo = $composer->getRepositoryManager()->getLocalRepository();
2149 $installedRepo = new CompositeRepository(array($localRepo, $platformRepo));
2150 $repos = new CompositeRepository(array_merge(array($installedRepo), $composer->getRepositoryManager()->getRepositories()));
2151 } else {
2152 $defaultRepos = Factory::createDefaultRepositories($this->getIO());
2153 $output->writeln('No composer.json found in the current directory, showing available packages from ' . implode(', ', array_keys($defaultRepos)));
2154 $installedRepo = $platformRepo;
2155 $repos = new CompositeRepository(array_merge(array($installedRepo), $defaultRepos));
2156 }
2157
2158 if ($composer) {
2159 $commandEvent = new CommandEvent(PluginEvents::COMMAND, 'show', $input, $output);
2160 $composer->getEventDispatcher()->dispatch($commandEvent->getName(), $commandEvent);
2161 }
2162
2163
2164  if ($input->getArgument('package') || !empty($package)) {
2165 $versions = array();
2166 if (empty($package)) {
2167 list($package, $versions) = $this->getPackage($installedRepo, $repos, $input->getArgument('package'), $input->getArgument('version'));
2168
2169 if (!$package) {
2170 throw new \InvalidArgumentException('Package '.$input->getArgument('package').' not found');
2171 }
2172 } else {
2173 $versions = array($package->getPrettyVersion() => $package->getVersion());
2174 }
2175
2176 $this->printMeta($input, $output, $package, $versions, $installedRepo, $repos);
2177 $this->printLinks($input, $output, $package, 'requires');
2178 $this->printLinks($input, $output, $package, 'devRequires', 'requires (dev)');
2179 if ($package->getSuggests()) {
2180 $output->writeln("\n<info>suggests</info>");
2181 foreach ($package->getSuggests() as $suggested => $reason) {
2182 $output->writeln($suggested . ' <comment>' . $reason . '</comment>');
2183 }
2184 }
2185 $this->printLinks($input, $output, $package, 'provides');
2186 $this->printLinks($input, $output, $package, 'conflicts');
2187 $this->printLinks($input, $output, $package, 'replaces');
2188
2189 return;
2190 }
2191
2192
2193  $packages = array();
2194
2195 if ($repos instanceof CompositeRepository) {
2196 $repos = $repos->getRepositories();
2197 } elseif (!is_array($repos)) {
2198 $repos = array($repos);
2199 }
2200
2201 foreach ($repos as $repo) {
2202 if ($repo === $platformRepo) {
2203 $type = '<info>platform</info>:';
2204 } elseif (
2205 $repo === $installedRepo
2206 || ($installedRepo instanceof CompositeRepository && in_array($repo, $installedRepo->getRepositories(), true))
2207 ) {
2208 $type = '<info>installed</info>:';
2209 } else {
2210 $type = '<comment>available</comment>:';
2211 }
2212 if ($repo instanceof ComposerRepository && $repo->hasProviders()) {
2213 foreach ($repo->getProviderNames() as $name) {
2214 $packages[$type][$name] = $name;
2215 }
2216 } else {
2217 foreach ($repo->getPackages() as $package) {
2218 if (!isset($packages[$type][$package->getName()])
2219 || !is_object($packages[$type][$package->getName()])
2220 || version_compare($packages[$type][$package->getName()]->getVersion(), $package->getVersion(), '<')
2221 ) {
2222 $packages[$type][$package->getName()] = $package;
2223 }
2224 }
2225 }
2226 }
2227
2228 $tree = !$input->getOption('platform') && !$input->getOption('installed') && !$input->getOption('available');
2229 $indent = $tree ? '  ' : '';
2230 foreach (array('<info>platform</info>:' => true, '<comment>available</comment>:' => false, '<info>installed</info>:' => true) as $type => $showVersion) {
2231 if (isset($packages[$type])) {
2232 if ($tree) {
2233 $output->writeln($type);
2234 }
2235 ksort($packages[$type]);
2236
2237 $nameLength = $versionLength = 0;
2238 foreach ($packages[$type] as $package) {
2239 if (is_object($package)) {
2240 $nameLength = max($nameLength, strlen($package->getPrettyName()));
2241 $versionLength = max($versionLength, strlen($this->versionParser->formatVersion($package)));
2242 } else {
2243 $nameLength = max($nameLength, $package);
2244 }
2245 }
2246 list($width) = $this->getApplication()->getTerminalDimensions();
2247 if (null === $width) {
2248
2249  
2250  $width = PHP_INT_MAX;
2251 }
2252 if (defined('PHP_WINDOWS_VERSION_BUILD')) {
2253 $width--;
2254 }
2255
2256 $writePath = !$input->getOption('name-only') && $input->getOption('path');
2257 $writeVersion = !$input->getOption('name-only') && !$input->getOption('path') && $showVersion && ($nameLength + $versionLength + 3 <= $width);
2258 $writeDescription = !$input->getOption('name-only') && !$input->getOption('path') && ($nameLength + ($showVersion ? $versionLength : 0) + 24 <= $width);
2259 foreach ($packages[$type] as $package) {
2260 if (is_object($package)) {
2261 $output->write($indent . str_pad($package->getPrettyName(), $nameLength, ' '), false);
2262
2263 if ($writeVersion) {
2264 $output->write(' ' . str_pad($this->versionParser->formatVersion($package), $versionLength, ' '), false);
2265 }
2266
2267 if ($writeDescription) {
2268 $description = strtok($package->getDescription(), "\r\n");
2269 $remaining = $width - $nameLength - $versionLength - 4;
2270 if (strlen($description) > $remaining) {
2271 $description = substr($description, 0, $remaining - 3) . '...';
2272 }
2273 $output->write(' ' . $description);
2274 }
2275
2276 if ($writePath) {
2277 $path = strtok(realpath($composer->getInstallationManager()->getInstallPath($package)), "\r\n");
2278 $output->write(' ' . $path);
2279 }
2280 } else {
2281 $output->write($indent . $package);
2282 }
2283 $output->writeln('');
2284 }
2285 if ($tree) {
2286 $output->writeln('');
2287 }
2288 }
2289 }
2290 }
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302 protected function getPackage(RepositoryInterface $installedRepo, RepositoryInterface $repos, $name, $version = null)
2303 {
2304 $name = strtolower($name);
2305 $constraint = null;
2306 if ($version) {
2307 $constraint = $this->versionParser->parseConstraints($version);
2308 }
2309
2310 $policy = new DefaultPolicy();
2311 $pool = new Pool('dev');
2312 $pool->addRepository($repos);
2313
2314 $matchedPackage = null;
2315 $versions = array();
2316 $matches = $pool->whatProvides($name, $constraint);
2317 foreach ($matches as $index => $package) {
2318
2319  if ($package->getName() !== $name) {
2320 unset($matches[$index]);
2321 continue;
2322 }
2323
2324
2325  if (null === $version && $installedRepo->hasPackage($package)) {
2326 $matchedPackage = $package;
2327 }
2328
2329 $versions[$package->getPrettyVersion()] = $package->getVersion();
2330 $matches[$index] = $package->getId();
2331 }
2332
2333
2334  if (!$matchedPackage && $matches && $prefered = $policy->selectPreferedPackages($pool, array(), $matches)) {
2335 $matchedPackage = $pool->literalToPackage($prefered[0]);
2336 }
2337
2338 return array($matchedPackage, $versions);
2339 }
2340
2341
2342
2343
2344 protected function printMeta(InputInterface $input, OutputInterface $output, CompletePackageInterface $package, array $versions, RepositoryInterface $installedRepo, RepositoryInterface $repos)
2345 {
2346 $output->writeln('<info>name</info>     : ' . $package->getPrettyName());
2347 $output->writeln('<info>descrip.</info> : ' . $package->getDescription());
2348 $output->writeln('<info>keywords</info> : ' . join(', ', $package->getKeywords() ?: array()));
2349 $this->printVersions($input, $output, $package, $versions, $installedRepo, $repos);
2350 $output->writeln('<info>type</info>     : ' . $package->getType());
2351 $output->writeln('<info>license</info>  : ' . implode(', ', $package->getLicense()));
2352 $output->writeln('<info>source</info>   : ' . sprintf('[%s] <comment>%s</comment> %s', $package->getSourceType(), $package->getSourceUrl(), $package->getSourceReference()));
2353 $output->writeln('<info>dist</info>     : ' . sprintf('[%s] <comment>%s</comment> %s', $package->getDistType(), $package->getDistUrl(), $package->getDistReference()));
2354 $output->writeln('<info>names</info>    : ' . implode(', ', $package->getNames()));
2355
2356 if ($package->isAbandoned()) {
2357 $replacement = ($package->getReplacementPackage() !== null)
2358 ? ' The author suggests using the ' . $package->getReplacementPackage(). ' package instead.'
2359 : null;
2360
2361 $output->writeln(
2362 sprintf('<error>Attention: This package is abandoned and no longer maintained.%s</error>', $replacement)
2363 );
2364 }
2365
2366 if ($package->getSupport()) {
2367 $output->writeln("\n<info>support</info>");
2368 foreach ($package->getSupport() as $type => $value) {
2369 $output->writeln('<comment>' . $type . '</comment> : '.$value);
2370 }
2371 }
2372
2373 if ($package->getAutoload()) {
2374 $output->writeln("\n<info>autoload</info>");
2375 foreach ($package->getAutoload() as $type => $autoloads) {
2376 $output->writeln('<comment>' . $type . '</comment>');
2377
2378 if ($type === 'psr-0') {
2379 foreach ($autoloads as $name => $path) {
2380 $output->writeln(($name ?: '*') . ' => ' . (is_array($path) ? implode(', ', $path) : ($path ?: '.')));
2381 }
2382 } elseif ($type === 'psr-4') {
2383 foreach ($autoloads as $name => $path) {
2384 $output->writeln(($name ?: '*') . ' => ' . (is_array($path) ? implode(', ', $path) : ($path ?: '.')));
2385 }
2386 } elseif ($type === 'classmap') {
2387 $output->writeln(implode(', ', $autoloads));
2388 }
2389 }
2390 if ($package->getIncludePaths()) {
2391 $output->writeln('<comment>include-path</comment>');
2392 $output->writeln(implode(', ', $package->getIncludePaths()));
2393 }
2394 }
2395 }
2396
2397
2398
2399
2400 protected function printVersions(InputInterface $input, OutputInterface $output, CompletePackageInterface $package, array $versions, RepositoryInterface $installedRepo, RepositoryInterface $repos)
2401 {
2402 uasort($versions, 'version_compare');
2403 $versions = array_keys(array_reverse($versions));
2404
2405
2406  if ($installedRepo->hasPackage($package)) {
2407 $installedVersion = $package->getPrettyVersion();
2408 $key = array_search($installedVersion, $versions);
2409 if (false !== $key) {
2410 $versions[$key] = '<info>* ' . $installedVersion . '</info>';
2411 }
2412 }
2413
2414 $versions = implode(', ', $versions);
2415
2416 $output->writeln('<info>versions</info> : ' . $versions);
2417 }
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428 protected function printLinks(InputInterface $input, OutputInterface $output, CompletePackageInterface $package, $linkType, $title = null)
2429 {
2430 $title = $title ?: $linkType;
2431 if ($links = $package->{'get'.ucfirst($linkType)}()) {
2432 $output->writeln("\n<info>" . $title . "</info>");
2433
2434 foreach ($links as $link) {
2435 $output->writeln($link->getTarget() . ' <comment>' . $link->getPrettyConstraint() . '</comment>');
2436 }
2437 }
2438 }
2439 }
2440 <?php
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452 namespace Composer\Command;
2453
2454 use Composer\Installer;
2455 use Composer\Plugin\CommandEvent;
2456 use Composer\Plugin\PluginEvents;
2457 use Symfony\Component\Console\Input\InputInterface;
2458 use Symfony\Component\Console\Input\InputOption;
2459 use Symfony\Component\Console\Input\InputArgument;
2460 use Symfony\Component\Console\Output\OutputInterface;
2461
2462
2463
2464
2465
2466 class UpdateCommand extends Command
2467 {
2468 protected function configure()
2469 {
2470 $this
2471 ->setName('update')
2472 ->setDescription('Updates your dependencies to the latest version according to composer.json, and updates the composer.lock file.')
2473 ->setDefinition(array(
2474 new InputArgument('packages', InputArgument::IS_ARRAY | InputArgument::OPTIONAL, 'Packages that should be updated, if not provided all packages are.'),
2475 new InputOption('prefer-source', null, InputOption::VALUE_NONE, 'Forces installation from package sources when possible, including VCS information.'),
2476 new InputOption('prefer-dist', null, InputOption::VALUE_NONE, 'Forces installation from package dist even for dev versions.'),
2477 new InputOption('dry-run', null, InputOption::VALUE_NONE, 'Outputs the operations but will not execute anything (implicitly enables --verbose).'),
2478 new InputOption('dev', null, InputOption::VALUE_NONE, 'Enables installation of require-dev packages (enabled by default, only present for BC).'),
2479 new InputOption('no-dev', null, InputOption::VALUE_NONE, 'Disables installation of require-dev packages.'),
2480 new InputOption('lock', null, InputOption::VALUE_NONE, 'Only updates the lock file hash to suppress warning about the lock file being out of date.'),
2481 new InputOption('no-plugins', null, InputOption::VALUE_NONE, 'Disables all plugins.'),
2482 new InputOption('no-custom-installers', null, InputOption::VALUE_NONE, 'DEPRECATED: Use no-plugins instead.'),
2483 new InputOption('no-autoloader', null, InputOption::VALUE_NONE, 'Skips autoloader generation'),
2484 new InputOption('no-scripts', null, InputOption::VALUE_NONE, 'Skips the execution of all scripts defined in composer.json file.'),
2485 new InputOption('no-progress', null, InputOption::VALUE_NONE, 'Do not output download progress.'),
2486 new InputOption('with-dependencies', null, InputOption::VALUE_NONE, 'Add also all dependencies of whitelisted packages to the whitelist.'),
2487 new InputOption('verbose', 'v|vv|vvv', InputOption::VALUE_NONE, 'Shows more details including new commits pulled in when updating packages.'),
2488 new InputOption('optimize-autoloader', 'o', InputOption::VALUE_NONE, 'Optimize autoloader during autoloader dump.'),
2489 new InputOption('ignore-platform-reqs', null, InputOption::VALUE_NONE, 'Ignore platform requirements (php & ext- packages).'),
2490 new InputOption('prefer-stable', null, InputOption::VALUE_NONE, 'Prefer stable versions of dependencies.'),
2491 new InputOption('prefer-lowest', null, InputOption::VALUE_NONE, 'Prefer lowest versions of dependencies.'),
2492 ))
2493 ->setHelp(<<<EOT
2494 The <info>update</info> command reads the composer.json file from the
2495 current directory, processes it, and updates, removes or installs all the
2496 dependencies.
2497
2498 <info>php composer.phar update</info>
2499
2500 To limit the update operation to a few packages, you can list the package(s)
2501 you want to update as such:
2502
2503 <info>php composer.phar update vendor/package1 foo/mypackage [...]</info>
2504
2505 You may also use an asterisk (*) pattern to limit the update operation to package(s)
2506 from a specific vendor:
2507
2508 <info>php composer.phar update vendor/package1 foo/* [...]</info>
2509 EOT
2510 )
2511 ;
2512 }
2513
2514 protected function execute(InputInterface $input, OutputInterface $output)
2515 {
2516 if ($input->getOption('no-custom-installers')) {
2517 $output->writeln('<warning>You are using the deprecated option "no-custom-installers". Use "no-plugins" instead.</warning>');
2518 $input->setOption('no-plugins', true);
2519 }
2520
2521 $composer = $this->getComposer(true, $input->getOption('no-plugins'));
2522 $composer->getDownloadManager()->setOutputProgress(!$input->getOption('no-progress'));
2523 $io = $this->getIO();
2524
2525 $commandEvent = new CommandEvent(PluginEvents::COMMAND, 'update', $input, $output);
2526 $composer->getEventDispatcher()->dispatch($commandEvent->getName(), $commandEvent);
2527
2528 $install = Installer::create($io, $composer);
2529
2530 $preferSource = false;
2531 $preferDist = false;
2532
2533 $config = $composer->getConfig();
2534
2535 switch ($config->get('preferred-install')) {
2536 case 'source':
2537 $preferSource = true;
2538 break;
2539 case 'dist':
2540 $preferDist = true;
2541 break;
2542 case 'auto':
2543 default:
2544
2545  break;
2546 }
2547 if ($input->getOption('prefer-source') || $input->getOption('prefer-dist')) {
2548 $preferSource = $input->getOption('prefer-source');
2549 $preferDist = $input->getOption('prefer-dist');
2550 }
2551
2552 $optimize = $input->getOption('optimize-autoloader') || $config->get('optimize-autoloader');
2553
2554 $install
2555 ->setDryRun($input->getOption('dry-run'))
2556 ->setVerbose($input->getOption('verbose'))
2557 ->setPreferSource($preferSource)
2558 ->setPreferDist($preferDist)
2559 ->setDevMode(!$input->getOption('no-dev'))
2560 ->setDumpAutoloader(!$input->getOption('no-autoloader'))
2561 ->setRunScripts(!$input->getOption('no-scripts'))
2562 ->setOptimizeAutoloader($optimize)
2563 ->setUpdate(true)
2564 ->setUpdateWhitelist($input->getOption('lock') ? array('lock') : $input->getArgument('packages'))
2565 ->setWhitelistDependencies($input->getOption('with-dependencies'))
2566 ->setIgnorePlatformRequirements($input->getOption('ignore-platform-reqs'))
2567 ->setPreferStable($input->getOption('prefer-stable'))
2568 ->setPreferLowest($input->getOption('prefer-lowest'))
2569 ;
2570
2571 if ($input->getOption('no-plugins')) {
2572 $install->disablePlugins();
2573 }
2574
2575 return $install->run();
2576 }
2577 }
2578 <?php
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590 namespace Composer\Command;
2591
2592 use Symfony\Component\Console\Input\InputInterface;
2593 use Symfony\Component\Console\Input\InputArgument;
2594 use Symfony\Component\Console\Input\InputOption;
2595 use Symfony\Component\Console\Output\OutputInterface;
2596 use Composer\Config;
2597 use Composer\Config\JsonConfigSource;
2598 use Composer\Factory;
2599 use Composer\Json\JsonFile;
2600
2601
2602
2603
2604
2605 class ConfigCommand extends Command
2606 {
2607
2608
2609
2610 protected $config;
2611
2612
2613
2614
2615 protected $configFile;
2616
2617
2618
2619
2620 protected $configSource;
2621
2622
2623
2624
2625 protected function configure()
2626 {
2627 $this
2628 ->setName('config')
2629 ->setDescription('Set config options')
2630 ->setDefinition(array(
2631 new InputOption('global', 'g', InputOption::VALUE_NONE, 'Apply command to the global config file'),
2632 new InputOption('editor', 'e', InputOption::VALUE_NONE, 'Open editor'),
2633 new InputOption('auth', 'a', InputOption::VALUE_NONE, 'Affect auth config file (only used for --editor)'),
2634 new InputOption('unset', null, InputOption::VALUE_NONE, 'Unset the given setting-key'),
2635 new InputOption('list', 'l', InputOption::VALUE_NONE, 'List configuration settings'),
2636 new InputOption('file', 'f', InputOption::VALUE_REQUIRED, 'If you want to choose a different composer.json or config.json', 'composer.json'),
2637 new InputOption('absolute', null, InputOption::VALUE_NONE, 'Returns absolute paths when fetching *-dir config values instead of relative'),
2638 new InputArgument('setting-key', null, 'Setting key'),
2639 new InputArgument('setting-value', InputArgument::IS_ARRAY, 'Setting value'),
2640 ))
2641 ->setHelp(<<<EOT
2642 This command allows you to edit some basic composer settings in either the
2643 local composer.json file or the global config.json file.
2644
2645 To edit the global config.json file:
2646
2647     <comment>%command.full_name% --global</comment>
2648
2649 To add a repository:
2650
2651     <comment>%command.full_name% repositories.foo vcs http://bar.com</comment>
2652
2653 You can add a repository to the global config.json file by passing in the
2654 <info>--global</info> option.
2655
2656 To edit the file in an external editor:
2657
2658     <comment>%command.full_name% --editor</comment>
2659
2660 To choose your editor you can set the "EDITOR" env variable.
2661
2662 To get a list of configuration values in the file:
2663
2664     <comment>%command.full_name% --list</comment>
2665
2666 You can always pass more than one option. As an example, if you want to edit the
2667 global config.json file.
2668
2669     <comment>%command.full_name% --editor --global</comment>
2670 EOT
2671 )
2672 ;
2673 }
2674
2675
2676
2677
2678 protected function initialize(InputInterface $input, OutputInterface $output)
2679 {
2680 parent::initialize($input, $output);
2681
2682 if ($input->getOption('global') && 'composer.json' !== $input->getOption('file')) {
2683 throw new \RuntimeException('--file and --global can not be combined');
2684 }
2685
2686 $this->config = Factory::createConfig($this->getIO());
2687
2688
2689  
2690  $configFile = $input->getOption('global')
2691 ? ($this->config->get('home') . '/config.json')
2692 : $input->getOption('file');
2693
2694 $this->configFile = new JsonFile($configFile);
2695 $this->configSource = new JsonConfigSource($this->configFile);
2696
2697 $authConfigFile = $input->getOption('global')
2698 ? ($this->config->get('home') . '/auth.json')
2699 : dirname(realpath($input->getOption('file'))) . '/auth.json';
2700
2701 $this->authConfigFile = new JsonFile($authConfigFile);
2702 $this->authConfigSource = new JsonConfigSource($this->authConfigFile, true);
2703
2704
2705  if ($input->getOption('global') && !$this->configFile->exists()) {
2706 touch($this->configFile->getPath());
2707 $this->configFile->write(array('config' => new \ArrayObject));
2708 @chmod($this->configFile->getPath(), 0600);
2709 }
2710 if ($input->getOption('global') && !$this->authConfigFile->exists()) {
2711 touch($this->authConfigFile->getPath());
2712 $this->authConfigFile->write(array('http-basic' => new \ArrayObject, 'github-oauth' => new \ArrayObject));
2713 @chmod($this->authConfigFile->getPath(), 0600);
2714 }
2715
2716 if (!$this->configFile->exists()) {
2717 throw new \RuntimeException('No composer.json found in the current directory');
2718 }
2719 }
2720
2721
2722
2723
2724 protected function execute(InputInterface $input, OutputInterface $output)
2725 {
2726
2727  if ($input->getOption('editor')) {
2728 $editor = escapeshellcmd(getenv('EDITOR'));
2729 if (!$editor) {
2730 if (defined('PHP_WINDOWS_VERSION_BUILD')) {
2731 $editor = 'notepad';
2732 } else {
2733 foreach (array('vim', 'vi', 'nano', 'pico', 'ed') as $candidate) {
2734 if (exec('which '.$candidate)) {
2735 $editor = $candidate;
2736 break;
2737 }
2738 }
2739 }
2740 }
2741
2742 $file = $input->getOption('auth') ? $this->authConfigFile->getPath() : $this->configFile->getPath();
2743 system($editor . ' ' . $file . (defined('PHP_WINDOWS_VERSION_BUILD') ? '' : ' > `tty`'));
2744
2745 return 0;
2746 }
2747
2748 if (!$input->getOption('global')) {
2749 $this->config->merge($this->configFile->read());
2750 $this->config->merge(array('config' => $this->authConfigFile->exists() ? $this->authConfigFile->read() : array()));
2751 }
2752
2753
2754  if ($input->getOption('list')) {
2755 $this->listConfiguration($this->config->all(), $this->config->raw(), $output);
2756
2757 return 0;
2758 }
2759
2760 $settingKey = $input->getArgument('setting-key');
2761 if (!$settingKey) {
2762 return 0;
2763 }
2764
2765
2766  if (array() !== $input->getArgument('setting-value') && $input->getOption('unset')) {
2767 throw new \RuntimeException('You can not combine a setting value with --unset');
2768 }
2769
2770
2771  if (array() === $input->getArgument('setting-value') && !$input->getOption('unset')) {
2772 $data = $this->config->all();
2773 if (preg_match('/^repos?(?:itories)?(?:\.(.+))?/', $settingKey, $matches)) {
2774 if (empty($matches[1])) {
2775 $value = isset($data['repositories']) ? $data['repositories'] : array();
2776 } else {
2777 if (!isset($data['repositories'][$matches[1]])) {
2778 throw new \InvalidArgumentException('There is no '.$matches[1].' repository defined');
2779 }
2780
2781 $value = $data['repositories'][$matches[1]];
2782 }
2783 } elseif (strpos($settingKey, '.')) {
2784 $bits = explode('.', $settingKey);
2785 $data = $data['config'];
2786 foreach ($bits as $bit) {
2787 if (isset($data[$bit])) {
2788 $data = $data[$bit];
2789 } elseif (isset($data[implode('.', $bits)])) {
2790
2791  $data = $data[implode('.', $bits)];
2792 break;
2793 } else {
2794 throw new \RuntimeException($settingKey.' is not defined');
2795 }
2796 array_shift($bits);
2797 }
2798
2799 $value = $data;
2800 } elseif (isset($data['config'][$settingKey])) {
2801 $value = $this->config->get($settingKey, $input->getOption('absolute') ? 0 : Config::RELATIVE_PATHS);
2802 } else {
2803 throw new \RuntimeException($settingKey.' is not defined');
2804 }
2805
2806 if (is_array($value)) {
2807 $value = json_encode($value);
2808 }
2809
2810 $output->writeln($value);
2811
2812 return 0;
2813 }
2814
2815 $values = $input->getArgument('setting-value'); 
2816
2817
2818  if (preg_match('/^repos?(?:itories)?\.(.+)/', $settingKey, $matches)) {
2819 if ($input->getOption('unset')) {
2820 return $this->configSource->removeRepository($matches[1]);
2821 }
2822
2823 if (2 !== count($values)) {
2824 throw new \RuntimeException('You must pass the type and a url. Example: php composer.phar config repositories.foo vcs http://bar.com');
2825 }
2826
2827 return $this->configSource->addRepository($matches[1], array(
2828 'type' => $values[0],
2829 'url' => $values[1],
2830 ));
2831 }
2832
2833
2834  if (preg_match('/^(github-oauth|http-basic)\.(.+)/', $settingKey, $matches)) {
2835 if ($input->getOption('unset')) {
2836 $this->authConfigSource->removeConfigSetting($matches[1].'.'.$matches[2]);
2837 $this->configSource->removeConfigSetting($matches[1].'.'.$matches[2]);
2838
2839 return;
2840 }
2841
2842 if ($matches[1] === 'github-oauth') {
2843 if (1 !== count($values)) {
2844 throw new \RuntimeException('Too many arguments, expected only one token');
2845 }
2846 $this->configSource->removeConfigSetting($matches[1].'.'.$matches[2]);
2847 $this->authConfigSource->addConfigSetting($matches[1].'.'.$matches[2], $values[0]);
2848 } elseif ($matches[1] === 'http-basic') {
2849 if (2 !== count($values)) {
2850 throw new \RuntimeException('Expected two arguments (username, password), got '.count($values));
2851 }
2852 $this->configSource->removeConfigSetting($matches[1].'.'.$matches[2]);
2853 $this->authConfigSource->addConfigSetting($matches[1].'.'.$matches[2], array('username' => $values[0], 'password' => $values[1]));
2854 }
2855
2856 return;
2857 }
2858
2859 $booleanValidator = function ($val) { return in_array($val, array('true', 'false', '1', '0'), true); };
2860 $booleanNormalizer = function ($val) { return $val !== 'false' && (bool) $val; };
2861
2862
2863  $uniqueConfigValues = array(
2864 'process-timeout' => array('is_numeric', 'intval'),
2865 'use-include-path' => array($booleanValidator, $booleanNormalizer),
2866 'preferred-install' => array(
2867 function ($val) { return in_array($val, array('auto', 'source', 'dist'), true); },
2868 function ($val) { return $val; }
2869 ),
2870 'store-auths' => array(
2871 function ($val) { return in_array($val, array('true', 'false', 'prompt'), true); },
2872 function ($val) {
2873 if ('prompt' === $val) {
2874 return 'prompt';
2875 }
2876
2877 return $val !== 'false' && (bool) $val;
2878 }
2879 ),
2880 'notify-on-install' => array($booleanValidator, $booleanNormalizer),
2881 'vendor-dir' => array('is_string', function ($val) { return $val; }),
2882 'bin-dir' => array('is_string', function ($val) { return $val; }),
2883 'cache-dir' => array('is_string', function ($val) { return $val; }),
2884 'cache-files-dir' => array('is_string', function ($val) { return $val; }),
2885 'cache-repo-dir' => array('is_string', function ($val) { return $val; }),
2886 'cache-vcs-dir' => array('is_string', function ($val) { return $val; }),
2887 'cache-ttl' => array('is_numeric', 'intval'),
2888 'cache-files-ttl' => array('is_numeric', 'intval'),
2889 'cache-files-maxsize' => array(
2890 function ($val) { return preg_match('/^\s*([0-9.]+)\s*(?:([kmg])(?:i?b)?)?\s*$/i', $val) > 0; },
2891 function ($val) { return $val; }
2892 ),
2893 'discard-changes' => array(
2894 function ($val) { return in_array($val, array('stash', 'true', 'false', '1', '0'), true); },
2895 function ($val) {
2896 if ('stash' === $val) {
2897 return 'stash';
2898 }
2899
2900 return $val !== 'false' && (bool) $val;
2901 }
2902 ),
2903 'autoloader-suffix' => array('is_string', function ($val) { return $val === 'null' ? null : $val; }),
2904 'optimize-autoloader' => array($booleanValidator, $booleanNormalizer),
2905 'prepend-autoloader' => array($booleanValidator, $booleanNormalizer),
2906 'github-expose-hostname' => array($booleanValidator, $booleanNormalizer),
2907 );
2908 $multiConfigValues = array(
2909 'github-protocols' => array(
2910 function ($vals) {
2911 if (!is_array($vals)) {
2912 return 'array expected';
2913 }
2914
2915 foreach ($vals as $val) {
2916 if (!in_array($val, array('git', 'https', 'ssh'))) {
2917 return 'valid protocols include: git, https, ssh';
2918 }
2919 }
2920
2921 return true;
2922 },
2923 function ($vals) {
2924 return $vals;
2925 }
2926 ),
2927 'github-domains' => array(
2928 function ($vals) {
2929 if (!is_array($vals)) {
2930 return 'array expected';
2931 }
2932
2933 return true;
2934 },
2935 function ($vals) {
2936 return $vals;
2937 }
2938 ),
2939 );
2940
2941 foreach ($uniqueConfigValues as $name => $callbacks) {
2942 if ($settingKey === $name) {
2943 if ($input->getOption('unset')) {
2944 return $this->configSource->removeConfigSetting($settingKey);
2945 }
2946
2947 list($validator, $normalizer) = $callbacks;
2948 if (1 !== count($values)) {
2949 throw new \RuntimeException('You can only pass one value. Example: php composer.phar config process-timeout 300');
2950 }
2951
2952 if (true !== $validation = $validator($values[0])) {
2953 throw new \RuntimeException(sprintf(
2954 '"%s" is an invalid value'.($validation ? ' ('.$validation.')' : ''),
2955 $values[0]
2956 ));
2957 }
2958
2959 return $this->configSource->addConfigSetting($settingKey, $normalizer($values[0]));
2960 }
2961 }
2962
2963 foreach ($multiConfigValues as $name => $callbacks) {
2964 if ($settingKey === $name) {
2965 if ($input->getOption('unset')) {
2966 return $this->configSource->removeConfigSetting($settingKey);
2967 }
2968
2969 list($validator, $normalizer) = $callbacks;
2970 if (true !== $validation = $validator($values)) {
2971 throw new \RuntimeException(sprintf(
2972 '%s is an invalid value'.($validation ? ' ('.$validation.')' : ''),
2973 json_encode($values)
2974 ));
2975 }
2976
2977 return $this->configSource->addConfigSetting($settingKey, $normalizer($values));
2978 }
2979 }
2980
2981 throw new \InvalidArgumentException('Setting '.$settingKey.' does not exist or is not supported by this command');
2982 }
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992 protected function listConfiguration(array $contents, array $rawContents, OutputInterface $output, $k = null)
2993 {
2994 $origK = $k;
2995 foreach ($contents as $key => $value) {
2996 if ($k === null && !in_array($key, array('config', 'repositories'))) {
2997 continue;
2998 }
2999
3000 $rawVal = isset($rawContents[$key]) ? $rawContents[$key] : null;
3001
3002 if (is_array($value) && (!is_numeric(key($value)) || ($key === 'repositories' && null === $k))) {
3003 $k .= preg_replace('{^config\.}', '', $key . '.');
3004 $this->listConfiguration($value, $rawVal, $output, $k);
3005
3006 if (substr_count($k, '.') > 1) {
3007 $k = str_split($k, strrpos($k, '.', -2));
3008 $k = $k[0] . '.';
3009 } else {
3010 $k = $origK;
3011 }
3012
3013 continue;
3014 }
3015
3016 if (is_array($value)) {
3017 $value = array_map(function ($val) {
3018 return is_array($val) ? json_encode($val) : $val;
3019 }, $value);
3020
3021 $value = '['.implode(', ', $value).']';
3022 }
3023
3024 if (is_bool($value)) {
3025 $value = var_export($value, true);
3026 }
3027
3028 if (is_string($rawVal) && $rawVal != $value) {
3029 $output->writeln('[<comment>' . $k . $key . '</comment>] <info>' . $rawVal . ' (' . $value . ')</info>');
3030 } else {
3031 $output->writeln('[<comment>' . $k . $key . '</comment>] <info>' . $value . '</info>');
3032 }
3033 }
3034 }
3035 }
3036 <?php
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048 namespace Composer\Command;
3049
3050 use Composer\Installer;
3051 use Composer\Plugin\CommandEvent;
3052 use Composer\Plugin\PluginEvents;
3053 use Symfony\Component\Console\Input\InputInterface;
3054 use Symfony\Component\Console\Input\InputOption;
3055 use Symfony\Component\Console\Input\InputArgument;
3056 use Symfony\Component\Console\Output\OutputInterface;
3057
3058
3059
3060
3061
3062
3063
3064 class InstallCommand extends Command
3065 {
3066 protected function configure()
3067 {
3068 $this
3069 ->setName('install')
3070 ->setDescription('Installs the project dependencies from the composer.lock file if present, or falls back on the composer.json.')
3071 ->setDefinition(array(
3072 new InputOption('prefer-source', null, InputOption::VALUE_NONE, 'Forces installation from package sources when possible, including VCS information.'),
3073 new InputOption('prefer-dist', null, InputOption::VALUE_NONE, 'Forces installation from package dist even for dev versions.'),
3074 new InputOption('dry-run', null, InputOption::VALUE_NONE, 'Outputs the operations but will not execute anything (implicitly enables --verbose).'),
3075 new InputOption('dev', null, InputOption::VALUE_NONE, 'Enables installation of require-dev packages (enabled by default, only present for BC).'),
3076 new InputOption('no-dev', null, InputOption::VALUE_NONE, 'Disables installation of require-dev packages.'),
3077 new InputOption('no-plugins', null, InputOption::VALUE_NONE, 'Disables all plugins.'),
3078 new InputOption('no-custom-installers', null, InputOption::VALUE_NONE, 'DEPRECATED: Use no-plugins instead.'),
3079 new InputOption('no-autoloader', null, InputOption::VALUE_NONE, 'Skips autoloader generation'),
3080 new InputOption('no-scripts', null, InputOption::VALUE_NONE, 'Skips the execution of all scripts defined in composer.json file.'),
3081 new InputOption('no-progress', null, InputOption::VALUE_NONE, 'Do not output download progress.'),
3082 new InputOption('verbose', 'v|vv|vvv', InputOption::VALUE_NONE, 'Shows more details including new commits pulled in when updating packages.'),
3083 new InputOption('optimize-autoloader', 'o', InputOption::VALUE_NONE, 'Optimize autoloader during autoloader dump'),
3084 new InputOption('ignore-platform-reqs', null, InputOption::VALUE_NONE, 'Ignore platform requirements (php & ext- packages).'),
3085 new InputArgument('packages', InputArgument::IS_ARRAY | InputArgument::OPTIONAL, 'Should not be provided, use composer require instead to add a given package to composer.json.'),
3086 ))
3087 ->setHelp(<<<EOT
3088 The <info>install</info> command reads the composer.lock file from
3089 the current directory, processes it, and downloads and installs all the
3090 libraries and dependencies outlined in that file. If the file does not
3091 exist it will look for composer.json and do the same.
3092
3093 <info>php composer.phar install</info>
3094
3095 EOT
3096 )
3097 ;
3098 }
3099
3100 protected function execute(InputInterface $input, OutputInterface $output)
3101 {
3102 if ($args = $input->getArgument('packages')) {
3103 $output->writeln('<error>Invalid argument '.implode(' ', $args).'. Use "composer require '.implode(' ', $args).'" instead to add packages to your composer.json.</error>');
3104
3105 return 1;
3106 }
3107
3108 if ($input->getOption('no-custom-installers')) {
3109 $output->writeln('<warning>You are using the deprecated option "no-custom-installers". Use "no-plugins" instead.</warning>');
3110 $input->setOption('no-plugins', true);
3111 }
3112
3113 $composer = $this->getComposer(true, $input->getOption('no-plugins'));
3114 $composer->getDownloadManager()->setOutputProgress(!$input->getOption('no-progress'));
3115 $io = $this->getIO();
3116
3117 $commandEvent = new CommandEvent(PluginEvents::COMMAND, 'install', $input, $output);
3118 $composer->getEventDispatcher()->dispatch($commandEvent->getName(), $commandEvent);
3119
3120 $install = Installer::create($io, $composer);
3121
3122 $preferSource = false;
3123 $preferDist = false;
3124
3125 $config = $composer->getConfig();
3126
3127 switch ($config->get('preferred-install')) {
3128 case 'source':
3129 $preferSource = true;
3130 break;
3131 case 'dist':
3132 $preferDist = true;
3133 break;
3134 case 'auto':
3135 default:
3136
3137  break;
3138 }
3139 if ($input->getOption('prefer-source') || $input->getOption('prefer-dist')) {
3140 $preferSource = $input->getOption('prefer-source');
3141 $preferDist = $input->getOption('prefer-dist');
3142 }
3143
3144 $optimize = $input->getOption('optimize-autoloader') || $config->get('optimize-autoloader');
3145
3146 $install
3147 ->setDryRun($input->getOption('dry-run'))
3148 ->setVerbose($input->getOption('verbose'))
3149 ->setPreferSource($preferSource)
3150 ->setPreferDist($preferDist)
3151 ->setDevMode(!$input->getOption('no-dev'))
3152 ->setDumpAutoloader(!$input->getOption('no-autoloader'))
3153 ->setRunScripts(!$input->getOption('no-scripts'))
3154 ->setOptimizeAutoloader($optimize)
3155 ->setIgnorePlatformRequirements($input->getOption('ignore-platform-reqs'))
3156 ;
3157
3158 if ($input->getOption('no-plugins')) {
3159 $install->disablePlugins();
3160 }
3161
3162 return $install->run();
3163 }
3164 }
3165 <?php
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177 namespace Composer\Command;
3178
3179 use Composer\Package\Loader\ValidatingArrayLoader;
3180 use Composer\Util\ConfigValidator;
3181 use Symfony\Component\Console\Input\InputArgument;
3182 use Symfony\Component\Console\Input\InputInterface;
3183 use Symfony\Component\Console\Input\InputOption;
3184 use Symfony\Component\Console\Output\OutputInterface;
3185
3186
3187
3188
3189
3190
3191
3192 class ValidateCommand extends Command
3193 {
3194
3195
3196
3197 protected function configure()
3198 {
3199 $this
3200 ->setName('validate')
3201 ->setDescription('Validates a composer.json')
3202 ->setDefinition(array(
3203 new InputOption('no-check-all', null, InputOption::VALUE_NONE, 'Do not make a complete validation'),
3204 new InputArgument('file', InputArgument::OPTIONAL, 'path to composer.json file', './composer.json')
3205 ))
3206 ->setHelp(<<<EOT
3207 The validate command validates a given composer.json
3208
3209 EOT
3210 );
3211 }
3212
3213
3214
3215
3216
3217
3218
3219 protected function execute(InputInterface $input, OutputInterface $output)
3220 {
3221 $file = $input->getArgument('file');
3222
3223 if (!file_exists($file)) {
3224 $output->writeln('<error>' . $file . ' not found.</error>');
3225
3226 return 1;
3227 }
3228 if (!is_readable($file)) {
3229 $output->writeln('<error>' . $file . ' is not readable.</error>');
3230
3231 return 1;
3232 }
3233
3234 $validator = new ConfigValidator($this->getIO());
3235 $checkAll = $input->getOption('no-check-all') ? 0 : ValidatingArrayLoader::CHECK_ALL;
3236 list($errors, $publishErrors, $warnings) = $validator->validate($file, $checkAll);
3237
3238
3239  if (!$errors && !$publishErrors && !$warnings) {
3240 $output->writeln('<info>' . $file . ' is valid</info>');
3241 } elseif (!$errors && !$publishErrors) {
3242 $output->writeln('<info>' . $file . ' is valid, but with a few warnings</info>');
3243 $output->writeln('<warning>See http://getcomposer.org/doc/04-schema.md for details on the schema</warning>');
3244 } elseif (!$errors) {
3245 $output->writeln('<info>' . $file . ' is valid for simple usage with composer but has</info>');
3246 $output->writeln('<info>strict errors that make it unable to be published as a package:</info>');
3247 $output->writeln('<warning>See http://getcomposer.org/doc/04-schema.md for details on the schema</warning>');
3248 } else {
3249 $output->writeln('<error>' . $file . ' is invalid, the following errors/warnings were found:</error>');
3250 }
3251
3252 $messages = array(
3253 'error' => array_merge($errors, $publishErrors),
3254 'warning' => $warnings,
3255 );
3256
3257 foreach ($messages as $style => $msgs) {
3258 foreach ($msgs as $msg) {
3259 $output->writeln('<' . $style . '>' . $msg . '</' . $style . '>');
3260 }
3261 }
3262
3263 return $errors || $publishErrors ? 1 : 0;
3264 }
3265 }
3266 <?php
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278 namespace Composer\Command;
3279
3280 use Composer\DependencyResolver\Pool;
3281 use Composer\Plugin\CommandEvent;
3282 use Composer\Plugin\PluginEvents;
3283 use Symfony\Component\Console\Input\InputInterface;
3284 use Symfony\Component\Console\Input\InputArgument;
3285 use Symfony\Component\Console\Input\InputOption;
3286 use Symfony\Component\Console\Output\OutputInterface;
3287
3288
3289
3290
3291
3292 class DependsCommand extends Command
3293 {
3294 protected $linkTypes = array(
3295 'require' => array('requires', 'requires'),
3296 'require-dev' => array('devRequires', 'requires (dev)'),
3297 );
3298
3299 protected function configure()
3300 {
3301 $this
3302 ->setName('depends')
3303 ->setDescription('Shows which packages depend on the given package')
3304 ->setDefinition(array(
3305 new InputArgument('package', InputArgument::REQUIRED, 'Package to inspect'),
3306 new InputOption('link-type', '', InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'Link types to show (require, require-dev)', array_keys($this->linkTypes)),
3307 ))
3308 ->setHelp(<<<EOT
3309 Displays detailed information about where a package is referenced.
3310
3311 <info>php composer.phar depends composer/composer</info>
3312
3313 EOT
3314 )
3315 ;
3316 }
3317
3318 protected function execute(InputInterface $input, OutputInterface $output)
3319 {
3320 $composer = $this->getComposer();
3321
3322 $commandEvent = new CommandEvent(PluginEvents::COMMAND, 'depends', $input, $output);
3323 $composer->getEventDispatcher()->dispatch($commandEvent->getName(), $commandEvent);
3324
3325 $repo = $composer->getRepositoryManager()->getLocalRepository();
3326 $needle = $input->getArgument('package');
3327
3328 $pool = new Pool();
3329 $pool->addRepository($repo);
3330
3331 $packages = $pool->whatProvides($needle);
3332 if (empty($packages)) {
3333 throw new \InvalidArgumentException('Could not find package "'.$needle.'" in your project.');
3334 }
3335
3336 $linkTypes = $this->linkTypes;
3337
3338 $types = array_map(function ($type) use ($linkTypes) {
3339 $type = rtrim($type, 's');
3340 if (!isset($linkTypes[$type])) {
3341 throw new \InvalidArgumentException('Unexpected link type: '.$type.', valid types: '.implode(', ', array_keys($linkTypes)));
3342 }
3343
3344 return $type;
3345 }, $input->getOption('link-type'));
3346
3347 $messages = array();
3348 $outputPackages = array();
3349 foreach ($repo->getPackages() as $package) {
3350 foreach ($types as $type) {
3351 foreach ($package->{'get'.$linkTypes[$type][0]}() as $link) {
3352 if ($link->getTarget() === $needle) {
3353 if (!isset($outputPackages[$package->getName()])) {
3354 $messages[] = '<info>'.$package->getPrettyName() . '</info> ' . $linkTypes[$type][1] . ' ' . $needle .' (<info>' . $link->getPrettyConstraint() . '</info>)';
3355 $outputPackages[$package->getName()] = true;
3356 }
3357 }
3358 }
3359 }
3360 }
3361
3362 if ($messages) {
3363 sort($messages);
3364 $output->writeln($messages);
3365 } else {
3366 $output->writeln('<info>There is no installed package depending on "'.$needle.'".</info>');
3367 }
3368 }
3369 }
3370 <?php
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382 namespace Composer\Command;
3383
3384 use Symfony\Component\Console\Input\InputInterface;
3385 use Symfony\Component\Console\Input\InputArgument;
3386 use Symfony\Component\Console\Input\InputOption;
3387 use Symfony\Component\Console\Output\OutputInterface;
3388 use Composer\Repository\CompositeRepository;
3389 use Composer\Repository\PlatformRepository;
3390 use Composer\Repository\RepositoryInterface;
3391 use Composer\Factory;
3392 use Composer\Plugin\CommandEvent;
3393 use Composer\Plugin\PluginEvents;
3394
3395
3396
3397
3398 class SearchCommand extends Command
3399 {
3400 protected $matches;
3401 protected $lowMatches = array();
3402 protected $tokens;
3403 protected $output;
3404 protected $onlyName;
3405
3406 protected function configure()
3407 {
3408 $this
3409 ->setName('search')
3410 ->setDescription('Search for packages')
3411 ->setDefinition(array(
3412 new InputOption('only-name', 'N', InputOption::VALUE_NONE, 'Search only in name'),
3413 new InputArgument('tokens', InputArgument::IS_ARRAY | InputArgument::REQUIRED, 'tokens to search for'),
3414 ))
3415 ->setHelp(<<<EOT
3416 The search command searches for packages by its name
3417 <info>php composer.phar search symfony composer</info>
3418
3419 EOT
3420 )
3421 ;
3422 }
3423
3424 protected function execute(InputInterface $input, OutputInterface $output)
3425 {
3426
3427  $platformRepo = new PlatformRepository;
3428 if ($composer = $this->getComposer(false)) {
3429 $localRepo = $composer->getRepositoryManager()->getLocalRepository();
3430 $installedRepo = new CompositeRepository(array($localRepo, $platformRepo));
3431 $repos = new CompositeRepository(array_merge(array($installedRepo), $composer->getRepositoryManager()->getRepositories()));
3432 } else {
3433 $defaultRepos = Factory::createDefaultRepositories($this->getIO());
3434 $output->writeln('No composer.json found in the current directory, showing packages from ' . implode(', ', array_keys($defaultRepos)));
3435 $installedRepo = $platformRepo;
3436 $repos = new CompositeRepository(array_merge(array($installedRepo), $defaultRepos));
3437 }
3438
3439 if ($composer) {
3440 $commandEvent = new CommandEvent(PluginEvents::COMMAND, 'search', $input, $output);
3441 $composer->getEventDispatcher()->dispatch($commandEvent->getName(), $commandEvent);
3442 }
3443
3444 $onlyName = $input->getOption('only-name');
3445
3446 $flags = $onlyName ? RepositoryInterface::SEARCH_NAME : RepositoryInterface::SEARCH_FULLTEXT;
3447 $results = $repos->search(implode(' ', $input->getArgument('tokens')), $flags);
3448
3449 foreach ($results as $result) {
3450 $output->writeln($result['name'] . (isset($result['description']) ? ' '. $result['description'] : ''));
3451 }
3452 }
3453 }
3454 <?php
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466 namespace Composer\Command;
3467
3468 use Composer\Composer;
3469 use Composer\Factory;
3470 use Composer\Util\Filesystem;
3471 use Composer\Util\RemoteFilesystem;
3472 use Composer\Downloader\FilesystemException;
3473 use Symfony\Component\Console\Input\InputInterface;
3474 use Symfony\Component\Console\Input\InputOption;
3475 use Symfony\Component\Console\Input\InputArgument;
3476 use Symfony\Component\Console\Output\OutputInterface;
3477 use Symfony\Component\Finder\Finder;
3478
3479
3480
3481
3482
3483
3484 class SelfUpdateCommand extends Command
3485 {
3486 const HOMEPAGE = 'getcomposer.org';
3487 const OLD_INSTALL_EXT = '-old.phar';
3488
3489 protected function configure()
3490 {
3491 $this
3492 ->setName('self-update')
3493 ->setAliases(array('selfupdate'))
3494 ->setDescription('Updates composer.phar to the latest version.')
3495 ->setDefinition(array(
3496 new InputOption('rollback', 'r', InputOption::VALUE_NONE, 'Revert to an older installation of composer'),
3497 new InputOption('clean-backups', null, InputOption::VALUE_NONE, 'Delete old backups during an update. This makes the current version of composer the only backup available after the update'),
3498 new InputArgument('version', InputArgument::OPTIONAL, 'The version to update to'),
3499 new InputOption('no-progress', null, InputOption::VALUE_NONE, 'Do not output download progress.'),
3500 ))
3501 ->setHelp(<<<EOT
3502 The <info>self-update</info> command checks getcomposer.org for newer
3503 versions of composer and if found, installs the latest.
3504
3505 <info>php composer.phar self-update</info>
3506
3507 EOT
3508 )
3509 ;
3510 }
3511
3512 protected function execute(InputInterface $input, OutputInterface $output)
3513 {
3514 $baseUrl = (extension_loaded('openssl') ? 'https' : 'http') . '://' . self::HOMEPAGE;
3515 $config = Factory::createConfig();
3516 $remoteFilesystem = new RemoteFilesystem($this->getIO(), $config);
3517 $cacheDir = $config->get('cache-dir');
3518 $rollbackDir = $config->get('home');
3519 $localFilename = realpath($_SERVER['argv'][0]) ?: $_SERVER['argv'][0];
3520
3521
3522  $tmpDir = is_writable(dirname($localFilename)) ? dirname($localFilename) : $cacheDir;
3523
3524
3525  if (!is_writable($tmpDir)) {
3526 throw new FilesystemException('Composer update failed: the "'.$tmpDir.'" directory used to download the temp file could not be written');
3527 }
3528 if (!is_writable($localFilename)) {
3529 throw new FilesystemException('Composer update failed: the "'.$localFilename.'" file could not be written');
3530 }
3531
3532 if ($input->getOption('rollback')) {
3533 return $this->rollback($output, $rollbackDir, $localFilename);
3534 }
3535
3536 $latestVersion = trim($remoteFilesystem->getContents(self::HOMEPAGE, $baseUrl. '/version', false));
3537 $updateVersion = $input->getArgument('version') ?: $latestVersion;
3538
3539 if (preg_match('{^[0-9a-f]{40}$}', $updateVersion) && $updateVersion !== $latestVersion) {
3540 $output->writeln('<error>You can not update to a specific SHA-1 as those phars are not available for download</error>');
3541
3542 return 1;
3543 }
3544
3545 if (Composer::VERSION === $updateVersion) {
3546 $output->writeln('<info>You are already using composer version '.$updateVersion.'.</info>');
3547
3548 return 0;
3549 }
3550
3551 $tempFilename = $tmpDir . '/' . basename($localFilename, '.phar').'-temp.phar';
3552 $backupFile = sprintf(
3553 '%s/%s-%s%s',
3554 $rollbackDir,
3555 strtr(Composer::RELEASE_DATE, ' :', '_-'),
3556 preg_replace('{^([0-9a-f]{7})[0-9a-f]{33}$}', '$1', Composer::VERSION),
3557 self::OLD_INSTALL_EXT
3558 );
3559
3560 $output->writeln(sprintf("Updating to version <info>%s</info>.", $updateVersion));
3561 $remoteFilename = $baseUrl . (preg_match('{^[0-9a-f]{40}$}', $updateVersion) ? '/composer.phar' : "/download/{$updateVersion}/composer.phar");
3562 $remoteFilesystem->copy(self::HOMEPAGE, $remoteFilename, $tempFilename, !$input->getOption('no-progress'));
3563 if (!file_exists($tempFilename)) {
3564 $output->writeln('<error>The download of the new composer version failed for an unexpected reason</error>');
3565
3566 return 1;
3567 }
3568
3569
3570  if ($input->getOption('clean-backups')) {
3571 $finder = $this->getOldInstallationFinder($rollbackDir);
3572
3573 $fs = new Filesystem;
3574 foreach ($finder as $file) {
3575 $file = (string) $file;
3576 $output->writeln('<info>Removing: '.$file.'</info>');
3577 $fs->remove($file);
3578 }
3579 }
3580
3581 if ($err = $this->setLocalPhar($localFilename, $tempFilename, $backupFile)) {
3582 $output->writeln('<error>The file is corrupted ('.$err->getMessage().').</error>');
3583 $output->writeln('<error>Please re-run the self-update command to try again.</error>');
3584
3585 return 1;
3586 }
3587
3588 if (file_exists($backupFile)) {
3589 $output->writeln('Use <info>composer self-update --rollback</info> to return to version '.Composer::VERSION);
3590 } else {
3591 $output->writeln('<warning>A backup of the current version could not be written to '.$backupFile.', no rollback possible</warning>');
3592 }
3593 }
3594
3595 protected function rollback(OutputInterface $output, $rollbackDir, $localFilename)
3596 {
3597 $rollbackVersion = $this->getLastBackupVersion($rollbackDir);
3598 if (!$rollbackVersion) {
3599 throw new \UnexpectedValueException('Composer rollback failed: no installation to roll back to in "'.$rollbackDir.'"');
3600 }
3601
3602 if (!is_writable($rollbackDir)) {
3603 throw new FilesystemException('Composer rollback failed: the "'.$rollbackDir.'" dir could not be written to');
3604 }
3605
3606 $old = $rollbackDir . '/' . $rollbackVersion . self::OLD_INSTALL_EXT;
3607
3608 if (!is_file($old)) {
3609 throw new FilesystemException('Composer rollback failed: "'.$old.'" could not be found');
3610 }
3611 if (!is_readable($old)) {
3612 throw new FilesystemException('Composer rollback failed: "'.$old.'" could not be read');
3613 }
3614
3615 $oldFile = $rollbackDir . "/{$rollbackVersion}" . self::OLD_INSTALL_EXT;
3616 $output->writeln(sprintf("Rolling back to version <info>%s</info>.", $rollbackVersion));
3617 if ($err = $this->setLocalPhar($localFilename, $oldFile)) {
3618 $output->writeln('<error>The backup file was corrupted ('.$err->getMessage().') and has been removed.</error>');
3619
3620 return 1;
3621 }
3622
3623 return 0;
3624 }
3625
3626 protected function setLocalPhar($localFilename, $newFilename, $backupTarget = null)
3627 {
3628 try {
3629 @chmod($newFilename, 0777 & ~umask());
3630 if (!ini_get('phar.readonly')) {
3631
3632  $phar = new \Phar($newFilename);
3633
3634  unset($phar);
3635 }
3636
3637
3638  if ($backupTarget && file_exists($localFilename)) {
3639 @copy($localFilename, $backupTarget);
3640 }
3641
3642 rename($newFilename, $localFilename);
3643 } catch (\Exception $e) {
3644 if ($backupTarget) {
3645 @unlink($newFilename);
3646 }
3647 if (!$e instanceof \UnexpectedValueException && !$e instanceof \PharException) {
3648 throw $e;
3649 }
3650
3651 return $e;
3652 }
3653 }
3654
3655 protected function getLastBackupVersion($rollbackDir)
3656 {
3657 $finder = $this->getOldInstallationFinder($rollbackDir);
3658 $finder->sortByName();
3659 $files = iterator_to_array($finder);
3660
3661 if (count($files)) {
3662 return basename(end($files), self::OLD_INSTALL_EXT);
3663 }
3664
3665 return false;
3666 }
3667
3668 protected function getOldInstallationFinder($rollbackDir)
3669 {
3670 $finder = Finder::create()
3671 ->depth(0)
3672 ->files()
3673 ->name('*' . self::OLD_INSTALL_EXT)
3674 ->in($rollbackDir);
3675
3676 return $finder;
3677 }
3678 }
3679 <?php
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691 namespace Composer\Command;
3692
3693 use Composer\Json\JsonFile;
3694 use Composer\Package\Version\VersionParser;
3695 use Composer\Plugin\CommandEvent;
3696 use Composer\Plugin\PluginEvents;
3697 use Composer\Package\PackageInterface;
3698 use Composer\Repository\RepositoryInterface;
3699 use Symfony\Component\Console\Helper\TableHelper;
3700 use Symfony\Component\Console\Input\InputInterface;
3701 use Symfony\Component\Console\Input\InputOption;
3702 use Symfony\Component\Console\Output\OutputInterface;
3703
3704
3705
3706
3707 class LicensesCommand extends Command
3708 {
3709 protected function configure()
3710 {
3711 $this
3712 ->setName('licenses')
3713 ->setDescription('Show information about licenses of dependencies')
3714 ->setDefinition(array(
3715 new InputOption('format', 'f', InputOption::VALUE_REQUIRED, 'Format of the output: text or json', 'text'),
3716 new InputOption('no-dev', null, InputOption::VALUE_NONE, 'Disables search in require-dev packages.'),
3717 ))
3718 ->setHelp(<<<EOT
3719 The license command displays detailed information about the licenses of
3720 the installed dependencies.
3721
3722 EOT
3723 )
3724 ;
3725 }
3726
3727 protected function execute(InputInterface $input, OutputInterface $output)
3728 {
3729 $composer = $this->getComposer();
3730
3731 $commandEvent = new CommandEvent(PluginEvents::COMMAND, 'licenses', $input, $output);
3732 $composer->getEventDispatcher()->dispatch($commandEvent->getName(), $commandEvent);
3733
3734 $root = $composer->getPackage();
3735 $repo = $composer->getRepositoryManager()->getLocalRepository();
3736
3737 $versionParser = new VersionParser;
3738
3739 if ($input->getOption('no-dev')) {
3740 $packages = $this->filterRequiredPackages($repo, $root);
3741 } else {
3742 $packages = $this->appendPackages($repo->getPackages(), array());
3743 }
3744
3745 ksort($packages);
3746
3747 switch ($format = $input->getOption('format')) {
3748 case 'text':
3749 $output->writeln('Name: <comment>'.$root->getPrettyName().'</comment>');
3750 $output->writeln('Version: <comment>'.$versionParser->formatVersion($root).'</comment>');
3751 $output->writeln('Licenses: <comment>'.(implode(', ', $root->getLicense()) ?: 'none').'</comment>');
3752 $output->writeln('Dependencies:');
3753
3754 $table = $this->getHelperSet()->get('table');
3755 $table->setLayout(TableHelper::LAYOUT_BORDERLESS);
3756 $table->setHorizontalBorderChar('');
3757 foreach ($packages as $package) {
3758 $table->addRow(array(
3759 $package->getPrettyName(),
3760 $versionParser->formatVersion($package),
3761 implode(', ', $package->getLicense()) ?: 'none',
3762 ));
3763 }
3764 $table->render($output);
3765 break;
3766
3767 case 'json':
3768 foreach ($packages as $package) {
3769 $dependencies[$package->getPrettyName()] = array(
3770 'version' => $versionParser->formatVersion($package),
3771 'license' => $package->getLicense(),
3772 );
3773 }
3774
3775 $output->writeln(JsonFile::encode(array(
3776 'name' => $root->getPrettyName(),
3777 'version' => $versionParser->formatVersion($root),
3778 'license' => $root->getLicense(),
3779 'dependencies' => $dependencies,
3780 )));
3781 break;
3782
3783 default:
3784 throw new \RuntimeException(sprintf('Unsupported format "%s".  See help for supported formats.', $format));
3785 }
3786 }
3787
3788
3789
3790
3791
3792
3793
3794 private function filterRequiredPackages(RepositoryInterface $repo, PackageInterface $package, $bucket = array())
3795 {
3796 $requires = array_keys($package->getRequires());
3797
3798 $packageListNames = array_keys($bucket);
3799 $packages = array_filter(
3800 $repo->getPackages(),
3801 function ($package) use ($requires, $packageListNames) {
3802 return in_array($package->getName(), $requires) && !in_array($package->getName(), $packageListNames);
3803 }
3804 );
3805
3806 $bucket = $this->appendPackages($packages, $bucket);
3807
3808 foreach ($packages as $package) {
3809 $bucket = $this->filterRequiredPackages($repo, $package, $bucket);
3810 }
3811
3812 return $bucket;
3813 }
3814
3815
3816
3817
3818
3819
3820
3821
3822 public function appendPackages(array $packages, array $bucket)
3823 {
3824 foreach ($packages as $package) {
3825 $bucket[$package->getName()] = $package;
3826 }
3827
3828 return $bucket;
3829 }
3830 }
3831 <?php
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843 namespace Composer\Command;
3844
3845 use Composer\DependencyResolver\Pool;
3846 use Composer\Factory;
3847 use Composer\Package\CompletePackageInterface;
3848 use Composer\Repository\CompositeRepository;
3849 use Composer\Repository\RepositoryInterface;
3850 use Composer\Util\ProcessExecutor;
3851 use Symfony\Component\Console\Input\InputArgument;
3852 use Symfony\Component\Console\Input\InputOption;
3853 use Symfony\Component\Console\Input\InputInterface;
3854 use Symfony\Component\Console\Output\OutputInterface;
3855
3856
3857
3858
3859 class HomeCommand extends Command
3860 {
3861
3862
3863
3864 protected function configure()
3865 {
3866 $this
3867 ->setName('browse')
3868 ->setAliases(array('home'))
3869 ->setDescription('Opens the package\'s repository URL or homepage in your browser.')
3870 ->setDefinition(array(
3871 new InputArgument('packages', InputArgument::IS_ARRAY | InputArgument::REQUIRED, 'Package(s) to browse to.'),
3872 new InputOption('homepage', 'H', InputOption::VALUE_NONE, 'Open the homepage instead of the repository URL.'),
3873 ))
3874 ->setHelp(<<<EOT
3875 The home command opens a package's repository URL or
3876 homepage in your default browser.
3877
3878 To open the homepage by default, use -H or --homepage.
3879 EOT
3880 );
3881 }
3882
3883
3884
3885
3886 protected function execute(InputInterface $input, OutputInterface $output)
3887 {
3888 $repo = $this->initializeRepo();
3889 $return = 0;
3890
3891 foreach ($input->getArgument('packages') as $packageName) {
3892 $package = $this->getPackage($repo, $packageName);
3893
3894 if (!$package instanceof CompletePackageInterface) {
3895 $return = 1;
3896 $output->writeln('<warning>Package '.$packageName.' not found</warning>');
3897
3898 continue;
3899 }
3900
3901 $support = $package->getSupport();
3902 $url = isset($support['source']) ? $support['source'] : $package->getSourceUrl();
3903 if (!$url || $input->getOption('homepage')) {
3904 $url = $package->getHomepage();
3905 }
3906
3907 if (!filter_var($url, FILTER_VALIDATE_URL)) {
3908 $return = 1;
3909 $output->writeln('<warning>'.($input->getOption('homepage') ? 'Invalid or missing homepage' : 'Invalid or missing repository URL').' for '.$packageName.'</warning>');
3910
3911 continue;
3912 }
3913
3914 $this->openBrowser($url);
3915 }
3916
3917 return $return;
3918 }
3919
3920
3921
3922
3923
3924
3925
3926
3927 protected function getPackage(RepositoryInterface $repos, $name)
3928 {
3929 $name = strtolower($name);
3930 $pool = new Pool('dev');
3931 $pool->addRepository($repos);
3932 $matches = $pool->whatProvides($name);
3933
3934 foreach ($matches as $index => $package) {
3935
3936  if ($package->getName() !== $name) {
3937 unset($matches[$index]);
3938 continue;
3939 }
3940
3941 return $package;
3942 }
3943 }
3944
3945
3946
3947
3948
3949
3950 private function openBrowser($url)
3951 {
3952 $url = ProcessExecutor::escape($url);
3953
3954 if (defined('PHP_WINDOWS_VERSION_MAJOR')) {
3955 return passthru('start "web" explorer "' . $url . '"');
3956 }
3957
3958 passthru('which xdg-open', $linux);
3959 passthru('which open', $osx);
3960
3961 if (0 === $linux) {
3962 passthru('xdg-open ' . $url);
3963 } elseif (0 === $osx) {
3964 passthru('open ' . $url);
3965 } else {
3966 $this->getIO()->write('no suitable browser opening command found, open yourself: ' . $url);
3967 }
3968 }
3969
3970
3971
3972
3973
3974
3975 private function initializeRepo()
3976 {
3977 $composer = $this->getComposer(false);
3978
3979 if ($composer) {
3980 $repo = new CompositeRepository($composer->getRepositoryManager()->getRepositories());
3981 } else {
3982 $defaultRepos = Factory::createDefaultRepositories($this->getIO());
3983 $repo = new CompositeRepository($defaultRepos);
3984 }
3985
3986 return $repo;
3987 }
3988 }
3989 <?php
3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
4001 namespace Composer\Command;
4002
4003 use Symfony\Component\Console\Input\InputInterface;
4004 use Symfony\Component\Console\Input\InputArgument;
4005 use Symfony\Component\Console\Input\InputOption;
4006 use Symfony\Component\Console\Output\OutputInterface;
4007 use Composer\Factory;
4008 use Composer\Installer;
4009 use Composer\Json\JsonFile;
4010 use Composer\Json\JsonManipulator;
4011 use Composer\Package\Version\VersionParser;
4012 use Composer\Plugin\CommandEvent;
4013 use Composer\Plugin\PluginEvents;
4014 use Composer\Repository\CompositeRepository;
4015 use Composer\Repository\PlatformRepository;
4016
4017
4018
4019
4020
4021 class RequireCommand extends InitCommand
4022 {
4023 protected function configure()
4024 {
4025 $this
4026 ->setName('require')
4027 ->setDescription('Adds required packages to your composer.json and installs them')
4028 ->setDefinition(array(
4029 new InputArgument('packages', InputArgument::IS_ARRAY | InputArgument::OPTIONAL, 'Required package with a version constraint, e.g. foo/bar:1.0.0 or foo/bar=1.0.0 or "foo/bar 1.0.0"'),
4030 new InputOption('dev', null, InputOption::VALUE_NONE, 'Add requirement to require-dev.'),
4031 new InputOption('prefer-source', null, InputOption::VALUE_NONE, 'Forces installation from package sources when possible, including VCS information.'),
4032 new InputOption('prefer-dist', null, InputOption::VALUE_NONE, 'Forces installation from package dist even for dev versions.'),
4033 new InputOption('no-progress', null, InputOption::VALUE_NONE, 'Do not output download progress.'),
4034 new InputOption('no-update', null, InputOption::VALUE_NONE, 'Disables the automatic update of the dependencies.'),
4035 new InputOption('update-no-dev', null, InputOption::VALUE_NONE, 'Run the dependency update with the --no-dev option.'),
4036 new InputOption('update-with-dependencies', null, InputOption::VALUE_NONE, 'Allows inherited dependencies to be updated with explicit dependencies.'),
4037 new InputOption('ignore-platform-reqs', null, InputOption::VALUE_NONE, 'Ignore platform requirements (php & ext- packages).'),
4038 new InputOption('sort-packages', null, InputOption::VALUE_NONE, 'Sorts packages when adding/updating a new dependency'),
4039 ))
4040 ->setHelp(<<<EOT
4041 The require command adds required packages to your composer.json and installs them
4042
4043 If you do not want to install the new dependencies immediately you can call it with --no-update
4044
4045 EOT
4046 )
4047 ;
4048 }
4049
4050 protected function execute(InputInterface $input, OutputInterface $output)
4051 {
4052 $file = Factory::getComposerFile();
4053
4054 $newlyCreated = !file_exists($file);
4055 if (!file_exists($file) && !file_put_contents($file, "{\n}\n")) {
4056 $output->writeln('<error>'.$file.' could not be created.</error>');
4057
4058 return 1;
4059 }
4060 if (!is_readable($file)) {
4061 $output->writeln('<error>'.$file.' is not readable.</error>');
4062
4063 return 1;
4064 }
4065 if (!is_writable($file)) {
4066 $output->writeln('<error>'.$file.' is not writable.</error>');
4067
4068 return 1;
4069 }
4070
4071 $json = new JsonFile($file);
4072 $composerDefinition = $json->read();
4073 $composerBackup = file_get_contents($json->getPath());
4074
4075 $composer = $this->getComposer();
4076 $repos = $composer->getRepositoryManager()->getRepositories();
4077
4078 $this->repos = new CompositeRepository(array_merge(
4079 array(new PlatformRepository),
4080 $repos
4081 ));
4082
4083 $requirements = $this->determineRequirements($input, $output, $input->getArgument('packages'));
4084
4085 $requireKey = $input->getOption('dev') ? 'require-dev' : 'require';
4086 $removeKey = $input->getOption('dev') ? 'require' : 'require-dev';
4087 $baseRequirements = array_key_exists($requireKey, $composerDefinition) ? $composerDefinition[$requireKey] : array();
4088 $requirements = $this->formatRequirements($requirements);
4089
4090
4091  $versionParser = new VersionParser();
4092 foreach ($requirements as $constraint) {
4093 $versionParser->parseConstraints($constraint);
4094 }
4095
4096 $sortPackages = $input->getOption('sort-packages');
4097
4098 if (!$this->updateFileCleanly($json, $baseRequirements, $requirements, $requireKey, $removeKey, $sortPackages)) {
4099 foreach ($requirements as $package => $version) {
4100 $baseRequirements[$package] = $version;
4101
4102 if (isset($composerDefinition[$removeKey][$package])) {
4103 unset($composerDefinition[$removeKey][$package]);
4104 }
4105 }
4106
4107 $composerDefinition[$requireKey] = $baseRequirements;
4108 $json->write($composerDefinition);
4109 }
4110
4111 $output->writeln('<info>'.$file.' has been '.($newlyCreated ? 'created' : 'updated').'</info>');
4112
4113 if ($input->getOption('no-update')) {
4114 return 0;
4115 }
4116 $updateDevMode = !$input->getOption('update-no-dev');
4117
4118
4119  $this->resetComposer();
4120 $composer = $this->getComposer();
4121 $composer->getDownloadManager()->setOutputProgress(!$input->getOption('no-progress'));
4122 $io = $this->getIO();
4123
4124 $commandEvent = new CommandEvent(PluginEvents::COMMAND, 'require', $input, $output);
4125 $composer->getEventDispatcher()->dispatch($commandEvent->getName(), $commandEvent);
4126
4127 $install = Installer::create($io, $composer);
4128
4129 $install
4130 ->setVerbose($input->getOption('verbose'))
4131 ->setPreferSource($input->getOption('prefer-source'))
4132 ->setPreferDist($input->getOption('prefer-dist'))
4133 ->setDevMode($updateDevMode)
4134 ->setUpdate(true)
4135 ->setUpdateWhitelist(array_keys($requirements))
4136 ->setWhitelistDependencies($input->getOption('update-with-dependencies'))
4137 ->setIgnorePlatformRequirements($input->getOption('ignore-platform-reqs'))
4138 ;
4139
4140 $status = $install->run();
4141 if ($status !== 0) {
4142 if ($newlyCreated) {
4143 $output->writeln("\n".'<error>Installation failed, deleting '.$file.'.</error>');
4144 unlink($json->getPath());
4145 } else {
4146 $output->writeln("\n".'<error>Installation failed, reverting '.$file.' to its original content.</error>');
4147 file_put_contents($json->getPath(), $composerBackup);
4148 }
4149 }
4150
4151 return $status;
4152 }
4153
4154 private function updateFileCleanly($json, array $base, array $new, $requireKey, $removeKey, $sortPackages)
4155 {
4156 $contents = file_get_contents($json->getPath());
4157
4158 $manipulator = new JsonManipulator($contents);
4159
4160 foreach ($new as $package => $constraint) {
4161 if (!$manipulator->addLink($requireKey, $package, $constraint, $sortPackages)) {
4162 return false;
4163 }
4164 if (!$manipulator->removeSubNode($removeKey, $package)) {
4165 return false;
4166 }
4167 }
4168
4169 file_put_contents($json->getPath(), $manipulator->getContents());
4170
4171 return true;
4172 }
4173
4174 protected function interact(InputInterface $input, OutputInterface $output)
4175 {
4176 return;
4177 }
4178 }
4179 <?php
4180
4181
4182
4183
4184
4185
4186
4187
4188
4189
4190
4191 namespace Composer\Command;
4192
4193 use Composer\Plugin\CommandEvent;
4194 use Composer\Plugin\PluginEvents;
4195 use Symfony\Component\Console\Input\InputInterface;
4196 use Symfony\Component\Console\Input\InputOption;
4197 use Symfony\Component\Console\Output\OutputInterface;
4198
4199
4200
4201
4202 class DumpAutoloadCommand extends Command
4203 {
4204 protected function configure()
4205 {
4206 $this
4207 ->setName('dump-autoload')
4208 ->setAliases(array('dumpautoload'))
4209 ->setDescription('Dumps the autoloader')
4210 ->setDefinition(array(
4211 new InputOption('optimize', 'o', InputOption::VALUE_NONE, 'Optimizes PSR0 and PSR4 packages to be loaded with classmaps too, good for production.'),
4212 new InputOption('no-dev', null, InputOption::VALUE_NONE, 'Disables autoload-dev rules.'),
4213 ))
4214 ->setHelp(<<<EOT
4215 <info>php composer.phar dump-autoload</info>
4216 EOT
4217 )
4218 ;
4219 }
4220
4221 protected function execute(InputInterface $input, OutputInterface $output)
4222 {
4223 $composer = $this->getComposer();
4224
4225 $commandEvent = new CommandEvent(PluginEvents::COMMAND, 'dump-autoload', $input, $output);
4226 $composer->getEventDispatcher()->dispatch($commandEvent->getName(), $commandEvent);
4227
4228 $installationManager = $composer->getInstallationManager();
4229 $localRepo = $composer->getRepositoryManager()->getLocalRepository();
4230 $package = $composer->getPackage();
4231 $config = $composer->getConfig();
4232
4233 $optimize = $input->getOption('optimize') || $config->get('optimize-autoloader');
4234
4235 if ($optimize) {
4236 $output->writeln('<info>Generating optimized autoload files</info>');
4237 } else {
4238 $output->writeln('<info>Generating autoload files</info>');
4239 }
4240
4241 $generator = $composer->getAutoloadGenerator();
4242 $generator->setDevMode(!$input->getOption('no-dev'));
4243 $generator->dump($config, $localRepo, $package, $installationManager, 'composer', $optimize);
4244 }
4245 }
4246 <?php
4247
4248
4249
4250
4251
4252
4253
4254
4255
4256
4257
4258 namespace Composer\Command;
4259
4260 use Composer\Factory;
4261 use Symfony\Component\Console\Input\InputInterface;
4262 use Symfony\Component\Console\Input\InputArgument;
4263 use Symfony\Component\Console\Input\StringInput;
4264 use Symfony\Component\Console\Output\OutputInterface;
4265
4266
4267
4268
4269 class GlobalCommand extends Command
4270 {
4271 protected function configure()
4272 {
4273 $this
4274 ->setName('global')
4275 ->setDescription('Allows running commands in the global composer dir ($COMPOSER_HOME).')
4276 ->setDefinition(array(
4277 new InputArgument('command-name', InputArgument::REQUIRED, ''),
4278 new InputArgument('args', InputArgument::IS_ARRAY | InputArgument::OPTIONAL, ''),
4279 ))
4280 ->setHelp(<<<EOT
4281 Use this command as a wrapper to run other Composer commands
4282 within the global context of COMPOSER_HOME.
4283
4284 You can use this to install CLI utilities globally, all you need
4285 is to add the COMPOSER_HOME/vendor/bin dir to your PATH env var.
4286
4287 COMPOSER_HOME is c:\Users\<user>\AppData\Roaming\Composer on Windows
4288 and /home/<user>/.composer on unix systems.
4289
4290 Note: This path may vary depending on customizations to bin-dir in
4291 composer.json or the environmental variable COMPOSER_BIN_DIR.
4292
4293 EOT
4294 )
4295 ;
4296 }
4297
4298 public function run(InputInterface $input, OutputInterface $output)
4299 {
4300
4301  $tokens = preg_split('{\s+}', $input->__toString());
4302 $args = array();
4303 foreach ($tokens as $token) {
4304 if ($token && $token[0] !== '-') {
4305 $args[] = $token;
4306 if (count($args) >= 2) {
4307 break;
4308 }
4309 }
4310 }
4311
4312
4313  if (count($args) < 2) {
4314 return parent::run($input, $output);
4315 }
4316
4317
4318  $config = Factory::createConfig();
4319 chdir($config->get('home'));
4320 $output->writeln('<info>Changed current directory to '.$config->get('home').'</info>');
4321
4322
4323  $input = new StringInput(preg_replace('{\bg(?:l(?:o(?:b(?:a(?:l)?)?)?)?)?\b}', '', $input->__toString(), 1));
4324
4325 return $this->getApplication()->run($input, $output);
4326 }
4327 }
4328 <?php
4329
4330
4331
4332
4333
4334
4335
4336
4337
4338
4339
4340 namespace Composer\Command;
4341
4342 use Composer\Config\JsonConfigSource;
4343 use Composer\Installer;
4344 use Composer\Plugin\CommandEvent;
4345 use Composer\Plugin\PluginEvents;
4346 use Composer\Json\JsonFile;
4347 use Composer\Factory;
4348 use Symfony\Component\Console\Input\InputInterface;
4349 use Symfony\Component\Console\Input\InputOption;
4350 use Symfony\Component\Console\Input\InputArgument;
4351 use Symfony\Component\Console\Output\OutputInterface;
4352
4353
4354
4355
4356
4357 class RemoveCommand extends Command
4358 {
4359 protected function configure()
4360 {
4361 $this
4362 ->setName('remove')
4363 ->setDescription('Removes a package from the require or require-dev')
4364 ->setDefinition(array(
4365 new InputArgument('packages', InputArgument::IS_ARRAY, 'Packages that should be removed.'),
4366 new InputOption('dev', null, InputOption::VALUE_NONE, 'Removes a package from the require-dev section.'),
4367 new InputOption('no-progress', null, InputOption::VALUE_NONE, 'Do not output download progress.'),
4368 new InputOption('no-update', null, InputOption::VALUE_NONE, 'Disables the automatic update of the dependencies.'),
4369 new InputOption('update-no-dev', null, InputOption::VALUE_NONE, 'Run the dependency update with the --no-dev option.'),
4370 new InputOption('update-with-dependencies', null, InputOption::VALUE_NONE, 'Allows inherited dependencies to be updated with explicit dependencies.'),
4371 new InputOption('ignore-platform-reqs', null, InputOption::VALUE_NONE, 'Ignore platform requirements (php & ext- packages).'),
4372 ))
4373 ->setHelp(<<<EOT
4374 The <info>remove</info> command removes a package from the current
4375 list of installed packages
4376
4377 <info>php composer.phar remove</info>
4378
4379 EOT
4380 )
4381 ;
4382 }
4383
4384 protected function execute(InputInterface $input, OutputInterface $output)
4385 {
4386 $packages = $input->getArgument('packages');
4387
4388 $file = Factory::getComposerFile();
4389
4390 $jsonFile = new JsonFile($file);
4391 $composer = $jsonFile->read();
4392 $composerBackup = file_get_contents($jsonFile->getPath());
4393
4394 $json = new JsonConfigSource($jsonFile);
4395
4396 $type = $input->getOption('dev') ? 'require-dev' : 'require';
4397 $altType = !$input->getOption('dev') ? 'require-dev' : 'require';
4398
4399 foreach ($packages as $package) {
4400 if (isset($composer[$type][$package])) {
4401 $json->removeLink($type, $package);
4402 } elseif (isset($composer[$altType][$package])) {
4403 $output->writeln('<warning>'.$package.' could not be found in '.$type.' but it is present in '.$altType.'</warning>');
4404 $dialog = $this->getHelperSet()->get('dialog');
4405 if ($this->getIO()->isInteractive()) {
4406 if ($dialog->askConfirmation($output, $dialog->getQuestion('Do you want to remove it from '.$altType, 'yes', '?'), true)) {
4407 $json->removeLink($altType, $package);
4408 }
4409 }
4410 } else {
4411 $output->writeln('<warning>'.$package.' is not required in your composer.json and has not been removed</warning>');
4412 }
4413 }
4414
4415 if ($input->getOption('no-update')) {
4416 return 0;
4417 }
4418
4419
4420  $composer = $this->getComposer();
4421 $composer->getDownloadManager()->setOutputProgress(!$input->getOption('no-progress'));
4422 $io = $this->getIO();
4423
4424 $commandEvent = new CommandEvent(PluginEvents::COMMAND, 'remove', $input, $output);
4425 $composer->getEventDispatcher()->dispatch($commandEvent->getName(), $commandEvent);
4426
4427 $install = Installer::create($io, $composer);
4428
4429 $updateDevMode = !$input->getOption('update-no-dev');
4430 $install
4431 ->setVerbose($input->getOption('verbose'))
4432 ->setDevMode($updateDevMode)
4433 ->setUpdate(true)
4434 ->setUpdateWhitelist($packages)
4435 ->setWhitelistDependencies($input->getOption('update-with-dependencies'))
4436 ->setIgnorePlatformRequirements($input->getOption('ignore-platform-reqs'))
4437 ;
4438
4439 $status = $install->run();
4440 if ($status !== 0) {
4441 $output->writeln("\n".'<error>Removal failed, reverting '.$file.' to its original content.</error>');
4442 file_put_contents($jsonFile->getPath(), $composerBackup);
4443 }
4444
4445 return $status;
4446 }
4447 }
4448 <?php
4449
4450
4451
4452
4453
4454
4455
4456
4457
4458
4459
4460 namespace Composer\Command\Helper;
4461
4462 use Symfony\Component\Console\Helper\DialogHelper as BaseDialogHelper;
4463
4464 class DialogHelper extends BaseDialogHelper
4465 {
4466
4467
4468
4469
4470
4471
4472
4473
4474
4475
4476
4477 public function getQuestion($question, $default = null, $sep = ':')
4478 {
4479 return $default !== null ?
4480 sprintf('<info>%s</info> [<comment>%s</comment>]%s ', $question, $default, $sep) :
4481 sprintf('<info>%s</info>%s ', $question, $sep);
4482 }
4483 }
4484 <?php