Apply lints
This commit is contained in:
parent
5156ab826b
commit
0117b2f0b4
6 changed files with 69 additions and 45 deletions
|
@ -1,5 +1,7 @@
|
||||||
# 2.0.5
|
# 2.0.5
|
||||||
* Use `dart:developer` to find the Observatory URI.
|
* Use `dart:developer` to find the Observatory URI.
|
||||||
|
* Use the app's logger when necessary.
|
||||||
|
* Apply `package:pedantic`.
|
||||||
|
|
||||||
# 2.0.4
|
# 2.0.4
|
||||||
* Forcibly close app loggers on shutdown.
|
* Forcibly close app loggers on shutdown.
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
include: package:pedantic/analysis_options.yaml
|
||||||
analyzer:
|
analyzer:
|
||||||
strong-mode:
|
strong-mode:
|
||||||
implicit-casts: false
|
implicit-casts: false
|
||||||
|
linter:
|
||||||
|
rules:
|
||||||
|
- unnecessary_const
|
||||||
|
- unnecessary_new
|
|
@ -3,8 +3,8 @@ import 'package:angel_hot/angel_hot.dart';
|
||||||
import 'server.dart';
|
import 'server.dart';
|
||||||
|
|
||||||
main() async {
|
main() async {
|
||||||
var hot = new HotReloader(createServer, [
|
var hot = HotReloader(createServer, [
|
||||||
new Directory('src'),
|
Directory('src'),
|
||||||
'server.dart',
|
'server.dart',
|
||||||
// Also allowed: Platform.script,
|
// Also allowed: Platform.script,
|
||||||
Uri.parse('package:angel_hot/angel_hot.dart')
|
Uri.parse('package:angel_hot/angel_hot.dart')
|
||||||
|
|
|
@ -6,21 +6,21 @@ import 'package:logging/logging.dart';
|
||||||
import 'src/foo.dart';
|
import 'src/foo.dart';
|
||||||
|
|
||||||
Future<Angel> createServer() async {
|
Future<Angel> createServer() async {
|
||||||
var app = new Angel()..serializer = json.encode;
|
var app = Angel()..serializer = json.encode;
|
||||||
hierarchicalLoggingEnabled = true;
|
hierarchicalLoggingEnabled = true;
|
||||||
|
|
||||||
// Edit this line, and then refresh the page in your browser!
|
// Edit this line, and then refresh the page in your browser!
|
||||||
app.get('/', (req, res) => {'hello': 'hot world!'});
|
app.get('/', (req, res) => {'hello': 'hot world!'});
|
||||||
app.get('/foo', (req, res) => new Foo(bar: 'baz'));
|
app.get('/foo', (req, res) => Foo(bar: 'baz'));
|
||||||
|
|
||||||
app.fallback((req, res) => throw new AngelHttpException.notFound());
|
app.fallback((req, res) => throw AngelHttpException.notFound());
|
||||||
|
|
||||||
app.encoders.addAll({
|
app.encoders.addAll({
|
||||||
'gzip': gzip.encoder,
|
'gzip': gzip.encoder,
|
||||||
'deflate': zlib.encoder,
|
'deflate': zlib.encoder,
|
||||||
});
|
});
|
||||||
|
|
||||||
app.logger = new Logger.detached('angel')
|
app.logger = Logger.detached('angel')
|
||||||
..onRecord.listen((rec) {
|
..onRecord.listen((rec) {
|
||||||
print(rec);
|
print(rec);
|
||||||
if (rec.error != null) {
|
if (rec.error != null) {
|
||||||
|
|
|
@ -22,10 +22,10 @@ class HotReloader {
|
||||||
vm.VmService _client;
|
vm.VmService _client;
|
||||||
vm.IsolateRef _mainIsolate;
|
vm.IsolateRef _mainIsolate;
|
||||||
final StreamController<WatchEvent> _onChange =
|
final StreamController<WatchEvent> _onChange =
|
||||||
new StreamController<WatchEvent>.broadcast();
|
StreamController<WatchEvent>.broadcast();
|
||||||
final List _paths = [];
|
final List _paths = [];
|
||||||
final StringRenderer _renderer = new StringRenderer(pretty: false);
|
final StringRenderer _renderer = StringRenderer(pretty: false);
|
||||||
final Queue<HttpRequest> _requestQueue = new Queue<HttpRequest>();
|
final Queue<HttpRequest> _requestQueue = Queue<HttpRequest>();
|
||||||
HttpServer _io;
|
HttpServer _io;
|
||||||
AngelHttp _server;
|
AngelHttp _server;
|
||||||
Duration _timeout;
|
Duration _timeout;
|
||||||
|
@ -65,16 +65,16 @@ class HotReloader {
|
||||||
/// URI's can be `package:` URI's as well.
|
/// URI's can be `package:` URI's as well.
|
||||||
HotReloader(this.generator, Iterable paths,
|
HotReloader(this.generator, Iterable paths,
|
||||||
{Duration timeout,
|
{Duration timeout,
|
||||||
this.vmServiceHost: 'localhost',
|
this.vmServiceHost = 'localhost',
|
||||||
this.vmServicePort: 8181,
|
this.vmServicePort = 8181,
|
||||||
this.enableHotkeys: true}) {
|
this.enableHotkeys = true}) {
|
||||||
_timeout = timeout ?? new Duration(seconds: 5);
|
_timeout = timeout ?? Duration(seconds: 5);
|
||||||
_paths.addAll(paths ?? []);
|
_paths.addAll(paths ?? []);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future close() async {
|
Future close() async {
|
||||||
_onChange.close();
|
|
||||||
await _io?.close(force: true);
|
await _io?.close(force: true);
|
||||||
|
await _onChange.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
void sendError(HttpRequest request, int status, String title_, e) {
|
void sendError(HttpRequest request, int status, String title_, e) {
|
||||||
|
@ -119,7 +119,7 @@ class HotReloader {
|
||||||
_requestQueue.add(request);
|
_requestQueue.add(request);
|
||||||
else {
|
else {
|
||||||
_requestQueue.add(request);
|
_requestQueue.add(request);
|
||||||
new Timer(timeout, () {
|
Timer(timeout, () {
|
||||||
if (_requestQueue.remove(request)) {
|
if (_requestQueue.remove(request)) {
|
||||||
// Send 502 response
|
// Send 502 response
|
||||||
sendError(request, HttpStatus.badGateway, '502 Bad Gateway',
|
sendError(request, HttpStatus.badGateway, '502 Bad Gateway',
|
||||||
|
@ -133,7 +133,23 @@ class HotReloader {
|
||||||
var s = await generator();
|
var s = await generator();
|
||||||
await Future.forEach(s.startupHooks, s.configure);
|
await Future.forEach(s.startupHooks, s.configure);
|
||||||
s.optimizeForProduction();
|
s.optimizeForProduction();
|
||||||
return new AngelHttp.custom(s, startShared);
|
return AngelHttp.custom(s, startShared);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _logWarning(String msg) {
|
||||||
|
if (_server?.app?.logger != null) {
|
||||||
|
_server.app.logger.warning(msg);
|
||||||
|
} else {
|
||||||
|
print(yellow.wrap('WARNING: $msg'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _logInfo(String msg) {
|
||||||
|
if (_server?.app?.logger != null) {
|
||||||
|
_server.app.logger.info(msg);
|
||||||
|
} else {
|
||||||
|
print(lightGray.wrap(msg));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Starts listening to requests and filesystem events.
|
/// Starts listening to requests and filesystem events.
|
||||||
|
@ -142,13 +158,13 @@ class HotReloader {
|
||||||
_server = await _generateServer();
|
_server = await _generateServer();
|
||||||
|
|
||||||
if (_paths?.isNotEmpty != true)
|
if (_paths?.isNotEmpty != true)
|
||||||
print(yellow.wrap(
|
_logWarning(
|
||||||
'WARNING: You have instantiated a HotReloader without providing any filesystem paths to watch.'));
|
'You have instantiated a HotReloader without providing any filesystem paths to watch.');
|
||||||
|
|
||||||
if (!Platform.executableArguments.contains('--observe') &&
|
if (!Platform.executableArguments.contains('--observe') &&
|
||||||
!Platform.executableArguments.contains('--enable-vm-service')) {
|
!Platform.executableArguments.contains('--enable-vm-service')) {
|
||||||
stderr.writeln(yellow.wrap(
|
_logWarning(
|
||||||
'WARNING: You have instantiated a HotReloader without passing `--enable-vm-service` or `--observe` to the Dart VM. Hot reloading will be disabled.'));
|
'You have instantiated a HotReloader without passing `--enable-vm-service` or `--observe` to the Dart VM. Hot reloading will be disabled.');
|
||||||
isHot = false;
|
isHot = false;
|
||||||
} else {
|
} else {
|
||||||
var info = await dev.Service.getInfo();
|
var info = await dev.Service.getInfo();
|
||||||
|
@ -173,14 +189,14 @@ class HotReloader {
|
||||||
//.transform(new _Debounce(new Duration(seconds: 1)))
|
//.transform(new _Debounce(new Duration(seconds: 1)))
|
||||||
.listen(_handleWatchEvent);
|
.listen(_handleWatchEvent);
|
||||||
|
|
||||||
while (!_requestQueue.isEmpty) await _handle(_requestQueue.removeFirst());
|
while (_requestQueue.isNotEmpty) await _handle(_requestQueue.removeFirst());
|
||||||
var server = _io = await HttpServer.bind(address ?? '127.0.0.1', port ?? 0);
|
var server = _io = await HttpServer.bind(address ?? '127.0.0.1', port ?? 0);
|
||||||
server.listen(handleRequest);
|
server.listen(handleRequest);
|
||||||
|
|
||||||
// Print a Flutter-like prompt...
|
// Print a Flutter-like prompt...
|
||||||
if (enableHotkeys) {
|
if (enableHotkeys) {
|
||||||
var serverUri = new Uri(
|
var serverUri =
|
||||||
scheme: 'http', host: server.address.address, port: server.port);
|
Uri(scheme: 'http', host: server.address.address, port: server.port);
|
||||||
var observatoryUri = await dev.Service.getInfo().then((i) => i.serverUri);
|
var observatoryUri = await dev.Service.getInfo().then((i) => i.serverUri);
|
||||||
|
|
||||||
print(styleBold.wrap(
|
print(styleBold.wrap(
|
||||||
|
@ -215,10 +231,10 @@ class HotReloader {
|
||||||
sub = stdin.expand((l) => l).listen((ch) async {
|
sub = stdin.expand((l) => l).listen((ch) async {
|
||||||
if (ch == $r) {
|
if (ch == $r) {
|
||||||
_handleWatchEvent(
|
_handleWatchEvent(
|
||||||
new WatchEvent(ChangeType.MODIFY, '[manual-reload]'), isHot);
|
WatchEvent(ChangeType.MODIFY, '[manual-reload]'), isHot);
|
||||||
}
|
}
|
||||||
if (ch == $R) {
|
if (ch == $R) {
|
||||||
print('Manually restarting server...\n');
|
_logInfo('Manually restarting server...\n');
|
||||||
await _killServer();
|
await _killServer();
|
||||||
await _server.close();
|
await _server.close();
|
||||||
var addr = _io.address.address;
|
var addr = _io.address.address;
|
||||||
|
@ -227,8 +243,8 @@ class HotReloader {
|
||||||
await startServer(addr, port);
|
await startServer(addr, port);
|
||||||
} else if (ch == $q) {
|
} else if (ch == $q) {
|
||||||
stdin.echoMode = stdin.lineMode = true;
|
stdin.echoMode = stdin.lineMode = true;
|
||||||
close();
|
await close();
|
||||||
sub.cancel();
|
await sub.cancel();
|
||||||
exit(0);
|
exit(0);
|
||||||
} else if (ch == $h) {
|
} else if (ch == $h) {
|
||||||
print(
|
print(
|
||||||
|
@ -266,7 +282,7 @@ class HotReloader {
|
||||||
} else
|
} else
|
||||||
await _listenToStat(path.toFilePath());
|
await _listenToStat(path.toFilePath());
|
||||||
} else {
|
} else {
|
||||||
throw new ArgumentError(
|
throw ArgumentError(
|
||||||
'Hot reload paths must be a FileSystemEntity, a Uri, a String or a Glob. You provided: $path');
|
'Hot reload paths must be a FileSystemEntity, a Uri, a String or a Glob. You provided: $path');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -277,22 +293,22 @@ class HotReloader {
|
||||||
try {
|
try {
|
||||||
var stat = await FileStat.stat(path);
|
var stat = await FileStat.stat(path);
|
||||||
if (stat.type == FileSystemEntityType.link) {
|
if (stat.type == FileSystemEntityType.link) {
|
||||||
var lnk = new Link(path);
|
var lnk = Link(path);
|
||||||
var p = await lnk.resolveSymbolicLinks();
|
var p = await lnk.resolveSymbolicLinks();
|
||||||
return await _listenToStat(p);
|
return await _listenToStat(p);
|
||||||
} else if (stat.type == FileSystemEntityType.file) {
|
} else if (stat.type == FileSystemEntityType.file) {
|
||||||
var file = new File(path);
|
var file = File(path);
|
||||||
if (!await file.exists()) return null;
|
if (!await file.exists()) return null;
|
||||||
} else if (stat.type == FileSystemEntityType.directory) {
|
} else if (stat.type == FileSystemEntityType.directory) {
|
||||||
var dir = new Directory(path);
|
var dir = Directory(path);
|
||||||
if (!await dir.exists()) return null;
|
if (!await dir.exists()) return null;
|
||||||
} else
|
} else
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
var watcher = new Watcher(path);
|
var watcher = Watcher(path);
|
||||||
|
|
||||||
watcher.events.listen(_onChange.add, onError: (e) {
|
watcher.events.listen(_onChange.add, onError: (e) {
|
||||||
stderr.writeln('Could not listen to file changes at ${path}: $e');
|
_logWarning('Could not listen to file changes at ${path}: $e');
|
||||||
});
|
});
|
||||||
|
|
||||||
// print('Listening for file changes at ${path}...');
|
// print('Listening for file changes at ${path}...');
|
||||||
|
@ -305,15 +321,15 @@ class HotReloader {
|
||||||
var r = await _listen();
|
var r = await _listen();
|
||||||
|
|
||||||
if (r == null) {
|
if (r == null) {
|
||||||
print(yellow.wrap(
|
_logWarning(
|
||||||
'WARNING: Unable to watch path "$path" from working directory "${Directory.current.path}". Please ensure that it exists.'));
|
'Unable to watch path "$path" from working directory "${Directory.current.path}". Please ensure that it exists.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future _killServer() async {
|
Future _killServer() async {
|
||||||
if (_server != null) {
|
if (_server != null) {
|
||||||
// Do this asynchronously, because we really don't care about the old server anymore.
|
// Do this asynchronously, because we really don't care about the old server anymore.
|
||||||
new Future(() async {
|
scheduleMicrotask(() async {
|
||||||
// Disconnect active WebSockets
|
// Disconnect active WebSockets
|
||||||
try {
|
try {
|
||||||
var ws = _server.app.container.make<AngelWebSocket>();
|
var ws = _server.app.container.make<AngelWebSocket>();
|
||||||
|
@ -322,7 +338,7 @@ class HotReloader {
|
||||||
try {
|
try {
|
||||||
await client.close();
|
await client.close();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
stderr.writeln(
|
_logWarning(
|
||||||
'Couldn\'t close WebSocket from session #${client.request.session.id}: $e');
|
'Couldn\'t close WebSocket from session #${client.request.session.id}: $e');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -339,7 +355,7 @@ class HotReloader {
|
||||||
}
|
}
|
||||||
|
|
||||||
_handleWatchEvent(WatchEvent e, [bool hot = true]) async {
|
_handleWatchEvent(WatchEvent e, [bool hot = true]) async {
|
||||||
print('${e.path} changed. Reloading server...\n');
|
_logInfo('${e.path} changed. Reloading server...\n');
|
||||||
await _killServer();
|
await _killServer();
|
||||||
_server = null;
|
_server = null;
|
||||||
|
|
||||||
|
@ -347,14 +363,14 @@ class HotReloader {
|
||||||
var report = await _client.reloadSources(_mainIsolate.id);
|
var report = await _client.reloadSources(_mainIsolate.id);
|
||||||
|
|
||||||
if (!report.success) {
|
if (!report.success) {
|
||||||
stderr.writeln(
|
_logWarning(
|
||||||
'Hot reload failed - perhaps some sources have not been generated yet.');
|
'Hot reload failed - perhaps some sources have not been generated yet.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var s = await _generateServer();
|
var s = await _generateServer();
|
||||||
_server = s;
|
_server = s;
|
||||||
while (!_requestQueue.isEmpty) await _handle(_requestQueue.removeFirst());
|
while (_requestQueue.isNotEmpty) await _handle(_requestQueue.removeFirst());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -365,10 +381,10 @@ class _Debounce<S> extends StreamTransformerBase<S, S> {
|
||||||
const _Debounce(this._delay);
|
const _Debounce(this._delay);
|
||||||
|
|
||||||
Stream<S> bind(Stream<S> stream) {
|
Stream<S> bind(Stream<S> stream) {
|
||||||
var initial = new DateTime.now();
|
var initial = DateTime.now();
|
||||||
var next = initial.subtract(this._delay);
|
var next = initial.subtract(this._delay);
|
||||||
return stream.where((S data) {
|
return stream.where((S data) {
|
||||||
var now = new DateTime.now();
|
var now = DateTime.now();
|
||||||
if (now.isAfter(next)) {
|
if (now.isAfter(next)) {
|
||||||
next = now.add(this._delay);
|
next = now.add(this._delay);
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -18,3 +18,4 @@ dependencies:
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
http: ^0.11.3
|
http: ^0.11.3
|
||||||
logging: ^0.11.0
|
logging: ^0.11.0
|
||||||
|
pedantic: ^1.0.0
|
||||||
|
|
Loading…
Reference in a new issue