Skip to content

Commit 6da4b3d

Browse files
authored
Merge pull request #36 from larapack/single-files
Support single files
2 parents 8de41bb + 2854f07 commit 6da4b3d

File tree

4 files changed

+327
-13
lines changed

4 files changed

+327
-13
lines changed

src/Hooks.php

+66-12
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
namespace Larapack\Hooks;
44

55
use Carbon\Carbon;
6-
use Illuminate\Database\Migrations\Migrator;
76
use Illuminate\Filesystem\Filesystem;
87
use Illuminate\Foundation\Application;
98
use Symfony\Component\Console\Input\ArrayInput;
@@ -910,7 +909,13 @@ protected function migrateHook(Hook $hook)
910909
{
911910
$migrations = (array) $hook->getComposerHookKey('migrations', []);
912911

913-
$this->migrator->run($this->realPath($migrations, $hook->getPath().'/')->all());
912+
foreach ($migrations as $path) {
913+
if ($this->filesystem->isDirectory($hook->getPath().'/'.$path)) {
914+
$this->migrator->run($this->realPath([$path], $hook->getPath().'/')->all());
915+
} else {
916+
$this->migrator->runFiles($this->realPath([$path], $hook->getPath().'/')->all());
917+
}
918+
}
914919
}
915920

916921
/**
@@ -922,7 +927,13 @@ protected function unmigrateHook(Hook $hook)
922927
{
923928
$migrations = (array) $hook->getComposerHookKey('migrations', []);
924929

925-
$this->migrator->reset($this->realPath($migrations, $hook->getPath().'/')->all());
930+
foreach ($migrations as $path) {
931+
if ($this->filesystem->isDirectory($hook->getPath().'/'.$path)) {
932+
$this->migrator->reset($this->realPath([$path], $hook->getPath().'/')->all());
933+
} else {
934+
$this->migrator->resetFiles($this->realPath([$path], $hook->getPath().'/')->all());
935+
}
936+
}
926937
}
927938

928939
/**
@@ -968,10 +979,17 @@ protected function publishHook(Hook $hook, $force = false)
968979
continue;
969980
}
970981

971-
$allFiles = collect($this->filesystem->allFiles($realLocation))
972-
->map(function ($file) use ($realLocation) {
982+
if ($filesystem->isDirectory($realLocation)) {
983+
$allFiles = collect($filesystem->allFiles($realLocation))->map(function ($file) use ($realLocation) {
973984
return substr($file->getRealPath(), strlen($realLocation) + 1);
974985
});
986+
} else {
987+
$allFiles = collect([new \Symfony\Component\Finder\SplFileInfo(
988+
$realLocation,
989+
'',
990+
basename($realLocation)
991+
)]);
992+
}
975993

976994
$newFiles = $allFiles->filter(function ($filename) use ($publishPath, $filesystem) {
977995
return !$filesystem->exists($publishPath.'/'.$filename);
@@ -996,6 +1014,16 @@ protected function publishHook(Hook $hook, $force = false)
9961014

9971015
$newFiles->merge($updatedFiles)
9981016
->each(function ($filename) use ($realLocation, $publishPath, $filesystem) {
1017+
if (!$filesystem->isDirectory($realLocation)) {
1018+
$directory = substr($publishPath, 0, -strlen(basename($publishPath)));
1019+
1020+
if (!$filesystem->isDirectory($directory)) {
1021+
$filesystem->makeDirectory($directory, 0755, true, true);
1022+
}
1023+
1024+
return $filesystem->copy($realLocation, $publishPath);
1025+
}
1026+
9991027
$directory = substr($publishPath.'/'.$filename, 0, -strlen(basename($filename)));
10001028

10011029
if (!$filesystem->isDirectory($directory)) {
@@ -1028,17 +1056,33 @@ protected function unpublishHook(Hook $hook)
10281056
continue;
10291057
}
10301058

1031-
$allFiles = collect($this->filesystem->allFiles($realLocation))
1032-
->map(function ($file) use ($realLocation) {
1033-
return substr($file->getRealPath(), strlen($realLocation) + 1);
1034-
});
1059+
if ($filesystem->isDirectory($realLocation)) {
1060+
$allFiles = collect($this->filesystem->allFiles($realLocation))
1061+
->map(function ($file) use ($realLocation) {
1062+
return substr($file->getRealPath(), strlen($realLocation) + 1);
1063+
});
1064+
} else {
1065+
$allFiles = collect([new \Symfony\Component\Finder\SplFileInfo(
1066+
$realLocation,
1067+
'',
1068+
basename($realLocation)
1069+
)]);
1070+
}
10351071

10361072
$existingFiles = $allFiles->filter(function ($filename) use ($publishPath, $filesystem) {
1037-
return $filesystem->exists($publishPath.'/'.$filename);
1073+
if ($filesystem->isDirectory($publishPath)) {
1074+
return $filesystem->exists($publishPath.'/'.$filename);
1075+
}
1076+
1077+
return $filesystem->exists($publishPath);
10381078
});
10391079

10401080
$existingFiles->each(function ($filename) use ($publishPath, $filesystem) {
1041-
$filesystem->delete($publishPath.'/'.$filename);
1081+
if ($filesystem->isDirectory($publishPath)) {
1082+
return $filesystem->delete($publishPath.'/'.$filename);
1083+
}
1084+
1085+
$filesystem->delete($publishPath);
10421086
});
10431087
}
10441088
}
@@ -1055,7 +1099,17 @@ protected function runSeeders($folders, $basePath)
10551099

10561100
$this->realPath($folders, $basePath)
10571101
->each(function ($folder) use ($filesystem) {
1058-
collect($filesystem->files($folder))->filter(function ($file) {
1102+
if ($filesystem->isDirectory($folder)) {
1103+
$files = $filesystem->files($folder);
1104+
} else {
1105+
$files = [new \Symfony\Component\Finder\SplFileInfo(
1106+
$folder,
1107+
'',
1108+
basename($folder)
1109+
)];
1110+
}
1111+
1112+
collect($files)->filter(function ($file) {
10591113
return $file->getExtension() == 'php';
10601114
})->each(function ($file) {
10611115
$class = substr($file->getFilename(), 0, -4);

src/HooksServiceProvider.php

+11-1
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,21 @@ public function register()
3434
// Register Hooks system and aliases
3535
$this->app->singleton(Hooks::class, function ($app) {
3636
$filesystem = $app[Filesystem::class];
37-
$migrator = $app['migrator'];
37+
$migrator = $app[Migrator::class];
3838

3939
return new Hooks($filesystem, $migrator);
4040
});
41+
4142
$this->app->alias(Hooks::class, 'hooks');
43+
44+
// The migrator is responsible for actually running and rollback the migration
45+
// files in the application. We'll pass in our database connection resolver
46+
// so the migrator can resolve any of these connections when it needs to.
47+
$this->app->singleton(Migrator::class, function ($app) {
48+
$repository = $app['migration.repository'];
49+
50+
return new Migrator($repository, $app['db'], $app['files']);
51+
});
4252
}
4353

4454
/**

src/Migrator.php

+97
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
<?php
2+
3+
namespace Larapack\Hooks;
4+
5+
use Illuminate\Database\Migrations\Migrator as BaseMigrator;
6+
use Illuminate\Support\Arr;
7+
8+
/*
9+
use Illuminate\Support\Str;
10+
use Illuminate\Support\Collection;
11+
use Illuminate\Filesystem\Filesystem;
12+
use Illuminate\Database\ConnectionResolverInterface as Resolver;
13+
*/
14+
15+
class Migrator extends BaseMigrator
16+
{
17+
public function runFiles(array $files, array $options = [])
18+
{
19+
$this->notes = [];
20+
21+
$this->requireFiles($migrations = $this->pendingMigrations(
22+
$files, $this->repository->getRan()
23+
));
24+
25+
// Once we have all these migrations that are outstanding we are ready to run
26+
// we will go ahead and run them "up". This will execute each migration as
27+
// an operation against a database. Then we'll return this list of them.
28+
$this->runPending($migrations, $options);
29+
30+
return $migrations;
31+
}
32+
33+
public function resetFiles(array $files = [], $pretend = false)
34+
{
35+
$this->notes = [];
36+
37+
$files = collect($files)->keyBy(function ($file) {
38+
return rtrim(basename($file), '.php');
39+
})->all();
40+
41+
// Next, we will reverse the migration list so we can run them back in the
42+
// correct order for resetting this database. This will allow us to get
43+
// the database back into its "empty" state ready for the migrations.
44+
$migrations = array_reverse($this->repository->getRan());
45+
46+
if (count($migrations) === 0) {
47+
$this->note('<info>Nothing to rollback.</info>');
48+
49+
return [];
50+
}
51+
52+
return $this->resetMigrationsByFiles($migrations, $files, $pretend);
53+
}
54+
55+
protected function resetMigrationsByFiles(array $migrations, array $files, $pretend = false)
56+
{
57+
// Since the getRan method that retrieves the migration name just gives us the
58+
// migration name, we will format the names into objects with the name as a
59+
// property on the objects so that we can pass it to the rollback method.
60+
$migrations = collect($migrations)->map(function ($m) {
61+
return (object) ['migration' => $m];
62+
})->all();
63+
64+
return $this->rollbackMigrationsByFiles(
65+
$migrations, $files, compact('pretend')
66+
);
67+
}
68+
69+
protected function rollbackMigrationsByFiles(array $migrations, $files, array $options)
70+
{
71+
$rolledBack = [];
72+
73+
$this->requireFiles($files);
74+
75+
// Next we will run through all of the migrations and call the "down" method
76+
// which will reverse each migration in order. This getLast method on the
77+
// repository already returns these migration's names in reverse order.
78+
foreach ($migrations as $migration) {
79+
$migration = (object) $migration;
80+
81+
if (!$file = Arr::get($files, $migration->migration)) {
82+
$this->note("<fg=red>Migration not found:</> {$migration->migration}");
83+
84+
continue;
85+
}
86+
87+
$rolledBack[] = $file;
88+
89+
$this->runDown(
90+
$file, $migration,
91+
$options['pretend'] ?? false
92+
);
93+
}
94+
95+
return $rolledBack;
96+
}
97+
}

0 commit comments

Comments
 (0)