diff --git a/.php_cs b/.php_cs index ac954ab5e..68b16e224 100644 --- a/.php_cs +++ b/.php_cs @@ -53,6 +53,7 @@ return PhpCsFixer\Config::create() 'standardize_not_equals' => true, 'ternary_operator_spaces' => true, 'trailing_comma_in_multiline_array' => true, + 'unary_operator_spaces' => true, )) ->setFinder($finder) ; diff --git a/doc/03-cli.md b/doc/03-cli.md index 68f7ba762..296cb101b 100644 --- a/doc/03-cli.md +++ b/doc/03-cli.md @@ -190,7 +190,7 @@ If you do not want to choose requirements interactively, you can pass them to the command. ```sh -php composer.phar require vendor/package:2.* vendor/package2:dev-master +php composer.phar require "vendor/package:2.*" vendor/package2:dev-master ``` If you do not specify a package, composer will prompt you to search for a package, and given results, provide a list of matches to require. @@ -649,7 +649,7 @@ provide a version as third argument, otherwise the latest version is used. If the directory does not currently exist, it will be created during installation. ```sh -php composer.phar create-project doctrine/orm path 2.2.* +php composer.phar create-project doctrine/orm path "2.2.*" ``` It is also possible to run the command without params in a directory with an diff --git a/doc/faqs/how-to-install-composer-programmatically.md b/doc/faqs/how-to-install-composer-programmatically.md index ba6536e54..3b378a5ab 100644 --- a/doc/faqs/how-to-install-composer-programmatically.md +++ b/doc/faqs/how-to-install-composer-programmatically.md @@ -1,7 +1,7 @@ # How do I install Composer programmatically? As noted on the download page, the installer script contains a -signature which changes when the installer code changes and as such +checksum which changes when the installer code changes and as such it should not be relied upon in the long term. An alternative is to use this script which only works with UNIX utilities: @@ -9,13 +9,13 @@ An alternative is to use this script which only works with UNIX utilities: ```bash #!/bin/sh -EXPECTED_SIGNATURE="$(wget -q -O - https://composer.github.io/installer.sig)" +EXPECTED_CHECKSUM="$(wget -q -O - https://composer.github.io/installer.sig)" php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" -ACTUAL_SIGNATURE="$(php -r "echo hash_file('sha384', 'composer-setup.php');")" +ACTUAL_CHECKSUM="$(php -r "echo hash_file('sha384', 'composer-setup.php');")" -if [ "$EXPECTED_SIGNATURE" != "$ACTUAL_SIGNATURE" ] +if [ "$EXPECTED_CHECKSUM" != "$ACTUAL_CHECKSUM" ] then - >&2 echo 'ERROR: Invalid installer signature' + >&2 echo 'ERROR: Invalid installer checksum' rm composer-setup.php exit 1 fi diff --git a/phpunit.xml.dist b/phpunit.xml.dist index e26271845..728125c15 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,13 +1,15 @@ getComposer(false); + $config = null; + if ($composer) { + $config = $composer->getConfig(); $commandEvent = new CommandEvent(PluginEvents::COMMAND, 'archive', $input, $output); $eventDispatcher = $composer->getEventDispatcher(); $eventDispatcher->dispatch($commandEvent->getName(), $commandEvent); $eventDispatcher->dispatchScript(ScriptEvents::PRE_ARCHIVE_CMD); } + if (!$config) { + $config = Factory::createConfig(); + } + if (null === $input->getOption('format')) { $input->setOption('format', $config->get('archive-format')); } diff --git a/src/Composer/Console/Application.php b/src/Composer/Console/Application.php index 4182298d6..febf811e5 100644 --- a/src/Composer/Console/Application.php +++ b/src/Composer/Console/Application.php @@ -220,7 +220,12 @@ class Application extends BaseApplication $io->writeError(sprintf('Warning: This development build of composer is over 60 days old. It is recommended to update it by running "%s self-update" to get the latest version.', $_SERVER['PHP_SELF'])); } - if (!Platform::isWindows() && function_exists('exec') && !getenv('COMPOSER_ALLOW_SUPERUSER') && !file_exists('/.dockerenv')) { + if ( + !Platform::isWindows() + && function_exists('exec') + && !getenv('COMPOSER_ALLOW_SUPERUSER') + && (ini_get('open_basedir') || !file_exists('/.dockerenv')) + ) { if (function_exists('posix_getuid') && posix_getuid() === 0) { if ($commandName !== 'self-update' && $commandName !== 'selfupdate') { $io->writeError('Do not run Composer as root/super user! See https://getcomposer.org/root for details'); diff --git a/src/Composer/DependencyResolver/Operation/UpdateOperation.php b/src/Composer/DependencyResolver/Operation/UpdateOperation.php index 4764acb7c..38ca6e330 100644 --- a/src/Composer/DependencyResolver/Operation/UpdateOperation.php +++ b/src/Composer/DependencyResolver/Operation/UpdateOperation.php @@ -13,6 +13,7 @@ namespace Composer\DependencyResolver\Operation; use Composer\Package\PackageInterface; +use Composer\Package\Version\VersionParser; /** * Solver update operation. @@ -85,7 +86,9 @@ class UpdateOperation extends SolverOperation $toVersion = $this->targetPackage->getFullPrettyVersion(true, PackageInterface::DISPLAY_DIST_REF); } - return 'Updating '.$this->initialPackage->getPrettyName().' ('.$fromVersion.' => '.$toVersion.')'; + $actionName = VersionParser::isUpgrade($this->initialPackage->getVersion(), $this->targetPackage->getVersion()) ? 'Updating' : 'Downgrading'; + + return $actionName.' '.$this->initialPackage->getPrettyName().' ('.$fromVersion.' => '.$toVersion.')'; } /** diff --git a/tests/Composer/Test/Command/ArchiveCommandTest.php b/tests/Composer/Test/Command/ArchiveCommandTest.php new file mode 100644 index 000000000..4a777988d --- /dev/null +++ b/tests/Composer/Test/Command/ArchiveCommandTest.php @@ -0,0 +1,103 @@ + + * Jordi Boggiano + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Composer\Test\Command; + +use Composer\Composer; +use Composer\Config; +use Composer\Factory; +use Composer\Test\TestCase; +use Symfony\Component\Console\Input\ArrayInput; + +class ArchiveCommandTest extends TestCase +{ + public function testUsesConfigFromComposerObject() + { + $input = new ArrayInput(array()); + + $output = $this->getMockBuilder('Symfony\Component\Console\Output\OutputInterface') + ->getMock(); + + $ed = $this->getMockBuilder('Composer\EventDispatcher\EventDispatcher') + ->disableOriginalConstructor()->getMock(); + + $composer = new Composer; + $config = new Config; + $config->merge(array('config' => array('archive-format' => 'zip'))); + $composer->setConfig($config); + + $manager = $this->getMockBuilder('Composer\Package\Archiver\ArchiveManager') + ->disableOriginalConstructor()->getMock(); + + $package = $this->getMockBuilder('Composer\Package\RootPackageInterface') + ->getMock(); + + $manager->expects($this->once())->method('archive') + ->with($package, 'zip', '.', null, false)->willReturn(getcwd()); + + $composer->setArchiveManager($manager); + $composer->setEventDispatcher($ed); + $composer->setPackage($package); + + $command = $this->getMockBuilder('Composer\Command\ArchiveCommand') + ->setMethods(array( + 'mergeApplicationDefinition', + 'bind', + 'getSynopsis', + 'initialize', + 'isInteractive', + 'getComposer', + ))->getMock(); + $command->expects($this->atLeastOnce())->method('getComposer') + ->willReturn($composer); + $command->method('isInteractive')->willReturn(false); + + $command->run($input, $output); + } + + public function testUsesConfigFromFactoryWhenComposerIsNotDefined() + { + $input = new ArrayInput(array()); + + $output = $this->getMockBuilder('Symfony\Component\Console\Output\OutputInterface') + ->getMock(); + $config = Factory::createConfig(); + + $command = $this->getMockBuilder('Composer\Command\ArchiveCommand') + ->setMethods(array( + 'mergeApplicationDefinition', + 'bind', + 'getSynopsis', + 'initialize', + 'isInteractive', + 'getComposer', + 'archive', + ))->getMock(); + $command->expects($this->once())->method('getComposer') + ->willReturn(null); + $command->expects($this->once())->method('archive') + ->with( + $this->isInstanceOf('Composer\IO\IOInterface'), + $config, + null, + null, + 'tar', + '.', + null, + false, + null + ); + $command->method('isInteractive')->willReturn(false); + + $command->run($input, $output); + } +} diff --git a/tests/Composer/Test/Fixtures/installer/partial-update-from-lock.test b/tests/Composer/Test/Fixtures/installer/partial-update-from-lock.test index faffbead0..32018105d 100644 --- a/tests/Composer/Test/Fixtures/installer/partial-update-from-lock.test +++ b/tests/Composer/Test/Fixtures/installer/partial-update-from-lock.test @@ -75,7 +75,7 @@ update b/unstable } --EXPECT-- Updating a/old (0.9.0 => 1.0.0) -Updating b/unstable (1.1.0-alpha => 1.0.0) -Updating c/uptodate (2.0.0 => 1.0.0) +Downgrading b/unstable (1.1.0-alpha => 1.0.0) +Downgrading c/uptodate (2.0.0 => 1.0.0) Installing d/removed (1.0.0) Installing e/newreq (1.0.0) diff --git a/tests/Composer/Test/Fixtures/installer/update-downgrades-unstable-packages.test b/tests/Composer/Test/Fixtures/installer/update-downgrades-unstable-packages.test index f418cd33d..aa86c161e 100644 --- a/tests/Composer/Test/Fixtures/installer/update-downgrades-unstable-packages.test +++ b/tests/Composer/Test/Fixtures/installer/update-downgrades-unstable-packages.test @@ -46,4 +46,4 @@ Downgrading from unstable to more stable package should work even if already ins --RUN-- update --EXPECT-- -Updating a/a (dev-master abcd => 1.0.0) +Downgrading a/a (dev-master abcd => 1.0.0) diff --git a/tests/Composer/Test/Fixtures/installer/update-prefer-lowest-stable.test b/tests/Composer/Test/Fixtures/installer/update-prefer-lowest-stable.test index cd3988a9e..8cf5918e9 100644 --- a/tests/Composer/Test/Fixtures/installer/update-prefer-lowest-stable.test +++ b/tests/Composer/Test/Fixtures/installer/update-prefer-lowest-stable.test @@ -37,4 +37,4 @@ Updates packages to their lowest stable version update --prefer-lowest --prefer-stable --EXPECT-- Updating a/a (1.0.0-rc1 => 1.0.1) -Updating a/b (1.0.1 => 1.0.0) +Downgrading a/b (1.0.1 => 1.0.0)