blob: c918ca4e398a783f0c17c21747eebca163826368 [file] [log] [blame]
// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'dart:async';
import 'dart:io';
import 'package:build_daemon/constants.dart';
import 'package:build_daemon/src/daemon.dart';
import 'package:build_runner/src/daemon/constants.dart';
import 'package:logging/logging.dart';
import '../daemon/asset_server.dart';
import '../daemon/daemon_builder.dart';
import 'base_command.dart';
/// A command that starts the Build Daemon.
class DaemonCommand extends BuildRunnerCommand {
@override
String get description => 'Starts the build daemon.';
@override
bool get hidden => true;
@override
String get name => 'daemon';
@override
Future<int> run() async {
var workingDirectory = Directory.current.path;
var options = readOptions();
var daemon = Daemon(workingDirectory);
var requestedOptions = argResults.arguments.toSet();
if (!daemon.tryGetLock()) {
var runningOptions = await currentOptions(workingDirectory);
var version = await runningVersion(workingDirectory);
if (version != currentVersion) {
stdout
..writeln('Running Version: $version')
..writeln('Current Version: $currentVersion')
..writeln(versionSkew);
return 1;
} else if (!(runningOptions.length == requestedOptions.length &&
runningOptions.containsAll(requestedOptions))) {
stdout
..writeln('Running Options: $runningOptions')
..writeln('Requested Options: $requestedOptions')
..writeln(optionsSkew);
return 1;
} else {
stdout.writeln('Daemon is already running.');
print(readyToConnectLog);
return 0;
}
} else {
stdout.writeln('Starting daemon...');
BuildRunnerDaemonBuilder builder;
// Ensure we capture any logs that happen during startup.
var startupLogSub =
Logger.root.onRecord.listen((record) => stdout.writeln('$record\n'));
builder = await BuildRunnerDaemonBuilder.create(
packageGraph,
builderApplications,
options,
);
await startupLogSub.cancel();
// Forward server logs to daemon command STDIO.
var logSub =
builder.logs.listen((serverLog) => stdout.writeln(serverLog.log));
var server = await AssetServer.run(builder, packageGraph.root.name);
File(assetServerPortFilePath(workingDirectory))
.writeAsStringSync('${server.port}');
await daemon.start(requestedOptions, builder, builder.changes);
stdout.writeln(readyToConnectLog);
await logSub.cancel();
await daemon.onDone.whenComplete(() async {
await server.stop();
});
// Clients can disconnect from the daemon mid build.
// As a result we try to relinquish resources which can
// cause the build to hang. To ensure there are no ghost processes
// fast exit.
exit(0);
}
return 0;
}
}