Skip to content

Commit 186a011

Browse files
authored
Merge pull request #3 from digital-entropy/patch
Patchwork
2 parents 70fa8b3 + 8946ce4 commit 186a011

File tree

4 files changed

+94
-50
lines changed

4 files changed

+94
-50
lines changed

README.md

+36-19
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,7 @@ LARAVEL PATCHER
77

88
#### Requirements:
99
* PHP : 8.\*
10-
* Laravel: 9.\*
11-
12-
##### Background :
13-
Once upon a time, our team do a stupid thing that affect our production database.
14-
It was happens many times, and we are usually go tinkering or direct edit on a
15-
database to fix those problems.
16-
Then, our team leader [Rifki Alhuraibi](https://github.com/veelasky/) comes up with
17-
the idea about the package that handle history change of our patch activity (like the
18-
one in database migration), so we made this package.
19-
Also, we commonly need to bulk insert data to our application, this package also help
20-
us in those activity.
10+
* Laravel: 9.\*
2111

2212
### INSTALLATION
2313
do either of this methods below.
@@ -29,7 +19,6 @@ composer require dentro/laravel-patcher
2919
```json
3020
{
3121
"require": {
32-
...
3322
"dentro/laravel-patcher": "^1.0"
3423
}
3524
}
@@ -53,16 +42,10 @@ Those file will be like:
5342
```php
5443
<?php
5544

56-
use Jalameta\Patcher\Patch;
45+
use Dentro\Patcher\Patch;
5746

5847
class WhatDoYouWantToPatch extends Patch
5948
{
60-
/**
61-
* Run patch script.
62-
*
63-
* @return void
64-
* @throws \Exception
65-
*/
6649
public function patch()
6750
{
6851
//
@@ -126,3 +109,37 @@ Patching: 2020_10_09_124616_add_attachment_beep
126109
Patched: 2020_10_09_124616_add_attachment_beep (0.06 seconds)
127110
```
128111

112+
#### SKIPPING THE PATCH
113+
You might need to skip single patch when run ```php artisan patcher:run```.
114+
Due to patch is unnecessary or patch is not eligible to run in your environment.
115+
Here you can add the ```eligible``` method to your patch class to evaluate the condition
116+
before running the ```patch``` method.
117+
118+
```php
119+
<?php
120+
121+
use Dentro\Patcher\Patch;
122+
use App\Models\User;
123+
124+
class WhatDoYouWantToPatch extends Patch
125+
{
126+
public function eligible(): bool
127+
{
128+
return User::query()->where('id', 331)->exists();
129+
}
130+
131+
public function patch()
132+
{
133+
$user = User::query()->find(331);
134+
// do something with user.
135+
}
136+
}
137+
```
138+
then the output of ```php artisan patcher:run``` will be:
139+
```shell script
140+
➜ php artisan patcher:run
141+
Patching: 2020_09_29_190531_fix_double_sections
142+
Skipped: 2020_09_29_190531_fix_double_sections is not eligible to run in current condition.
143+
Patching: 2020_10_09_124616_add_attachment_beep
144+
Patched: 2020_10_09_124616_add_attachment_beep (0.06 seconds)
145+
```

src/Console/PatchCommand.php

-3
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,6 @@
33
namespace Dentro\Patcher\Console;
44

55
use Illuminate\Console\ConfirmableTrait;
6-
use Illuminate\Database\SQLiteConnection;
7-
use Illuminate\Database\Events\SchemaLoaded;
8-
use Illuminate\Database\SqlServerConnection;
96
use Illuminate\Database\Console\Migrations\MigrateCommand;
107

118
class PatchCommand extends MigrateCommand

src/Patch.php

+18-8
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use Illuminate\Console\Command;
66
use Illuminate\Container\Container;
77
use Illuminate\Database\Migrations\Migration;
8+
use Illuminate\Log\Logger;
89

910
abstract class Patch extends Migration
1011
{
@@ -13,29 +14,28 @@ abstract class Patch extends Migration
1314
*
1415
* @var \Illuminate\Console\Command
1516
*/
16-
protected $command;
17+
protected Command $command;
1718

1819
/**
1920
* The container instance.
2021
*
2122
* @var \Illuminate\Container\Container
2223
*/
23-
protected $container;
24+
protected Container $container;
2425

2526
/**
2627
* Logger.
2728
*
2829
* @var \Illuminate\Log\Logger
2930
*/
30-
protected $logger;
31+
protected Logger $logger;
3132

3233
/**
33-
* Patch constructor.
34+
* Enables, if supported, wrapping the patch within a transaction.
35+
*
36+
* @var bool
3437
*/
35-
public function __construct()
36-
{
37-
$this->logger = app('log')->driver(PatcherServiceProvider::$LOG_CHANNEL);
38-
}
38+
public $withinTransaction = false;
3939

4040
/**
4141
* Run patch script.
@@ -69,4 +69,14 @@ public function setContainer(Container $container): Patch
6969

7070
return $this;
7171
}
72+
73+
/**
74+
* Set Logger instance.
75+
*
76+
* @param \Illuminate\Log\Logger $logger
77+
*/
78+
public function setLogger(Logger $logger): void
79+
{
80+
$this->logger = $logger;
81+
}
7282
}

src/Patcher.php

+40-20
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,10 @@ public function runPending(array $migrations, array $options = []): void
2727

2828
$batch = $this->repository->getNextBatchNumber();
2929

30-
$pretend = $options['pretend'] ?? false;
31-
3230
$step = $options['step'] ?? false;
3331

3432
foreach ($migrations as $file) {
35-
$this->patch($file, $batch, $pretend);
33+
$this->patch($file, $batch);
3634

3735
if ($step) {
3836
$batch++;
@@ -45,40 +43,60 @@ public function runPending(array $migrations, array $options = []): void
4543
*
4644
* @param string $file
4745
* @param int $batch
48-
* @param bool $pretend
49-
*
5046
* @return void
5147
* @throws \Throwable
5248
*/
53-
protected function patch(string $file, int $batch, bool $pretend): void
49+
protected function patch(string $file, int $batch): void
5450
{
55-
$migration = $this->resolvePath($file);
51+
$patch = $this->resolvePath($file);
5652

5753
$name = $this->getMigrationName($file);
5854

59-
$migration->setContainer(app())->setCommand(app('command.patcher'));
60-
61-
$this->note("<comment>Patching:</comment> {$name}");
55+
$this->note("<comment>Patching:</comment> $name");
6256

6357
$startTime = microtime(true);
6458

65-
$this->runPatch($migration);
59+
if ($patch instanceof Patch && $this->isEligible($patch)) {
60+
$patch
61+
->setContainer(app())
62+
->setCommand(app('command.patcher'))
63+
->setLogger(app('log')->driver(PatcherServiceProvider::$LOG_CHANNEL));
64+
65+
$this->runPatch($patch);
6666

67-
$runTime = round(microtime(true) - $startTime, 2);
67+
$runTime = round(microtime(true) - $startTime, 2);
68+
69+
$this->repository->log($name, $batch);
70+
71+
$this->note("<info>Patched:</info> $name ($runTime seconds).");
72+
} else {
73+
$this->note("<comment>Skipped:</comment> $name is not eligible to run in current condition.");
74+
}
75+
}
6876

69-
$this->repository->log($name, $batch);
77+
/**
78+
* Determine if patcher should run.
79+
*
80+
* @param \Dentro\Patcher\Patch $patch
81+
* @return bool
82+
*/
83+
public function isEligible(Patch $patch): bool
84+
{
85+
if (method_exists($patch, 'eligible')) {
86+
return $patch->eligible();
87+
}
7088

71-
$this->note("<info>Patched:</info> {$name} ({$runTime} seconds)");
89+
return true;
7290
}
7391

7492
/**
7593
* Run a migration inside a transaction if the database supports it.
7694
*
77-
* @param object $patch
95+
* @param \Dentro\Patcher\Patch $patch
7896
* @return void
7997
* @throws \Throwable
8098
*/
81-
protected function runPatch(object $patch): void
99+
protected function runPatch(Patch $patch): void
82100
{
83101
$connection = $this->resolveConnection(
84102
$patch->getConnection()
@@ -102,9 +120,11 @@ protected function runPatch(object $patch): void
102120
}
103121
};
104122

105-
$this->getSchemaGrammar($connection)->supportsSchemaTransactions()
106-
&& $patch->withinTransaction
107-
? $connection->transaction($callback)
108-
: $callback();
123+
if ($patch->withinTransaction && $this->getSchemaGrammar($connection)->supportsSchemaTransactions()) {
124+
$connection->transaction($callback);
125+
return;
126+
}
127+
128+
$callback();
109129
}
110130
}

0 commit comments

Comments
 (0)