Skip to content

Commit 0728d98

Browse files
Add db seed/wipe/truncate CLI support, tests, and changelog for 1.13.0
1 parent 139d7a0 commit 0728d98

5 files changed

Lines changed: 138 additions & 12 deletions

File tree

CHANGELOG.md

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,19 @@
22

33
All notable changes to **codemonster-ru/annabel** will be documented in this file.
44

5-
## [1.12.0]
5+
## [1.13.0] - 2025-12-22
6+
7+
### Added
8+
9+
- Added support for database CLI seed commands (`make:seed`, `seed`) when `codemonster-ru/database` is installed.
10+
- Added support for database maintenance commands (`db:wipe`, `db:truncate`) in the Annabel CLI.
11+
- Added console tests to verify registered commands and aliases.
12+
13+
### Changed
14+
15+
- Updated README with the latest database CLI commands.
16+
17+
## [1.12.0] - 2025-12-10
618

719
### Added
820

README.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,12 @@ router()->get('/', fn() => view('home', ['title' => 'Welcome to Annabel']));
4141

4242
Annabel ships with a lightweight CLI similar to Laravel's `artisan`. It already supports:
4343

44-
- `about` show version, base path, and loaded providers
45-
- `route:list` list registered routes
46-
- `config:get key` read a config value
47-
- `container:list` show container bindings/instances
48-
- `serve` run PHP built-in server (default 127.0.0.1:8000)
49-
- With `codemonster-ru/database` installed: `make:migration`, `migrate`, `migrate:rollback`, `migrate:status` (appear in `annabel list`; connection is checked when commands run)
44+
- `about` - show version, base path, and loaded providers
45+
- `route:list` - list registered routes
46+
- `config:get key` - read a config value
47+
- `container:list` - show container bindings/instances
48+
- `serve` - run PHP built-in server (default 127.0.0.1:8000)
49+
- With `codemonster-ru/database` installed: `make:migration`, `migrate`, `migrate:rollback`, `migrate:status`, `make:seed`, `seed` (appear in `annabel list`; connection is checked when commands run)
5050

5151
```bash
5252
php vendor/bin/annabel
@@ -56,7 +56,7 @@ php vendor/bin/annabel help list
5656

5757
## Database Integration
5858

59-
Annabel ships with firstclass integration for
59+
Annabel ships with first-class integration for
6060
[`codemonster-ru/database`](https://github.com/codemonster-ru/database).
6161

6262
### 1. Create `config/database.php`

src/Database/ConsoleDatabaseCLIKernel.php

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,27 +8,42 @@
88
use Codemonster\Database\CLI\Commands\MigrateCommand;
99
use Codemonster\Database\CLI\Commands\RollbackCommand;
1010
use Codemonster\Database\CLI\Commands\StatusCommand;
11+
use Codemonster\Database\CLI\Commands\MakeSeedCommand;
12+
use Codemonster\Database\CLI\Commands\SeedCommand;
13+
use Codemonster\Database\CLI\Commands\TruncateCommand;
14+
use Codemonster\Database\CLI\Commands\WipeCommand;
1115
use Codemonster\Database\Contracts\ConnectionInterface;
1216
use Codemonster\Database\Migrations\MigrationPathResolver;
1317
use Codemonster\Database\Migrations\Migrator;
14-
use Codemonster\Database\Migrations\MigrationRepository;
18+
use Codemonster\Database\Seeders\SeedPathResolver;
19+
use Codemonster\Database\Seeders\SeederRunner;
1520

1621
/**
1722
* Custom kernel that avoids touching the database until a command executes.
1823
*/
1924
class ConsoleDatabaseCLIKernel extends DatabaseCLIKernel
2025
{
21-
public function __construct(ConnectionInterface $connection, ?MigrationPathResolver $paths = null)
22-
{
26+
public function __construct(
27+
ConnectionInterface $connection,
28+
?MigrationPathResolver $paths = null,
29+
?SeedPathResolver $seedPaths = null
30+
) {
2331
$this->paths = $paths ?? new MigrationPathResolver();
2432

2533
if (empty($this->paths->getPaths())) {
2634
$this->paths->addPath(getcwd() . DIRECTORY_SEPARATOR . 'database' . DIRECTORY_SEPARATOR . 'migrations');
2735
}
2836

37+
$this->seedPaths = $seedPaths ?? new SeedPathResolver();
38+
39+
if (empty($this->seedPaths->getPaths())) {
40+
$this->seedPaths->addPath(getcwd() . DIRECTORY_SEPARATOR . 'database' . DIRECTORY_SEPARATOR . 'seeds');
41+
}
42+
2943
$repository = new LazyMigrationRepository($connection);
3044

3145
$this->migrator = new Migrator($repository, $connection, $this->paths);
46+
$this->seeder = new SeederRunner($connection, $this->seedPaths);
3247
$this->commands = new CommandRegistry();
3348

3449
$this->registerDefaultCommands();
@@ -40,6 +55,10 @@ protected function registerDefaultCommands(): void
4055
$this->commands->register(new RollbackCommand($this->migrator));
4156
$this->commands->register(new StatusCommand($this->migrator));
4257
$this->commands->register(new MakeMigrationCommand($this->paths));
58+
$this->commands->register(new SeedCommand($this->seeder));
59+
$this->commands->register(new MakeSeedCommand($this->seedPaths));
60+
$this->commands->register(new WipeCommand($this->migrator->getConnection()));
61+
$this->commands->register(new TruncateCommand($this->migrator->getConnection()));
4362
}
4463

4564
public function getRegistry(): CommandRegistry
@@ -52,8 +71,18 @@ public function getPathResolver(): MigrationPathResolver
5271
return $this->paths;
5372
}
5473

74+
public function getSeedPathResolver(): SeedPathResolver
75+
{
76+
return $this->seedPaths;
77+
}
78+
5579
public function getMigrator(): Migrator
5680
{
5781
return $this->migrator;
5882
}
83+
84+
public function getSeeder(): SeederRunner
85+
{
86+
return $this->seeder;
87+
}
5988
}

src/Providers/DatabaseServiceProvider.php

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,10 @@
99
use Codemonster\Database\DatabaseManager;
1010
use Codemonster\Database\Contracts\ConnectionInterface;
1111
use Codemonster\Database\Migrations\MigrationPathResolver;
12+
use Codemonster\Database\Migrations\MigrationRepository;
1213
use Codemonster\Database\Migrations\Migrator;
1314
use Codemonster\Database\CLI\DatabaseCLIKernel;
15+
use Codemonster\Database\Seeders\SeedPathResolver;
1416

1517
class DatabaseServiceProvider implements ServiceProviderInterface
1618
{
@@ -63,6 +65,27 @@ public function register(): void
6365
return new LazyMigrationRepository($connection, $table);
6466
});
6567

68+
$this->app->singleton(SeedPathResolver::class, function () {
69+
$resolver = new SeedPathResolver();
70+
$paths = config('database.seeds.paths') ?? null;
71+
72+
if (is_string($paths)) {
73+
$paths = [$paths];
74+
}
75+
76+
if (is_array($paths)) {
77+
foreach ($paths as $path) {
78+
$resolver->addPath($path);
79+
}
80+
}
81+
82+
if (empty($resolver->getPaths())) {
83+
$resolver->addPath(base_path('database/seeds'));
84+
}
85+
86+
return $resolver;
87+
});
88+
6689
$this->app->singleton(Migrator::class, function ($app) {
6790
$repository = $app->make(MigrationRepository::class);
6891
$connection = $app->make(ConnectionInterface::class);
@@ -74,8 +97,9 @@ public function register(): void
7497
$this->app->singleton(DatabaseCLIKernel::class, function ($app) {
7598
$connection = $app->make(ConnectionInterface::class);
7699
$paths = $app->make(MigrationPathResolver::class);
100+
$seedPaths = $app->make(SeedPathResolver::class);
77101

78-
return new ConsoleDatabaseCLIKernel($connection, $paths);
102+
return new ConsoleDatabaseCLIKernel($connection, $paths, $seedPaths);
79103
});
80104
}
81105

tests/Console/ConsoleTest.php

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,67 @@ public function test_help_alias_is_resolved(): void
3232
$this->assertStringContainsString('list', $output);
3333
}
3434

35+
public function test_registered_commands_include_database_commands(): void
36+
{
37+
$console = new Console();
38+
$commandNames = array_keys($console->getCommands());
39+
$expected = [
40+
'list',
41+
'about',
42+
'route:list',
43+
'config:get',
44+
'container:list',
45+
'serve',
46+
'make:migration',
47+
'migrate',
48+
'migrate:rollback',
49+
'migrate:status',
50+
'make:seed',
51+
'seed',
52+
'db:wipe',
53+
'db:truncate',
54+
];
55+
56+
foreach ($expected as $name) {
57+
$this->assertContains($name, $commandNames, "Missing command [{$name}].");
58+
}
59+
}
60+
61+
public function test_registered_commands_match_expected_list(): void
62+
{
63+
$console = new Console();
64+
$commandNames = array_keys($console->getCommands());
65+
$expected = [
66+
'list',
67+
'about',
68+
'route:list',
69+
'config:get',
70+
'container:list',
71+
'serve',
72+
'make:migration',
73+
'migrate',
74+
'migrate:rollback',
75+
'migrate:status',
76+
'make:seed',
77+
'seed',
78+
'db:wipe',
79+
'db:truncate',
80+
];
81+
82+
sort($commandNames);
83+
sort($expected);
84+
85+
$this->assertSame($expected, $commandNames);
86+
}
87+
88+
public function test_command_aliases_are_registered(): void
89+
{
90+
$console = new Console();
91+
92+
$this->assertSame(['help'], $console->getAliasesFor('list'));
93+
$this->assertSame([], $console->getAliasesFor('about'));
94+
}
95+
3596
private function captureOutput(callable $callback): string
3697
{
3798
ob_start();

0 commit comments

Comments
 (0)