CLI & Runbook
A professional application often needs a command-line interface (CLI) for administrative tasks like starting the server, running migrations, or seeding the database. We use Artisanal to build a Laravel-style CLI for our movie catalog.
Artisanal CLI
The CLI is defined in bin/cli.dart. It uses a command-based structure where each task is a separate command.
- Entry Point
- Serve Command
- Migrate Command
- Seed Command
The entry point initializes the CLI and registers the available commands.
Future<void> main(List<String> args) async {
final runner =
CommandRunner(
'movie-catalog',
'CLI for the Ormed + Shelf movie catalog example.',
)
..addCommand(ServeCommand())
..addCommand(MigrateCommand())
..addCommand(SeedCommand());
await runner.run(args);
}
Starts the Shelf server.
String get name => 'serve';
String get description => 'Start the Shelf server.';
Future<void> run() async {
final host = argResults?['host'] as String? ?? '0.0.0.0';
final port = int.parse(argResults?['port'] as String? ?? '8080');
io.title('Movie Catalog Server');
io.note(Style().hyperlink('Starting on $host:$port').render());
await runServer(host: host, port: port);
}
ServeCommand() {
argParser
..addOption('host', defaultsTo: '0.0.0.0')
..addOption('port', defaultsTo: '8080');
}
Runs the database migrations.
String get name => 'migrate';
String get description => 'Run database migrations.';
Future<void> run() async {
io.section('Running migrations');
final exitCode = await runProcess(['migrate']);
if (exitCode == 0) {
io.success('Migrations complete.');
} else {
io.error('Migration failed with code $exitCode.');
}
}
Seeds the database with initial data.
String get name => 'seed';
String get description => 'Run database seeders.';
Future<void> run() async {
io.section('Seeding data');
final exitCode = await runProcess(['seed']);
if (exitCode == 0) {
io.success('Seed complete.');
} else {
io.error('Seed failed with code $exitCode.');
}
}
Runbook
Here's a quick reference for the common commands you'll use during development:
1. Code Generation
Run this whenever you change your models or add new ones.
dart run build_runner build --delete-conflicting-outputs
2. Database Setup
Prepare your database by running migrations and seeding it with data.
# Apply all pending migrations
dart run ormed_cli:ormed migrate
# Run the database seeders
dart run ormed_cli:ormed seed
3. Running Tests
Ensure everything is working correctly.
dart test
4. Starting the Server
You can start the server directly or via the Artisanal CLI.
# Start server directly
dart run bin/server.dart
# Start server using the CLI (recommended)
dart run bin/cli.dart serve