-
Notifications
You must be signed in to change notification settings - Fork 0
Open
Labels
✨ Type: FeatureNew functionality or enhancementNew functionality or enhancement🟡 Priority: MediumStandard priority tasksStandard priority tasks
Milestone
Description
Overview
Add basic CLI commands (migrate, list, rollback) to the core package with a factory pattern that allows database-specific implementations to extend the base CLI with their own commands.
Motivation
- Provide out-of-the-box CLI functionality for users
- Keep basic commands simple and in core (no need for separate package)
- Allow DBMS-specific packages (
@migration-script-runner/postgresql, etc.) to extend with custom commands - Improve developer experience with ready-to-use CLI
Proposed Structure
src/
├── cli/
│ ├── commands/
│ │ ├── migrate.ts # Run pending migrations
│ │ ├── list.ts # List migrations with status
│ │ └── rollback.ts # Rollback last migration
│ ├── createCLI.ts # Factory for creating/extending CLI
│ └── index.ts # Exports
├── interface/
├── logger/
├── model/
└── service/
bin/
└── msr # CLI entry point
Basic Commands
1. migrate
Run all pending migrations.
msr migrate [options]
Options:
-c, --config <path> Configuration file path
-h, --help Display help2. list
List all migrations with their status.
msr list [options]
Options:
-n, --number <count> Number of migrations to display
-c, --config <path> Configuration file path
-h, --help Display help3. rollback
Rollback the last migration (requires down() support).
msr rollback [options]
Options:
-c, --config <path> Configuration file path
-h, --help Display helpCLI Factory Pattern
The createCLI() factory allows DBMS-specific packages to extend base commands:
// src/cli/createCLI.ts
import { Command } from 'commander';
import { IMigrationScriptHandler } from '../interface';
export interface CLIOptions {
handler: IMigrationScriptHandler;
name?: string;
description?: string;
version?: string;
}
export function createCLI(options: CLIOptions): Command {
const program = new Command();
program
.name(options.name || 'msr')
.description(options.description || 'Migration Script Runner')
.version(options.version || '1.0.0');
// Add base commands
addMigrateCommand(program, options.handler);
addListCommand(program, options.handler);
addRollbackCommand(program, options.handler);
return program;
}Example: Extending in PostgreSQL Package
// @migration-script-runner/postgresql
import { createCLI } from '@migration-script-runner/core/cli';
import { PostgresHandler } from './PostgresHandler';
// Create base CLI with PostgreSQL handler
const program = createCLI({
handler: new PostgresHandler(),
name: 'msr-pg',
description: 'PostgreSQL Migration Runner'
});
// Add PostgreSQL-specific commands
program
.command('pg:dump')
.description('Create PostgreSQL database dump')
.action(async () => {
// PostgreSQL-specific logic
});
program
.command('pg:vacuum')
.description('Run VACUUM on database')
.action(async () => {
// PostgreSQL-specific logic
});
program.parse();Implementation Details
Command: migrate
// src/cli/commands/migrate.ts
import { Command } from 'commander';
import { IMigrationScriptHandler } from '../../interface';
import { MigrationScriptExecutor } from '../../service';
export function addMigrateCommand(program: Command, handler: IMigrationScriptHandler) {
program
.command('migrate')
.description('Run all pending migrations')
.option('-c, --config <path>', 'Configuration file path')
.action(async (options) => {
const executor = new MigrationScriptExecutor(handler);
const result = await executor.migrate();
if (result.success) {
console.log(`✓ Successfully executed ${result.executed.length} migrations`);
process.exit(0);
} else {
console.error(`✗ Migration failed:`, result.errors);
process.exit(1);
}
});
}Command: list
// src/cli/commands/list.ts
export function addListCommand(program: Command, handler: IMigrationScriptHandler) {
program
.command('list')
.description('List all migrations with status')
.option('-n, --number <count>', 'Number of migrations to display', '0')
.option('-c, --config <path>', 'Configuration file path')
.action(async (options) => {
const executor = new MigrationScriptExecutor(handler);
await executor.list(parseInt(options.number));
process.exit(0);
});
}Command: rollback
// src/cli/commands/rollback.ts
export function addRollbackCommand(program: Command, handler: IMigrationScriptHandler) {
program
.command('rollback')
.description('Rollback the last migration')
.option('-c, --config <path>', 'Configuration file path')
.action(async (options) => {
// Rollback logic (requires #50 - down() support)
console.log('Rollback functionality requires down() migration support');
process.exit(1);
});
}Dependencies
{
"dependencies": {
"commander": "^11.0.0"
}
}Benefits
- ✅ Out-of-the-box CLI for basic operations
- ✅ Extensible for database-specific implementations
- ✅ No need for separate CLI package (keeps it simple)
- ✅ Consistent command structure across all DBMS packages
- ✅ Easy to test and maintain
Acceptance Criteria
-
createCLI()factory function implemented -
migratecommand functional -
listcommand functional -
rollbackcommand stub (full implementation in Make backup/restore optional to support down() migrations #50) - CLI entry point in
bin/msr - Commander.js integrated
- Help text for all commands
- Error handling for invalid options
- Tests for CLI commands
- Documentation with usage examples
- Example showing how to extend CLI
Related Issues
- Make backup/restore optional to support down() migrations #50 - Make backup/restore optional to support down() migrations (rollback command)
- Add support for SQL migration files (Hybrid TypeScript/SQL handler) #58 - Add support for SQL migration files (CLI should support both .ts and .sql)
- Future: Database-specific implementation packages (PostgreSQL, MySQL, etc.)
Priority
Low (Backlog) - Nice to have but not blocking core functionality
Notes
- Keep CLI simple - don't add too many options initially
- Focus on the factory pattern that enables extension
- Rollback command is a stub until Make backup/restore optional to support down() migrations #50 is implemented
- Consider adding init command to generate migration files
- May want to add validate command to check migration file naming
Metadata
Metadata
Assignees
Labels
✨ Type: FeatureNew functionality or enhancementNew functionality or enhancement🟡 Priority: MediumStandard priority tasksStandard priority tasks