diff --git a/bin/angel.dart b/bin/angel.dart index f07a31f..f8919c4 100644 --- a/bin/angel.dart +++ b/bin/angel.dart @@ -1,5 +1,5 @@ #!/usr/bin/env dart -library angel_cli.tool; +library demon.tool; import "dart:io"; import "package:args/command_runner.dart"; @@ -18,7 +18,8 @@ main(List args) { ..addCommand(new InitCommand()) ..addCommand(new TestCommand()) ..addCommand(new PluginCommand()) - ..addCommand(new StartCommand()); + ..addCommand(new StartCommand()) + ..addCommand(new RenameCommand()); return runner.run(args).then((_) {}).catchError((exc) { stderr.writeln("Oops, something went wrong: $exc"); diff --git a/lib/angel_cli.dart b/lib/angel_cli.dart index 4d3fa99..3a879ac 100644 --- a/lib/angel_cli.dart +++ b/lib/angel_cli.dart @@ -1,3 +1,3 @@ -library angel_cli; +library demon; export 'src/commands/commands.dart'; \ No newline at end of file diff --git a/lib/src/commands/commands.dart b/lib/src/commands/commands.dart index 1cda4c4..bccb48f 100644 --- a/lib/src/commands/commands.dart +++ b/lib/src/commands/commands.dart @@ -4,6 +4,7 @@ export "doctor.dart"; export "key.dart"; export "init.dart"; export "plugin.dart"; +export "rename.dart"; export "service.dart"; export "start.dart"; export "test.dart"; \ No newline at end of file diff --git a/lib/src/commands/key.dart b/lib/src/commands/key.dart index 56b922d..f2a66f7 100644 --- a/lib/src/commands/key.dart +++ b/lib/src/commands/key.dart @@ -24,7 +24,7 @@ class KeyCommand extends Command { if (await file.exists()) { var contents = await file.readAsString(); contents = contents.replaceAll(new RegExp(r'jwt_secret:[^\n]+\n?'), ''); - await file.writeAsString(contents.trim() + '\njwt_secret: $secret'); + await file.writeAsString(contents.trim() + '\njwt_secret: "$secret"'); } } } diff --git a/lib/src/commands/rename.dart b/lib/src/commands/rename.dart new file mode 100644 index 0000000..cfa9bee --- /dev/null +++ b/lib/src/commands/rename.dart @@ -0,0 +1,136 @@ +import 'dart:io'; +import 'package:analyzer/analyzer.dart'; +import 'package:args/command_runner.dart'; +import 'package:console/console.dart'; +import 'package:pubspec/pubspec.dart'; + +class RenameCommand extends Command { + @override + String get name => 'rename'; + + @override + String get description => 'Renames the current project.'; + + @override + String get invocation => '$name '; + + @override + run() async { + String newName; + + if (argResults.rest.isNotEmpty) + newName = argResults.rest.first; + else { + var p = new Prompter('Enter new project name: '); + newName = await p.prompt(checker: (String str) => str.isNotEmpty); + } + + var ch = new Chooser(['Yes', 'No'], + message: 'Rename the project to `$newName`? '); + var choice = await ch.choose(); + + if (choice == 'Yes') { + print('Renaming project to `$newName`...'); + var pubspecFile = + new File.fromUri(Directory.current.uri.resolve('pubspec.yaml')); + + if (!await pubspecFile.exists()) { + throw new Exception('No pubspec.yaml found in current directory.'); + } else { + var pubspec = await PubSpec.load(Directory.current); + var oldName = pubspec.name; + var newPubspec = + new PubSpec.fromJson(pubspec.toJson()..['name'] = newName); + await newPubspec.save(Directory.current); + await renameDartFiles(oldName, newName); + print('Now running `pub get`...'); + var pub = await Process.start('pub', ['get']); + stdout.addStream(pub.stdout); + stderr.addStream(pub.stderr); + await pub.exitCode; + } + } + } + + renameDartFiles(String oldName, String newName) async { + var entry = + new File.fromUri(Directory.current.uri.resolve('lib/$oldName.dart')); + + if (await entry.exists()) { + await entry.rename('lib/$newName.dart'); + print('Renaming library file `${entry.absolute.path}`...'); + } + + await for (FileSystemEntity file + in Directory.current.list(recursive: true)) { + if (file is File && file.path.endsWith('.dart')) { + var contents = await file.readAsString(); + var ast = parseCompilationUnit(contents); + var visitor = new RenamingVisitor(oldName, newName) + ..visitCompilationUnit(ast); + + if (visitor.replace.isNotEmpty) { + visitor.replace.forEach((range, replacement) { + if (range.first is int) { + contents = + contents.replaceRange(range.first, range.last, replacement); + } else if (range.first is String) { + contents = contents.replaceAll(range.first, replacement); + } + }); + + await file.writeAsString(contents); + print('Updated file `${file.absolute.path}`.'); + } + } + } + } +} + +class RenamingVisitor extends RecursiveAstVisitor { + final String oldName, newName; + final Map replace = {}; + + RenamingVisitor(this.oldName, this.newName); + + String updateUri(String uri) { + if (uri == 'package:$oldName/$oldName.dart') { + return 'package:$newName/$newName.dart'; + } else if (uri.startsWith('package:$oldName/')) { + return 'package:$newName/' + uri.replaceFirst('package:$oldName/', ''); + } else + return uri; + } + + @override + visitExportDirective(ExportDirective ctx) { + var uri = ctx.uri.stringValue, updated = updateUri(uri); + if (uri != updated) replace[[uri]] = updated; + } + + @override + visitImportDirective(ImportDirective ctx) { + var uri = ctx.uri.stringValue, updated = updateUri(uri); + if (uri != updated) replace[[uri]] = updated; + } + + @override + visitLibraryDirective(LibraryDirective ctx) { + var name = ctx.name.name; + + if (name.startsWith(oldName)) { + replace[[ctx.offset, ctx.end]] = + 'library ' + name.replaceFirst(oldName, newName) + ';'; + } + } + + @override + visitPartOfDirective(PartOfDirective ctx) { + var name = ctx.libraryName.name; + + if (name.startsWith(oldName)) { + replace[[ctx.offset, ctx.end]] = + 'part of ' + name.replaceFirst(oldName, newName) + ';'; + } + } +} diff --git a/lib/src/commands/service.dart b/lib/src/commands/service.dart index 8325e57..d238ede 100644 --- a/lib/src/commands/service.dart +++ b/lib/src/commands/service.dart @@ -132,9 +132,7 @@ class $name extends MemoryModel with _\$${name}SerializerMixin { factory $name.fromJson(Map json) => _\$${name}FromJson(json); - $name({String id, this.name, this.desc}) { - this.id = id; - } + $name({this.id, this.name, this.desc}); } ''' .trim()); @@ -186,9 +184,7 @@ class $name extends Model with _\$${name}SerializerMixin { factory $name.fromJson(Map json) => _\$${name}FromJson(json); - $name({String id, this.name, this.desc}) { - this.id = id; - } + $name({this.id, this.name, this.desc}); } ''' .trim()); diff --git a/lib/src/commands/start.dart b/lib/src/commands/start.dart index 9950a2e..c340ed7 100644 --- a/lib/src/commands/start.dart +++ b/lib/src/commands/start.dart @@ -16,6 +16,10 @@ class StartCommand extends Command { StartCommand() : super() { argParser + ..addFlag('multi', + help: 'Starts bin/multi_server.dart, instead of the standard server.', + negatable: false, + defaultsTo: false) ..addFlag('production', help: 'Starts the server in production mode.', negatable: false, @@ -58,8 +62,8 @@ class StartCommand extends Command { try { var scripts = await Process.start('pub', ['global', 'run', 'scripts', 'start']); - scripts.stdout.pipe(stdout); - scripts.stderr.pipe(stderr); + stdout.addStream(scripts.stdout); + stderr.addStream(scripts.stderr); int code = await scripts.exitCode; if (code != 0) { @@ -80,20 +84,27 @@ class StartCommand extends Command { if (argResults['production']) env['ANGEL_ENV'] = 'production'; - server = await Process.start(Platform.executable, ['bin/server.dart'], + server = await Process.start( + Platform.executable, + [ + argResults['multi'] == true + ? 'bin/multi_server.dart' + : 'bin/server.dart' + ], environment: env); try { if (isNew) { - server.stdout.pipe(stdout); - server.stderr.pipe(stderr); + stdout.addStream(server.stdout); + stderr.addStream(server.stderr); } } catch (e) { print(e); } if (!isNew) { - print('Successfully restarted server.'); + print( + '${new DateTime.now().toIso8601String()}Successfully restarted server.'); } exitCode = await server.exitCode; diff --git a/pubspec.yaml b/pubspec.yaml index cec3a79..ae02f9e 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,17 +1,19 @@ -name: angel_cli -version: 1.0.0-dev+18 -description: Command-line tools for the Angel framework. -environment: +author: "Tobe O " +description: "Command-line tools for the Angel framework." +homepage: "https://github.com/angel-dart/angel_cli" +name: "angel_cli" +version: "1.0.0-dev+19" +dependencies: + analyzer: "^0.29.0" + args: "^0.13.7" + console: "^2.2.3" + glob: "^1.1.0" + id: "^1.0.0" + pubspec: "^0.0.14" + random_string: "^0.0.1" + watcher: "^0.9.7" + yaml: "^2.0.0" +environment: sdk: ">=1.19.0" -author: Tobe O -homepage: https://github.com/angel-dart/angel_cli -executables: - angel: angel -dependencies: - args: ^0.13.7 - 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 +executables: + angel: "angel"