Skip to content

Commit 680f2c3

Browse files
committed
Deduplicate patches on package level
1 parent 0acea47 commit 680f2c3

File tree

3 files changed

+42
-6
lines changed

3 files changed

+42
-6
lines changed

src/Patcher.php

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -157,28 +157,42 @@ private function computeTargetPackageApplications()
157157
}
158158

159159
foreach ($patchesByPackage as $targetPackageName => $packagePatches) {
160+
/** @var PatchApplication[] $applications */
160161
$applications = [];
161162

162163
$targetPackage = $repo->findPackage($targetPackageName, '*');
163164

164165
if (null === $targetPackage) {
165-
// No package to pach, nothing to do
166+
// No package to patch, nothing to do
166167
continue;
167168
}
168169

169170
/** @var Patch $patch */
170171
foreach ($packagePatches as $patch) {
171172
if ($patch->canBeAppliedTo($targetPackage)) {
172173
$sourcePackage = $repo->findPackage($patch->getSourcePackage(), '*');
173-
$applications[] = new PatchApplication(
174+
175+
$applicationHash = $this->computeApplicationHash($sourcePackage, $patch);
176+
177+
if (isset($applications[$applicationHash])) {
178+
$this->logger->notice(sprintf('Skipping patch <info>%s</info> (<comment>%s</comment> as it was already added by package <comment>%s</comment>',
179+
$patch->getDescription(),
180+
$patch->getSourcePackage(),
181+
$applications[$applicationHash]->getSourcePackage()->getName()
182+
));
183+
}
184+
185+
$applications[$applicationHash] = new PatchApplication(
174186
$patch,
175187
$sourcePackage,
176188
$targetPackage,
177-
$this->computeApplicationHash($sourcePackage, $patch)
189+
$applicationHash
178190
);
179191
}
180192
}
181193

194+
$applications = array_values($applications);
195+
182196
$packageApplications[$targetPackage->getName()] = new PackagePatchApplication($targetPackage, $applications);
183197
}
184198

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
namespace Creativestyle\Composer\Patchset\Tests\Functional;
44

5-
class BasicPatchingTest extends SandboxTestCase
5+
class CoreFeatureTest extends SandboxTestCase
66
{
77
const PACKAGEA_PATCH1_APPLICATIONS = [
88
'/vendor/test/package-a/src/test.php' => 'patched-in-echo'
@@ -108,4 +108,26 @@ public function testThatLayeredPatchesAreAppliedInCorrectOrder()
108108
$this->assertNotContains('Applied patch', $updateRun->getFullOutput(), 'no patches were applied', true);
109109
}
110110

111+
public function testThatPatchesAreDeduplicated()
112+
{
113+
// Same patch coming from multiple patchsets shall be applied only once
114+
115+
$project = $this->getSandbox()->createProjectSandBox('test/project-template', 'dev-master', [
116+
'require' => [
117+
'test/patchset'=> '~1.0',
118+
'test/patchset-extra'=> '~1.0',
119+
'test/package-a'=> 'dev-master',
120+
'creativestyle/composer-plugin-patchset'=> 'dev-master'
121+
]
122+
]);
123+
124+
$installRun = $project->runComposerCommand('install');
125+
126+
$this->assertThatComposerRunHasAppliedPatches($installRun,
127+
array_merge_recursive(
128+
self::PACKAGEA_PATCH1_APPLICATIONS,
129+
self::PACKAGEA_PATCH2_APPLICATIONS
130+
)
131+
);
132+
}
111133
}

tests/Functional/Fixtures/ProjectSandbox.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ class ProjectSandbox
6868
public function __construct(
6969
$packageName,
7070
$packageVersion,
71-
array $config = [],
71+
array $config,
7272
ComposerSandbox $repository,
7373
ProcessExecutor $executor,
7474
Filesystem $filesystem,
@@ -145,7 +145,7 @@ public function runComposerCommand($cmd, ...$args)
145145
// to be applied to our source fixtures and the project templates modified.
146146
$_ENV['COMPOSER_MIRROR_PATH_REPOS'] = '1';
147147

148-
$cmdElements = array_merge([$this->composerBinary, $cmd], $args);
148+
$cmdElements = array_merge([$this->composerBinary, '--ansi', $cmd], $args);
149149
$cmdString = $cmdElements[0] . ' ' .implode(' ', array_map([ProcessExecutor::class, 'escape'], array_slice($cmdElements, 1)));
150150

151151
$fullOut = '';

0 commit comments

Comments
 (0)