Migrated to angel3

This commit is contained in:
thomashii 2021-06-11 13:07:53 +08:00
parent a82f7479c6
commit dcd001fc65
30 changed files with 256 additions and 227 deletions

12
AUTHORS.md Normal file
View file

@ -0,0 +1,12 @@
Primary Authors
===============
* __[Thomas Hii](dukefirehawk.apps@gmail.com)__
Thomas is the current maintainer of the code base. He has refactored and migrated the
code base to support NNBD.
* __[Tobe O](thosakwe@gmail.com)__
Tobe has written much of the original code prior to NNBD migration. He has moved on and
is no longer involved with the project.

View file

@ -1,3 +1,6 @@
# 3.0.0
* Migrated to work with Dart SDK 2.12.x Non NNBD
# 2.1.7+1
* Fix a bug where new directories were not being created in
`init`.

View file

@ -1,4 +1,4 @@
# angel_cli
# angel3_cli
![Screenshot of Terminal](screenshots/screenshot.png)
@ -12,7 +12,7 @@ Includes functionality such as:
* To install:
```bash
$ pub global activate angel_cli
$ pub global activate angel3_cli
```
* Install development version
@ -22,5 +22,5 @@ $ pub global activate angel_cli
And then, for information on each command:
```bash
$ angel help
$ angel3 help
```

View file

@ -1,4 +1,5 @@
# Todo
* Migrate inflection2, mustache4dart2 and prompts packages to NNBD
* `service`
* Add tests

View file

@ -1,3 +1,4 @@
include: package:pedantic/analysis_options.yaml
analyzer:
strong-mode:
implicit-casts: false

View file

@ -1,19 +1,20 @@
#!/usr/bin/env dart
library angel_cli.tool;
import "dart:io";
import "package:args/command_runner.dart";
import 'package:angel_cli/angel_cli.dart';
library angel3_cli.tool;
import 'dart:io';
import 'package:args/command_runner.dart';
import 'package:angel3_cli/angel3_cli.dart';
import 'package:io/ansi.dart';
final String DOCTOR = "doctor";
final String DOCTOR = 'doctor';
main(List<String> args) async {
var runner = new CommandRunner(
"angel",
void main(List<String> args) async {
var runner = CommandRunner(
'angel',
asciiArt.trim() +
'\n\n' +
"Command-line tools for the Angel framework." +
'Command-line tools for the Angel framework.' +
'\n\n' +
'https://angel-dart.github.io');
@ -21,19 +22,19 @@ main(List<String> args) async {
.addFlag('verbose', help: 'Print verbose output.', negatable: false);
runner
..addCommand(new DeployCommand())
..addCommand(new DoctorCommand())
..addCommand(new KeyCommand())
..addCommand(new InitCommand())
..addCommand(new InstallCommand())
..addCommand(new RenameCommand())
..addCommand(new MakeCommand());
..addCommand(DeployCommand())
..addCommand(DoctorCommand())
..addCommand(KeyCommand())
..addCommand(InitCommand())
..addCommand(InstallCommand())
..addCommand(RenameCommand())
..addCommand(MakeCommand());
return await runner.run(args).catchError((exc, st) {
if (exc is String) {
stdout.writeln(exc);
} else {
stderr.writeln("Oops, something went wrong: $exc");
stderr.writeln('Oops, something went wrong: $exc');
if (args.contains('--verbose')) {
stderr.writeln(st);
}

View file

@ -1,3 +1,3 @@
library angel_cli;
library angel3_cli;
export 'src/commands/commands.dart';

View file

@ -1,9 +1,9 @@
library angel_cli.commands;
library angel3_cli.commands;
export "deploy.dart";
export "doctor.dart";
export "key.dart";
export "init.dart";
export "install.dart";
export "make.dart";
export "rename.dart";
export 'deploy.dart';
export 'doctor.dart';
export 'key.dart';
export 'init.dart';
export 'install.dart';
export 'make.dart';
export 'rename.dart';

View file

@ -20,7 +20,7 @@ class NginxCommand extends Command {
}
@override
run() async {
Future run() async {
var webPath = p.join(p.current, 'web');
var nginxText = '''
server {
@ -42,7 +42,7 @@ server {
if (!argResults.wasParsed('out')) {
print(nginxText);
} else {
var file = new File(argResults['out'] as String);
var file = File(argResults['out'] as String);
await file.create(recursive: true);
await file.writeAsString(nginxText);
print(green.wrap(

View file

@ -27,7 +27,7 @@ class SystemdCommand extends Command {
}
@override
run() async {
Future run() async {
var projectPath = p.absolute(p.current);
var pubspec = await loadPubspec();
var user = argResults['user'];
@ -55,7 +55,7 @@ WantedBy=multi-user.target
: p.join('etc', 'systemd', 'system');
var serviceFilename = p.join(systemdPath,
p.setExtension(argResults['install'] as String, '.service'));
var file = new File(serviceFilename);
var file = File(serviceFilename);
await file.create(recursive: true);
await file.writeAsString(systemdText);
print(green.wrap(
@ -76,7 +76,7 @@ WantedBy=multi-user.target
print(red.wrap('$ballot Failed to install service system-wide.'));
}
} else {
var file = new File(argResults['out'] as String);
var file = File(argResults['out'] as String);
await file.create(recursive: true);
await file.writeAsString(systemdText);
print(green.wrap(

View file

@ -1,34 +1,35 @@
import "dart:convert";
import "dart:io";
import "package:args/command_runner.dart";
import 'dart:convert';
import 'dart:io';
import 'package:args/command_runner.dart';
import 'package:io/ansi.dart';
import '../util.dart';
class DoctorCommand extends Command {
@override
String get name => "doctor";
String get name => 'doctor';
@override
String get description =>
"Ensures that the current system is capable of running Angel.";
'Ensures that the current system is capable of running Angel.';
@override
run() async {
print("Checking your system for dependencies...");
Future run() async {
print('Checking your system for dependencies...');
await _checkForGit();
}
_checkForGit() async {
Future _checkForGit() async {
try {
var git = await Process.start("git", ["--version"]);
var git = await Process.start('git', ['--version']);
if (await git.exitCode == 0) {
var version = await git.stdout.transform(utf8.decoder).join();
print(green.wrap(
"$checkmark Git executable found: v${version.replaceAll('git version', '').trim()}"));
} else
throw Exception("Git executable exit code not 0");
} else {
throw Exception('Git executable exit code not 0');
}
} catch (exc) {
print(red.wrap("$ballot Git executable not found"));
print(red.wrap('$ballot Git executable not found'));
}
}
}

View file

@ -1,6 +1,6 @@
import 'dart:async';
import "dart:io";
import "package:args/command_runner.dart";
import 'dart:io';
import 'package:args/command_runner.dart';
import 'package:io/ansi.dart';
import 'package:path/path.dart' as p;
import 'package:prompts/prompts.dart' as prompts;
@ -15,11 +15,11 @@ class InitCommand extends Command {
final KeyCommand _key = KeyCommand();
@override
String get name => "init";
String get name => 'init';
@override
String get description =>
"Initializes a new Angel project in the current directory.";
'Initializes a new Angel project in the current directory.';
InitCommand() {
argParser
@ -33,10 +33,10 @@ class InitCommand extends Command {
}
@override
run() async {
Directory projectDir =
Directory(argResults.rest.isEmpty ? "." : argResults.rest[0]);
print("Creating new Angel project in ${projectDir.absolute.path}...");
void run() async {
var projectDir =
Directory(argResults.rest.isEmpty ? '.' : argResults.rest[0]);
print('Creating new Angel project in ${projectDir.absolute.path}...');
await _cloneRepo(projectDir);
// await preBuild(projectDir);
var secret = rs.randomAlphaNumeric(32);
@ -64,7 +64,7 @@ class InitCommand extends Command {
await _pubGet(projectDir);
}
print(green.wrap("$checkmark Successfully initialized Angel project."));
print(green.wrap('$checkmark Successfully initialized Angel project.'));
stdout
..writeln()
@ -87,21 +87,27 @@ class InitCommand extends Command {
..writeln('Happy coding!');
}
_deleteRecursive(FileSystemEntity entity, [bool self = true]) async {
Future _deleteRecursive(FileSystemEntity entity, [bool self = true]) async {
if (entity is Directory) {
await for (var entity in entity.list(recursive: true)) {
try {
await _deleteRecursive(entity);
} catch (e) {}
} catch (e) {
print(e);
}
}
try {
if (self != false) await entity.delete(recursive: true);
} catch (e) {}
} catch (e) {
print(e);
}
} else if (entity is File) {
try {
await entity.delete(recursive: true);
} catch (e) {}
} catch (e) {
print(e);
}
} else if (entity is Link) {
var path = await entity.resolveSymbolicLinks();
var stat = await FileStat.stat(path);
@ -117,7 +123,7 @@ class InitCommand extends Command {
}
}
_cloneRepo(Directory projectDir) async {
Future _cloneRepo(Directory projectDir) async {
Directory boilerplateDir;
try {
@ -125,12 +131,12 @@ class InitCommand extends Command {
var shouldDelete = prompts.getBool(
"Directory '${projectDir.absolute.path}' already exists. Overwrite it?");
if (!shouldDelete)
throw "Chose not to overwrite existing directory.";
else if (projectDir.absolute.uri.normalizePath().toFilePath() !=
Directory.current.absolute.uri.normalizePath().toFilePath())
if (!shouldDelete) {
throw 'Chose not to overwrite existing directory.';
} else if (projectDir.absolute.uri.normalizePath().toFilePath() !=
Directory.current.absolute.uri.normalizePath().toFilePath()) {
await projectDir.delete(recursive: true);
else {
} else {
await _deleteRecursive(projectDir, false);
}
}
@ -165,11 +171,11 @@ class InitCommand extends Command {
print(darkGray.wrap(
'\$ git clone --depth 1 ${boilerplate.url} ${boilerplateDir.absolute.path}'));
git = await Process.start(
"git",
'git',
[
"clone",
"--depth",
"1",
'clone',
'--depth',
'1',
boilerplate.url,
boilerplateDir.absolute.path
],
@ -180,13 +186,13 @@ class InitCommand extends Command {
print(darkGray.wrap(
'\$ git clone --depth 1 --single-branch -b ${boilerplate.ref} ${boilerplate.url} ${boilerplateDir.absolute.path}'));
git = await Process.start(
"git",
'git',
[
"clone",
"--depth",
"1",
"--single-branch",
"-b",
'clone',
'--depth',
'1',
'--single-branch',
'-b',
boilerplate.ref,
boilerplate.url,
boilerplateDir.absolute.path
@ -196,19 +202,19 @@ class InitCommand extends Command {
}
if (await git.exitCode != 0) {
throw Exception("Could not clone repo.");
throw Exception('Could not clone repo.');
}
}
// Otherwise, pull from git.
else if (!(argResults['offline'] as bool)) {
print(darkGray.wrap('\$ git pull origin $branch'));
var git = await Process.start("git", ['pull', 'origin', '$branch'],
var git = await Process.start('git', ['pull', 'origin', '$branch'],
mode: ProcessStartMode.inheritStdio,
workingDirectory: boilerplateDir.absolute.path);
if (await git.exitCode != 0) {
print(yellow.wrap(
"Update of $branch failed. Attempting to continue with existing contents."));
'Update of $branch failed. Attempting to continue with existing contents.'));
}
} else {
print(darkGray.wrap(
@ -222,27 +228,27 @@ class InitCommand extends Command {
await preBuild(projectDir).catchError((_) => null);
}
var gitDir = Directory.fromUri(projectDir.uri.resolve(".git"));
var gitDir = Directory.fromUri(projectDir.uri.resolve('.git'));
if (await gitDir.exists()) await gitDir.delete(recursive: true);
} catch (e) {
await boilerplateDir.delete(recursive: true).catchError((_) => null);
if (e is! String) {
print(red.wrap("$ballot Could not initialize Angel project."));
print(red.wrap('$ballot Could not initialize Angel project.'));
}
rethrow;
}
}
_pubGet(Directory projectDir) async {
Future _pubGet(Directory projectDir) async {
var pubPath = resolvePub();
print(darkGray.wrap('Running pub at "$pubPath"...'));
print(darkGray.wrap('\$ $pubPath get'));
var pub = await Process.start(pubPath, ["get"],
var pub = await Process.start(pubPath, ['get'],
workingDirectory: projectDir.absolute.path,
mode: ProcessStartMode.inheritStdio);
var code = await pub.exitCode;
print("Pub process exited with code $code");
print('Pub process exited with code $code');
}
}
@ -261,49 +267,49 @@ Future preBuild(Directory projectDir) async {
if (buildCode != 0) throw Exception('Failed to pre-build resources.');
}
const RepoArchiveLocation = "https://github.com/angel-dart";
const RepoLocation = "https://github.com/dukefirehawk";
const RepoArchiveLocation = 'https://github.com/angel-dart';
const RepoLocation = 'https://github.com/dukefirehawk';
const BoilerplateInfo graphQLBoilerplate = const BoilerplateInfo(
const BoilerplateInfo graphQLBoilerplate = BoilerplateInfo(
'GraphQL',
"A starting point for GraphQL API servers.",
'${RepoLocation}/boilerplates.git',
'A starting point for GraphQL API servers.',
'$RepoLocation/boilerplates.git',
ref: 'graphql-sdk-2.12.x',
);
const BoilerplateInfo ormBoilerplate = const BoilerplateInfo(
const BoilerplateInfo ormBoilerplate = BoilerplateInfo(
'ORM',
"A starting point for applications that use Angel's ORM.",
'${RepoLocation}/boilerplates.git',
'$RepoLocation/boilerplates.git',
ref: 'orm-sdk-2.12.x',
);
const BoilerplateInfo basicBoilerplate = const BoilerplateInfo(
const BoilerplateInfo basicBoilerplate = BoilerplateInfo(
'Basic',
'Minimal starting point for Angel 2.x - A simple server with only a few additional packages.',
'${RepoLocation}/boilerplates.git',
'$RepoLocation/boilerplates.git',
ref: 'basic-sdk-2.12.x');
const BoilerplateInfo legacyBoilerplate = const BoilerplateInfo(
const BoilerplateInfo legacyBoilerplate = BoilerplateInfo(
'Legacy',
'Minimal starting point for applications running Angel 1.1.x.',
'${RepoArchiveLocation}/angel.git',
'$RepoArchiveLocation/angel.git',
ref: '1.1.x',
);
const BoilerplateInfo sharedBoilerplate = const BoilerplateInfo(
const BoilerplateInfo sharedBoilerplate = BoilerplateInfo(
'Shared',
'Holds common models and files shared across multiple Dart projects.',
'${RepoLocation}/boilerplate_shared.git');
'$RepoLocation/boilerplate_shared.git');
const BoilerplateInfo sharedOrmBoilerplate = const BoilerplateInfo(
const BoilerplateInfo sharedOrmBoilerplate = BoilerplateInfo(
'Shared (ORM)',
'Holds common models and files shared across multiple Dart projects.',
'${RepoLocation}/boilerplate_shared.git',
'$RepoLocation/boilerplate_shared.git',
ref: 'orm',
);
const List<BoilerplateInfo> boilerplates = const [
const List<BoilerplateInfo> boilerplates = [
basicBoilerplate,
//legacyBoilerplate,
ormBoilerplate,
@ -317,7 +323,7 @@ class BoilerplateInfo {
final bool needsPrebuild;
const BoilerplateInfo(this.name, this.description, this.url,
{this.ref, this.needsPrebuild: false});
{this.ref, this.needsPrebuild = false});
@override
String toString() => '$name ($description)';

View file

@ -46,7 +46,7 @@ class InstallCommand extends Command {
}
@override
run() async {
Future run() async {
print(yellow.wrap(
'WARNING: The `install` command is no longer considered necessary, and has been deprecated.\n'
'Expect it to be removed in an upcoming release.\n\n'
@ -65,8 +65,9 @@ class InstallCommand extends Command {
} else if (argResults['update'] as bool) {
await update();
} else if (argResults.rest.isNotEmpty) {
if (!await installRepo.exists())
if (!await installRepo.exists()) {
throw 'No local add-on database exists. Run `angel install --update` first.';
}
var pubspec = await loadPubspec();
@ -74,8 +75,9 @@ class InstallCommand extends Command {
var packageDir =
Directory.fromUri(installRepo.uri.resolve(packageName));
if (!await packageDir.exists())
if (!await packageDir.exists()) {
throw 'No add-on named "$packageName" is installed. You might need to run `angel install --update`.';
}
print('Installing $packageName...');
Map values = {
@ -83,14 +85,15 @@ class InstallCommand extends Command {
'pubspec': pubspec,
};
List<Glob> globs = [];
var globs = <Glob>[];
var projectPubspec = await loadPubspec(packageDir);
var deps = projectPubspec.dependencies.keys
.map((k) {
var dep = projectPubspec.dependencies[k];
if (dep is HostedDependency)
if (dep is HostedDependency) {
return MakerDependency(k, dep.version.toString());
}
return null;
})
.where((d) => d != null)
@ -98,8 +101,9 @@ class InstallCommand extends Command {
deps.addAll(projectPubspec.devDependencies.keys.map((k) {
var dep = projectPubspec.devDependencies[k];
if (dep is HostedDependency)
if (dep is HostedDependency) {
return MakerDependency(k, dep.version.toString(), dev: true);
}
return null;
}).where((d) => d != null));
@ -151,7 +155,7 @@ class InstallCommand extends Command {
var name = p.basename(entity.path);
var target = dst.uri.resolve(name);
var targetFile = File.fromUri(target);
bool allClear = !await targetFile.exists();
var allClear = !await targetFile.exists();
if (!allClear) {
print('The file ${entity.absolute.path} already exists.');
@ -199,7 +203,7 @@ class InstallCommand extends Command {
if (!await installRepo.exists()) {
throw 'No local add-on database exists. Run `angel install --update` first.';
} else {
List<Pubspec> repos = [];
var repos = <Pubspec>[];
await for (var entity in installRepo.list()) {
if (entity is Directory) {

View file

@ -10,7 +10,7 @@ class KeyCommand extends Command {
String get description => 'Generates a new `angel_auth` key.';
@override
run() async {
Future run() async {
var secret = rs.randomAlphaNumeric(32);
print('Generated new development JWT secret: $secret');
await changeSecret(File('config/default.yaml'), secret);
@ -20,7 +20,7 @@ class KeyCommand extends Command {
await changeSecret(File('config/production.yaml'), secret);
}
changeSecret(File file, String secret) async {
Future changeSecret(File file, String secret) async {
if (await file.exists()) {
var contents = await file.readAsString();
contents = contents.replaceAll(RegExp(r'jwt_secret:[^\n]+\n?'), '');

View file

@ -30,8 +30,7 @@ class ControllerCommand extends Command {
}
@override
run() async {
var pubspec = await loadPubspec();
Future run() async {
String name;
if (argResults.wasParsed('name')) name = argResults['name'] as String;
@ -39,24 +38,24 @@ class ControllerCommand extends Command {
name = prompts.get('Name of controller class');
}
List<MakerDependency> deps = [
var deps = <MakerDependency>[
const MakerDependency('angel_framework', '^2.0.0')
];
//${pubspec.name}.src.models.${rc.snakeCase}
var rc = new ReCase(name);
var controllerLib = new Library((controllerLib) {
var rc = ReCase(name);
var controllerLib = Library((controllerLib) {
if (argResults['websocket'] as bool) {
deps.add(const MakerDependency('angel_websocket', '^2.0.0'));
controllerLib.directives
.add(new Directive.import('package:angel_websocket/server.dart'));
.add(Directive.import('package:angel_websocket/server.dart'));
} else {
controllerLib.directives.add(new Directive.import(
'package:angel_framework/angel_framework.dart'));
controllerLib.directives.add(
Directive.import('package:angel_framework/angel_framework.dart'));
}
controllerLib.body.add(new Class((clazz) {
controllerLib.body.add(Class((clazz) {
clazz
..name = '${rc.pascalCase}Controller'
..extend = refer(argResults['websocket'] as bool
@ -65,24 +64,24 @@ class ControllerCommand extends Command {
if (argResults['websocket'] as bool) {
// XController(AngelWebSocket ws) : super(ws);
clazz.constructors.add(new Constructor((b) {
clazz.constructors.add(Constructor((b) {
b
..requiredParameters.add(new Parameter((b) => b
..requiredParameters.add(Parameter((b) => b
..name = 'ws'
..type = refer('AngelWebSocket')))
..initializers.add(new Code('super(ws)'));
..initializers.add(Code('super(ws)'));
}));
clazz.methods.add(new Method((meth) {
clazz.methods.add(Method((meth) {
meth
..name = 'hello'
..returns = refer('void')
..annotations
.add(refer('ExposeWs').call([literal('get_${rc.snakeCase}')]))
..requiredParameters.add(new Parameter((b) => b
..requiredParameters.add(Parameter((b) => b
..name = 'socket'
..type = refer('WebSocketContext')))
..body = new Block((block) {
..body = Block((block) {
block.addExpression(refer('socket').property('send').call([
literal('got_${rc.snakeCase}'),
literalMap({'message': literal('Hello, world!')}),
@ -93,7 +92,7 @@ class ControllerCommand extends Command {
clazz
..annotations
.add(refer('Expose').call([literal('/${rc.snakeCase}')]))
..methods.add(new Method((meth) {
..methods.add(Method((meth) {
meth
..name = 'hello'
..returns = refer('String')
@ -106,14 +105,15 @@ class ControllerCommand extends Command {
}));
});
var outputDir = new Directory.fromUri(
var outputDir = Directory.fromUri(
Directory.current.uri.resolve(argResults['output-dir'] as String));
var controllerFile =
new File.fromUri(outputDir.uri.resolve('${rc.snakeCase}.dart'));
if (!await controllerFile.exists())
File.fromUri(outputDir.uri.resolve('${rc.snakeCase}.dart'));
if (!await controllerFile.exists()) {
await controllerFile.create(recursive: true);
await controllerFile.writeAsString(new DartFormatter()
.format(controllerLib.accept(new DartEmitter()).toString()));
}
await controllerFile.writeAsString(
DartFormatter().format(controllerLib.accept(DartEmitter()).toString()));
print(green.wrap(
'$checkmark Created controller file "${controllerFile.absolute.path}"'));

View file

@ -18,10 +18,11 @@ Future depend(Iterable<MakerDependency> deps) async {
for (var dep in deps) {
var isPresent = false;
if (dep.dev)
if (dep.dev) {
isPresent = pubspec.devDependencies.containsKey(dep.name);
else
} else {
isPresent = pubspec.dependencies.containsKey(dep.name);
}
if (!isPresent) {
missing.add(dep);

View file

@ -3,7 +3,7 @@ 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:inflection2/inflection2.dart';
import 'package:inflection3/inflection3.dart';
import 'package:io/ansi.dart';
import 'package:prompts/prompts.dart' as prompts;
import 'package:recase/recase.dart';

View file

@ -32,7 +32,7 @@ class ModelCommand extends Command {
}
@override
run() async {
Future run() async {
String name;
if (argResults.wasParsed('name')) name = argResults['name'] as String;
@ -40,16 +40,16 @@ class ModelCommand extends Command {
name = prompts.get('Name of model class');
}
List<MakerDependency> deps = [
var deps = <MakerDependency>[
const MakerDependency('angel_model', '^1.0.0'),
];
var rc = new ReCase(name);
var rc = ReCase(name);
var modelLib = new Library((modelLib) {
var modelLib = Library((modelLib) {
if (argResults['orm'] as bool && argResults['migration'] as bool) {
modelLib.directives.addAll([
new Directive.import('package:angel_migration/angel_migration.dart'),
Directive.import('package:angel_migration/angel_migration.dart'),
]);
}
@ -58,8 +58,8 @@ class ModelCommand extends Command {
// argResults['migration'] as bool;
if (needsSerialize) {
modelLib.directives.add(new Directive.import(
'package:angel_serialize/angel_serialize.dart'));
modelLib.directives.add(
Directive.import('package:angel_serialize/angel_serialize.dart'));
deps.add(const MakerDependency('angel_serialize', '^2.0.0'));
deps.add(const MakerDependency('angel_serialize_generator', '^2.0.0'));
deps.add(const MakerDependency('build_runner', '^1.0.0'));
@ -73,16 +73,16 @@ class ModelCommand extends Command {
if (argResults['orm'] as bool) {
modelLib.directives.addAll([
new Directive.import('package:angel_orm/angel_orm.dart'),
Directive.import('package:angel_orm/angel_orm.dart'),
]);
deps.add(const MakerDependency('angel_orm', '^2.0.0'));
}
modelLib.body.addAll([
new Code("part '${rc.snakeCase}.g.dart';"),
Code("part '${rc.snakeCase}.g.dart';"),
]);
modelLib.body.add(new Class((modelClazz) {
modelLib.body.add(Class((modelClazz) {
modelClazz
..abstract = true
..name = needsSerialize ? '_${rc.pascalCase}' : rc.pascalCase
@ -105,14 +105,13 @@ class ModelCommand extends Command {
});
// Save model file
var outputDir = new Directory.fromUri(
var outputDir = Directory.fromUri(
Directory.current.uri.resolve(argResults['output-dir'] as String));
var modelFile =
new File.fromUri(outputDir.uri.resolve('${rc.snakeCase}.dart'));
var modelFile = 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()));
await modelFile.writeAsString(
DartFormatter().format(modelLib.accept(DartEmitter()).toString()));
print(green
.wrap('$checkmark Created model file "${modelFile.absolute.path}".'));

View file

@ -10,10 +10,10 @@ import 'maker.dart';
class PluginCommand extends Command {
@override
String get name => "plugin";
String get name => 'plugin';
@override
String get description => "Creates a new plug-in within the given project.";
String get description => 'Creates a new plug-in within the given project.';
PluginCommand() {
argParser
@ -25,7 +25,7 @@ class PluginCommand extends Command {
}
@override
run() async {
Future run() async {
var pubspec = await loadPubspec();
String name;
if (argResults.wasParsed('name')) name = argResults['name'] as String;
@ -34,18 +34,18 @@ class PluginCommand extends Command {
name = prompts.get('Name of plug-in class');
}
List<MakerDependency> deps = [
var deps = <MakerDependency>[
const MakerDependency('angel_framework', '^2.0.0')
];
var rc = new ReCase(name);
final pluginDir = new Directory.fromUri(
var rc = ReCase(name);
final pluginDir = Directory.fromUri(
Directory.current.uri.resolve(argResults['output-dir'] as String));
final pluginFile =
new File.fromUri(pluginDir.uri.resolve("${rc.snakeCase}.dart"));
File.fromUri(pluginDir.uri.resolve('${rc.snakeCase}.dart'));
if (!await pluginFile.exists()) await pluginFile.create(recursive: true);
await pluginFile.writeAsString(
new DartFormatter().format(_generatePlugin(pubspec, rc)));
await pluginFile
.writeAsString(DartFormatter().format(_generatePlugin(pubspec, rc)));
if (deps.isNotEmpty) await depend(deps);

View file

@ -2,10 +2,9 @@ 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:inflection2/inflection2.dart';
import 'package:inflection3/inflection3.dart';
import 'package:io/ansi.dart';
import 'package:prompts/prompts.dart' as prompts;
import 'package:pubspec_parse/pubspec_parse.dart';
import 'package:recase/recase.dart';
import '../service_generators/service_generators.dart';
import '../../util.dart';
@ -46,8 +45,8 @@ class ServiceCommand extends Command {
];
// '${pubspec.name}.src.services.${rc.snakeCase}'
var rc = new ReCase(name);
var serviceLib = new Library((serviceLib) {
var rc = ReCase(name);
var serviceLib = Library((serviceLib) {
var generator = prompts.choose(
'Choose which type of service to create', serviceGenerators);
@ -64,37 +63,37 @@ class ServiceCommand extends Command {
if (generator.goesFirst) {
generator.applyToLibrary(serviceLib, name, rc.snakeCase);
serviceLib.directives.add(new Directive.import(
'package:angel_framework/angel_framework.dart'));
serviceLib.directives.add(
Directive.import('package:angel_framework/angel_framework.dart'));
} else {
serviceLib.directives.add(new Directive.import(
'package:angel_framework/angel_framework.dart'));
serviceLib.directives.add(
Directive.import('package:angel_framework/angel_framework.dart'));
generator.applyToLibrary(serviceLib, name, rc.snakeCase);
}
if (argResults['typed'] as bool) {
serviceLib.directives
.add(new Directive.import('../models/${rc.snakeCase}.dart'));
.add(Directive.import('../models/${rc.snakeCase}.dart'));
}
// configureServer() {}
serviceLib.body.add(new Method((configureServer) {
serviceLib.body.add(Method((configureServer) {
configureServer
..name = 'configureServer'
..returns = refer('AngelConfigurer');
configureServer.body = new Block((block) {
configureServer.body = Block((block) {
generator.applyToConfigureServer(
serviceLib, configureServer, block, name, rc.snakeCase);
// return (Angel app) async {}
var closure = new Method((closure) {
var closure = Method((closure) {
closure
..modifier = MethodModifier.async
..requiredParameters.add(new Parameter((b) => b
..requiredParameters.add(Parameter((b) => b
..name = 'app'
..type = refer('Angel')));
closure.body = new Block((block) {
closure.body = Block((block) {
generator.beforeService(serviceLib, block, name, rc.snakeCase);
// app.use('/api/todos', new MapService());
@ -102,7 +101,7 @@ class ServiceCommand extends Command {
serviceLib, closure, name, rc.snakeCase);
if (argResults['typed'] as bool) {
var tb = new TypeReference((b) => b
var tb = TypeReference((b) => b
..symbol = 'TypedService'
..types.add(refer(rc.pascalCase)));
service = tb.newInstance([service]);
@ -120,13 +119,13 @@ class ServiceCommand extends Command {
}));
});
final outputDir = new Directory.fromUri(
final outputDir = Directory.fromUri(
Directory.current.uri.resolve(argResults['output-dir'] as String));
final serviceFile =
new File.fromUri(outputDir.uri.resolve("${rc.snakeCase}.dart"));
File.fromUri(outputDir.uri.resolve("${rc.snakeCase}.dart"));
if (!await serviceFile.exists()) await serviceFile.create(recursive: true);
await serviceFile.writeAsString(new DartFormatter()
.format(serviceLib.accept(new DartEmitter()).toString()));
await serviceFile.writeAsString(
DartFormatter().format(serviceLib.accept(DartEmitter()).toString()));
print(green.wrap(
'$checkmark Successfully generated service file "${serviceFile.absolute.path}".'));

View file

@ -10,10 +10,10 @@ import 'maker.dart';
class TestCommand extends Command {
@override
String get name => "test";
String get name => 'test';
@override
String get description => "Creates a new test within the given project.";
String get description => 'Creates a new test within the given project.';
TestCommand() {
argParser
@ -28,7 +28,7 @@ class TestCommand extends Command {
}
@override
run() async {
Future run() async {
var pubspec = await loadPubspec();
String name;
if (argResults.wasParsed('name')) name = argResults['name'] as String;
@ -37,20 +37,20 @@ class TestCommand extends Command {
name = prompter.get('Name of test');
}
List<MakerDependency> deps = [
var deps = <MakerDependency>[
const MakerDependency('angel_framework', '^2.0.0'),
const MakerDependency('angel_test', '^2.0.0', dev: true),
const MakerDependency('test', '^1.0.0', dev: true),
];
var rc = new ReCase(name);
final testDir = new Directory.fromUri(
var rc = ReCase(name);
final testDir = Directory.fromUri(
Directory.current.uri.resolve(argResults['output-dir'] as String));
final testFile =
new File.fromUri(testDir.uri.resolve("${rc.snakeCase}_test.dart"));
File.fromUri(testDir.uri.resolve('${rc.snakeCase}_test.dart'));
if (!await testFile.exists()) await testFile.create(recursive: true);
await testFile
.writeAsString(new DartFormatter().format(_generateTest(pubspec, rc)));
.writeAsString(DartFormatter().format(_generateTest(pubspec, rc)));
if (deps.isNotEmpty) await depend(deps);
@ -58,7 +58,7 @@ class TestCommand extends Command {
'$checkmark Successfully generated test file "${testFile.absolute.path}".'));
if (argResults['run-configuration'] as bool) {
final runConfig = new File.fromUri(Directory.current.uri
final runConfig = File.fromUri(Directory.current.uri
.resolve('.idea/runConfigurations/${name}_Tests.xml'));
if (!await runConfig.exists()) await runConfig.create(recursive: true);

View file

@ -5,8 +5,9 @@ final RegExp _leadingSlashes = RegExp(r'^/+');
String resolvePub() {
var exec = File(Platform.resolvedExecutable);
var pubPath = exec.parent.uri.resolve('pub').path;
if (Platform.isWindows)
if (Platform.isWindows) {
pubPath = pubPath.replaceAll(_leadingSlashes, '') + '.bat';
}
pubPath = Uri.decodeFull(pubPath);
return pubPath;
}

View file

@ -8,8 +8,6 @@ import 'package:glob/list_local_fs.dart';
import 'package:io/ansi.dart';
import 'package:prompts/prompts.dart' as prompts;
import 'package:recase/recase.dart';
import '../util.dart';
import 'pub.dart';
class RenameCommand extends Command {
@override
@ -22,12 +20,12 @@ class RenameCommand extends Command {
String get invocation => '$name <new name>';
@override
run() async {
Future run() async {
String newName;
if (argResults.rest.isNotEmpty)
if (argResults.rest.isNotEmpty) {
newName = argResults.rest.first;
else {
} else {
newName = prompts.get('Rename project to');
}
@ -63,7 +61,7 @@ class RenameCommand extends Command {
}
}
renamePubspec(Directory dir, String oldName, String newName) async {
Future renamePubspec(Directory dir, String oldName, String newName) async {
// var pubspec = await loadPubspec(dir);
print(cyan.wrap('Renaming your project to `$newName.`'));
@ -86,7 +84,7 @@ renamePubspec(Directory dir, String oldName, String newName) async {
// await newPubspec.save(dir);
}
renameDartFiles(Directory dir, String oldName, String newName) async {
Future renameDartFiles(Directory dir, String oldName, String newName) async {
if (!await dir.exists()) return;
// Try to replace MongoDB URL
@ -154,24 +152,25 @@ class RenamingVisitor extends RecursiveAstVisitor {
return 'package:$newName/$newName.dart';
} else if (uri.startsWith('package:$oldName/')) {
return 'package:$newName/' + uri.replaceFirst('package:$oldName/', '');
} else
} else {
return uri;
}
}
@override
visitExportDirective(ExportDirective ctx) {
void visitExportDirective(ExportDirective ctx) {
var uri = ctx.uri.stringValue, updated = updateUri(uri);
if (uri != updated) replace[[uri]] = updated;
}
@override
visitImportDirective(ImportDirective ctx) {
void visitImportDirective(ImportDirective ctx) {
var uri = ctx.uri.stringValue, updated = updateUri(uri);
if (uri != updated) replace[[uri]] = updated;
}
@override
visitLibraryDirective(LibraryDirective ctx) {
void visitLibraryDirective(LibraryDirective ctx) {
var name = ctx.name.name;
if (name.startsWith(oldName)) {
@ -181,7 +180,7 @@ class RenamingVisitor extends RecursiveAstVisitor {
}
@override
visitPartOfDirective(PartOfDirective ctx) {
void visitPartOfDirective(PartOfDirective ctx) {
if (ctx.libraryName != null) {
var name = ctx.libraryName.name;

View file

@ -1,6 +1,6 @@
import 'generator.dart';
import 'package:code_builder/code_builder.dart';
import 'package:inflection2/inflection2.dart';
import 'package:inflection3/inflection3.dart';
import '../make/maker.dart';
class FileServiceGenerator extends ServiceGenerator {
@ -8,7 +8,7 @@ class FileServiceGenerator extends ServiceGenerator {
@override
List<MakerDependency> get dependencies =>
const [const MakerDependency('angel_file_service', '^2.0.0')];
const [MakerDependency('angel_file_service', '^2.0.0')];
@override
bool get goesFirst => true;

View file

@ -1,6 +1,6 @@
import 'generator.dart';
import 'package:code_builder/code_builder.dart';
import 'package:inflection2/inflection2.dart';
import 'package:inflection3/inflection3.dart';
import '../make/maker.dart';
class MongoServiceGenerator extends ServiceGenerator {
@ -8,7 +8,7 @@ class MongoServiceGenerator extends ServiceGenerator {
@override
List<MakerDependency> get dependencies =>
const [const MakerDependency('angel_mongo', '^2.0.0')];
const [MakerDependency('angel_mongo', '^2.0.0')];
@override
bool get createsModel => false;
@ -20,7 +20,7 @@ class MongoServiceGenerator extends ServiceGenerator {
BlockBuilder block,
String name,
String lower) {
configureServer.requiredParameters.add(new Parameter((b) => b
configureServer.requiredParameters.add(Parameter((b) => b
..name = 'db'
..type = refer('Db')));
}
@ -28,8 +28,8 @@ class MongoServiceGenerator extends ServiceGenerator {
@override
void applyToLibrary(LibraryBuilder library, String name, String lower) {
library.directives.addAll([
new Directive.import('package:angel_mongo/angel_mongo.dart'),
new Directive.import('package:mongo_dart/mongo_dart.dart'),
Directive.import('package:angel_mongo/angel_mongo.dart'),
Directive.import('package:mongo_dart/mongo_dart.dart'),
]);
}

View file

@ -1,6 +1,6 @@
import 'generator.dart';
import 'package:code_builder/code_builder.dart';
import 'package:inflection2/inflection2.dart';
import 'package:inflection3/inflection3.dart';
import '../make/maker.dart';
class RethinkServiceGenerator extends ServiceGenerator {
@ -8,7 +8,7 @@ class RethinkServiceGenerator extends ServiceGenerator {
@override
List<MakerDependency> get dependencies =>
const [const MakerDependency('angel_rethink', '^2.0.0')];
const [MakerDependency('angel_rethink', '^2.0.0')];
@override
bool get createsModel => false;
@ -21,10 +21,10 @@ class RethinkServiceGenerator extends ServiceGenerator {
String name,
String lower) {
configureServer.requiredParameters.addAll([
new Parameter((b) => b
Parameter((b) => b
..name = 'connection'
..type = refer('Connection')),
new Parameter((b) => b
Parameter((b) => b
..name = 'r'
..type = refer('Rethinkdb')),
]);
@ -35,7 +35,7 @@ class RethinkServiceGenerator extends ServiceGenerator {
library.directives.addAll([
'package:angel_rethink/angel_rethink.dart',
'package:rethinkdb_dart/rethinkdb_dart.dart'
].map((str) => new Directive.import(str)));
].map((str) => Directive.import(str)));
}
@override

View file

@ -6,10 +6,10 @@ import 'mongo.dart';
import 'rethink.dart';
export 'generator.dart';
const List<ServiceGenerator> serviceGenerators = const [
const MapServiceGenerator(),
const FileServiceGenerator(),
const MongoServiceGenerator(),
const RethinkServiceGenerator(),
const CustomServiceGenerator()
const List<ServiceGenerator> serviceGenerators = [
MapServiceGenerator(),
FileServiceGenerator(),
MongoServiceGenerator(),
RethinkServiceGenerator(),
CustomServiceGenerator()
];

View file

@ -7,7 +7,7 @@ final Random _rnd = Random.secure();
String randomAlphaNumeric(int length) {
var b = StringBuffer();
for (int i = 0; i < length; i++) {
for (var i = 0; i < length; i++) {
b.writeCharCode(_valid.codeUnitAt(_rnd.nextInt(_valid.length)));
}

View file

@ -12,16 +12,16 @@ final String ballot = ansiOutputEnabled ? '\u2717' : '[Failure]';
String get homeDirPath =>
Platform.environment['HOME'] ?? Platform.environment['USERPROFILE'];
Directory get homeDir => new Directory(homeDirPath);
Directory get homeDir => Directory(homeDirPath);
Directory get angelDir => Directory(p.join(homeDir.path, '.angel'));
Future<Pubspec> loadPubspec([Directory directory]) {
directory ??= Directory.current;
var file = new File.fromUri(directory.uri.resolve('pubspec.yaml'));
var file = File.fromUri(directory.uri.resolve('pubspec.yaml'));
return file
.readAsString()
.then((yaml) => new Pubspec.parse(yaml, sourceUrl: file.uri));
.then((yaml) => Pubspec.parse(yaml, sourceUrl: file.uri));
}
// From: https://gist.github.com/tobischw/98dcd2563eec9a2a87bda8299055358a

View file

@ -1,8 +1,7 @@
#author: Tobe O <thosakwe@gmail.com>
description: Command-line tools for the Angel framework, including scaffolding.
homepage: https://github.com/dukefirehawk/angel/packages/angel_cli
name: angel_cli
name: angel3_cli
version: 3.0.0
description: Command-line tools for the Angel framework, including scaffolding.
homepage: https://github.com/dukefirehawk/angel3_cli
environment:
sdk: ">=2.10.0 <3.0.0"
dependencies:
@ -13,7 +12,7 @@ dependencies:
glob: ^2.0.0
http: ^0.13.0
io: ^0.3.5
inflection2: ^0.4.2
inflection3: ^0.5.0
mustache4dart2: ^0.1.0
path: ^1.0.0
prompts: ^1.3.1
@ -23,5 +22,7 @@ dependencies:
shutdown: ^0.4.0
watcher: ^1.0.0
yaml: ^3.0.0
dev_dependencies:
pedantic: ^1.11.0
executables:
angel: angel
angel3: angel3