Skip to content

Commit 366f289

Browse files
committed
Fixing bug when patching/updating a file the user has deleted
1 parent 10a49fa commit 366f289

File tree

2 files changed

+49
-19
lines changed

2 files changed

+49
-19
lines changed

src/Update/RecipePatcher.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,14 @@ class RecipePatcher
1919
{
2020
private string $rootDir;
2121
private Filesystem $filesystem;
22+
private IOInterface $io;
2223
private ProcessExecutor $processExecutor;
2324

2425
public function __construct(string $rootDir, IOInterface $io)
2526
{
2627
$this->rootDir = $rootDir;
2728
$this->filesystem = new Filesystem();
29+
$this->io = $io;
2830
$this->processExecutor = new ProcessExecutor($io);
2931
}
3032

@@ -50,6 +52,7 @@ public function applyPatch(RecipePatch $patch): bool
5052

5153
$output = '';
5254
$statusCode = $this->processExecutor->execute('git apply "_flex_recipe_update.patch" -3', $output, $this->rootDir);
55+
$this->io->debug('git apply output: '.$output);
5356

5457
if ($statusCode === 0) {
5558
// successful with no conflicts
@@ -88,6 +91,16 @@ public function generatePatch(array $originalFiles, array $newFiles): RecipePatc
8891
}
8992
}
9093

94+
// If a file is being modified, but does not exist in the current project,
95+
// it cannot be patched. Ignore these files and leave them deleted.
96+
$modifiedFiles = array_intersect_key(array_keys($originalFiles), array_keys($newFiles));
97+
foreach ($modifiedFiles as $modifiedFile) {
98+
if (!file_exists($this->rootDir.'/'.$modifiedFile)) {
99+
unset($originalFiles[$modifiedFile]);
100+
unset($newFiles[$modifiedFile]);
101+
}
102+
}
103+
91104
$tmpPath = sys_get_temp_dir().'/_flex_recipe_update'.uniqid(mt_rand(), true);
92105
$this->filesystem->mkdir($tmpPath);
93106

tests/Update/RecipePatcherTest.php

Lines changed: 36 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,19 @@ public function getGeneratePatchTests(): iterable
174174
];
175175
}
176176

177+
public function testGeneratePatchOnDeletedFile()
178+
{
179+
// make sure the target directory is empty
180+
$this->getFilesystem()->remove(FLEX_TEST_DIR);
181+
$this->getFilesystem()->mkdir(FLEX_TEST_DIR);
182+
183+
$patcher = new RecipePatcher(FLEX_TEST_DIR, $this->createMock(IOInterface::class));
184+
185+
// try to update a file that does not exist in the project
186+
$patch = $patcher->generatePatch(['.env' => 'original contents'], ['.env' => 'new contents']);
187+
$this->assertSame('', $patch->getPatch());
188+
}
189+
177190
/**
178191
* @dataProvider getApplyPatchTests
179192
*/
@@ -294,11 +307,30 @@ public function testIntegration(bool $useNullForMissingFiles)
294307
$files = $this->getFilesForPatching();
295308
(new Process(['git', 'init'], FLEX_TEST_DIR))->mustRun();
296309

310+
$startingFiles = [
311+
'.env' => $files['dot_env_clean']['in_app'],
312+
'package.json' => $files['package_json_conflict']['in_app'],
313+
// no webpack_encore.yaml in app
314+
'config/packages/security.yaml' => $files['security_removed']['in_app'],
315+
// no cache.yaml in app - the update patch will be skipped
316+
];
317+
foreach ($startingFiles as $file => $contents) {
318+
if (!file_exists(dirname(FLEX_TEST_DIR.'/'.$file))) {
319+
@mkdir(dirname(FLEX_TEST_DIR.'/'.$file), 0777, true);
320+
}
321+
322+
file_put_contents(FLEX_TEST_DIR.'/'.$file, $contents);
323+
}
324+
// commit the files in the app
325+
(new Process(['git', 'add', '-A'], FLEX_TEST_DIR))->mustRun();
326+
(new Process(['git', 'commit', '-m', 'committing in app start files'], FLEX_TEST_DIR))->mustRun();
327+
297328
$patcher = new RecipePatcher(FLEX_TEST_DIR, $this->createMock(IOInterface::class));
298329
$originalFiles = [
299330
'.env' => $files['dot_env_clean']['original_recipe'],
300331
'package.json' => $files['package_json_conflict']['original_recipe'],
301332
'config/packages/security.yaml' => $files['security_removed']['original_recipe'],
333+
'config/packages/cache.yaml' => 'original cache.yaml',
302334
];
303335
if ($useNullForMissingFiles) {
304336
$originalFiles['config/packages/webpack_encore.yaml'] = null;
@@ -307,31 +339,16 @@ public function testIntegration(bool $useNullForMissingFiles)
307339
$updatedFiles = [
308340
'.env' => $files['dot_env_clean']['updated_recipe'],
309341
'package.json' => $files['package_json_conflict']['updated_recipe'],
310-
'config/packages/webpack_encore.yaml' => $files['webpack_encore_added']['updated_recipe']
342+
'config/packages/webpack_encore.yaml' => $files['webpack_encore_added']['updated_recipe'],
343+
'config/packages/cache.yaml' => 'updated cache.yaml',
311344
];
312345
if ($useNullForMissingFiles) {
313346
$updatedFiles['config/packages/security.yaml'] = null;
314347
}
315-
$recipePatch = $patcher->generatePatch($originalFiles, $updatedFiles);
316-
317-
$startingFiles = [
318-
'.env' => $files['dot_env_clean']['in_app'],
319-
'package.json' => $files['package_json_conflict']['in_app'],
320-
// no webpack_encore.yaml in app
321-
'config/packages/security.yaml' => $files['security_removed']['in_app'],
322-
];
323-
foreach ($startingFiles as $file => $contents) {
324-
if (!file_exists(dirname(FLEX_TEST_DIR.'/'.$file))) {
325-
@mkdir(dirname(FLEX_TEST_DIR.'/'.$file), 0777, true);
326-
}
327-
328-
file_put_contents(FLEX_TEST_DIR.'/'.$file, $contents);
329-
}
330-
// commit the files in the app
331-
(new Process(['git', 'add', '-A'], FLEX_TEST_DIR))->mustRun();
332-
(new Process(['git', 'commit', '-m', 'committing in app start files'], FLEX_TEST_DIR))->mustRun();
333348

349+
$recipePatch = $patcher->generatePatch($originalFiles, $updatedFiles);
334350
$appliedCleanly = $patcher->applyPatch($recipePatch);
351+
335352
$this->assertFalse($appliedCleanly);
336353
$this->assertSame($files['dot_env_clean']['expected'], file_get_contents(FLEX_TEST_DIR.'/.env'));
337354
$this->assertSame($files['package_json_conflict']['expected'], file_get_contents(FLEX_TEST_DIR.'/package.json'));

0 commit comments

Comments
 (0)