New generators for Controller + Model

This commit is contained in:
Tobe O 2018-07-14 17:47:49 -04:00
parent 77c3f08063
commit 0a59aa77df
21 changed files with 328 additions and 274 deletions

View file

@ -2,6 +2,7 @@
<module type="WEB_MODULE" version="4"> <module type="WEB_MODULE" version="4">
<component name="NewModuleRootManager"> <component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$"> <content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/.dart_tool" />
<excludeFolder url="file://$MODULE_DIR$/.pub" /> <excludeFolder url="file://$MODULE_DIR$/.pub" />
<excludeFolder url="file://$MODULE_DIR$/.tmp" /> <excludeFolder url="file://$MODULE_DIR$/.tmp" />
<excludeFolder url="file://$MODULE_DIR$/build" /> <excludeFolder url="file://$MODULE_DIR$/build" />

View file

@ -1,7 +0,0 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="build.dart" type="DartCommandLineRunConfigurationType" factoryName="Dart Command Line Application" singleton="true" nameIsGenerated="true">
<option name="filePath" value="$PROJECT_DIR$/tool/build.dart" />
<option name="workingDirectory" value="$PROJECT_DIR$" />
<method />
</configuration>
</component>

View file

@ -1,2 +1,3 @@
analyzer: analyzer:
strong-mode: true strong-mode:
implicit-casts: false

View file

@ -2,7 +2,7 @@ import 'dart:io';
import 'package:args/command_runner.dart'; import 'package:args/command_runner.dart';
import 'package:code_builder/code_builder.dart'; import 'package:code_builder/code_builder.dart';
import "package:console/console.dart"; import "package:console/console.dart";
import 'package:pubspec/pubspec.dart'; import 'package:pubspec_parse/pubspec_parse.dart';
import 'package:recase/recase.dart'; import 'package:recase/recase.dart';
import 'deprecated.dart'; import 'deprecated.dart';
@ -31,7 +31,7 @@ class ControllerCommand extends Command {
await controllerFile.create(recursive: true); await controllerFile.create(recursive: true);
await controllerFile.writeAsString( await controllerFile.writeAsString(
_generateController(await PubSpec.load(Directory.current), recase)); _generateController(await Pubspec.load(Directory.current), recase));
_pen.green(); _pen.green();
_pen("${Icon.CHECKMARK} Successfully generated controller $name."); _pen("${Icon.CHECKMARK} Successfully generated controller $name.");
@ -41,7 +41,7 @@ class ControllerCommand extends Command {
NewInstanceBuilder _expose(String path) => new TypeBuilder('Expose') NewInstanceBuilder _expose(String path) => new TypeBuilder('Expose')
.constInstance([], namedArguments: {'path': literal(path)}); .constInstance([], namedArguments: {'path': literal(path)});
String _generateController(PubSpec pubspec, ReCase recase) { String _generateController(Pubspec pubspec, ReCase recase) {
var lower = recase.snakeCase; var lower = recase.snakeCase;
var lib = new LibraryBuilder('${pubspec.name}.routes.controllers.$lower'); var lib = new LibraryBuilder('${pubspec.name}.routes.controllers.$lower');
lib.addDirective( lib.addDirective(

View file

@ -6,7 +6,7 @@ import 'package:glob/glob.dart';
import 'package:homedir/homedir.dart'; import 'package:homedir/homedir.dart';
import 'package:mustache4dart/mustache4dart.dart' as mustache; import 'package:mustache4dart/mustache4dart.dart' as mustache;
import 'package:path/path.dart' as p; import 'package:path/path.dart' as p;
import 'package:pubspec/pubspec.dart'; import 'package:pubspec_parse/pubspec_parse.dart';
import 'package:yaml/yaml.dart' as yaml; import 'package:yaml/yaml.dart' as yaml;
import 'make/maker.dart'; import 'make/maker.dart';
@ -61,7 +61,7 @@ class InstallCommand extends Command {
if (!await installRepo.exists()) if (!await installRepo.exists())
throw 'No local add-on database exists. Run `angel install --update` first.'; throw 'No local add-on database exists. Run `angel install --update` first.';
var pubspec = await PubSpec.load(Directory.current); var pubspec = await Pubspec.load(Directory.current);
for (var packageName in argResults.rest) { for (var packageName in argResults.rest) {
var packageDir = var packageDir =
@ -78,7 +78,7 @@ class InstallCommand extends Command {
List<Glob> globs = []; List<Glob> globs = [];
var projectPubspec = await PubSpec.load(packageDir); var projectPubspec = await Pubspec.load(packageDir);
var deps = projectPubspec.dependencies.keys var deps = projectPubspec.dependencies.keys
.map((k) { .map((k) {
var dep = projectPubspec.dependencies[k]; var dep = projectPubspec.dependencies[k];
@ -207,16 +207,16 @@ class InstallCommand extends Command {
} }
} }
Future<List<PubSpec>> list() async { Future<List<Pubspec>> list() async {
if (!await installRepo.exists()) { if (!await installRepo.exists()) {
throw 'No local add-on database exists. Run `angel install --update` first.'; throw 'No local add-on database exists. Run `angel install --update` first.';
} else { } else {
List<PubSpec> repos = []; List<Pubspec> repos = [];
await for (var entity in installRepo.list()) { await for (var entity in installRepo.list()) {
if (entity is Directory) { if (entity is Directory) {
try { try {
repos.add(await PubSpec.load(entity)); repos.add(await Pubspec.load(entity));
} catch (_) { } catch (_) {
// Ignore failures... // Ignore failures...
} }

View file

@ -1,15 +1,14 @@
import 'dart:io'; import 'dart:io';
import 'package:args/command_runner.dart'; import 'package:args/command_runner.dart';
import 'package:code_builder/dart/core.dart';
import 'package:code_builder/code_builder.dart'; import 'package:code_builder/code_builder.dart';
import 'package:console/console.dart'; import 'package:dart_style/dart_style.dart';
import 'package:pubspec/pubspec.dart'; import 'package:io/ansi.dart';
import 'package:prompts/prompts.dart' as prompts;
import 'package:recase/recase.dart'; import 'package:recase/recase.dart';
import '../../util.dart';
import 'maker.dart'; import 'maker.dart';
class ControllerCommand extends Command { class ControllerCommand extends Command {
final TextPen _pen = new TextPen();
@override @override
String get name => 'controller'; String get name => 'controller';
@ -32,73 +31,83 @@ class ControllerCommand extends Command {
@override @override
run() async { run() async {
var pubspec = await PubSpec.load(Directory.current); var pubspec = await loadPubspec();
String name; String name;
if (argResults.wasParsed('name')) name = argResults['name']; if (argResults.wasParsed('name')) name = argResults['name'] as String;
if (name?.isNotEmpty != true) { if (name?.isNotEmpty != true) {
var p = new Prompter('Name of Controller class: '); name = prompts.get('Name of controller class');
name = await p.prompt(checker: (s) => s.isNotEmpty);
} }
List<MakerDependency> deps = [ List<MakerDependency> deps = [
const MakerDependency('angel_framework', '^1.0.0') const MakerDependency('angel_framework', '^1.0.0')
]; ];
// ${pubspec.name}.src.models.${rc.snakeCase}
var rc = new ReCase(name); var rc = new ReCase(name);
var controllerLib = var controllerLib = new Library((controllerLib) {
new LibraryBuilder('${pubspec.name}.src.controllers.${rc.snakeCase}'); if (argResults['websocket'] as bool) {
if (argResults['websocket']) {
deps.add(const MakerDependency('angel_websocket', '^1.0.0')); deps.add(const MakerDependency('angel_websocket', '^1.0.0'));
controllerLib.addDirective( controllerLib.directives
new ImportBuilder('package:angel_websocket/server.dart')); .add(new Directive.import('package:angel_websocket/server.dart'));
} else
controllerLib.addDirective(
new ImportBuilder('package:angel_framework/angel_framework.dart'));
TypeBuilder parentType = new TypeBuilder(
argResults['websocket'] ? 'WebSocketController' : 'Controller');
ClassBuilder clazz =
new ClassBuilder('${rc.pascalCase}Controller', asExtends: parentType);
controllerLib.addMember(clazz);
if (argResults['websocket']) {
var meth = new MethodBuilder('hello', returnType: lib$core.$void);
meth.addAnnotation(new TypeBuilder('ExposeWs')
.constInstance([literal('get_${rc.snakeCase}')]));
meth.addPositional(
parameter('socket', [new TypeBuilder('WebSocketContext')]));
meth.addStatement(reference('socket').invoke('send', [
literal('got_${rc.snakeCase}'),
map({'message': literal('Hello, world!')})
]));
clazz.addMethod(meth);
} else { } else {
clazz.addAnnotation(new TypeBuilder('Expose') controllerLib.directives.add(new Directive.import(
.constInstance([literal('/${rc.snakeCase}')])); 'package:angel_framework/angel_framework.dart'));
var meth = new MethodBuilder('hello',
returnType: lib$core.String, returns: literal('Hello, world!'));
meth.addAnnotation(
new TypeBuilder('Expose').constInstance([literal('/')]));
clazz.addMethod(meth);
} }
controllerLib.body.add(new Class((clazz) {
clazz
..name = '${rc.pascalCase}Controller'
..extend = refer(argResults['websocket'] as bool
? 'WebSocketController'
: 'Controller');
if (argResults['websocket'] as bool) {
clazz.methods.add(new Method((meth) {
meth
..name = 'hello'
..returns = refer('void')
..annotations.add(refer('ExposeWs')
.constInstance([literal('get_${rc.snakeCase}')]))
..requiredParameters.add(new Parameter((b) => b
..name = 'socket'
..type = refer('WebSocketContext')))
..body = new Block((block) {
block.addExpression(refer('socket').property('send').call([
literal('got_${rc.snakeCase}'),
literalMap({'message': literal('Hello, world!')}),
]));
});
}));
} else {
clazz
..annotations.add(
refer('Expose').constInstance([literal('/${rc.snakeCase}')]))
..methods.add(new Method((meth) {
meth
..name = 'hello'
..returns = refer('String')
..body = literal('Hello, world').returned.statement
..annotations.add(refer('Expose').constInstance([
literal('/'),
]));
}));
}
}));
});
var outputDir = new Directory.fromUri( var outputDir = new Directory.fromUri(
Directory.current.uri.resolve(argResults['output-dir'])); Directory.current.uri.resolve(argResults['output-dir'] as String));
var controllerFile = var controllerFile =
new File.fromUri(outputDir.uri.resolve('${rc.snakeCase}.dart')); new File.fromUri(outputDir.uri.resolve('${rc.snakeCase}.dart'));
if (!await controllerFile.exists()) if (!await controllerFile.exists())
await controllerFile.create(recursive: true); await controllerFile.create(recursive: true);
await controllerFile await controllerFile.writeAsString(new DartFormatter()
.writeAsString(prettyToSource(controllerLib.buildAst())); .format(controllerLib.accept(new DartEmitter()).toString()));
_pen
..green() print(green.wrap(
..call( '$checkmark Created controller file "${controllerFile.absolute.path}"'));
'${Icon.CHECKMARK} Created controller file "${controllerFile.absolute.path}".')
..call()
..reset();
if (deps.isNotEmpty) await depend(deps); if (deps.isNotEmpty) await depend(deps);
} }

View file

@ -1,18 +1,21 @@
import 'dart:async'; import 'dart:async';
import 'dart:io'; import 'dart:io';
import 'package:pubspec/pubspec.dart'; import 'package:io/ansi.dart';
import 'package:pubspec_parse/pubspec_parse.dart';
import 'package:pub_semver/pub_semver.dart'; import 'package:pub_semver/pub_semver.dart';
import '../pub.dart'; import '../pub.dart';
import '../../util.dart';
class MakerDependency { class MakerDependency {
final String name, version; final String name, version;
final bool dev; final bool dev;
const MakerDependency(this.name, this.version, {this.dev: false}); const MakerDependency(this.name, this.version, {this.dev: false});
} }
Future depend(Iterable<MakerDependency> deps) async { Future depend(Iterable<MakerDependency> deps) async {
var pubspec = await PubSpec.load(Directory.current); var pubspec = await loadPubspec();
Map<String, DependencyReference> newDeps = {}, newDevDeps = {}; var missing = <MakerDependency>[];
for (var dep in deps) { for (var dep in deps) {
var isPresent = false; var isPresent = false;
@ -22,37 +25,62 @@ Future depend(Iterable<MakerDependency> deps) async {
isPresent = pubspec.dependencies.containsKey(dep.name); isPresent = pubspec.dependencies.containsKey(dep.name);
if (!isPresent) { if (!isPresent) {
print('Installing ${dep.name}@${dep.version}...'); // TODO: https://github.com/dart-lang/pubspec_parse/issues/17:
// print('Installing ${dep.name}@${dep.version}...');
if (dep.dev) //
newDevDeps[dep.name] = // if (dep.dev) {
new HostedReference(new VersionConstraint.parse(dep.version)); // pubspec.devDependencies[dep.name] = new HostedDependency(
else // version: new VersionConstraint.parse(dep.version),
newDeps[dep.name] = // );
new HostedReference(new VersionConstraint.parse(dep.version)); // } else {
} // pubspec.dependencies[dep.name] = new HostedDependency(
// version: new VersionConstraint.parse(dep.version),
if (newDeps.isNotEmpty || newDevDeps.isNotEmpty) { // );
var newPubspec = pubspec.copy( // }
dependencies:
new Map<String, DependencyReference>.from(pubspec.dependencies)
..addAll(newDeps),
devDependencies:
new Map<String, DependencyReference>.from(pubspec.devDependencies)
..addAll(newDevDeps));
await newPubspec.save(Directory.current);
var pubPath = resolvePub();
print('Now running `$pubPath get`...');
var pubGet = await Process.start(pubPath, ['get']);
pubGet.stdout.listen(stdout.add);
pubGet.stderr.listen(stderr.add);
var code = await pubGet.exitCode;
if (code != 0) throw 'pub get terminated with exit code $code';
} }
} }
missing.sort((a, b) {
if (!a.dev) {
if (b.dev) {
return -1;
} else {
return 0;
}
} else {
if (b.dev) {
return 0;
} else {
return 1;
}
}
});
if (missing.isNotEmpty) {
print(yellow.wrap(missing.length == 1
? 'You are missing one dependency:'
: 'You are missing ${missing.length} dependencies:'));
print('\n');
for (var dep in missing) {
var m = ' * ${dep.name}@${dep.version}';
if (dep.dev) m += ' (dev dependency)';
print(yellow.wrap(m));
}
}
// if (isPresent) {
// TODO: https://github.com/dart-lang/pubspec_parse/issues/17
// await savePubspec(pubspec);
// var pubPath = resolvePub();
//
// print('Now running `$pubPath get`...');
//
// var pubGet = await Process.start(pubPath, ['get']);
// pubGet.stdout.listen(stdout.add);
// pubGet.stderr.listen(stderr.add);
//
// var code = await pubGet.exitCode;
//
// if (code != 0) throw 'pub get terminated with exit code $code';
} }

View file

@ -1,16 +1,15 @@
import 'dart:io'; import 'dart:io';
import 'package:args/command_runner.dart'; import 'package:args/command_runner.dart';
import 'package:code_builder/dart/core.dart';
import 'package:code_builder/code_builder.dart'; import 'package:code_builder/code_builder.dart';
import 'package:console/console.dart'; import 'package:dart_style/dart_style.dart';
import 'package:inflection/inflection.dart'; import 'package:inflection/inflection.dart';
import 'package:pubspec/pubspec.dart'; import 'package:io/ansi.dart';
import 'package:prompts/prompts.dart' as prompts;
import 'package:recase/recase.dart'; import 'package:recase/recase.dart';
import '../../util.dart';
import 'maker.dart'; import 'maker.dart';
class ModelCommand extends Command { class ModelCommand extends Command {
final TextPen _pen = new TextPen();
@override @override
String get name => 'model'; String get name => 'model';
@ -38,13 +37,12 @@ class ModelCommand extends Command {
@override @override
run() async { run() async {
var pubspec = await PubSpec.load(Directory.current); var pubspec = await loadPubspec();
String name; String name;
if (argResults.wasParsed('name')) name = argResults['name']; if (argResults.wasParsed('name')) name = argResults['name'] as String;
if (name?.isNotEmpty != true) { if (name?.isNotEmpty != true) {
var p = new Prompter('Name of Model class: '); name = prompts.get('Name of model class');
name = await p.prompt(checker: (s) => s.isNotEmpty);
} }
List<MakerDependency> deps = [ List<MakerDependency> deps = [
@ -53,107 +51,148 @@ class ModelCommand extends Command {
]; ];
var rc = new ReCase(name); var rc = new ReCase(name);
var modelLib =
new LibraryBuilder('${pubspec.name}.src.models.${rc.snakeCase}');
modelLib.addDirective(
new ImportBuilder('package:angel_model/angel_model.dart'));
var needsSerialize = argResults['serializable'] || argResults['orm']; 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) { if (needsSerialize) {
modelLib.addDirective( modelLib.directives.add(new Directive.import(
new ImportBuilder('package:angel_serialize/angel_serialize.dart')); 'package:angel_serialize/angel_serialize.dart'));
deps.add(const MakerDependency('angel_serialize', '^1.0.0-alpha')); deps.add(const MakerDependency('angel_serialize', '^2.0.0'));
} }
if (argResults['orm']) { if (argResults['orm'] as bool) {
modelLib modelLib.directives
.addDirective(new ImportBuilder('package:angel_orm/angel_orm.dart')); .add(new Directive.import('package:angel_orm/angel_orm.dart'));
deps.add(const MakerDependency('angel_orm', '^1.0.0-alpha')); deps.add(const MakerDependency('angel_orm', '^1.0.0-alpha'));
} }
var modelClazz = new ClassBuilder( modelLib.body.add(new Class((modelClazz) {
needsSerialize ? '_${rc.pascalCase}' : rc.pascalCase, modelClazz
asExtends: new TypeBuilder('Model')); ..name = needsSerialize ? '_${rc.pascalCase}' : rc.pascalCase
modelLib.addMember(modelClazz); ..extend = refer('Model');
if (needsSerialize) { if (needsSerialize) {
modelLib.addDirective(new PartBuilder('${rc.snakeCase}.g.dart')); // TODO: Add parts
modelClazz.addAnnotation(reference('serializable')); // modelLib.addDirective(new PartBuilder('${rc.snakeCase}.g.dart'));
modelClazz.annotations.add(refer('serializable'));
} }
if (argResults['orm']) { if (argResults['orm'] as bool) {
modelClazz.addAnnotation(reference('orm')); modelClazz.annotations.add(refer('orm'));
} }
}));
});
// Save model file // Save model file
var outputDir = new Directory.fromUri( var outputDir = new Directory.fromUri(
Directory.current.uri.resolve(argResults['output-dir'])); Directory.current.uri.resolve(argResults['output-dir'] as String));
var modelFile = var modelFile =
new File.fromUri(outputDir.uri.resolve('${rc.snakeCase}.dart')); new File.fromUri(outputDir.uri.resolve('${rc.snakeCase}.dart'));
if (!await modelFile.exists()) await modelFile.create(recursive: true); if (!await modelFile.exists()) await modelFile.create(recursive: true);
await modelFile.writeAsString(prettyToSource(modelLib.buildAst()));
_pen
..green()
..call(
'${Icon.CHECKMARK} Created model file "${modelFile.absolute.path}".')
..call()
..reset();
if (argResults['migration']) { 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')); deps.add(const MakerDependency('angel_migration', '^1.0.0-alpha'));
var migrationLib = new LibraryBuilder() var migrationLib = new Library((migrationLib) {
..addDirective( migrationLib
new ImportBuilder('package:angel_migration/angel_migration.dart')); ..directives.add(new Directive.import(
var migrationClazz = new ClassBuilder('${rc.pascalCase}Migration', 'package:angel_migration.dart/angel_migration.dart'))
asExtends: new TypeBuilder('Migration')); ..body.add(new Class((migrationClazz) {
migrationLib.addMember(migrationClazz); migrationClazz
..name = '${rc.pascalCase}Migration'
..extend = refer('Migration');
var tableName = pluralize(rc.snakeCase); var tableName = pluralize(rc.snakeCase);
// up() // up()
var up = new MethodBuilder('up', returnType: lib$core.$void); migrationClazz.methods.add(new Method((up) {
migrationClazz.addMethod(up); up
up.addAnnotation(lib$core.override); ..name = 'up'
up.addPositional(parameter('schema', [new TypeBuilder('Schema')])); ..returns = refer('void')
..annotations.add(refer('override'))
..requiredParameters.add(new Parameter((b) => b
..name = 'schema'
..type = refer('Schema')))
..body = new Block((block) {
// (table) { ... } // (table) { ... }
var callback = new MethodBuilder.closure(); var callback = new Method((callback) {
callback.addPositional(parameter('table')); callback
..requiredParameters
.add(new Parameter((b) => b..name = 'table'))
..body = new Block((block) {
var table = refer('table');
var cascade = reference('table').cascade((table) => [ block.addExpression(
table.invoke('serial', [literal('id')]).invoke('primaryKey', []), (table.property('serial').call([literal('id')]))
table.invoke('date', [literal('created_at')]), .property('primaryKey')
table.invoke('date', [literal('updated_at')]) .call([]),
]); );
callback.addStatement(cascade);
up.addStatement( block.addExpression(
reference('schema').invoke('create', [literal(tableName), callback])); 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() // down()
var down = new MethodBuilder('down', returnType: lib$core.$void); migrationClazz.methods.add(new Method((down) {
migrationClazz.addMethod(down); down
down.addAnnotation(lib$core.override); ..name = 'down'
down.addPositional(parameter('schema', [new TypeBuilder('Schema')])); ..returns = refer('void')
down.addStatement( ..annotations.add(refer('override'))
reference('schema').invoke('drop', [literal(tableName)])); ..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 // Save migration file
var migrationDir = new Directory.fromUri( var migrationDir = new Directory.fromUri(
Directory.current.uri.resolve(argResults['migration-dir'])); Directory.current.uri.resolve(argResults['migration-dir'] as String));
var migrationFile = var migrationFile =
new File.fromUri(migrationDir.uri.resolve('${rc.snakeCase}.dart')); new File.fromUri(migrationDir.uri.resolve('${rc.snakeCase}.dart'));
if (!await migrationFile.exists()) if (!await migrationFile.exists())
await migrationFile.create(recursive: true); await migrationFile.create(recursive: true);
await migrationFile
.writeAsString(prettyToSource(migrationLib.buildAst())); await migrationFile.writeAsString(new DartFormatter()
_pen .format(migrationLib.accept(new DartEmitter()).toString()));
..green()
..call( print(green.wrap(
'${Icon.CHECKMARK} Created migration file "${migrationFile.absolute.path}".') '$checkmark Created migration file "${migrationFile.absolute.path}".'));
..call()
..reset();
} }
if (deps.isNotEmpty) await depend(deps); if (deps.isNotEmpty) await depend(deps);

View file

@ -2,7 +2,7 @@ import 'dart:io';
import 'package:args/command_runner.dart'; import 'package:args/command_runner.dart';
import "package:console/console.dart"; import "package:console/console.dart";
import 'package:dart_style/dart_style.dart'; import 'package:dart_style/dart_style.dart';
import 'package:pubspec/pubspec.dart'; import 'package:pubspec_parse/pubspec_parse.dart';
import 'package:recase/recase.dart'; import 'package:recase/recase.dart';
import 'maker.dart'; import 'maker.dart';
@ -26,7 +26,7 @@ class PluginCommand extends Command {
@override @override
run() async { run() async {
var pubspec = await PubSpec.load(Directory.current); var pubspec = await Pubspec.load(Directory.current);
String name; String name;
if (argResults.wasParsed('name')) name = argResults['name']; if (argResults.wasParsed('name')) name = argResults['name'];
@ -56,7 +56,7 @@ class PluginCommand extends Command {
_pen(); _pen();
} }
String _generatePlugin(PubSpec pubspec, ReCase rc) { String _generatePlugin(Pubspec pubspec, ReCase rc) {
return ''' return '''
library ${pubspec.name}.src.config.plugins.${rc.snakeCase}; library ${pubspec.name}.src.config.plugins.${rc.snakeCase};

View file

@ -3,7 +3,7 @@ import 'package:args/command_runner.dart';
import 'package:code_builder/code_builder.dart'; import 'package:code_builder/code_builder.dart';
import 'package:console/console.dart'; import 'package:console/console.dart';
import 'package:inflection/inflection.dart'; import 'package:inflection/inflection.dart';
import 'package:pubspec/pubspec.dart'; import 'package:pubspec_parse/pubspec_parse.dart';
import 'package:recase/recase.dart'; import 'package:recase/recase.dart';
import '../service_generators/service_generators.dart'; import '../service_generators/service_generators.dart';
import 'maker.dart'; import 'maker.dart';
@ -32,7 +32,7 @@ class ServiceCommand extends Command {
@override @override
run() async { run() async {
var pubspec = await PubSpec.load(Directory.current); var pubspec = await Pubspec.load(Directory.current);
String name; String name;
if (argResults.wasParsed('name')) name = argResults['name']; if (argResults.wasParsed('name')) name = argResults['name'];

View file

@ -2,7 +2,7 @@ import 'dart:io';
import 'package:args/command_runner.dart'; import 'package:args/command_runner.dart';
import "package:console/console.dart"; import "package:console/console.dart";
import 'package:dart_style/dart_style.dart'; import 'package:dart_style/dart_style.dart';
import 'package:pubspec/pubspec.dart'; import 'package:pubspec_parse/pubspec_parse.dart';
import 'package:recase/recase.dart'; import 'package:recase/recase.dart';
import 'maker.dart'; import 'maker.dart';
@ -29,7 +29,7 @@ class TestCommand extends Command {
@override @override
run() async { run() async {
var pubspec = await PubSpec.load(Directory.current); var pubspec = await Pubspec.load(Directory.current);
String name; String name;
if (argResults.wasParsed('name')) name = argResults['name']; if (argResults.wasParsed('name')) name = argResults['name'];
@ -87,7 +87,7 @@ class TestCommand extends Command {
.trim(); .trim();
} }
String _generateTest(PubSpec pubspec, ReCase rc) { String _generateTest(Pubspec pubspec, ReCase rc) {
return ''' return '''
import 'dart:io'; import 'dart:io';
import 'package:${pubspec.name}/${pubspec.name}.dart'; import 'package:${pubspec.name}/${pubspec.name}.dart';

View file

@ -2,7 +2,7 @@ import 'dart:io';
import 'package:args/command_runner.dart'; import 'package:args/command_runner.dart';
import "package:console/console.dart"; import "package:console/console.dart";
import 'package:dart_style/dart_style.dart'; import 'package:dart_style/dart_style.dart';
import 'package:pubspec/pubspec.dart'; import 'package:pubspec_parse/pubspec_parse.dart';
import 'package:recase/recase.dart'; import 'package:recase/recase.dart';
import 'deprecated.dart'; import 'deprecated.dart';
@ -19,7 +19,7 @@ class PluginCommand extends Command {
run() async { run() async {
warnDeprecated(this.name, _pen); warnDeprecated(this.name, _pen);
var pubspec = await PubSpec.load(Directory.current); var pubspec = await Pubspec.load(Directory.current);
final name = await readInput("Name of Plugin: "), final name = await readInput("Name of Plugin: "),
lower = new ReCase(name).snakeCase; lower = new ReCase(name).snakeCase;
final testDir = new Directory("lib/src/config/plugins"); final testDir = new Directory("lib/src/config/plugins");
@ -35,7 +35,7 @@ class PluginCommand extends Command {
_pen(); _pen();
} }
String _generatePlugin(PubSpec pubspec, String name, String lower) { String _generatePlugin(Pubspec pubspec, String name, String lower) {
return ''' return '''
library ${pubspec.name}.config.plugins.$lower; library ${pubspec.name}.config.plugins.$lower;

View file

@ -1,26 +0,0 @@
import 'dart:async';
import 'dart:convert';
import 'package:http/src/base_client.dart' as http;
import 'package:pub_semver/pub_semver.dart';
final Version PACKAGE_VERSION = new Version(1, 2, 0, build: '5');
Future<Version> fetchCurrentVersion(http.BaseClient client) async {
var response =
await client.get('https://pub.dartlang.org/api/packages/angel_cli');
var json = JSON.decode(response.body) as Map;
if (!(json.containsKey('latest')) ||
!(json['latest'].containsKey('pubspec')) ||
!(json['latest']['pubspec'].containsKey('version'))) {
throw new StateError(
'GET https://pub.dartlang.org/api/packages/angel_cli returned an invalid pub API response.');
}
return new Version.parse(json['latest']['pubspec']['version']);
}
Future<Version> checkForUpdate(http.BaseClient client) async {
var current = await fetchCurrentVersion(client);
if (PACKAGE_VERSION.compareTo(current) < 0) {
return current;
}
return null;
}

View file

@ -4,7 +4,7 @@ import 'package:args/command_runner.dart';
import 'package:console/console.dart'; import 'package:console/console.dart';
import 'package:dart_style/dart_style.dart'; import 'package:dart_style/dart_style.dart';
import 'package:glob/glob.dart'; import 'package:glob/glob.dart';
import 'package:pubspec/pubspec.dart'; import 'package:pubspec_parse/pubspec_parse.dart';
import 'pub.dart'; import 'pub.dart';
class RenameCommand extends Command { class RenameCommand extends Command {
@ -40,7 +40,7 @@ class RenameCommand extends Command {
if (!await pubspecFile.exists()) { if (!await pubspecFile.exists()) {
throw new Exception('No pubspec.yaml found in current directory.'); throw new Exception('No pubspec.yaml found in current directory.');
} else { } else {
var pubspec = await PubSpec.load(Directory.current); var pubspec = await Pubspec.load(Directory.current);
var oldName = pubspec.name; var oldName = pubspec.name;
await renamePubspec(Directory.current, oldName, newName); await renamePubspec(Directory.current, oldName, newName);
await renameDartFiles(Directory.current, oldName, newName); await renameDartFiles(Directory.current, oldName, newName);
@ -57,8 +57,8 @@ class RenameCommand extends Command {
} }
renamePubspec(Directory dir, String oldName, String newName) async { renamePubspec(Directory dir, String oldName, String newName) async {
var pubspec = await PubSpec.load(dir); var pubspec = await Pubspec.load(dir);
var newPubspec = new PubSpec.fromJson(pubspec.toJson()..['name'] = newName); var newPubspec = new Pubspec.fromJson(pubspec.toJson()..['name'] = newName);
await newPubspec.save(dir); await newPubspec.save(dir);
} }

View file

@ -4,7 +4,7 @@ import 'package:code_builder/code_builder.dart';
import 'package:console/console.dart'; import 'package:console/console.dart';
import 'package:dart_style/dart_style.dart'; import 'package:dart_style/dart_style.dart';
import 'package:inflection/inflection.dart'; import 'package:inflection/inflection.dart';
import 'package:pubspec/pubspec.dart'; import 'package:pubspec_parse/pubspec_parse.dart';
import 'package:recase/recase.dart'; import 'package:recase/recase.dart';
import 'service_generators/service_generators.dart'; import 'service_generators/service_generators.dart';
import 'deprecated.dart'; import 'deprecated.dart';
@ -23,7 +23,7 @@ class ServiceCommand extends Command {
run() async { run() async {
warnDeprecated(this.name, _pen); warnDeprecated(this.name, _pen);
var pubspec = await PubSpec.load(Directory.current); var pubspec = await Pubspec.load(Directory.current);
var name = await readInput('Name of Service (not plural): '); var name = await readInput('Name of Service (not plural): ');
var chooser = new Chooser<String>( var chooser = new Chooser<String>(
serviceGenerators.map<String>((g) => g.name).toList(), serviceGenerators.map<String>((g) => g.name).toList(),
@ -151,7 +151,7 @@ class ServiceCommand extends Command {
} }
_generateModel( _generateModel(
PubSpec pubspec, String name, String lower, DartFormatter fmt) async { Pubspec pubspec, String name, String lower, DartFormatter fmt) async {
var file = new File('lib/src/models/$lower.dart'); var file = new File('lib/src/models/$lower.dart');
if (!await file.exists()) await file.createSync(recursive: true); if (!await file.exists()) await file.createSync(recursive: true);
@ -173,7 +173,7 @@ class $name extends Model {
} }
_generateValidator( _generateValidator(
PubSpec pubspec, String lower, ReCase rc, DartFormatter fmt) async { Pubspec pubspec, String lower, ReCase rc, DartFormatter fmt) async {
var file = new File('lib/src/validators/$lower.dart'); var file = new File('lib/src/validators/$lower.dart');
if (!await file.exists()) await file.createSync(recursive: true); if (!await file.exists()) await file.createSync(recursive: true);
@ -204,7 +204,7 @@ final Validator create${rc.pascalCase} = ${rc.camelCase}.extend({})
.trim(); .trim();
} }
_generateTests(PubSpec pubspec, String lower, DartFormatter fmt) { _generateTests(Pubspec pubspec, String lower, DartFormatter fmt) {
return fmt.format(''' return fmt.format('''
import 'dart:io'; import 'dart:io';
import 'package:${pubspec.name}/${pubspec.name}.dart'; import 'package:${pubspec.name}/${pubspec.name}.dart';

View file

@ -2,7 +2,7 @@ import 'dart:io';
import 'package:args/command_runner.dart'; import 'package:args/command_runner.dart';
import "package:console/console.dart"; import "package:console/console.dart";
import 'package:dart_style/dart_style.dart'; import 'package:dart_style/dart_style.dart';
import 'package:pubspec/pubspec.dart'; import 'package:pubspec_parse/pubspec_parse.dart';
import 'package:recase/recase.dart'; import 'package:recase/recase.dart';
import 'deprecated.dart'; import 'deprecated.dart';
@ -28,7 +28,7 @@ class TestCommand extends Command {
if (!await testFile.exists()) await testFile.create(recursive: true); if (!await testFile.exists()) await testFile.create(recursive: true);
await testFile.writeAsString(new DartFormatter() await testFile.writeAsString(new DartFormatter()
.format(_generateTest(await PubSpec.load(Directory.current), lower))); .format(_generateTest(await Pubspec.load(Directory.current), lower)));
final runConfig = new File('./.idea/runConfigurations/${name}_tests.xml'); final runConfig = new File('./.idea/runConfigurations/${name}_tests.xml');
@ -56,7 +56,7 @@ class TestCommand extends Command {
.trim(); .trim();
} }
String _generateTest(PubSpec pubspec, String lower) { String _generateTest(Pubspec pubspec, String lower) {
return ''' return '''
import 'dart:io'; import 'dart:io';
import 'package:${pubspec.name}/${pubspec.name}.dart'; import 'package:${pubspec.name}/${pubspec.name}.dart';

18
lib/src/util.dart Normal file
View file

@ -0,0 +1,18 @@
import 'dart:async';
import 'dart:io';
import 'package:io/ansi.dart';
import 'package:pubspec_parse/pubspec_parse.dart';
import 'package:yamlicious/yamlicious.dart';
final String checkmark = ansiOutputEnabled ? '\u2713' : '[Success]';
Future<Pubspec> loadPubspec() {
var file = new File('pubspec.yaml');
return file
.readAsString()
.then((yaml) => new Pubspec.parse(yaml, sourceUrl: file.uri));
}
Future savePubspec(Pubspec pubspec) async {
var text = toYamlString(pubspec);
}

View file

@ -1,30 +1,35 @@
author: "Tobe O <thosakwe@gmail.com>" author: Tobe O <thosakwe@gmail.com>
description: "Command-line tools for the Angel framework." description: Command-line tools for the Angel framework.
homepage: "https://github.com/angel-dart/angel_cli" homepage: https://github.com/angel-dart/angel_cli
name: "angel_cli" name: angel_cli
version: 1.2.0+5 version: 1.3.0
dependencies: dependencies:
# analyzer: "^0.29.0" # analyzer: ^0.29.0
args: ^0.13.4 args: ^1.0.0
code_builder: ^1.0.0 code_builder: ^3.0.0
console: "^2.2.3" #console: ^2.2.3
dart2_constant: ^1.0.0
dart_style: ^1.0.0 dart_style: ^1.0.0
glob: "^1.1.0" glob: ^1.1.0
homedir: ^0.0.4 homedir: ^0.0.4
http: ^0.11.3 http: ^0.11.3
id: "^1.0.0" id: ^1.0.0
inflection: "^0.4.1" io: ^0.3.2
mustache4dart: ^2.1.0 inflection: ^0.4.1
pubspec: "^0.0.14" #mustache4dart: ^2.1.0
random_string: "^0.0.1" path: ^1.0.0
recase: "^1.0.0" prompts: ^1.0.0
watcher: "^0.9.7" pubspec_parse: ^0.1.2
yaml: "^2.0.0" random_string: ^0.0.1
recase: ^1.0.0
watcher: ^0.9.7
yaml: ^2.0.0
yamlicious: ^0.0.5
dev_dependencies: dev_dependencies:
build: ^0.7.0 #build: ^0.7.0
build_runner: ^0.3.0 #build_runner: ^0.3.0
check_for_update: ^1.0.0 #check_for_update: ^1.0.0
environment: environment:
sdk: ">=1.19.0" sdk: ">=2.0.0-dev <3.0.0"
executables: executables:
angel: "angel" angel: angel

View file

@ -1,4 +0,0 @@
import 'package:build_runner/build_runner.dart';
import 'phases.dart';
main() => build(phaseGroup, deleteFilesByDefault: true);

View file

@ -1,6 +0,0 @@
import 'package:build_runner/build_runner.dart';
import 'package:check_for_update/builder.dart';
final PhaseGroup phaseGroup = new PhaseGroup.singleAction(
new CheckForUpdateBuilder(subDirectory: 'lib/src/commands'),
new InputSet('angel_cli', const ['pubspec.yaml']));

View file

@ -1,4 +0,0 @@
import 'package:build_runner/build_runner.dart';
import 'phases.dart';
main() => watch(phaseGroup, deleteFilesByDefault: true);