build method

  1. @override
Future<void> build(
  1. BuildStep buildStep
)

Generates the outputs for a given BuildStep.

Implementation

@override
Future<void> build(BuildStep buildStep) async {
  final libraryReader = LibraryReader(await buildStep.inputLibrary);
  final fieldses = await sqliteFieldsFromBuildStep(buildStep);
  final now = DateTime.now().toUtc();
  final timestamp =
      [now.month, now.day, now.hour, now.minute, now.second].map(_padToTwo).toList().join('');
  final version = int.parse('${now.year}$timestamp');
  final output = schemaGenerator.createMigration(libraryReader, fieldses, version: version);

  if (output == null) return;

  final stopwatch = Stopwatch();
  stopwatch.start();

  // in a perfect world, the schema would not be edited in such a brittle way
  // however, reruning the schema generator here doesn't pick up the new migration
  // because it uses the LibraryReader from before the migration is created.
  // this should be revisited in a few build versions to make this flow less brittle
  // and more predictable by using the same schema generator to do all the heavy lifting
  final newSetPiece = 'final migrations = <Migration>{\n  const Migration$version(),';
  final newPart = "brick_sqlite/db.dart';\npart '$version.migration.dart';";

  await replaceWithinFile(
    'db/schema.g.dart',
    'final migrations = <Migration>{',
    newSetPiece,
  );
  await replaceWithinFile(
    'db/schema.g.dart',
    "brick_sqlite/db.dart';",
    newPart,
  );

  await manuallyUpsertBrickFile('db/$version.migration.dart', output);
  await buildStep.writeAsString(buildStep.inputId.changeExtension(outputExtension), output);
  await replaceWithinFile(
    'db/schema.g.dart',
    RegExp(r'final schema =(?:\n\s+)? Schema\(([\d]+|null),'),
    'final schema = Schema($version,',
  );

  logStopwatch('Generated new migration (db/$version.migration.dart)', stopwatch);
}