execute method

  1. @override
Future<int> execute(
  1. List<String> arguments
)
override

Implementation

@override
Future<int> execute(List<String> arguments) async {
  if (arguments.isEmpty) {
    arguments.add(_readMigrationName());
  }

  String migrationName = arguments[0].toLowerCase();

  if (!RegExp(r'^[A-Za-z][A-Za-z_]*$').hasMatch(migrationName)) {
    Console.error(
      'Migration names may only contain letters and underscores.',
    );
    return ExitCode.usage;
  }

  if (arguments.length < 2) {
    arguments.add(_readTableName());
  }

  final tableName = arguments[1].toLowerCase();

  if (!RegExp(r'^[A-Za-z][A-Za-z0-9_]*$').hasMatch(tableName)) {
    Console.error(
      'Table names may only contain letters, digits, and underscores.',
    );
    return ExitCode.usage;
  }

  String filePath =
      '${workingDirectory.path}/lib/database/migrations/${pascalToSnake(migrationName)}.dart';
  File newFile = File(filePath);

  if (newFile.existsSync()) {
    stdout.writeln(
      ' \x1B[41m\x1B[37m ERROR \x1B[0m Migration already exists.',
    );
    return ExitCode.failure;
  }

  await newFile.create(recursive: true);

  String str = _alterMigrationStub
      .replaceFirst('MigrationALterNameClass', snakeToPascal(migrationName))
      .replaceFirst('TableName', tableName);

  await newFile.writeAsString(str);

  File migrate = File(
    '${workingDirectory.path}/lib/database/migrations/migrate.dart',
  );

  var migrateSource = _newMigrateFileContents;
  if (migrate.existsSync()) {
    migrateSource = migrate.readAsStringSync();
  }

  final importRegExp = RegExp(r'import .+;');
  final migrationRegisterRegex = RegExp(
    r'migrationRegister\s*\(\s*\[\s*([\s\S]*?)\s*\]\s*\)',
    multiLine: true,
  );

  var importMatch = importRegExp.allMatches(migrateSource);
  if (importMatch.isNotEmpty) {
    migrateSource = migrateSource.replaceFirst(
      importMatch.last.group(0).toString(),
      "${importMatch.last.group(0)}\nimport '${pascalToSnake(migrationName)}.dart';",
    );
  }

  Match? migrationRegisterMatch = migrationRegisterRegex.firstMatch(
    migrateSource,
  );

  if (migrationRegisterMatch != null) {
    String existingMigrations = migrationRegisterMatch.group(1)?.trim() ?? '';
    String newMigrations;

    if (existingMigrations.isEmpty) {
      newMigrations = '${migrationName.pascalCase}()';
    } else {
      existingMigrations = existingMigrations.replaceAll(
        RegExp(r',\s*$'),
        '',
      );
      newMigrations =
          '$existingMigrations,\n      ${migrationName.pascalCase}()';
    }

    migrateSource = migrateSource.replaceAll(
      migrationRegisterRegex,
      'migrationRegister([\n      $newMigrations,\n    ])',
    );
  }

  migrate.writeAsStringSync(migrateSource);

  stdout.writeln(
    ' \x1B[44m\x1B[37m INFO \x1B[0m Migration [$filePath] created successfully.',
  );
  return ExitCode.success;
}