Skip to content

Commit b77d805

Browse files
committed
Don't remove still-referenced files when updating recipes
1 parent 4ae50d3 commit b77d805

File tree

3 files changed

+32
-9
lines changed

3 files changed

+32
-9
lines changed

src/Command/UpdateRecipesCommand.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
153153
$recipeUpdate = new RecipeUpdate($originalRecipe, $newRecipe, $symfonyLock, $this->rootDir);
154154
$this->configurator->populateUpdate($recipeUpdate);
155155
$originalComposerJsonHash = $this->flex->getComposerJsonHash();
156-
$patcher = new RecipePatcher($this->rootDir, $io);
156+
$patcher = new RecipePatcher($this->rootDir, $io, $symfonyLock);
157157

158158
try {
159159
$patch = $patcher->generatePatch($recipeUpdate->getOriginalFiles(), $recipeUpdate->getNewFiles());

src/Update/RecipePatcher.php

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,19 +15,22 @@
1515
use Composer\Util\ProcessExecutor;
1616
use Symfony\Component\Filesystem\Exception\IOException;
1717
use Symfony\Component\Filesystem\Filesystem;
18+
use Symfony\Flex\Lock;
1819

1920
class RecipePatcher
2021
{
2122
private $rootDir;
2223
private $filesystem;
2324
private $io;
2425
private $processExecutor;
26+
private $symfonyLock;
2527

26-
public function __construct(string $rootDir, IOInterface $io)
28+
public function __construct(string $rootDir, IOInterface $io, Lock $symfonyLock)
2729
{
2830
$this->rootDir = $rootDir;
2931
$this->filesystem = new Filesystem();
3032
$this->io = $io;
33+
$this->symfonyLock = $symfonyLock;
3134
$this->processExecutor = new ProcessExecutor($io);
3235
}
3336

@@ -39,11 +42,30 @@ public function __construct(string $rootDir, IOInterface $io)
3942
public function applyPatch(RecipePatch $patch): bool
4043
{
4144
$withConflicts = $this->_applyPatchFile($patch);
45+
$lockedFiles = array_count_values(array_merge(...array_column($this->symfonyLock->all(), 'files')));
4246

47+
$nonRemovableFiles = [];
4348
foreach ($patch->getDeletedFiles() as $deletedFile) {
44-
if (file_exists($this->rootDir.'/'.$deletedFile)) {
45-
$this->execute(\sprintf('git rm %s', ProcessExecutor::escape($deletedFile)), $this->rootDir);
49+
if (!file_exists($this->rootDir.'/'.$deletedFile)) {
50+
continue;
51+
}
52+
53+
if (isset($lockedFiles[$deletedFile])) {
54+
$nonRemovableFiles[] = $deletedFile;
55+
56+
continue;
4657
}
58+
59+
$this->execute(\sprintf('git rm %s', ProcessExecutor::escape($deletedFile)), $this->rootDir);
60+
}
61+
62+
if ($nonRemovableFiles) {
63+
$this->io->writeError(' <warning>The following files were removed in the recipe, but are still referenced by other recipes. You might need to adjust them manually:</warning>');
64+
foreach ($nonRemovableFiles as $file) {
65+
$this->io->writeError(' - '.$file);
66+
}
67+
68+
$this->io->writeError('');
4769
}
4870

4971
return $withConflicts;

tests/Update/RecipePatcherTest.php

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use PHPUnit\Framework\TestCase;
1616
use Symfony\Component\Filesystem\Filesystem;
1717
use Symfony\Component\Process\Process;
18+
use Symfony\Flex\Lock;
1819
use Symfony\Flex\Update\RecipePatch;
1920
use Symfony\Flex\Update\RecipePatcher;
2021

@@ -52,7 +53,7 @@ public function testGeneratePatch(array $originalFiles, array $newFiles, string
5253
(new Process(['git', 'commit', '-m', '"original files"'], FLEX_TEST_DIR))->mustRun();
5354
}
5455

55-
$patcher = new RecipePatcher(FLEX_TEST_DIR, $this->createMock(IOInterface::class));
56+
$patcher = new RecipePatcher(FLEX_TEST_DIR, $this->createMock(IOInterface::class), $this->createMock(Lock::class));
5657

5758
$patch = $patcher->generatePatch($originalFiles, $newFiles);
5859
$this->assertSame($expectedPatch, rtrim($patch->getPatch(), "\n"));
@@ -189,7 +190,7 @@ public function testGeneratePatchOnDeletedFile()
189190
$this->getFilesystem()->remove(FLEX_TEST_DIR);
190191
$this->getFilesystem()->mkdir(FLEX_TEST_DIR);
191192

192-
$patcher = new RecipePatcher(FLEX_TEST_DIR, $this->createMock(IOInterface::class));
193+
$patcher = new RecipePatcher(FLEX_TEST_DIR, $this->createMock(IOInterface::class), $this->createMock(Lock::class));
193194

194195
// try to update a file that does not exist in the project
195196
$patch = $patcher->generatePatch(['.env' => 'original contents'], ['.env' => 'new contents']);
@@ -217,7 +218,7 @@ public function testApplyPatch(array $filesCurrentlyInApp, RecipePatch $recipePa
217218
(new Process(['git', 'commit', '-m', 'Committing original files'], FLEX_TEST_DIR))->mustRun();
218219
}
219220

220-
$patcher = new RecipePatcher(FLEX_TEST_DIR, $this->createMock(IOInterface::class));
221+
$patcher = new RecipePatcher(FLEX_TEST_DIR, $this->createMock(IOInterface::class), $this->createMock(Lock::class));
221222
$hadConflicts = !$patcher->applyPatch($recipePatch);
222223

223224
foreach ($expectedFiles as $file => $expectedContents) {
@@ -261,7 +262,7 @@ public function testApplyPatchOnSubfolder(array $filesCurrentlyInApp, RecipePatc
261262
(new Process(['git', 'commit', '-m', 'Committing original files'], $subProjectPath))->mustRun();
262263
}
263264

264-
$patcher = new RecipePatcher($subProjectPath, $this->createMock(IOInterface::class));
265+
$patcher = new RecipePatcher($subProjectPath, $this->createMock(IOInterface::class), $this->createMock(Lock::class));
265266
$hadConflicts = !$patcher->applyPatch($recipePatch);
266267

267268
foreach ($expectedFiles as $file => $expectedContents) {
@@ -390,7 +391,7 @@ public function testIntegration(bool $useNullForMissingFiles)
390391
(new Process(['git', 'add', '-A'], FLEX_TEST_DIR))->mustRun();
391392
(new Process(['git', 'commit', '-m', 'committing in app start files'], FLEX_TEST_DIR))->mustRun();
392393

393-
$patcher = new RecipePatcher(FLEX_TEST_DIR, $this->createMock(IOInterface::class));
394+
$patcher = new RecipePatcher(FLEX_TEST_DIR, $this->createMock(IOInterface::class), $this->createMock(Lock::class));
394395
$originalFiles = [
395396
'.env' => $files['dot_env_clean']['original_recipe'],
396397
'package.json' => $files['package_json_conflict']['original_recipe'],

0 commit comments

Comments
 (0)