2022-05-27 12:51:46 +00:00
|
|
|
<?php declare(strict_types=1);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* This file is part of Composer.
|
|
|
|
*
|
|
|
|
* (c) Nils Adermann <naderman@naderman.de>
|
|
|
|
* Jordi Boggiano <j.boggiano@seld.be>
|
|
|
|
*
|
|
|
|
* 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\Test\TestCase;
|
2023-12-08 17:26:05 +00:00
|
|
|
use InvalidArgumentException;
|
2022-05-27 12:51:46 +00:00
|
|
|
|
|
|
|
class UpdateCommandTest extends TestCase
|
|
|
|
{
|
|
|
|
/**
|
|
|
|
* @dataProvider provideUpdates
|
|
|
|
* @param array<mixed> $composerJson
|
|
|
|
* @param array<mixed> $command
|
|
|
|
*/
|
|
|
|
public function testUpdate(array $composerJson, array $command, string $expected): void
|
|
|
|
{
|
|
|
|
$this->initTempComposer($composerJson);
|
|
|
|
|
|
|
|
$appTester = $this->getApplicationTester();
|
2022-06-22 13:14:00 +00:00
|
|
|
$appTester->run(array_merge(['command' => 'update', '--dry-run' => true, '--no-audit' => true], $command));
|
2022-05-27 12:51:46 +00:00
|
|
|
|
2024-05-29 21:12:06 +00:00
|
|
|
self::assertStringMatchesFormat(trim($expected), trim($appTester->getDisplay(true)));
|
2022-05-27 12:51:46 +00:00
|
|
|
}
|
|
|
|
|
2022-11-24 13:39:08 +00:00
|
|
|
public static function provideUpdates(): \Generator
|
2022-05-27 12:51:46 +00:00
|
|
|
{
|
|
|
|
$rootDepAndTransitiveDep = [
|
|
|
|
'repositories' => [
|
|
|
|
'packages' => [
|
|
|
|
'type' => 'package',
|
|
|
|
'package' => [
|
|
|
|
['name' => 'root/req', 'version' => '1.0.0', 'require' => ['dep/pkg' => '^1']],
|
|
|
|
['name' => 'dep/pkg', 'version' => '1.0.0'],
|
|
|
|
['name' => 'dep/pkg', 'version' => '1.0.1'],
|
|
|
|
['name' => 'dep/pkg', 'version' => '1.0.2'],
|
|
|
|
],
|
|
|
|
],
|
|
|
|
],
|
|
|
|
'require' => [
|
|
|
|
'root/req' => '1.*',
|
|
|
|
],
|
|
|
|
];
|
|
|
|
|
|
|
|
yield 'simple update' => [
|
|
|
|
$rootDepAndTransitiveDep,
|
|
|
|
[],
|
|
|
|
<<<OUTPUT
|
|
|
|
Loading composer repositories with package information
|
|
|
|
Updating dependencies
|
|
|
|
Lock file operations: 2 installs, 0 updates, 0 removals
|
|
|
|
- Locking dep/pkg (1.0.2)
|
|
|
|
- Locking root/req (1.0.0)
|
|
|
|
Installing dependencies from lock file (including require-dev)
|
|
|
|
Package operations: 2 installs, 0 updates, 0 removals
|
|
|
|
- Installing dep/pkg (1.0.2)
|
|
|
|
- Installing root/req (1.0.0)
|
|
|
|
OUTPUT
|
|
|
|
];
|
|
|
|
|
2023-12-19 16:17:48 +00:00
|
|
|
yield 'simple update with very verbose output' => [
|
|
|
|
$rootDepAndTransitiveDep,
|
|
|
|
['-vv' => true],
|
|
|
|
<<<OUTPUT
|
|
|
|
Loading composer repositories with package information
|
|
|
|
Pool optimizer completed in %f seconds
|
|
|
|
Found %d package versions referenced in your dependency graph. %d (%d%%) were optimized away.
|
|
|
|
Updating dependencies
|
|
|
|
Dependency resolution completed in %f seconds
|
|
|
|
Analyzed %d packages to resolve dependencies
|
|
|
|
Analyzed %d rules to resolve dependencies
|
|
|
|
Lock file operations: 2 installs, 0 updates, 0 removals
|
|
|
|
Installs: dep/pkg:1.0.2, root/req:1.0.0
|
|
|
|
- Locking dep/pkg (1.0.2) from package repo (defining 4 packages)
|
|
|
|
- Locking root/req (1.0.0) from package repo (defining 4 packages)
|
|
|
|
Installing dependencies from lock file (including require-dev)
|
|
|
|
Package operations: 2 installs, 0 updates, 0 removals
|
|
|
|
Installs: dep/pkg:1.0.2, root/req:1.0.0
|
|
|
|
- Installing dep/pkg (1.0.2)
|
|
|
|
- Installing root/req (1.0.0)
|
|
|
|
OUTPUT
|
|
|
|
];
|
|
|
|
|
2022-05-27 12:51:46 +00:00
|
|
|
yield 'update with temporary constraint + --no-install' => [
|
|
|
|
$rootDepAndTransitiveDep,
|
|
|
|
['--with' => ['dep/pkg:1.0.0'], '--no-install' => true],
|
|
|
|
<<<OUTPUT
|
|
|
|
Loading composer repositories with package information
|
|
|
|
Updating dependencies
|
|
|
|
Lock file operations: 2 installs, 0 updates, 0 removals
|
|
|
|
- Locking dep/pkg (1.0.0)
|
|
|
|
- Locking root/req (1.0.0)
|
|
|
|
OUTPUT
|
|
|
|
];
|
|
|
|
|
|
|
|
yield 'update with temporary constraint failing resolution' => [
|
|
|
|
$rootDepAndTransitiveDep,
|
|
|
|
['--with' => ['dep/pkg:^2']],
|
|
|
|
<<<OUTPUT
|
|
|
|
Loading composer repositories with package information
|
|
|
|
Updating dependencies
|
|
|
|
Your requirements could not be resolved to an installable set of packages.
|
|
|
|
|
|
|
|
Problem 1
|
|
|
|
- Root composer.json requires root/req 1.* -> satisfiable by root/req[1.0.0].
|
|
|
|
- root/req 1.0.0 requires dep/pkg ^1 -> found dep/pkg[1.0.0, 1.0.1, 1.0.2] but it conflicts with your temporary update constraint (dep/pkg:^2).
|
2023-10-26 09:38:02 +00:00
|
|
|
OUTPUT
|
|
|
|
];
|
|
|
|
|
|
|
|
yield 'update with temporary constraint failing resolution on root package' => [
|
|
|
|
$rootDepAndTransitiveDep,
|
|
|
|
['--with' => ['root/req:^2']],
|
|
|
|
<<<OUTPUT
|
|
|
|
The temporary constraint "^2" for "root/req" must be a subset of the constraint in your composer.json (1.*)
|
|
|
|
Run `composer require root/req` or `composer require root/req:^2` instead to replace the constraint
|
2022-05-27 12:51:46 +00:00
|
|
|
OUTPUT
|
|
|
|
];
|
|
|
|
}
|
2023-12-08 17:26:05 +00:00
|
|
|
|
|
|
|
public function testInteractiveModeThrowsIfNoPackageEntered(): void
|
|
|
|
{
|
|
|
|
$this->expectException(InvalidArgumentException::class);
|
|
|
|
$this->expectExceptionMessage('You must enter minimum one package.');
|
|
|
|
|
|
|
|
$appTester = $this->getApplicationTester();
|
|
|
|
$appTester->setInputs(['']);
|
|
|
|
$appTester->run(['command' => 'update', '--interactive' => true]);
|
|
|
|
}
|
2022-05-27 12:51:46 +00:00
|
|
|
}
|