platform/lib/src/commands/service.dart

326 lines
8.1 KiB
Dart
Raw Normal View History

2016-12-21 17:34:15 +00:00
import 'dart:io';
import 'package:args/command_runner.dart';
import 'package:console/console.dart';
2016-09-14 04:33:28 +00:00
class ServiceCommand extends Command {
2016-12-21 17:34:15 +00:00
final String CUSTOM = 'Custom';
final String MEMORY = 'In-Memory';
final String MONGO = 'MongoDB';
final String MONGO_TYPED = 'MongoDB (typed)';
final String TRESTLE = 'Trestle';
2016-09-14 04:33:28 +00:00
final TextPen _pen = new TextPen();
2016-11-24 00:35:40 +00:00
@override
2016-12-21 17:34:15 +00:00
String get name => 'service';
2016-09-14 04:33:28 +00:00
2016-11-24 00:35:40 +00:00
@override
2016-12-21 17:34:15 +00:00
String get description => 'Creates a new service within the given project.';
2016-09-14 04:33:28 +00:00
@override
run() async {
2016-12-21 17:34:15 +00:00
var name = await readInput('Name of Service (not plural): ');
2016-09-15 01:28:12 +00:00
var chooser = new Chooser([TRESTLE, MONGO, MONGO_TYPED, MEMORY, CUSTOM],
2016-12-21 17:34:15 +00:00
message: 'What type of service would you like to create? ');
2016-09-14 04:33:28 +00:00
var type = await chooser.choose();
fail() {
_pen.red();
2016-12-21 17:34:15 +00:00
_pen('Could not successfully create service $name.');
2016-09-14 04:33:28 +00:00
_pen();
}
2016-12-21 17:34:15 +00:00
String serviceSource = '';
2016-09-14 04:33:28 +00:00
if (type == MONGO) {
serviceSource = _generateMongoService(name);
2016-12-21 17:34:15 +00:00
await _generateMemoryModel(name);
2016-09-15 01:28:12 +00:00
} else if (type == MONGO_TYPED) {
2016-11-24 00:35:40 +00:00
serviceSource = _generateMongoTypedService(name);
await _generateMongoModel(name);
2016-09-15 01:28:12 +00:00
} else if (type == MEMORY) {
serviceSource = _generateMemoryService(name);
} else if (type == CUSTOM) {
serviceSource = _generateCustomService(name);
} else if (type == TRESTLE) {
_pen.blue();
2016-12-21 17:34:15 +00:00
_pen('${Icon.STAR} Trestle services are not yet implemented. :(');
2016-09-15 01:28:12 +00:00
_pen();
} else {
2016-12-21 17:34:15 +00:00
print('Code to generate a $type service is not yet written.');
2016-09-15 01:28:12 +00:00
}
if (serviceSource.isEmpty) {
fail();
2016-12-21 17:34:15 +00:00
throw new Exception('Empty generated service code.');
2016-09-15 01:28:12 +00:00
}
2016-12-21 17:34:15 +00:00
var servicesDir = new Directory('lib/src/services');
2016-11-24 00:35:40 +00:00
var serviceFile =
2016-12-21 17:34:15 +00:00
new File.fromUri(servicesDir.uri.resolve('${name.toLowerCase()}.dart'));
var testDir = new Directory('test/services');
2016-11-24 00:35:40 +00:00
var testFile = new File.fromUri(
2016-12-21 17:34:15 +00:00
testDir.uri.resolve('${name.toLowerCase()}_test.dart'));
2016-09-15 01:28:12 +00:00
2016-11-24 00:35:40 +00:00
if (!await servicesDir.exists()) await servicesDir.create(recursive: true);
2016-09-15 01:28:12 +00:00
2016-11-24 00:35:40 +00:00
if (!await testDir.exists()) await testDir.create(recursive: true);
2016-09-15 05:19:06 +00:00
2016-09-15 01:28:12 +00:00
await serviceFile.writeAsString(serviceSource);
2016-11-24 00:42:29 +00:00
2016-12-21 17:34:15 +00:00
if (type == MONGO_TYPED || type == MEMORY) {
var serviceLibrary = new File('lib/src/models/models.dart');
2016-11-24 00:42:29 +00:00
await serviceLibrary.writeAsString(
2016-12-21 17:34:15 +00:00
'\nexport "${name.toLowerCase()}.dart";',
2016-11-24 00:42:29 +00:00
mode: FileMode.APPEND);
}
2016-09-15 01:28:12 +00:00
2016-09-15 05:19:06 +00:00
await testFile.writeAsString(_generateTests(name, type));
2016-11-24 00:35:40 +00:00
final runConfig = new File('./.idea/runConfigurations/${name}_tests.xml');
if (!await runConfig.exists()) {
await runConfig.create(recursive: true);
await runConfig.writeAsString(_generateRunConfiguration(name));
}
2016-09-15 01:28:12 +00:00
_pen.green();
2016-12-21 17:34:15 +00:00
_pen('${Icon.CHECKMARK} Successfully generated service $name.');
2016-09-15 01:28:12 +00:00
_pen();
}
_generateCustomService(String name) {
return '''
import 'package:angel_framework/angel_framework.dart';
2016-09-14 04:33:28 +00:00
2016-09-15 01:28:12 +00:00
class ${name}Service extends Service {
${name}Service():super() {
// Your logic here!
}
}
2016-11-24 00:35:40 +00:00
'''
.trim();
2016-09-15 01:28:12 +00:00
}
2016-12-21 17:34:15 +00:00
_generateMemoryModel(String name) async {
final lower = name.toLowerCase();
final file = new File('lib/src/models/$lower.dart');
if (!await file.exists()) await file.createSync(recursive: true);
await file.writeAsString('''
library angel.models.$lower;
import 'dart:convert';
import 'package:angel_framework/angel_framework.dart';
class $name extends MemoryModel {
String name, desc;
$name({String id, this.name, this.desc}) {
this.id = id;
}
factory $name.fromJson(String json) => new $name.fromMap(JSON.decode(json));
factory $name.fromMap(Map data) => new $name(
id: data['id']
name: data['name'],
desc: data['desc']);
Map toJson() {
return {
'id': id,
'name': name,
'desc': desc
};
}
}
'''
.trim());
}
2016-09-15 01:28:12 +00:00
_generateMemoryService(String name) {
return '''
import 'package:angel_framework/defs.dart';
import 'package:angel_framework/angel_framework.dart';
/// Store in-memory instances of this class.
class $name extends MemoryModel {
2016-12-21 17:34:15 +00:00
String name, desc;
$name({String id, this.name, this.desc}) {
this.id = id;
}
factory $name.fromJson(String json) => new $name.fromMap(JSON.decode(json));
factory $name.fromMap(Map data) => new $name(
id: data['id']
name: data['name'],
desc: data['desc']);
Map toJson() {
return {
'id': id,
'name': name,
'desc': desc
};
}
2016-09-15 01:28:12 +00:00
}
/// Manages [$name] in-memory.
class ${name}Service extends MemoryService<$name> {
${name}Service():super() {
// Your logic here!
}
}
2016-11-24 00:35:40 +00:00
'''
.trim();
}
_generateMongoModel(String name) async {
final lower = name.toLowerCase();
final file = new File('lib/src/models/$lower.dart');
if (!await file.exists()) await file.createSync(recursive: true);
await file.writeAsString('''
library angel.models.$lower;
import 'dart:convert';
import 'package:angel_mongo/model.dart';
class $name extends Model {
String name, desc;
2016-12-21 17:34:15 +00:00
$name({String id, this.name, this.desc}) {
this.id = id;
}
2016-11-24 00:35:40 +00:00
factory $name.fromJson(String json) => new $name.fromMap(JSON.decode(json));
factory $name.fromMap(Map data) => new $name(
2016-12-21 17:34:15 +00:00
id: data['id']
name: data['name'],
desc: data['desc']);
2016-11-24 00:35:40 +00:00
Map toJson() {
return {
2016-12-21 17:34:15 +00:00
'id': id,
'name': name,
'desc': desc
2016-11-24 00:35:40 +00:00
};
}
}
'''
.trim());
2016-09-14 04:33:28 +00:00
}
_generateMongoService(String name) {
2016-11-24 00:35:40 +00:00
final lower = name.toLowerCase();
2016-09-14 04:33:28 +00:00
return '''
2016-11-24 00:35:40 +00:00
import 'package:angel_framework/angel_framework.dart';
2016-09-15 01:28:12 +00:00
import 'package:angel_mongo/angel_mongo.dart';
2016-11-24 00:35:40 +00:00
import 'package:mongo_dart/mongo_dart.dart';
2016-09-14 04:33:28 +00:00
2016-11-24 00:35:40 +00:00
configureServer(Db db) {
return (Angel app) async {
2016-12-21 17:34:15 +00:00
app.use('/api/${lower}s', new ${name}Service(db.collection('${lower}s')));
2016-11-24 00:35:40 +00:00
2016-12-21 17:34:15 +00:00
HookedService service = app.service('api/${lower}s');
2016-11-24 00:35:40 +00:00
app.container.singleton(service.inner);
};
}
/// Manages [$name] in the database.
2016-09-15 00:21:15 +00:00
class ${name}Service extends MongoService {
${name}Service(collection):super(collection) {
2016-09-15 01:28:12 +00:00
// Your logic here!
2016-09-15 00:21:15 +00:00
}
}
2016-11-24 00:35:40 +00:00
'''
.trim();
}
_generateMongoTypedService(String name) {
final lower = name.toLowerCase();
return '''
import 'package:angel_framework/angel_framework.dart';
import 'package:angel_mongo/angel_mongo.dart';
import 'package:mongo_dart/mongo_dart.dart';
import '../models/$lower.dart';
export '../models/$lower.dart';
configureServer(Db db) {
return (Angel app) async {
2016-12-21 17:34:15 +00:00
app.use('/api/${lower}s', new ${name}Service(db.collection('${lower}s')));
2016-11-24 00:35:40 +00:00
2016-12-21 17:34:15 +00:00
HookedService service = app.service('api/${lower}s');
2016-11-24 00:35:40 +00:00
app.container.singleton(service.inner);
};
}
/// Manages [$name] in the database.
class ${name}Service extends MongoTypedService<$name> {
${name}Service(collection):super(collection) {
// Your logic here!
}
}
'''
.trim();
}
_generateRunConfiguration(String name) {
final lower = name.toLowerCase();
return '''
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="$name Tests" type="DartTestRunConfigurationType" factoryName="Dart Test" singleton="true">
<option name="filePath" value="\$PROJECT_DIR\$/test/services/${lower}_test.dart" />
<method />
</configuration>
</component>
'''
.trim();
2016-09-14 04:33:28 +00:00
}
2016-09-15 05:19:06 +00:00
_generateTests(String name, String type) {
return '''
import 'dart:io';
2016-12-10 18:52:14 +00:00
import 'package:angel/angel.dart';
2016-09-15 05:19:06 +00:00
import 'package:angel_framework/angel_framework.dart';
2016-12-10 18:52:14 +00:00
import 'package:angel_test/angel_test.dart';
2016-09-15 05:19:06 +00:00
import 'package:test/test.dart';
2016-12-10 18:52:14 +00:00
main() async {
Angel app;
TestClient client;
2016-09-15 05:19:06 +00:00
2016-12-10 18:52:14 +00:00
setUp(() async {
app = await createServer();
client = await connectTo(app, saveSession: false);
});
2016-09-15 05:19:06 +00:00
2016-12-10 18:52:14 +00:00
tearDown(() async {
await client.close();
app = null;
});
2016-09-15 05:19:06 +00:00
2016-12-10 18:52:14 +00:00
test('index via REST', () async {
final response = await client.get('/api/${name.toLowerCase()}');
expect(response, hasStatus(HttpStatus.OK));
});
2016-09-15 05:19:06 +00:00
2016-12-10 18:52:14 +00:00
test('Index ${name.toLowerCase()}s', () async {
final ${name.toLowerCase()}s = await client.service('api/${name.toLowerCase()}').index();
print(${name.toLowerCase()}s);
});
}
2016-09-15 05:19:06 +00:00
2016-12-21 17:34:15 +00:00
'''
.trim();
2016-09-15 05:19:06 +00:00
}
2016-11-24 00:35:40 +00:00
}