From 3223b6dc5173267ed26e5acaec93f0308cd73e29 Mon Sep 17 00:00:00 2001 From: flap152 Date: Sun, 1 Oct 2023 17:18:49 -0400 Subject: [PATCH 1/2] - Fix AnonymousMigrations parsing to account for } beyond the class delcaration (most probably in comments). - Added fixture and test case --- src/Tasks/AnonymousMigrations.php | 20 ++++++++++- .../Feature/Tasks/AnonymousMigrationsTest.php | 14 ++++++++ .../post-class-comments.after.php | 36 +++++++++++++++++++ .../post-class-comments.php | 36 +++++++++++++++++++ 4 files changed, 105 insertions(+), 1 deletion(-) create mode 100644 tests/fixtures/anonymous-migrations/post-class-comments.after.php create mode 100644 tests/fixtures/anonymous-migrations/post-class-comments.php diff --git a/src/Tasks/AnonymousMigrations.php b/src/Tasks/AnonymousMigrations.php index 7275669..9f437e5 100644 --- a/src/Tasks/AnonymousMigrations.php +++ b/src/Tasks/AnonymousMigrations.php @@ -4,6 +4,7 @@ use Illuminate\Support\Str; use Shift\Cli\Sdk\Contracts\Task; +use Shift\Cli\Sdk\Models\File; use Shift\Cli\Sdk\Traits\FindsFiles; class AnonymousMigrations implements Task @@ -22,6 +23,15 @@ public function perform(): int return 0; } + private function parseClass(string $contents) + { + static $finder; + + $finder ??= new \Shift\Cli\Sdk\Parsers\NikicParser(new \Shift\Cli\Sdk\Parsers\Finders\ClassDefinition()); + + return $finder->parse($contents); + } + private function updateMigrations(): void { foreach ($this->findFilesContaining('/\bclass\s+\S+\s+extends\s+Migration\s/') as $path) { @@ -77,14 +87,22 @@ private function updateStubs(): void private function convertClassDefinition($contents): ?string { + $file = File::fromString($contents); + $class = $this->parseClass($file->contents()); + $found = \preg_match('/^class\s+(\S+)\s+extends\s+Migration(\s+)/m', $contents, $matches); if (! $found) { return null; } + $contents = \substr_replace( $contents, + ';', + $class['offset']['end'] +1 , + 0 + ); $contents = \str_replace(\rtrim($matches[0]), 'return new class extends Migration', $contents); $contents = \preg_replace('/\b' . \preg_quote($matches[1], '/') . '::/', 'self::', $contents); - return Str::replaceLast('}', '};', $contents); + return $contents; } } diff --git a/tests/Feature/Tasks/AnonymousMigrationsTest.php b/tests/Feature/Tasks/AnonymousMigrationsTest.php index e069b76..d652a05 100644 --- a/tests/Feature/Tasks/AnonymousMigrationsTest.php +++ b/tests/Feature/Tasks/AnonymousMigrationsTest.php @@ -54,4 +54,18 @@ public function it_converts_migrations_and_stubs() $this->assertFileChanges('tests/fixtures/anonymous-migrations/simple.after.php', 'other/migrations/2014_10_12_000000_create_users_table.php'); $this->assertFileChanges('tests/fixtures/anonymous-migrations/stub.after.php', 'stubs/migration.stub'); } + + #[Test] + public function it_converts_with_comments_beyond_the_class() + { + $this->fakeProject([ + 'database/migrations/2015_10_12_000000_create_users_table.php' => 'tests/fixtures/anonymous-migrations/post-class-comments.php', + ]); + + $result = $this->subject->perform(); + + $this->assertSame(0, $result); + + $this->assertFileChanges('tests/fixtures/anonymous-migrations/post-class-comments.after.php', 'database/migrations/2015_10_12_000000_create_users_table.php'); + } } diff --git a/tests/fixtures/anonymous-migrations/post-class-comments.after.php b/tests/fixtures/anonymous-migrations/post-class-comments.after.php new file mode 100644 index 0000000..6a0ddfc --- /dev/null +++ b/tests/fixtures/anonymous-migrations/post-class-comments.after.php @@ -0,0 +1,36 @@ +integer('runtime')->nullable(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('videos', function (Blueprint $table) { + $table->dropColumn('runtime'); + }); + } +}; + +/* a closing bracket in a comment here can confuse the parsing +{ id: 1, name: "Doug" } +*/ diff --git a/tests/fixtures/anonymous-migrations/post-class-comments.php b/tests/fixtures/anonymous-migrations/post-class-comments.php new file mode 100644 index 0000000..e6773de --- /dev/null +++ b/tests/fixtures/anonymous-migrations/post-class-comments.php @@ -0,0 +1,36 @@ +integer('runtime')->nullable(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('videos', function (Blueprint $table) { + $table->dropColumn('runtime'); + }); + } +} + +/* a closing bracket in a comment here can confuse the parsing +{ id: 1, name: "Doug" } +*/ From 9987e271454f0880a7a90d07166a132b649a1461 Mon Sep 17 00:00:00 2001 From: flap152 Date: Thu, 19 Oct 2023 22:41:22 -0400 Subject: [PATCH 2/2] pint whitespace fixup --- src/Tasks/AnonymousMigrations.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/Tasks/AnonymousMigrations.php b/src/Tasks/AnonymousMigrations.php index 9f437e5..006a3df 100644 --- a/src/Tasks/AnonymousMigrations.php +++ b/src/Tasks/AnonymousMigrations.php @@ -2,7 +2,6 @@ namespace Shift\Cli\Tasks; -use Illuminate\Support\Str; use Shift\Cli\Sdk\Contracts\Task; use Shift\Cli\Sdk\Models\File; use Shift\Cli\Sdk\Traits\FindsFiles; @@ -94,9 +93,9 @@ private function convertClassDefinition($contents): ?string if (! $found) { return null; } - $contents = \substr_replace( $contents, + $contents = \substr_replace($contents, ';', - $class['offset']['end'] +1 , + $class['offset']['end'] + 1, 0 );