Skip to content

Commit e5e3f8a

Browse files
committed
Complete CLI command
1 parent 18eb4ed commit e5e3f8a

4 files changed

Lines changed: 190 additions & 38 deletions

File tree

src/Commands/SelfUpdate.php

Lines changed: 154 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -49,33 +49,32 @@ public function run(array $params)
4949
$this->patches->afterUpdate();
5050

5151

52-
// Display the menu, if user selects "quit" then abort
52+
// Display the merge menu, if user selects "quit" then abort
5353
if (! $this->mergeMenu())
5454
{
55-
CLI::write('Patch aborted. Workspace with codex and files:');
56-
CLI::write($codex->workspace);
57-
58-
// Write out the Codex
59-
$this->patches->getCodex()->save();
60-
61-
return;
55+
CLI::write('Process aborted.', 'red');
56+
return $this->complete();
6257
}
6358

6459
// Call the chosen merging method
6560
$this->patches->merge();
6661

67-
// Write out the Codex
68-
$this->patches->getCodex()->save();
62+
// Display the conflicts menu, if user selects "quit" then abort
63+
if (! $this->conflictsMenu())
64+
{
65+
CLI::write('Process aborted.', 'red');
66+
return $this->complete();
67+
}
6968

70-
return $result;
69+
return $this->complete();
7170
}
7271

7372
/**
7473
* Display and process the main menu
7574
*
7675
* @return bool Whether or not to continue with merge
7776
*/
78-
protected function mergeMenu()
77+
protected function mergeMenu(): bool
7978
{
8079
$codex = $this->patches->getCodex();
8180
$counts = [
@@ -94,13 +93,13 @@ protected function mergeMenu()
9493

9594
CLI::write('What would you like to do:');
9695
CLI::write('(P)roceed with the merge');
97-
CLI::write('(S)how all files');
96+
CLI::write('(L)ist all files');
9897
CLI::write('Show (C)hanged files (' . $counts['changed'] . ')');
9998
CLI::write('Show (A)dded files (' . $counts['added'] . ')');
10099
CLI::write('Show (D)eleted files (' . $counts['deleted'] . ')');
101100
CLI::write('(Q)uit');
102101

103-
switch (CLI::prompt('Selection?', ['p', 's', 'c', 'a', 'd', 'q']))
102+
switch (CLI::prompt('Selection?', ['p', 'l', 'c', 'a', 'd', 'q']))
104103
{
105104
case 'p':
106105
return true;
@@ -110,7 +109,7 @@ protected function mergeMenu()
110109
return false;
111110
break;
112111

113-
case 's':
112+
case 'l':
114113
$this->showFiles($codex->changedFiles, 'Changed');
115114
$this->showFiles($codex->addedFiles, 'Added');
116115
$this->showFiles($codex->deletedFiles, 'Deleted');
@@ -133,6 +132,125 @@ protected function mergeMenu()
133132
return $this->mergeMenu();
134133
}
135134

135+
/**
136+
* Display and process the conflicts menu
137+
*
138+
* @return bool
139+
*/
140+
protected function conflictsMenu(): bool
141+
{
142+
$codex = $this->patches->getCodex();
143+
$counts = [
144+
'changed' => count($codex->conflicts['changed']),
145+
'added' => count($codex->conflicts['added']),
146+
'deleted' => count($codex->conflicts['deleted']),
147+
];
148+
149+
if (! array_sum($counts))
150+
{
151+
CLI::write('Skipping conflict resolution.', 'green');
152+
return true;
153+
}
154+
155+
CLI::write('What would you like to do:');
156+
CLI::write('(L)ist conflict files');
157+
CLI::write('(G)uided resolution');
158+
CLI::write('(O)verwrite all files');
159+
CLI::write('(S)kip all files');
160+
CLI::write('(Q)uit');
161+
162+
switch (CLI::prompt('Selection?', ['l', 'g', 'o', 's', 'q']))
163+
{
164+
case 'p':
165+
return true;
166+
break;
167+
168+
case 's':
169+
return false;
170+
break;
171+
172+
case 'l':
173+
$this->showFiles($codex->conflicts['changed'], 'Changed');
174+
$this->showFiles($codex->conflicts['added'], 'Added');
175+
$this->showFiles($codex->conflicts['deleted'], 'Deleted');
176+
break;
177+
178+
case 'g':
179+
foreach ($codex->conflicts as $status => $files)
180+
{
181+
foreach ($files as $file)
182+
{
183+
if (! $this->resolveMenu($file, $status))
184+
{
185+
return false;
186+
}
187+
}
188+
}
189+
190+
return true;
191+
break;
192+
}
193+
194+
// If a non-returning item was select then run the menu again
195+
return $this->conflictsMenu();
196+
}
197+
198+
/**
199+
* Display and process the resolve menu
200+
*
201+
* @param array $files Array of files to list
202+
* @param string $status Changed/Added/Deleted
203+
*
204+
* @return bool False to quit out of the whole process
205+
*/
206+
protected function resolveMenu(string $file, string $status): bool
207+
{
208+
$codex = $this->patches->getCodex();
209+
210+
CLI::write(lang('Patches.conflict' . ucfirst($status)));
211+
CLI::write($file);
212+
213+
CLI::write('(D)isplay diff');
214+
CLI::write('(O)verwrite');
215+
CLI::write('(S)kip');
216+
CLI::write('(Q)uit');
217+
218+
switch (CLI::prompt('Selection?', ['d', 'o', 's', 'q']))
219+
{
220+
case 's':
221+
return true;
222+
break;
223+
224+
case 'q':
225+
return false;
226+
break;
227+
228+
case 'd':
229+
CLI::write($this->patches->diffFile($file));
230+
return $this->resolveMenu($file, $status);
231+
break;
232+
233+
case 'o':
234+
$current = $codex->workspace . 'current/' . $file;
235+
$project = $codex->config->rootPath . $file;
236+
237+
if ($status == 'Deleted')
238+
{
239+
unlink($project);
240+
}
241+
// Copy over the existing file
242+
else
243+
{
244+
copy_path($current, $project);
245+
}
246+
247+
return true;
248+
break;
249+
}
250+
251+
return true;
252+
}
253+
136254
/**
137255
* Display files in a table list.
138256
*
@@ -154,11 +272,31 @@ protected function showFiles(array $files, string $status): self
154272

155273
foreach ($files as $file)
156274
{
157-
$tbody[] = [$file, $status, ''];
275+
// Get the number of changes
276+
$diff = $this->patches->diffFile($file);
277+
278+
$tbody[] = [$file, $status, $diff ? count(explode("\n", $diff)) : 0];
158279
}
159280

160281
CLI::table($tbody, $thead);
161282

162283
return $this;
163284
}
285+
286+
/**
287+
* Write out the Codex and quit.
288+
*
289+
* @return $this
290+
*/
291+
protected function complete(): self
292+
{
293+
// Write out the Codex
294+
$codex = $this->patches->getCodex();
295+
$codex->save();
296+
297+
CLI::write('Workspace with codex and files:');
298+
CLI::write($codex->workspace);
299+
300+
return $this;
301+
}
164302
}

src/Language/en/Patches.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,7 @@
22

33
return [
44
'composerFailure' => 'Composer failed with error code {0}',
5+
'conflictChanged' => 'This file was changed but your copy does not match the original.',
6+
'conflictAdded' => 'This file was added but you already have a file there that does not match.',
7+
'conflictDeleted' => 'This file was deleted but your copy does not match the original.',
58
];

src/Patches.php

Lines changed: 18 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -328,35 +328,22 @@ public function copyPaths(string $destination): array
328328
*
329329
* @param string $file Relative path to the file
330330
*
331-
* @return array [diff content, percent changed]
331+
* @return string The diff
332332
*/
333-
public function diffFile(string $file): array
333+
public function diffFile(string $file): string
334334
{
335335
if (is_null($this->differ))
336336
{
337-
$this->differ = new Differ(new DiffOnlyOutputBuilder());
337+
$this->differ = new Differ(new DiffOnlyOutputBuilder(''));
338338
}
339339

340340
$file1 = $this->codex->workspace . 'legacy/' . $file;
341341
$file2 = $this->codex->workspace . 'current/' . $file;
342342

343-
if (! is_file($file1) && ! is_file($file2))
344-
{
345-
return ['', 0];
346-
}
347-
elseif (! is_file($file1))
348-
{
349-
return [file_get_contents($file2), 100];
350-
}
351-
elseif (! is_file($file2))
352-
{
353-
return [file_get_contents($file1), 100];
354-
}
343+
$contents1 = is_file($file1) ? file_get_contents($file1) : '';
344+
$contents2 = is_file($file2) ? file_get_contents($file2) : '';
355345

356-
$contents = file_get_contents($file2);
357-
$diff = $this->differ->diff(file_get_contents($file1), $contents);
358-
359-
return [$diff, round(strlen($diff) / 2 / strlen($contents) * 100, 1)];
346+
return $this->differ->diff($contents1, $contents2);
360347
}
361348

362349
/**
@@ -451,13 +438,16 @@ public function afterUpdate(): self
451438
// Update the array of legacy files to match the new filtered list
452439
$this->codex->legacyFiles = array_diff($this->codex->legacyFiles, $unchangedFiles);
453440

454-
$s = $this->codex->changedFiles == 1 ? '' : 's';
441+
$s = count($this->codex->changedFiles) == 1 ? '' : 's';
455442
$this->status(count($this->codex->changedFiles) . " changed file{$s} detected");
456443

444+
$s = count($this->codex->addedFiles) == 1 ? '' : 's';
445+
$this->status(count($this->codex->addedFiles) . " added file{$s} detected");
446+
457447
// Check for files that have been deleted
458448
$this->codex->deletedFiles = array_diff($this->codex->legacyFiles, $this->codex->changedFiles);
459449

460-
$s = $this->codex->deletedFiles == 1 ? '' : 's';
450+
$s = count($this->codex->deletedFiles) == 1 ? '' : 's';
461451
$this->status(count($this->codex->deletedFiles) . " deleted file{$s} detected");
462452

463453
return $this;
@@ -485,9 +475,15 @@ public function merge(): bool
485475
return false;
486476
}
487477

488-
$s = $this->codex->mergedFiles == 1 ? '' : 's';
478+
$s = count($this->codex->mergedFiles) == 1 ? '' : 's';
489479
$this->status(count($this->codex->mergedFiles) . " file{$s} merged");
490480

481+
$conflicts = count($this->codex->conflicts['changed'])
482+
+ count($this->codex->conflicts['added'])
483+
+ count($this->codex->conflicts['deleted']);
484+
$s = $conflicts == 1 ? '' : 's';
485+
$this->status($conflicts . " conflict{$s} detected");
486+
491487
// If events are allowed then trigger postpatch
492488
if ($this->codex->config->allowEvents)
493489
{

tests/unit/LibraryTest.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,4 +102,19 @@ public function testCopyPathsReturnsPaths()
102102

103103
$this->assertEquals($expected, $paths);
104104
}
105+
106+
public function testDiffFileReturnsExpectedValue()
107+
{
108+
$patches = new Patches($this->config);
109+
$patches->run();
110+
$codex = $patches->getCodex();
111+
112+
$file = $codex->addedFiles[0];
113+
file_put_contents($codex->workspace . 'legacy/' . $file, "0123456789\nabcdefghij");
114+
file_put_contents($codex->workspace . 'current/' . $file, "0123456789aba\nabcdefghij\nxyz");
115+
116+
$expected = "-0123456789\n-abcdefghij\n+0123456789aba\n+abcdefghij\n+xyz\n";
117+
118+
$this->assertEquals($expected, $patches->diffFile($file));
119+
}
105120
}

0 commit comments

Comments
 (0)