Updated to support SDK 2.12.x

This commit is contained in:
thomashii 2021-03-13 10:51:32 +08:00
parent 63e5c99c96
commit a82f7479c6
14 changed files with 102 additions and 87 deletions

View file

@ -9,12 +9,16 @@ Includes functionality such as:
* Renaming projects * Renaming projects
* Much more... * Much more...
To install: * To install:
```bash ```bash
$ pub global activate angel_cli $ pub global activate angel_cli
``` ```
* Install development version
`dart pub global activate --source path ./packages/cli`
`dart pub global activate --source git https://github.com/dukefirehawk/angel/packages/cli`
And then, for information on each command: And then, for information on each command:
```bash ```bash

View file

@ -11,7 +11,7 @@ class DeployCommand extends Command {
'Generates scaffolding + helper functionality for deploying servers. Run this in your project root.'; 'Generates scaffolding + helper functionality for deploying servers. Run this in your project root.';
DeployCommand() { DeployCommand() {
addSubcommand(new NginxCommand()); addSubcommand(NginxCommand());
addSubcommand(new SystemdCommand()); addSubcommand(SystemdCommand());
} }
} }

View file

@ -26,7 +26,7 @@ class DoctorCommand extends Command {
print(green.wrap( print(green.wrap(
"$checkmark Git executable found: v${version.replaceAll('git version', '').trim()}")); "$checkmark Git executable found: v${version.replaceAll('git version', '').trim()}"));
} else } else
throw new Exception("Git executable exit code not 0"); throw Exception("Git executable exit code not 0");
} catch (exc) { } catch (exc) {
print(red.wrap("$ballot Git executable not found")); print(red.wrap("$ballot Git executable not found"));
} }

View file

@ -12,7 +12,7 @@ import 'pub.dart';
import 'rename.dart'; import 'rename.dart';
class InitCommand extends Command { class InitCommand extends Command {
final KeyCommand _key = new KeyCommand(); final KeyCommand _key = KeyCommand();
@override @override
String get name => "init"; String get name => "init";
@ -35,21 +35,19 @@ class InitCommand extends Command {
@override @override
run() async { run() async {
Directory projectDir = Directory projectDir =
new Directory(argResults.rest.isEmpty ? "." : argResults.rest[0]); Directory(argResults.rest.isEmpty ? "." : argResults.rest[0]);
print("Creating new Angel project in ${projectDir.absolute.path}..."); print("Creating new Angel project in ${projectDir.absolute.path}...");
await _cloneRepo(projectDir); await _cloneRepo(projectDir);
// await preBuild(projectDir); // await preBuild(projectDir);
var secret = rs.randomAlphaNumeric(32); var secret = rs.randomAlphaNumeric(32);
print('Generated new development JWT secret: $secret'); print('Generated new development JWT secret: $secret');
await _key.changeSecret( await _key.changeSecret(
new File.fromUri(projectDir.uri.resolve('config/default.yaml')), File.fromUri(projectDir.uri.resolve('config/default.yaml')), secret);
secret);
secret = rs.randomAlphaNumeric(32); secret = rs.randomAlphaNumeric(32);
print('Generated new production JWT secret: $secret'); print('Generated new production JWT secret: $secret');
await _key.changeSecret( await _key.changeSecret(
new File.fromUri(projectDir.uri.resolve('config/production.yaml')), File.fromUri(projectDir.uri.resolve('config/production.yaml')), secret);
secret);
var name = argResults.wasParsed('project-name') var name = argResults.wasParsed('project-name')
? argResults['project-name'] as String ? argResults['project-name'] as String
@ -110,9 +108,9 @@ class InitCommand extends Command {
switch (stat.type) { switch (stat.type) {
case FileSystemEntityType.directory: case FileSystemEntityType.directory:
return await _deleteRecursive(new Directory(path)); return await _deleteRecursive(Directory(path));
case FileSystemEntityType.file: case FileSystemEntityType.file:
return await _deleteRecursive(new File(path)); return await _deleteRecursive(File(path));
default: default:
break; break;
} }
@ -198,7 +196,7 @@ class InitCommand extends Command {
} }
if (await git.exitCode != 0) { if (await git.exitCode != 0) {
throw new Exception("Could not clone repo."); throw Exception("Could not clone repo.");
} }
} }
@ -224,7 +222,7 @@ class InitCommand extends Command {
await preBuild(projectDir).catchError((_) => null); await preBuild(projectDir).catchError((_) => null);
} }
var gitDir = new Directory.fromUri(projectDir.uri.resolve(".git")); var gitDir = 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) { } catch (e) {
await boilerplateDir.delete(recursive: true).catchError((_) => null); await boilerplateDir.delete(recursive: true).catchError((_) => null);
@ -260,44 +258,48 @@ Future preBuild(Directory projectDir) async {
var buildCode = await build.exitCode; var buildCode = await build.exitCode;
if (buildCode != 0) throw new Exception('Failed to pre-build resources.'); if (buildCode != 0) throw Exception('Failed to pre-build resources.');
} }
const RepoArchiveLocation = "https://github.com/angel-dart";
const RepoLocation = "https://github.com/dukefirehawk";
const BoilerplateInfo graphQLBoilerplate = const BoilerplateInfo( const BoilerplateInfo graphQLBoilerplate = const BoilerplateInfo(
'GraphQL', 'GraphQL',
"A starting point for GraphQL API servers.", "A starting point for GraphQL API servers.",
'https://github.com/angel-dart/angel.git', '${RepoLocation}/boilerplates.git',
ref: 'graphql', ref: 'graphql-sdk-2.12.x',
); );
const BoilerplateInfo ormBoilerplate = const BoilerplateInfo( const BoilerplateInfo ormBoilerplate = const BoilerplateInfo(
'ORM', 'ORM',
"A starting point for applications that use Angel's ORM.", "A starting point for applications that use Angel's ORM.",
'https://github.com/angel-dart/angel.git', '${RepoLocation}/boilerplates.git',
ref: 'orm', ref: 'orm-sdk-2.12.x',
); );
const BoilerplateInfo basicBoilerplate = const BoilerplateInfo( const BoilerplateInfo basicBoilerplate = const BoilerplateInfo(
'Basic', 'Basic',
'Minimal starting point for Angel 2.x - A simple server with only a few additional packages.', 'Minimal starting point for Angel 2.x - A simple server with only a few additional packages.',
'https://github.com/angel-dart/angel.git'); '${RepoLocation}/boilerplates.git',
ref: 'basic-sdk-2.12.x');
const BoilerplateInfo legacyBoilerplate = const BoilerplateInfo( const BoilerplateInfo legacyBoilerplate = const BoilerplateInfo(
'Legacy', 'Legacy',
'Minimal starting point for applications running Angel 1.1.x.', 'Minimal starting point for applications running Angel 1.1.x.',
'https://github.com/angel-dart/angel.git', '${RepoArchiveLocation}/angel.git',
ref: '1.1.x', ref: '1.1.x',
); );
const BoilerplateInfo sharedBoilerplate = const BoilerplateInfo( const BoilerplateInfo sharedBoilerplate = const BoilerplateInfo(
'Shared', 'Shared',
'Holds common models and files shared across multiple Dart projects.', 'Holds common models and files shared across multiple Dart projects.',
'https://github.com/angel-dart/boilerplate_shared.git'); '${RepoLocation}/boilerplate_shared.git');
const BoilerplateInfo sharedOrmBoilerplate = const BoilerplateInfo( const BoilerplateInfo sharedOrmBoilerplate = const BoilerplateInfo(
'Shared (ORM)', 'Shared (ORM)',
'Holds common models and files shared across multiple Dart projects.', 'Holds common models and files shared across multiple Dart projects.',
'https://github.com/angel-dart/boilerplate_shared.git', '${RepoLocation}/boilerplate_shared.git',
ref: 'orm', ref: 'orm',
); );
@ -306,8 +308,8 @@ const List<BoilerplateInfo> boilerplates = const [
//legacyBoilerplate, //legacyBoilerplate,
ormBoilerplate, ormBoilerplate,
graphQLBoilerplate, graphQLBoilerplate,
sharedBoilerplate, //sharedBoilerplate,
sharedOrmBoilerplate, //sharedOrmBoilerplate,
]; ];
class BoilerplateInfo { class BoilerplateInfo {

View file

@ -3,7 +3,7 @@ import 'dart:io';
import 'package:args/command_runner.dart'; import 'package:args/command_runner.dart';
import 'package:glob/glob.dart'; import 'package:glob/glob.dart';
import 'package:io/ansi.dart'; import 'package:io/ansi.dart';
import 'package:mustache4dart/mustache4dart.dart' as mustache; import 'package:mustache4dart2/mustache4dart2.dart' as mustache;
import 'package:path/path.dart' as p; import 'package:path/path.dart' as p;
import 'package:prompts/prompts.dart' as prompts; import 'package:prompts/prompts.dart' as prompts;
import 'package:pubspec_parse/pubspec_parse.dart'; import 'package:pubspec_parse/pubspec_parse.dart';
@ -14,7 +14,7 @@ import 'make/maker.dart';
class InstallCommand extends Command { class InstallCommand extends Command {
static const String repo = 'https://github.com/angel-dart/install.git'; static const String repo = 'https://github.com/angel-dart/install.git';
static final Directory installRepo = static final Directory installRepo =
new Directory.fromUri(homeDir.uri.resolve('./.angel/addons')); Directory.fromUri(homeDir.uri.resolve('./.angel/addons'));
@override @override
String get name => 'install'; String get name => 'install';
@ -72,7 +72,7 @@ class InstallCommand extends Command {
for (var packageName in argResults.rest) { for (var packageName in argResults.rest) {
var packageDir = var packageDir =
new Directory.fromUri(installRepo.uri.resolve(packageName)); 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`.'; throw 'No add-on named "$packageName" is installed. You might need to run `angel install --update`.';
@ -90,7 +90,7 @@ class InstallCommand extends Command {
.map((k) { .map((k) {
var dep = projectPubspec.dependencies[k]; var dep = projectPubspec.dependencies[k];
if (dep is HostedDependency) if (dep is HostedDependency)
return new MakerDependency(k, dep.version.toString()); return MakerDependency(k, dep.version.toString());
return null; return null;
}) })
.where((d) => d != null) .where((d) => d != null)
@ -99,14 +99,13 @@ class InstallCommand extends Command {
deps.addAll(projectPubspec.devDependencies.keys.map((k) { deps.addAll(projectPubspec.devDependencies.keys.map((k) {
var dep = projectPubspec.devDependencies[k]; var dep = projectPubspec.devDependencies[k];
if (dep is HostedDependency) if (dep is HostedDependency)
return new MakerDependency(k, dep.version.toString(), dev: true); return MakerDependency(k, dep.version.toString(), dev: true);
return null; return null;
}).where((d) => d != null)); }).where((d) => d != null));
await depend(deps); await depend(deps);
var promptFile = var promptFile = File.fromUri(packageDir.uri.resolve('angel_cli.yaml'));
new File.fromUri(packageDir.uri.resolve('angel_cli.yaml'));
if (await promptFile.exists()) { if (await promptFile.exists()) {
var contents = await promptFile.readAsString(); var contents = await promptFile.readAsString();
@ -116,7 +115,7 @@ class InstallCommand extends Command {
// Loads globs // Loads globs
if (cfg['templates'] is List) { if (cfg['templates'] is List) {
globs.addAll( globs.addAll(
(cfg['templates'] as List).map((p) => new Glob(p.toString()))); (cfg['templates'] as List).map((p) => Glob(p.toString())));
} }
if (cfg['values'] is Map) { if (cfg['values'] is Map) {
@ -144,14 +143,14 @@ class InstallCommand extends Command {
await for (var entity in src.list()) { await for (var entity in src.list()) {
if (entity is Directory) { if (entity is Directory) {
var name = p.basename(entity.path); var name = p.basename(entity.path);
var newDir = new Directory.fromUri(dst.uri.resolve(name)); var newDir = Directory.fromUri(dst.uri.resolve(name));
await merge( await merge(
entity, newDir, prefix.isEmpty ? name : '$prefix/$name'); entity, newDir, prefix.isEmpty ? name : '$prefix/$name');
} else if (entity is File && } else if (entity is File &&
!entity.path.endsWith('angel_cli.yaml')) { !entity.path.endsWith('angel_cli.yaml')) {
var name = p.basename(entity.path); var name = p.basename(entity.path);
var target = dst.uri.resolve(name); var target = dst.uri.resolve(name);
var targetFile = new File.fromUri(target); var targetFile = File.fromUri(target);
bool allClear = !await targetFile.exists(); bool allClear = !await targetFile.exists();
if (!allClear) { if (!allClear) {
@ -187,7 +186,7 @@ class InstallCommand extends Command {
} }
} }
await merge(new Directory.fromUri(packageDir.uri.resolve('files')), await merge(Directory.fromUri(packageDir.uri.resolve('files')),
Directory.current, ''); Directory.current, '');
print('Successfully installed $packageName@${projectPubspec.version}.'); print('Successfully installed $packageName@${projectPubspec.version}.');
} }

View file

@ -13,17 +13,17 @@ class KeyCommand extends Command {
run() async { run() async {
var secret = rs.randomAlphaNumeric(32); var secret = rs.randomAlphaNumeric(32);
print('Generated new development JWT secret: $secret'); print('Generated new development JWT secret: $secret');
await changeSecret(new File('config/default.yaml'), secret); await changeSecret(File('config/default.yaml'), secret);
secret = rs.randomAlphaNumeric(32); secret = rs.randomAlphaNumeric(32);
print('Generated new production JWT secret: $secret'); print('Generated new production JWT secret: $secret');
await changeSecret(new File('config/production.yaml'), secret); await changeSecret(File('config/production.yaml'), secret);
} }
changeSecret(File file, String secret) async { changeSecret(File file, String secret) async {
if (await file.exists()) { if (await file.exists()) {
var contents = await file.readAsString(); var contents = await file.readAsString();
contents = contents.replaceAll(new RegExp(r'jwt_secret:[^\n]+\n?'), ''); contents = contents.replaceAll(RegExp(r'jwt_secret:[^\n]+\n?'), '');
await file.writeAsString(contents.trim() + '\njwt_secret: "$secret"'); await file.writeAsString(contents.trim() + '\njwt_secret: "$secret"');
} }
} }

View file

@ -15,11 +15,11 @@ class MakeCommand extends Command {
'Generates common code for your project, such as projects and controllers.'; 'Generates common code for your project, such as projects and controllers.';
MakeCommand() { MakeCommand() {
addSubcommand(new ControllerCommand()); addSubcommand(ControllerCommand());
addSubcommand(new MigrationCommand()); addSubcommand(MigrationCommand());
addSubcommand(new ModelCommand()); addSubcommand(ModelCommand());
addSubcommand(new PluginCommand()); addSubcommand(PluginCommand());
addSubcommand(new TestCommand()); addSubcommand(TestCommand());
addSubcommand(new ServiceCommand()); addSubcommand(ServiceCommand());
} }
} }

View file

@ -43,7 +43,7 @@ class ControllerCommand extends Command {
const MakerDependency('angel_framework', '^2.0.0') const MakerDependency('angel_framework', '^2.0.0')
]; ];
// ${pubspec.name}.src.models.${rc.snakeCase} //${pubspec.name}.src.models.${rc.snakeCase}
var rc = new ReCase(name); var rc = new ReCase(name);
var controllerLib = new Library((controllerLib) { var controllerLib = new Library((controllerLib) {

View file

@ -1,9 +1,9 @@
import 'dart:io'; import 'dart:io';
final RegExp _leadingSlashes = new RegExp(r'^/+'); final RegExp _leadingSlashes = RegExp(r'^/+');
String resolvePub() { String resolvePub() {
var exec = new File(Platform.resolvedExecutable); var exec = File(Platform.resolvedExecutable);
var pubPath = exec.parent.uri.resolve('pub').path; var pubPath = exec.parent.uri.resolve('pub').path;
if (Platform.isWindows) if (Platform.isWindows)
pubPath = pubPath.replaceAll(_leadingSlashes, '') + '.bat'; pubPath = pubPath.replaceAll(_leadingSlashes, '') + '.bat';

View file

@ -1,8 +1,10 @@
import 'dart:io'; import 'dart:io';
import 'package:analyzer/analyzer.dart'; import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/visitor.dart';
import 'package:args/command_runner.dart'; import 'package:args/command_runner.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:glob/list_local_fs.dart';
import 'package:io/ansi.dart'; import 'package:io/ansi.dart';
import 'package:prompts/prompts.dart' as prompts; import 'package:prompts/prompts.dart' as prompts;
import 'package:recase/recase.dart'; import 'package:recase/recase.dart';
@ -14,7 +16,7 @@ class RenameCommand extends Command {
String get name => 'rename'; String get name => 'rename';
@override @override
String get description => 'Renames the current project.'; String get description => 'Renames the current project (To be available).';
@override @override
String get invocation => '$name <new name>'; String get invocation => '$name <new name>';
@ -29,17 +31,20 @@ class RenameCommand extends Command {
newName = prompts.get('Rename project to'); newName = prompts.get('Rename project to');
} }
newName = new ReCase(newName).snakeCase; newName = ReCase(newName).snakeCase;
var choice = prompts.getBool('Rename the project to `$newName`?'); var choice = prompts.getBool('Rename the project to `$newName`?');
// TODO: To be available once the issue is fixed
if (choice) { if (choice) {
print('Rename the project is currently not available');
/*
print('Renaming project to `$newName`...'); print('Renaming project to `$newName`...');
var pubspecFile = var pubspecFile =
new File.fromUri(Directory.current.uri.resolve('pubspec.yaml')); File.fromUri(Directory.current.uri.resolve('pubspec.yaml'));
if (!await pubspecFile.exists()) { if (!await pubspecFile.exists()) {
throw new Exception('No pubspec.yaml found in current directory.'); throw Exception('No pubspec.yaml found in current directory.');
} else { } else {
var pubspec = await loadPubspec(); var pubspec = await loadPubspec();
var oldName = pubspec.name; var oldName = pubspec.name;
@ -53,6 +58,7 @@ class RenameCommand extends Command {
stderr.addStream(pub.stderr); stderr.addStream(pub.stderr);
await pub.exitCode; await pub.exitCode;
} }
*/
} }
} }
} }
@ -61,12 +67,12 @@ renamePubspec(Directory dir, String oldName, String newName) async {
// var pubspec = await loadPubspec(dir); // var pubspec = await loadPubspec(dir);
print(cyan.wrap('Renaming your project to `$newName.`')); print(cyan.wrap('Renaming your project to `$newName.`'));
var pubspecFile = new File.fromUri(dir.uri.resolve('pubspec.yaml')); var pubspecFile = File.fromUri(dir.uri.resolve('pubspec.yaml'));
if (await pubspecFile.exists()) { if (await pubspecFile.exists()) {
var contents = await pubspecFile.readAsString(), oldContents = contents; var contents = await pubspecFile.readAsString(), oldContents = contents;
contents = contents =
contents.replaceAll(new RegExp('name:\\s*$oldName'), 'name: $newName'); contents.replaceAll(RegExp('name:\\s*$oldName'), 'name: $newName');
if (contents != oldContents) { if (contents != oldContents) {
await pubspecFile.writeAsString(contents); await pubspecFile.writeAsString(contents);
@ -76,7 +82,7 @@ renamePubspec(Directory dir, String oldName, String newName) async {
// print(cyan // print(cyan
// .wrap('Note that this does not actually modify your `pubspec.yaml`.')); // .wrap('Note that this does not actually modify your `pubspec.yaml`.'));
// TODO: https://github.com/dart-lang/pubspec_parse/issues/17 // TODO: https://github.com/dart-lang/pubspec_parse/issues/17
// var newPubspec = new Pubspec.fromJson(pubspec.toJson()..['name'] = newName); // var newPubspec = Pubspec.fromJson(pubspec.toJson()..['name'] = newName);
// await newPubspec.save(dir); // await newPubspec.save(dir);
} }
@ -84,34 +90,39 @@ renameDartFiles(Directory dir, String oldName, String newName) async {
if (!await dir.exists()) return; if (!await dir.exists()) return;
// Try to replace MongoDB URL // Try to replace MongoDB URL
var configGlob = new Glob('config/**/*.yaml'); var configGlob = Glob('config/**/*.yaml');
try { try {
await for (var yamlFile in configGlob.list(root: dir.absolute.path)) { await for (var yamlFile in configGlob.list(root: dir.absolute.path)) {
if (yamlFile is File) { if (yamlFile is File) {
print( print(
'Replacing occurrences of "$oldName" with "$newName" in file "${yamlFile.absolute.path}"...'); 'Replacing occurrences of "$oldName" with "$newName" in file "${yamlFile.absolute.path}"...');
var contents = await yamlFile.readAsString(); if (yamlFile is File) {
contents = contents.replaceAll(oldName, newName); var contents = (yamlFile as File).readAsStringSync();
await yamlFile.writeAsString(contents); contents = contents.replaceAll(oldName, newName);
(yamlFile as File).writeAsStringSync(contents);
}
} }
} }
} catch (_) {} } catch (_) {}
var entry = new File.fromUri(dir.uri.resolve('lib/$oldName.dart')); var entry = File.fromUri(dir.uri.resolve('lib/$oldName.dart'));
if (await entry.exists()) { if (await entry.exists()) {
await entry.rename(dir.uri.resolve('lib/$newName.dart').toFilePath()); await entry.rename(dir.uri.resolve('lib/$newName.dart').toFilePath());
print('Renaming library file `${entry.absolute.path}`...'); print('Renaming library file `${entry.absolute.path}`...');
} }
var fmt = new DartFormatter(); var fmt = DartFormatter();
await for (FileSystemEntity file in dir.list(recursive: true)) { await for (FileSystemEntity file in dir.list(recursive: true)) {
if (file is File && file.path.endsWith('.dart')) { if (file is File && file.path.endsWith('.dart')) {
var contents = await file.readAsString(); var contents = await file.readAsString();
var ast = parseCompilationUnit(contents);
var visitor = new RenamingVisitor(oldName, newName) // TODO: Issue to be fixed: parseCompilationUnit uses Hubbub library which uses discontinued Google front_end library
..visitCompilationUnit(ast); // front_end package. Temporarily commeted out
//var ast = parseCompilationUnit(contents);
var visitor = RenamingVisitor(oldName, newName);
// ..visitCompilationUnit(ast);
if (visitor.replace.isNotEmpty) { if (visitor.replace.isNotEmpty) {
visitor.replace.forEach((range, replacement) { visitor.replace.forEach((range, replacement) {

View file

@ -12,7 +12,7 @@ class CustomServiceGenerator extends ServiceGenerator {
@override @override
void applyToLibrary(LibraryBuilder library, String name, String lower) { void applyToLibrary(LibraryBuilder library, String name, String lower) {
library.body.add(new Class((clazz) { library.body.add(Class((clazz) {
clazz clazz
..name = '${name}Service' ..name = '${name}Service'
..extend = refer('Service'); ..extend = refer('Service');

View file

@ -34,7 +34,7 @@ class RethinkServiceGenerator extends ServiceGenerator {
void applyToLibrary(LibraryBuilder library, String name, String lower) { void applyToLibrary(LibraryBuilder library, String name, String lower) {
library.directives.addAll([ library.directives.addAll([
'package:angel_rethink/angel_rethink.dart', 'package:angel_rethink/angel_rethink.dart',
'package:rethinkdb_driver/rethinkdb_driver.dart' 'package:rethinkdb_dart/rethinkdb_dart.dart'
].map((str) => new Directive.import(str))); ].map((str) => new Directive.import(str)));
} }

View file

@ -2,10 +2,10 @@ import 'dart:math';
const String _valid = const String _valid =
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
final Random _rnd = new Random.secure(); final Random _rnd = Random.secure();
String randomAlphaNumeric(int length) { String randomAlphaNumeric(int length) {
var b = new StringBuffer(); var b = StringBuffer();
for (int i = 0; i < length; i++) { for (int i = 0; i < length; i++) {
b.writeCharCode(_valid.codeUnitAt(_rnd.nextInt(_valid.length))); b.writeCharCode(_valid.codeUnitAt(_rnd.nextInt(_valid.length)));

View file

@ -1,28 +1,27 @@
author: Tobe O <thosakwe@gmail.com> #author: Tobe O <thosakwe@gmail.com>
description: Command-line tools for the Angel framework, including scaffolding. description: Command-line tools for the Angel framework, including scaffolding.
homepage: https://github.com/angel-dart/angel_cli homepage: https://github.com/dukefirehawk/angel/packages/angel_cli
name: angel_cli name: angel_cli
version: 2.1.7+1 version: 3.0.0
environment:
sdk: ">=2.10.0 <3.0.0"
dependencies: dependencies:
analyzer: ">=0.32.0 <2.0.0" analyzer: ^1.1.0
args: ^1.0.0 args: ^2.0.0
code_builder: ^3.0.0 code_builder: ^3.0.0
dart_style: ^1.0.0 dart_style: ^1.0.0
glob: ^1.1.0 glob: ^2.0.0
http: ^0.12.0 http: ^0.13.0
io: ^0.3.2 io: ^0.3.5
inflection2: ^0.4.2 inflection2: ^0.4.2
mustache4dart: ^3.0.0-dev.1.0 mustache4dart2: ^0.1.0
path: ^1.0.0 path: ^1.0.0
prompts: ^1.0.0 prompts: ^1.3.1
pubspec_parse: ^0.1.2 pubspec_parse: ^1.0.0
quiver: ^2.0.0 quiver: ^3.0.0
recase: ^2.0.0 recase: ^3.0.1
shutdown: ^0.4.0 shutdown: ^0.4.0
watcher: ^0.9.7 watcher: ^1.0.0
yaml: ^2.0.0 yaml: ^3.0.0
#yamlicious: ^0.0.5
environment:
sdk: ">=2.0.0-dev <3.0.0"
executables: executables:
angel: angel angel: angel