diff --git a/app/Commands/Docker.php b/app/Commands/Docker.php index 30dde4be..3eaded25 100644 --- a/app/Commands/Docker.php +++ b/app/Commands/Docker.php @@ -92,7 +92,9 @@ public function handle( Runner $runner, ResultRecorder $recorder, PermissionMana ->tty( $tty ) ->run( $command ); - $recorder->add( $response->process()->getOutput() ); + $output = $response->process()->getOutput() ?: $response->process()->getErrorOutput(); + + $recorder->add( trim( (string) $output ) ); return $response->ok() ? self::SUCCESS : self::FAILURE; } diff --git a/app/Commands/DockerCompose.php b/app/Commands/DockerCompose.php index fbd71d59..7522471d 100644 --- a/app/Commands/DockerCompose.php +++ b/app/Commands/DockerCompose.php @@ -103,7 +103,9 @@ public function handle( Runner $runner, Network $network, ResultRecorder $record ] ) ->run( $command ); - $recorder->add( $response->process()->getOutput() ); + $output = $response->process()->getOutput() ?: $response->process()->getErrorOutput(); + + $recorder->add( trim( (string) $output ) ); return $response->ok() ? self::SUCCESS : self::FAILURE; } diff --git a/app/Commands/LocalDocker/MigrateDomain.php b/app/Commands/LocalDocker/MigrateDomain.php index 911837b4..2cc1c5f1 100644 --- a/app/Commands/LocalDocker/MigrateDomain.php +++ b/app/Commands/LocalDocker/MigrateDomain.php @@ -2,10 +2,11 @@ namespace App\Commands\LocalDocker; -use Exception; +use App\Exceptions\DockerException; +use App\Exceptions\SystemExitException; use App\Recorders\ResultRecorder; use App\Services\Docker\Local\Config; -use App\Exceptions\SystemExitException; +use Exception; use Illuminate\Support\Facades\Artisan; /** @@ -36,12 +37,12 @@ class MigrateDomain extends BaseLocalDocker { * @param \App\Recorders\ResultRecorder $recorder * * @throws \App\Exceptions\SystemExitException - * @throws \Exception - * @return void + * @throws \Exception|\App\Exceptions\DockerException * + * @return int */ - public function handle( Config $config, ResultRecorder $recorder ): void { - Artisan::call( Wp::class, [ + public function handle( Config $config, ResultRecorder $recorder ): int { + $result = Artisan::call( Wp::class, [ 'args' => [ 'db', 'prefix', @@ -50,9 +51,13 @@ public function handle( Config $config, ResultRecorder $recorder ): void { '--quiet' => true, ] ); - $dbPrefix = trim( $recorder->first() ); + if ( $result === self::FAILURE ) { + throw new DockerException( $recorder->first() ); + } - Artisan::call( Wp::class, [ + $dbPrefix = $recorder->first(); + + $result = Artisan::call( Wp::class, [ 'args' => [ 'db', 'query', @@ -63,11 +68,15 @@ public function handle( Config $config, ResultRecorder $recorder ): void { '--quiet' => true, ] ); - $domain = trim( $recorder->offsetGet( 1 ) ); + if ( $result === self::FAILURE ) { + throw new DockerException( $recorder->offsetGet( 1 ) ); + } + + $domain = $recorder->offsetGet( 1 ); $sourceDomain = parse_url( $domain, PHP_URL_HOST ); if ( empty( $sourceDomain ) ) { - throw new Exception( sprintf( 'Invalid siteurl found in options table: %s', $domain ) ); + throw new Exception( sprintf( 'Invalid siteurl found in options table: "%s". Verify your project is using the same table_prefix as the imported database.', $domain ) ); } $targetDomain = $config->getProjectDomain(); @@ -111,6 +120,8 @@ public function handle( Config $config, ResultRecorder $recorder ): void { ] ); $this->info( 'Done.' ); + + return self::SUCCESS; } } diff --git a/app/Commands/LocalDocker/Wp.php b/app/Commands/LocalDocker/Wp.php index 1fe5c8e8..fd42bb34 100644 --- a/app/Commands/LocalDocker/Wp.php +++ b/app/Commands/LocalDocker/Wp.php @@ -41,15 +41,15 @@ class Wp extends BaseLocalDocker { * @param \App\Services\XdebugValidator $xdebugValidator * @param \App\Services\Docker\Container $container * - * @return int|null + * @return int */ - public function handle( Config $config, XdebugValidator $xdebugValidator, Container $container ): ?int { - $params = [ + public function handle( Config $config, XdebugValidator $xdebugValidator, Container $container ): int { + $params = array_filter( [ 'exec', ! $this->option( 'notty' ) ? '--tty' : '', '-w', $config->getWorkdir(), - ]; + ] ); if ( $this->option( 'xdebug' ) ) { @@ -79,7 +79,7 @@ public function handle( Config $config, XdebugValidator $xdebugValidator, Contai $params = array_merge( $params, $env, [ $containerId ], $exec, $this->argument( 'args' ) ); - return Artisan::call( Docker::class, $params ); + return (int) Artisan::call( Docker::class, $params ); } } diff --git a/app/Exceptions/DockerException.php b/app/Exceptions/DockerException.php new file mode 100644 index 00000000..2d0998a9 --- /dev/null +++ b/app/Exceptions/DockerException.php @@ -0,0 +1,12 @@ + app('git.version'), - 'version' => '5.6.2', + 'version' => '5.6.3', /* |-------------------------------------------------------------------------- diff --git a/tests/Feature/Commands/LocalDocker/MigrateDomainTest.php b/tests/Feature/Commands/LocalDocker/MigrateDomainTest.php index 0bd0e5da..13bfcccc 100644 --- a/tests/Feature/Commands/LocalDocker/MigrateDomainTest.php +++ b/tests/Feature/Commands/LocalDocker/MigrateDomainTest.php @@ -1,15 +1,17 @@ -wpCommand->shouldReceive( 'call' ) ->with( Wp::class, [ - 'args' => [ + 'args' => [ 'db', 'query', "UPDATE tribe_options SET option_value = REPLACE( option_value, 'test.com', 'test.tribe' ) WHERE option_name = 'siteurl'", @@ -61,7 +63,7 @@ public function test_it_calls_migrate_domain_command() { $this->wpCommand->shouldReceive( 'call' ) ->with( Wp::class, [ - 'args' => [ + 'args' => [ 'search-replace', 'test.com', 'test.tribe', @@ -72,7 +74,7 @@ public function test_it_calls_migrate_domain_command() { $this->wpCommand->shouldReceive( 'call' ) ->with( Wp::class, [ - 'args' => [ + 'args' => [ 'cache', 'flush', ], @@ -90,7 +92,7 @@ public function test_it_calls_migrate_domain_command() { $this->assertStringContainsString( 'Done.', $tester->getDisplay() ); } - public function test_it_throws_exeception_on_invalid_site_url() { + public function test_it_throws_an_exception_on_invalid_site_url() { $this->expectException( Exception::class ); $this->expectExceptionMessage( 'Invalid siteurl found in options table:' ); @@ -124,14 +126,12 @@ public function test_it_throws_exeception_on_invalid_site_url() { $command = $this->app->make( MigrateDomain::class ); - $tester = $this->runCommand( $command, [], [ + $this->runCommand( $command, [], [ 'Ready to search and replace "https://test.com" to "https://test.tribe" (This cannot be undone)?' => 'yes', ] ); - - $this->assertSame( 1, $tester->getStatusCode() ); } - public function test_it_throws_exception_on_matching_domains() { + public function test_it_throws_an_exception_on_matching_domains() { $this->expectException( Exception::class ); $this->expectExceptionMessage( 'Error: Source and target domains match:' ); @@ -166,14 +166,12 @@ public function test_it_throws_exception_on_matching_domains() { $command = $this->app->make( MigrateDomain::class ); - $tester = $this->runCommand( $command, [], [ + $this->runCommand( $command, [], [ 'Ready to search and replace "https://test.com" to "https://test.tribe" (This cannot be undone)?' => 'yes', ] ); - - $this->assertSame( 1, $tester->getStatusCode() ); } - public function test_it_throws_exception_on_no_confirmation() { + public function test_it_throws_an_exception_on_no_confirmation() { $this->expectException( SystemExitException::class ); $this->expectExceptionMessage( 'Cancelling' ); @@ -208,11 +206,71 @@ public function test_it_throws_exception_on_no_confirmation() { $command = $this->app->make( MigrateDomain::class ); - $tester = $this->runCommand( $command, [], [ + $this->runCommand( $command, [], [ 'Ready to search and replace "https://test.com" to "https://test.tribe" (This cannot be undone)?' => 'no', ] ); + } + + public function test_it_throws_an_exception_on_db_prefix_docker_error() { + $this->expectException( DockerException::class ); + + $this->wpCommand->shouldReceive( 'call' ) + ->with( Wp::class, [ + 'args' => [ + 'db', + 'prefix', + ], + '--notty' => true, + '--quiet' => true, + ] )->andReturn( Command::FAILURE ); + + $this->recorder->shouldReceive( 'first' )->andReturn( 'Error: No such container:' ); + + Artisan::swap( $this->wpCommand ); + + $command = $this->app->make( MigrateDomain::class ); + + $this->runCommand( $command, [], [ + 'Ready to search and replace "https://test.com" to "https://test.tribe" (This cannot be undone)?' => 'yes', + ] ); + } + + public function test_it_throws_an_exception_on_domain_site_url() { + $this->expectException( DockerException::class ); - $this->assertSame( 1, $tester->getStatusCode() ); + $this->wpCommand->shouldReceive( 'call' ) + ->with( Wp::class, [ + 'args' => [ + 'db', + 'prefix', + ], + '--notty' => true, + '--quiet' => true, + ] ); + + $this->recorder->shouldReceive( 'first' )->andReturn( 'tribe_' ); + + $this->wpCommand->shouldReceive( 'call' ) + ->with( Wp::class, [ + 'args' => [ + 'db', + 'query', + "SELECT option_value FROM tribe_options WHERE option_name = 'siteurl'", + '--skip-column-names', + ], + '--notty' => true, + '--quiet' => true, + ] )->andReturn( Command::FAILURE ); + + $this->recorder->shouldReceive( 'offsetGet' )->with( 1 )->andReturn( 'Error: No such container:' ); + + Artisan::swap( $this->wpCommand ); + + $command = $this->app->make( MigrateDomain::class ); + + $this->runCommand( $command, [], [ + 'Ready to search and replace "https://test.com" to "https://test.tribe" (This cannot be undone)?' => 'yes', + ] ); } } diff --git a/tests/Feature/Commands/LocalDocker/WpTest.php b/tests/Feature/Commands/LocalDocker/WpTest.php index 34bbe34a..81834299 100644 --- a/tests/Feature/Commands/LocalDocker/WpTest.php +++ b/tests/Feature/Commands/LocalDocker/WpTest.php @@ -65,7 +65,6 @@ public function test_it_calls_local_wp_command_with_options() { $this->docker->shouldReceive( 'call' )->with( Docker::class, [ 'exec', - '', '-w', '/application/www', '--env', @@ -110,7 +109,6 @@ public function test_it_warns_the_user_if_xdebug_is_not_correctly_configured() { $this->docker->shouldReceive( 'call' )->with( Docker::class, [ 'exec', - '', '-w', '/application/www', '--env',