Skip to content

Commit d309f02

Browse files
bug #965 Keep existing constraints in package.json (smnandre)
This PR was submitted for the 2.x branch but it was squashed and merged into the 1.x branch instead. Discussion ---------- Keep existing constraints in package.json When a dependency constraint is already set in the package.json, the PackageSynchroniser replaces it with even if the constraint is valid. This PR changes this behaviour and let the constraint untouched if it matches the one provided by the PHP package. Related issues: * #843 * #938 Commits ------- ae95fe1 Keep existing constraints in package.json
2 parents eb19d64 + ae95fe1 commit d309f02

File tree

3 files changed

+60
-2
lines changed

3 files changed

+60
-2
lines changed

src/PackageJsonSynchronizer.php

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
use Composer\Json\JsonFile;
1515
use Composer\Json\JsonManipulator;
16+
use Composer\Semver\VersionParser;
1617
use Seld\JsonLint\ParsingException;
1718

1819
/**
@@ -23,11 +24,13 @@ class PackageJsonSynchronizer
2324
{
2425
private $rootDir;
2526
private $vendorDir;
27+
private $versionParser;
2628

2729
public function __construct(string $rootDir, string $vendorDir = 'vendor')
2830
{
2931
$this->rootDir = $rootDir;
3032
$this->vendorDir = $vendorDir;
33+
$this->versionParser = new VersionParser();
3134
}
3235

3336
public function shouldSynchronize(): bool
@@ -136,8 +139,10 @@ private function registerDependencies(array $flexDependencies): bool
136139
$content['devDependencies'][$dependency] = $constraint;
137140
$didChangePackageJson = true;
138141
} elseif ($constraint !== $content[$parentNode][$dependency]) {
139-
$content[$parentNode][$dependency] = $constraint;
140-
$didChangePackageJson = true;
142+
if ($this->shouldUpdateConstraint($content[$parentNode][$dependency], $constraint)) {
143+
$content[$parentNode][$dependency] = $constraint;
144+
$didChangePackageJson = true;
145+
}
141146
}
142147
}
143148

@@ -163,6 +168,18 @@ private function registerDependencies(array $flexDependencies): bool
163168
return $didChangePackageJson;
164169
}
165170

171+
private function shouldUpdateConstraint(string $existingConstraint, string $constraint)
172+
{
173+
try {
174+
$existingConstraint = $this->versionParser->parseConstraints($existingConstraint);
175+
$constraint = $this->versionParser->parseConstraints($constraint);
176+
177+
return !$existingConstraint->matches($constraint);
178+
} catch (\UnexpectedValueException $e) {
179+
return true;
180+
}
181+
}
182+
166183
private function registerWebpackResources(array $phpPackages)
167184
{
168185
if (!file_exists($controllersJsonPath = $this->rootDir.'/assets/controllers.json')) {
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"name": "symfony/fixture",
3+
"devDependencies": {
4+
"@hotcookies": "^2",
5+
"@hotdogs": "^1.9",
6+
"@symfony/existing-package": "file:vendor/symfony/existing-package/Resources/assets"
7+
},
8+
"browserslist": [
9+
"defaults"
10+
]
11+
}

tests/PackageJsonSynchronizerTest.php

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,4 +245,34 @@ public function testExistingElevatedPackage()
245245
json_decode(file_get_contents($this->tempDir.'/package.json'), true)
246246
);
247247
}
248+
249+
public function testStricterConstraintsAreKeptNonMatchingAreReplaced()
250+
{
251+
(new Filesystem())->copy($this->tempDir.'/stricter_constraints_package.json', $this->tempDir.'/package.json', true);
252+
253+
$this->synchronizer->synchronize([
254+
[
255+
'name' => 'symfony/existing-package',
256+
'keywords' => ['symfony-ux'],
257+
],
258+
]);
259+
260+
// Should keep existing constraints when stricter than packages ones
261+
$this->assertSame(
262+
[
263+
'name' => 'symfony/fixture',
264+
'devDependencies' => [
265+
// this satisfies the constraint, so it's kept
266+
'@hotcookies' => '^2',
267+
// this was too low, so it's replaced
268+
'@hotdogs' => '^2',
269+
'@symfony/existing-package' => 'file:vendor/symfony/existing-package/Resources/assets',
270+
],
271+
'browserslist' => [
272+
'defaults',
273+
],
274+
],
275+
json_decode(file_get_contents($this->tempDir.'/package.json'), true)
276+
);
277+
}
248278
}

0 commit comments

Comments
 (0)