200 lines
6.8 KiB
Dart
200 lines
6.8 KiB
Dart
import 'dart:io';
|
|
import 'package:args/command_runner.dart';
|
|
import 'package:code_builder/code_builder.dart';
|
|
import 'package:dart_style/dart_style.dart';
|
|
import 'package:inflection/inflection.dart';
|
|
import 'package:io/ansi.dart';
|
|
import 'package:prompts/prompts.dart' as prompts;
|
|
import 'package:recase/recase.dart';
|
|
import '../../util.dart';
|
|
import 'maker.dart';
|
|
|
|
class ModelCommand extends Command {
|
|
@override
|
|
String get name => 'model';
|
|
|
|
@override
|
|
String get description => 'Generates a model class.';
|
|
|
|
ModelCommand() {
|
|
argParser
|
|
..addFlag('migration',
|
|
abbr: 'm',
|
|
help: 'Generate an angel_orm migration file.',
|
|
negatable: false)
|
|
..addFlag('orm', help: 'Generate angel_orm code.', negatable: false)
|
|
..addFlag('serializable',
|
|
help: 'Generate angel_serialize annotations.', defaultsTo: true)
|
|
..addOption('name',
|
|
abbr: 'n', help: 'Specifies a name for the model class.')
|
|
..addOption('output-dir',
|
|
help: 'Specifies a directory to create the model class in.',
|
|
defaultsTo: 'lib/src/models')
|
|
..addOption('migration-dir',
|
|
help: 'Specifies a directory to create the migration class in.',
|
|
defaultsTo: 'tool/migrations');
|
|
}
|
|
|
|
@override
|
|
run() async {
|
|
var pubspec = await loadPubspec();
|
|
String name;
|
|
if (argResults.wasParsed('name')) name = argResults['name'] as String;
|
|
|
|
if (name?.isNotEmpty != true) {
|
|
name = prompts.get('Name of model class');
|
|
}
|
|
|
|
List<MakerDependency> deps = [
|
|
const MakerDependency('angel_framework', '^1.0.0'),
|
|
const MakerDependency('angel_model', '^1.0.0'),
|
|
];
|
|
|
|
var rc = new ReCase(name);
|
|
|
|
var modelLib = new Library((modelLib) {
|
|
modelLib.directives
|
|
.add(new Directive.import('package:angel_model/angel_model.dart'));
|
|
|
|
var needsSerialize =
|
|
argResults['serializable'] as bool || argResults['orm'] as bool;
|
|
|
|
if (needsSerialize) {
|
|
modelLib.directives.add(new Directive.import(
|
|
'package:angel_serialize/angel_serialize.dart'));
|
|
deps.add(const MakerDependency('angel_serialize', '^2.0.0'));
|
|
}
|
|
|
|
if (argResults['orm'] as bool) {
|
|
modelLib.directives
|
|
.add(new Directive.import('package:angel_orm/angel_orm.dart'));
|
|
deps.add(const MakerDependency('angel_orm', '^1.0.0-alpha'));
|
|
}
|
|
|
|
modelLib.body.add(new Class((modelClazz) {
|
|
modelClazz
|
|
..name = needsSerialize ? '_${rc.pascalCase}' : rc.pascalCase
|
|
..extend = refer('Model');
|
|
|
|
if (needsSerialize) {
|
|
// TODO: Add parts
|
|
// modelLib.addDirective(new PartBuilder('${rc.snakeCase}.g.dart'));
|
|
modelClazz.annotations.add(refer('serializable'));
|
|
}
|
|
|
|
if (argResults['orm'] as bool) {
|
|
modelClazz.annotations.add(refer('orm'));
|
|
}
|
|
}));
|
|
});
|
|
|
|
// Save model file
|
|
var outputDir = new Directory.fromUri(
|
|
Directory.current.uri.resolve(argResults['output-dir'] as String));
|
|
var modelFile =
|
|
new File.fromUri(outputDir.uri.resolve('${rc.snakeCase}.dart'));
|
|
if (!await modelFile.exists()) await modelFile.create(recursive: true);
|
|
|
|
await modelFile.writeAsString(new DartFormatter()
|
|
.format(modelLib.accept(new DartEmitter()).toString()));
|
|
|
|
print(green
|
|
.wrap('$checkmark Created model file "${modelFile.absolute.path}".'));
|
|
|
|
if (argResults['migration'] as bool) {
|
|
deps.add(const MakerDependency('angel_migration', '^1.0.0-alpha'));
|
|
|
|
var migrationLib = new Library((migrationLib) {
|
|
migrationLib
|
|
..directives.add(new Directive.import(
|
|
'package:angel_migration.dart/angel_migration.dart'))
|
|
..body.add(new Class((migrationClazz) {
|
|
migrationClazz
|
|
..name = '${rc.pascalCase}Migration'
|
|
..extend = refer('Migration');
|
|
|
|
var tableName = pluralize(rc.snakeCase);
|
|
|
|
// up()
|
|
migrationClazz.methods.add(new Method((up) {
|
|
up
|
|
..name = 'up'
|
|
..returns = refer('void')
|
|
..annotations.add(refer('override'))
|
|
..requiredParameters.add(new Parameter((b) => b
|
|
..name = 'schema'
|
|
..type = refer('Schema')))
|
|
..body = new Block((block) {
|
|
// (table) { ... }
|
|
var callback = new Method((callback) {
|
|
callback
|
|
..requiredParameters
|
|
.add(new Parameter((b) => b..name = 'table'))
|
|
..body = new Block((block) {
|
|
var table = refer('table');
|
|
|
|
block.addExpression(
|
|
(table.property('serial').call([literal('id')]))
|
|
.property('primaryKey')
|
|
.call([]),
|
|
);
|
|
|
|
block.addExpression(
|
|
table.property('date').call([
|
|
literal('created_at'),
|
|
]),
|
|
);
|
|
|
|
block.addExpression(
|
|
table.property('date').call([
|
|
literal('updated_at'),
|
|
]),
|
|
);
|
|
});
|
|
});
|
|
|
|
block.addExpression(refer('schema').property('create').call([
|
|
literal(tableName),
|
|
callback.closure,
|
|
]));
|
|
});
|
|
}));
|
|
|
|
// down()
|
|
migrationClazz.methods.add(new Method((down) {
|
|
down
|
|
..name = 'down'
|
|
..returns = refer('void')
|
|
..annotations.add(refer('override'))
|
|
..requiredParameters.add(new Parameter((b) => b
|
|
..name = 'schema'
|
|
..type = refer('Schema')))
|
|
..body = new Block((block) {
|
|
block.addExpression(
|
|
refer('schema').property('drop').call([
|
|
literal(tableName),
|
|
]),
|
|
);
|
|
});
|
|
}));
|
|
}));
|
|
});
|
|
|
|
// Save migration file
|
|
var migrationDir = new Directory.fromUri(
|
|
Directory.current.uri.resolve(argResults['migration-dir'] as String));
|
|
var migrationFile =
|
|
new File.fromUri(migrationDir.uri.resolve('${rc.snakeCase}.dart'));
|
|
if (!await migrationFile.exists())
|
|
await migrationFile.create(recursive: true);
|
|
|
|
await migrationFile.writeAsString(new DartFormatter()
|
|
.format(migrationLib.accept(new DartEmitter()).toString()));
|
|
|
|
print(green.wrap(
|
|
'$checkmark Created migration file "${migrationFile.absolute.path}".'));
|
|
}
|
|
|
|
if (deps.isNotEmpty) await depend(deps);
|
|
}
|
|
}
|