diff --git a/bin/angel.dart b/bin/angel.dart index d16d426..f07a31f 100644 --- a/bin/angel.dart +++ b/bin/angel.dart @@ -13,6 +13,7 @@ main(List args) { runner ..addCommand(new DoctorCommand()) + ..addCommand(new KeyCommand()) ..addCommand(new ServiceCommand()) ..addCommand(new InitCommand()) ..addCommand(new TestCommand()) diff --git a/lib/src/commands/commands.dart b/lib/src/commands/commands.dart index 7e82dcc..1cda4c4 100644 --- a/lib/src/commands/commands.dart +++ b/lib/src/commands/commands.dart @@ -1,6 +1,7 @@ library angel_cli.commands; export "doctor.dart"; +export "key.dart"; export "init.dart"; export "plugin.dart"; export "service.dart"; diff --git a/lib/src/commands/init.dart b/lib/src/commands/init.dart index 68adc2a..856b0eb 100644 --- a/lib/src/commands/init.dart +++ b/lib/src/commands/init.dart @@ -2,8 +2,11 @@ import "dart:convert"; import "dart:io"; import "package:args/command_runner.dart"; import "package:console/console.dart"; +import 'package:random_string/random_string.dart' as rs; +import 'key.dart'; class InitCommand extends Command { + final KeyCommand _key = new KeyCommand(); final TextPen _pen = new TextPen(); @override @@ -20,10 +23,20 @@ class InitCommand extends Command { Directory projectDir = new Directory( argResults.arguments.isEmpty ? "." : argResults.arguments[0]); print("Creating new Angel project in ${projectDir.absolute.path}..."); - await _cloneRepo(projectDir);_pen.green(); - _pen("${Icon.CHECKMARK} Successfully initialized Angel project. Now running pub get..."); + await _cloneRepo(projectDir); + _pen.green(); + _pen( + "${Icon.CHECKMARK} Successfully initialized Angel project. Now running pub get..."); _pen(); await _pubGet(projectDir); + var secret = rs.randomAlphaNumeric(32); + print('Generated new JWT secret: $secret'); + await _key.changeSecret( + new File.fromUri(projectDir.uri.resolve('config/default.yaml')), + secret); + await _key.changeSecret( + new File.fromUri(projectDir.uri.resolve('config/production.yaml')), + secret); } _cloneRepo(Directory projectDir) async { @@ -55,8 +68,7 @@ class InitCommand extends Command { var gitDir = new Directory.fromUri(projectDir.uri.resolve(".git")); - if (await gitDir.exists()) - await gitDir.delete(recursive: true); + if (await gitDir.exists()) await gitDir.delete(recursive: true); } catch (e) { print(e); _pen.red(); @@ -67,7 +79,8 @@ class InitCommand extends Command { } _pubGet(Directory projectDir) async { - var pub = await Process.start("pub", ["get"], workingDirectory: projectDir.absolute.path); + var pub = await Process.start("pub", ["get"], + workingDirectory: projectDir.absolute.path); pub.stdout.pipe(stdout); pub.stderr.pipe(stderr); var code = await pub.exitCode; diff --git a/lib/src/commands/key.dart b/lib/src/commands/key.dart new file mode 100644 index 0000000..5f311e3 --- /dev/null +++ b/lib/src/commands/key.dart @@ -0,0 +1,37 @@ +import 'dart:convert'; +import 'dart:io'; +import 'package:args/command_runner.dart'; +import 'package:random_string/random_string.dart' as rs; + +class KeyCommand extends Command { + @override + String get name => 'key'; + + @override + String get description => 'Generates a new `angel_auth`key.'; + + @override + run() async { + var secret = rs.randomAlphaNumeric(32); + print('Generated new JWT secret: $secret'); + await changeSecret(new File('config/default.yaml'), secret); + await changeSecret(new File('config/production.yaml'), secret); + } + + changeSecret(File file, String secret) async { + if (await file.exists()) { + var sink = await file.openWrite(); + + await for (var chunk + in await file.openRead().transform(UTF8.decoder)) { + var lines = chunk.split('\n'); + + for (String line in lines) { + if (line.contains('jwt_secret:')) { + sink.writeln('jwt_secret: $secret'); + } else sink.writeln(line); + } + } + } + } +} diff --git a/lib/src/commands/start.dart b/lib/src/commands/start.dart index 1524ada..9950a2e 100644 --- a/lib/src/commands/start.dart +++ b/lib/src/commands/start.dart @@ -1,7 +1,11 @@ import 'dart:io'; import 'package:args/command_runner.dart'; +import 'package:watcher/watcher.dart'; import 'package:yaml/yaml.dart'; +Process server; +bool watching = false; + class StartCommand extends Command { @override String get name => 'start'; @@ -11,14 +15,38 @@ class StartCommand extends Command { 'Runs any `start` scripts, and then runs the server.'; StartCommand() : super() { - argParser.addFlag('production', - help: 'Starts the server in production mode.', - negatable: false, - defaultsTo: false); + argParser + ..addFlag('production', + help: 'Starts the server in production mode.', + negatable: false, + defaultsTo: false) + ..addFlag('watch', + abbr: 'w', + help: 'Restart the server on file changes.', + defaultsTo: true); } @override run() async { + if (argResults['watch']) { + new DirectoryWatcher('bin').events.listen((_) async => start()); + new DirectoryWatcher('config').events.listen((_) async => start()); + new DirectoryWatcher('lib').events.listen((_) async => start()); + } + + return await start(); + } + + start() async { + bool isNew = true; + if (server != null) { + isNew = false; + + if (!server.kill()) { + throw new Exception('Could not kill existing server process.'); + } + } + final pubspec = new File('pubspec.yaml'); if (await pubspec.exists()) { @@ -43,16 +71,30 @@ class StartCommand extends Command { } } - print('Starting server...'); + if (isNew) + print('Starting server...'); + else + print('Changes detected - restarting server...'); final env = {}; if (argResults['production']) env['ANGEL_ENV'] = 'production'; - final server = await Process.start(Platform.executable, ['bin/server.dart'], + server = await Process.start(Platform.executable, ['bin/server.dart'], environment: env); - server.stdout.pipe(stdout); - server.stderr.pipe(stderr); + + try { + if (isNew) { + server.stdout.pipe(stdout); + server.stderr.pipe(stderr); + } + } catch (e) { + print(e); + } + + if (!isNew) { + print('Successfully restarted server.'); + } exitCode = await server.exitCode; } diff --git a/pubspec.yaml b/pubspec.yaml index 5a55a92..78bbc2d 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,5 +1,5 @@ name: angel_cli -version: 1.0.0-dev+11 +version: 1.0.0-dev+12 description: Command-line tools for the Angel framework. environment: sdk: ">=1.19.0" @@ -9,6 +9,9 @@ executables: angel: angel dependencies: args: ^0.13.7 - id: ^1.0.0 console: ^2.2.3 + glob: ^1.1.0 + id: ^1.0.0 + random_string: ^0.0.1 + watcher: ^0.9.7 yaml: ^2.0.0 \ No newline at end of file