Skip to content
This repository was archived by the owner on Mar 20, 2025. It is now read-only.

Commit 4d85c93

Browse files
authored
Fix anonymous-migrations parsing beyond class declaration (#11)
1 parent cee60f6 commit 4d85c93

File tree

4 files changed

+105
-2
lines changed

4 files changed

+105
-2
lines changed

src/Tasks/AnonymousMigrations.php

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22

33
namespace Shift\Cli\Tasks;
44

5-
use Illuminate\Support\Str;
65
use Shift\Cli\Sdk\Contracts\Task;
6+
use Shift\Cli\Sdk\Models\File;
77
use Shift\Cli\Sdk\Traits\FindsFiles;
88

99
class AnonymousMigrations implements Task
@@ -22,6 +22,15 @@ public function perform(): int
2222
return 0;
2323
}
2424

25+
private function parseClass(string $contents)
26+
{
27+
static $finder;
28+
29+
$finder ??= new \Shift\Cli\Sdk\Parsers\NikicParser(new \Shift\Cli\Sdk\Parsers\Finders\ClassDefinition());
30+
31+
return $finder->parse($contents);
32+
}
33+
2534
private function updateMigrations(): void
2635
{
2736
foreach ($this->findFilesContaining('/\bclass\s+\S+\s+extends\s+Migration\s/') as $path) {
@@ -77,14 +86,22 @@ private function updateStubs(): void
7786

7887
private function convertClassDefinition($contents): ?string
7988
{
89+
$file = File::fromString($contents);
90+
$class = $this->parseClass($file->contents());
91+
8092
$found = \preg_match('/^class\s+(\S+)\s+extends\s+Migration(\s+)/m', $contents, $matches);
8193
if (! $found) {
8294
return null;
8395
}
96+
$contents = \substr_replace($contents,
97+
';',
98+
$class['offset']['end'] + 1,
99+
0
100+
);
84101

85102
$contents = \str_replace(\rtrim($matches[0]), 'return new class extends Migration', $contents);
86103
$contents = \preg_replace('/\b' . \preg_quote($matches[1], '/') . '::/', 'self::', $contents);
87104

88-
return Str::replaceLast('}', '};', $contents);
105+
return $contents;
89106
}
90107
}

tests/Feature/Tasks/AnonymousMigrationsTest.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,4 +54,18 @@ public function it_converts_migrations_and_stubs()
5454
$this->assertFileChanges('tests/fixtures/anonymous-migrations/simple.after.php', 'other/migrations/2014_10_12_000000_create_users_table.php');
5555
$this->assertFileChanges('tests/fixtures/anonymous-migrations/stub.after.php', 'stubs/migration.stub');
5656
}
57+
58+
#[Test]
59+
public function it_converts_with_comments_beyond_the_class()
60+
{
61+
$this->fakeProject([
62+
'database/migrations/2015_10_12_000000_create_users_table.php' => 'tests/fixtures/anonymous-migrations/post-class-comments.php',
63+
]);
64+
65+
$result = $this->subject->perform();
66+
67+
$this->assertSame(0, $result);
68+
69+
$this->assertFileChanges('tests/fixtures/anonymous-migrations/post-class-comments.after.php', 'database/migrations/2015_10_12_000000_create_users_table.php');
70+
}
5771
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<?php
2+
3+
use Illuminate\Database\Migrations\Migration;
4+
use Illuminate\Database\Schema\Blueprint;
5+
use Illuminate\Support\Facades\Schema;
6+
7+
return new class extends Migration
8+
{
9+
/**
10+
* Run the migrations.
11+
*
12+
* @return void
13+
*/
14+
public function up()
15+
{
16+
Schema::table('videos', function (Blueprint $table) {
17+
$table->integer('runtime')->nullable();
18+
});
19+
}
20+
21+
/**
22+
* Reverse the migrations.
23+
*
24+
* @return void
25+
*/
26+
public function down()
27+
{
28+
Schema::table('videos', function (Blueprint $table) {
29+
$table->dropColumn('runtime');
30+
});
31+
}
32+
};
33+
34+
/* a closing bracket in a comment here can confuse the parsing
35+
{ id: 1, name: "Doug" }
36+
*/
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<?php
2+
3+
use Illuminate\Database\Migrations\Migration;
4+
use Illuminate\Database\Schema\Blueprint;
5+
use Illuminate\Support\Facades\Schema;
6+
7+
class PostClassComments extends Migration
8+
{
9+
/**
10+
* Run the migrations.
11+
*
12+
* @return void
13+
*/
14+
public function up()
15+
{
16+
Schema::table('videos', function (Blueprint $table) {
17+
$table->integer('runtime')->nullable();
18+
});
19+
}
20+
21+
/**
22+
* Reverse the migrations.
23+
*
24+
* @return void
25+
*/
26+
public function down()
27+
{
28+
Schema::table('videos', function (Blueprint $table) {
29+
$table->dropColumn('runtime');
30+
});
31+
}
32+
}
33+
34+
/* a closing bracket in a comment here can confuse the parsing
35+
{ id: 1, name: "Doug" }
36+
*/

0 commit comments

Comments
 (0)