From c56886ac36f71b9b7f335ae767ddabcabf96e84a Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Fri, 7 Feb 2020 22:33:39 +0100 Subject: [PATCH 1/6] Avoid checking for .dockerenv if open_basedir is set, fixes #8585 --- src/Composer/Console/Application.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/Composer/Console/Application.php b/src/Composer/Console/Application.php index 6de2ee5d4..b884de15e 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'); From 3934877efeec5dc6f57396e24bae74b5d0ea1827 Mon Sep 17 00:00:00 2001 From: Victor Bocharsky Date: Fri, 7 Feb 2020 15:29:05 +0200 Subject: [PATCH 2/6] Wrap version constaints that contain * with double quotes Some shells like ZSH require wrapping * with quotes, otherwise, it shows an error like: > zsh: no matches found: 2.2.* But single quotes may cause issues on Windows CMD --- doc/03-cli.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/03-cli.md b/doc/03-cli.md index eccafbcc0..ff0ff0ce3 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. @@ -647,7 +647,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 From 97d077c43bfecd230cb6ed9f75034ec38ef9e0a8 Mon Sep 17 00:00:00 2001 From: Adriano Ferreira Date: Thu, 30 Jan 2020 10:38:53 -0200 Subject: [PATCH 3/6] Uses config data from Composer object whenever possible on ArchiveCommand It was previously blindly getting a new instance from the factory thus ignoring what is on Composer object config data. --- .php_cs | 1 + src/Composer/Command/ArchiveCommand.php | 8 +- .../Test/Command/ArchiveCommandTest.php | 121 ++++++++++++++++++ 3 files changed, 129 insertions(+), 1 deletion(-) create mode 100644 tests/Composer/Test/Command/ArchiveCommandTest.php 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/src/Composer/Command/ArchiveCommand.php b/src/Composer/Command/ArchiveCommand.php index d0d9542cb..bbe18a653 100644 --- a/src/Composer/Command/ArchiveCommand.php +++ b/src/Composer/Command/ArchiveCommand.php @@ -64,15 +64,21 @@ EOT protected function execute(InputInterface $input, OutputInterface $output) { - $config = Factory::createConfig(); $composer = $this->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/tests/Composer/Test/Command/ArchiveCommandTest.php b/tests/Composer/Test/Command/ArchiveCommandTest.php new file mode 100644 index 000000000..385b81b47 --- /dev/null +++ b/tests/Composer/Test/Command/ArchiveCommandTest.php @@ -0,0 +1,121 @@ + + * 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->any())->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(); + + $ed = $this->getMockBuilder('Composer\EventDispatcher\EventDispatcher') + ->disableOriginalConstructor()->getMock(); + + $composer = new Composer; + $config = Factory::createConfig(); + + $manager = $this->getMockBuilder('Composer\Package\Archiver\ArchiveManager') + ->disableOriginalConstructor()->getMock(); + + $factory = $this->getMockBuilder('Composer\Factory')->getMock(); + $factory->method('createArchiveManager')->willReturn($manager); + + $package = $this->getMockBuilder('Composer\Package\RootPackageInterface') + ->getMock(); + + $composer->setArchiveManager($manager); + $composer->setEventDispatcher($ed); + $composer->setPackage($package); + + $command = $this->getMockBuilder('Composer\Command\ArchiveCommand') + ->setMethods(array( + 'mergeApplicationDefinition', + 'bind', + 'getSynopsis', + 'initialize', + 'isInteractive', + 'getComposer', + 'archive', + ))->getMock(); + $command->expects($this->any())->method('getComposer') + ->willReturnOnConsecutiveCalls(null, $composer); + $command->expects($this->any())->method('archive') + ->with( + $this->isType('object'), + $config, + null, + null, + 'tar', + '.', + null, + false, + null + ); + $command->method('isInteractive')->willReturn(false); + + $command->run($input, $output); + } +} From 9940271c6ebc2a1b0f98e00def9d6b586468250a Mon Sep 17 00:00:00 2001 From: Klaus Date: Tue, 11 Feb 2020 09:11:45 +0100 Subject: [PATCH 4/6] rename signature to checksum --- doc/faqs/how-to-install-composer-programmatically.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) 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 From a180f4892167590be776e58eef2318b55a6ebc0f Mon Sep 17 00:00:00 2001 From: Ion Bazan Date: Tue, 11 Feb 2020 16:35:35 +0800 Subject: [PATCH 5/6] Distinguish between updates and downgrades in dry-run --- .../DependencyResolver/Operation/UpdateOperation.php | 5 ++++- .../partial-update-downgrades-non-whitelisted-unstable.test | 2 +- .../Test/Fixtures/installer/partial-update-from-lock.test | 4 ++-- .../Test/Fixtures/installer/partial-update-without-lock.test | 2 +- .../installer/update-downgrades-unstable-packages.test | 2 +- .../Test/Fixtures/installer/update-prefer-lowest-stable.test | 2 +- 6 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/Composer/DependencyResolver/Operation/UpdateOperation.php b/src/Composer/DependencyResolver/Operation/UpdateOperation.php index 836725ef5..8cfc6b700 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. @@ -74,7 +75,9 @@ class UpdateOperation extends SolverOperation */ public function __toString() { - return 'Updating '.$this->initialPackage->getPrettyName().' ('.$this->formatVersion($this->initialPackage).') to '. + $actionName = VersionParser::isUpgrade($this->initialPackage->getVersion(), $this->targetPackage->getVersion()) ? 'Updating' : 'Downgrading'; + + return $actionName.' '.$this->initialPackage->getPrettyName().' ('.$this->formatVersion($this->initialPackage).') to '. $this->targetPackage->getPrettyName(). ' ('.$this->formatVersion($this->targetPackage).')'; } } diff --git a/tests/Composer/Test/Fixtures/installer/partial-update-downgrades-non-whitelisted-unstable.test b/tests/Composer/Test/Fixtures/installer/partial-update-downgrades-non-whitelisted-unstable.test index 9b8d32f06..3a428c97c 100644 --- a/tests/Composer/Test/Fixtures/installer/partial-update-downgrades-non-whitelisted-unstable.test +++ b/tests/Composer/Test/Fixtures/installer/partial-update-downgrades-non-whitelisted-unstable.test @@ -66,6 +66,6 @@ update c/uptodate "platform-dev": [] } --EXPECT-- -Updating b/unstable (1.1.0-alpha) to b/unstable (1.0.0) +Downgrading b/unstable (1.1.0-alpha) to b/unstable (1.0.0) Updating a/old (0.9.0) to a/old (1.0.0) Installing d/removed (1.0.0) 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 ed2002e4e..a54d66ee9 100644 --- a/tests/Composer/Test/Fixtures/installer/partial-update-from-lock.test +++ b/tests/Composer/Test/Fixtures/installer/partial-update-from-lock.test @@ -74,8 +74,8 @@ update b/unstable "platform-dev": [] } --EXPECT-- -Updating b/unstable (1.1.0-alpha) to b/unstable (1.0.0) +Downgrading b/unstable (1.1.0-alpha) to b/unstable (1.0.0) Updating a/old (0.9.0) to a/old (1.0.0) -Updating c/uptodate (2.0.0) to c/uptodate (1.0.0) +Downgrading c/uptodate (2.0.0) to c/uptodate (1.0.0) Installing d/removed (1.0.0) Installing e/newreq (1.0.0) diff --git a/tests/Composer/Test/Fixtures/installer/partial-update-without-lock.test b/tests/Composer/Test/Fixtures/installer/partial-update-without-lock.test index e931a1f7d..94be9176c 100644 --- a/tests/Composer/Test/Fixtures/installer/partial-update-without-lock.test +++ b/tests/Composer/Test/Fixtures/installer/partial-update-without-lock.test @@ -48,4 +48,4 @@ update b/unstable "platform-dev": [] } --EXPECT-- -Updating b/unstable (1.1.0-alpha) to b/unstable (1.0.0) +Downgrading b/unstable (1.1.0-alpha) to b/unstable (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 1b6e55ef9..0cb42e6fa 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) to a/a (1.0.0) +Downgrading a/a (dev-master abcd) to a/a (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 00efd5688..68e3effe2 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) to a/a (1.0.1) -Updating a/b (1.0.1) to a/b (1.0.0) +Downgrading a/b (1.0.1) to a/b (1.0.0) From 11ae757e99a9bd035f90e9416b94cde4d44f9ae4 Mon Sep 17 00:00:00 2001 From: Ion Bazan Date: Tue, 11 Feb 2020 17:14:50 +0800 Subject: [PATCH 6/6] fix risky tests --- phpunit.xml.dist | 4 ++- .../Test/Command/ArchiveCommandTest.php | 28 ++++--------------- 2 files changed, 8 insertions(+), 24 deletions(-) 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 @@ getMock(); - $command->expects($this->any())->method('getComposer') + $command->expects($this->atLeastOnce())->method('getComposer') ->willReturn($composer); $command->method('isInteractive')->willReturn(false); @@ -70,26 +70,8 @@ class ArchiveCommandTest extends TestCase $output = $this->getMockBuilder('Symfony\Component\Console\Output\OutputInterface') ->getMock(); - - $ed = $this->getMockBuilder('Composer\EventDispatcher\EventDispatcher') - ->disableOriginalConstructor()->getMock(); - - $composer = new Composer; $config = Factory::createConfig(); - $manager = $this->getMockBuilder('Composer\Package\Archiver\ArchiveManager') - ->disableOriginalConstructor()->getMock(); - - $factory = $this->getMockBuilder('Composer\Factory')->getMock(); - $factory->method('createArchiveManager')->willReturn($manager); - - $package = $this->getMockBuilder('Composer\Package\RootPackageInterface') - ->getMock(); - - $composer->setArchiveManager($manager); - $composer->setEventDispatcher($ed); - $composer->setPackage($package); - $command = $this->getMockBuilder('Composer\Command\ArchiveCommand') ->setMethods(array( 'mergeApplicationDefinition', @@ -100,11 +82,11 @@ class ArchiveCommandTest extends TestCase 'getComposer', 'archive', ))->getMock(); - $command->expects($this->any())->method('getComposer') - ->willReturnOnConsecutiveCalls(null, $composer); - $command->expects($this->any())->method('archive') + $command->expects($this->once())->method('getComposer') + ->willReturn(null); + $command->expects($this->once())->method('archive') ->with( - $this->isType('object'), + $this->isInstanceOf('Composer\IO\IOInterface'), $config, null, null,