Skip to content

Commit 2d4c9bb

Browse files
committed
Prevent destructive commands from running
1 parent 42e6bda commit 2d4c9bb

File tree

7 files changed

+100
-4
lines changed

7 files changed

+100
-4
lines changed
+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<?php
2+
3+
namespace Illuminate\Console;
4+
5+
use function Laravel\Prompts\confirm;
6+
7+
trait Preventable
8+
{
9+
protected static $preventFromRunning = false;
10+
11+
/**
12+
* Whether to prevent command from running.
13+
*
14+
* @param bool $prevent
15+
* @return bool
16+
*/
17+
public static function preventFromRunning($prevent = true)
18+
{
19+
static::$preventFromRunning = $prevent;
20+
}
21+
22+
/**
23+
* Determine if the command is prevented from
24+
* running and display a warning if so.
25+
*
26+
* @return bool
27+
*/
28+
protected function preventedFromRunning()
29+
{
30+
if (! static::$preventFromRunning) {
31+
return false;
32+
}
33+
34+
$this->components->warn('Command has been prevented from running in this environment.');
35+
36+
return true;
37+
}
38+
}

src/Illuminate/Database/Console/Migrations/FreshCommand.php

+6-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
use Illuminate\Console\Command;
66
use Illuminate\Console\ConfirmableTrait;
7+
use Illuminate\Console\Preventable;
78
use Illuminate\Contracts\Events\Dispatcher;
89
use Illuminate\Database\Events\DatabaseRefreshed;
910
use Illuminate\Database\Migrations\Migrator;
@@ -13,7 +14,7 @@
1314
#[AsCommand(name: 'migrate:fresh')]
1415
class FreshCommand extends Command
1516
{
16-
use ConfirmableTrait;
17+
use ConfirmableTrait, Preventable;
1718

1819
/**
1920
* The console command name.
@@ -56,6 +57,10 @@ public function __construct(Migrator $migrator)
5657
*/
5758
public function handle()
5859
{
60+
if ($this->preventedFromRunning()) {
61+
return 1;
62+
}
63+
5964
if (! $this->confirmToProceed()) {
6065
return 1;
6166
}

src/Illuminate/Database/Console/Migrations/RefreshCommand.php

+6-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
use Illuminate\Console\Command;
66
use Illuminate\Console\ConfirmableTrait;
7+
use Illuminate\Console\Preventable;
78
use Illuminate\Contracts\Events\Dispatcher;
89
use Illuminate\Database\Events\DatabaseRefreshed;
910
use Symfony\Component\Console\Attribute\AsCommand;
@@ -12,7 +13,7 @@
1213
#[AsCommand(name: 'migrate:refresh')]
1314
class RefreshCommand extends Command
1415
{
15-
use ConfirmableTrait;
16+
use ConfirmableTrait, Preventable;
1617

1718
/**
1819
* The console command name.
@@ -35,6 +36,10 @@ class RefreshCommand extends Command
3536
*/
3637
public function handle()
3738
{
39+
if ($this->preventedFromRunning()) {
40+
return 1;
41+
}
42+
3843
if (! $this->confirmToProceed()) {
3944
return 1;
4045
}

src/Illuminate/Database/Console/Migrations/ResetCommand.php

+6-1
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,15 @@
33
namespace Illuminate\Database\Console\Migrations;
44

55
use Illuminate\Console\ConfirmableTrait;
6+
use Illuminate\Console\Preventable;
67
use Illuminate\Database\Migrations\Migrator;
78
use Symfony\Component\Console\Attribute\AsCommand;
89
use Symfony\Component\Console\Input\InputOption;
910

1011
#[AsCommand(name: 'migrate:reset')]
1112
class ResetCommand extends BaseCommand
1213
{
13-
use ConfirmableTrait;
14+
use ConfirmableTrait, Preventable;
1415

1516
/**
1617
* The console command name.
@@ -53,6 +54,10 @@ public function __construct(Migrator $migrator)
5354
*/
5455
public function handle()
5556
{
57+
if ($this->preventedFromRunning()) {
58+
return 1;
59+
}
60+
5661
if (! $this->confirmToProceed()) {
5762
return 1;
5863
}

src/Illuminate/Database/Console/WipeCommand.php

+6-1
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,14 @@
44

55
use Illuminate\Console\Command;
66
use Illuminate\Console\ConfirmableTrait;
7+
use Illuminate\Console\Preventable;
78
use Symfony\Component\Console\Attribute\AsCommand;
89
use Symfony\Component\Console\Input\InputOption;
910

1011
#[AsCommand(name: 'db:wipe')]
1112
class WipeCommand extends Command
1213
{
13-
use ConfirmableTrait;
14+
use ConfirmableTrait, Preventable;
1415

1516
/**
1617
* The console command name.
@@ -33,6 +34,10 @@ class WipeCommand extends Command
3334
*/
3435
public function handle()
3536
{
37+
if ($this->preventedFromRunning()) {
38+
return 1;
39+
}
40+
3641
if (! $this->confirmToProceed()) {
3742
return 1;
3843
}

tests/Database/DatabaseMigrationRefreshCommandTest.php

+21
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,27 @@ public function testRefreshCommandCallsCommandsWithStep()
7272
$this->runCommand($command, ['--step' => 2]);
7373
}
7474

75+
public function testRefreshCommandExitsWhenPrevented()
76+
{
77+
$command = new RefreshCommand;
78+
79+
$app = new ApplicationDatabaseRefreshStub(['path.database' => __DIR__]);
80+
$dispatcher = $app->instance(Dispatcher::class, $events = m::mock());
81+
$console = m::mock(ConsoleApplication::class)->makePartial();
82+
$console->__construct();
83+
$command->setLaravel($app);
84+
$command->setApplication($console);
85+
86+
RefreshCommand::preventFromRunning();
87+
88+
$code = $this->runCommand($command);
89+
90+
$this->assertSame(1, $code);
91+
92+
$console->shouldNotHaveBeenCalled();
93+
$dispatcher->shouldNotReceive('dispatch');
94+
}
95+
7596
protected function runCommand($command, $input = [])
7697
{
7798
return $command->run(new ArrayInput($input), new NullOutput);

tests/Database/DatabaseMigrationResetCommandTest.php

+17
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,23 @@ public function testResetCommandCanBePretended()
5252
$this->runCommand($command, ['--pretend' => true, '--database' => 'foo']);
5353
}
5454

55+
public function testRefreshCommandExitsWhenPrevented()
56+
{
57+
$command = new ResetCommand($migrator = m::mock(Migrator::class));
58+
59+
$app = new ApplicationDatabaseResetStub(['path.database' => __DIR__]);
60+
$app->useDatabasePath(__DIR__);
61+
$command->setLaravel($app);
62+
63+
ResetCommand::preventFromRunning();
64+
65+
$code = $this->runCommand($command);
66+
67+
$this->assertSame(1, $code);
68+
69+
$migrator->shouldNotHaveBeenCalled();
70+
}
71+
5572
protected function runCommand($command, $input = [])
5673
{
5774
return $command->run(new ArrayInput($input), new NullOutput);

0 commit comments

Comments
 (0)