Commit fb3bf7a9 authored by John McCutchan's avatar John McCutchan Committed by GitHub

Support hot reload with a prebuilt loader (#6743)

parent 10d20c77
......@@ -785,7 +785,6 @@ class _AdbLogReader extends DeviceLogReader {
DateTime time = _adbTimestampToDateTime(timestamp);
if (time.isBefore(_timeOrigin)) {
// Ignore log messages before the origin.
printTrace('skipped old log line: $line');
return;
}
}
......@@ -816,7 +815,6 @@ class _AdbLogReader extends DeviceLogReader {
return;
}
}
printTrace('skipped log line: $line');
}
void _stop() {
......
......@@ -62,6 +62,15 @@ class RunCommand extends RunCommandBase {
argParser.addOption('use-application-binary',
hide: !verboseHelp,
help: 'Specify a pre-built application binary to use when running.');
argParser.addOption('snapshotter',
hide: !verboseHelp,
help: 'Specify the path to the sky_snapshot binary.');
argParser.addOption('packages',
hide: !verboseHelp,
help: 'Specify the path to the .packages file.');
argParser.addOption('project_root',
hide: !verboseHelp,
help: 'Specify the project root directory.');
argParser.addFlag('machine',
hide: !verboseHelp,
help: 'Handle machine structured JSON command input\n'
......@@ -138,7 +147,7 @@ class RunCommand extends RunCommandBase {
bool shouldUseHotMode() {
bool hotArg = argResults['hot'] ?? false;
final bool shouldUseHotMode = hotArg && !runningWithPrebuiltApplication;
final bool shouldUseHotMode = hotArg;
return (getBuildMode() == BuildMode.debug) && shouldUseHotMode;
}
......@@ -220,7 +229,10 @@ class RunCommand extends RunCommandBase {
device,
target: targetFile,
debuggingOptions: options,
benchmarkMode: argResults['benchmark']
benchmarkMode: argResults['benchmark'],
applicationBinary: argResults['use-application-binary'],
projectRootPath: argResults['project_root'],
packagesFilePath: argResults['packages'],
);
} else {
runner = new RunAndStayResident(
......
......@@ -252,20 +252,31 @@ class DevFS {
/// Create a [DevFS] named [fsName] for the local files in [directory].
DevFS(VMService serviceProtocol,
String fsName,
this.rootDirectory)
this.rootDirectory, {
String packagesFilePath
})
: _operations = new ServiceProtocolDevFSOperations(serviceProtocol),
_httpWriter = new _DevFSHttpWriter(fsName, serviceProtocol),
fsName = fsName;
fsName = fsName {
_packagesFilePath =
packagesFilePath ?? path.join(rootDirectory.path, kPackagesFileName);
}
DevFS.operations(this._operations,
this.fsName,
this.rootDirectory)
: _httpWriter = null;
this.rootDirectory, {
String packagesFilePath,
})
: _httpWriter = null {
_packagesFilePath =
packagesFilePath ?? path.join(rootDirectory.path, kPackagesFileName);
}
final DevFSOperations _operations;
final _DevFSHttpWriter _httpWriter;
final String fsName;
final Directory rootDirectory;
String _packagesFilePath;
final Map<String, DevFSEntry> _entries = <String, DevFSEntry>{};
final Set<DevFSEntry> _dirtyEntries = new Set<DevFSEntry>();
final Set<DevFSEntry> _deletedEntries = new Set<DevFSEntry>();
......@@ -318,10 +329,10 @@ class DevFS {
fileFilter: fileFilter);
printTrace('Scanning package files');
String packagesFilePath = path.join(rootDirectory.path, kPackagesFileName);
StringBuffer sb;
if (FileSystemEntity.isFileSync(packagesFilePath)) {
PackageMap packageMap = new PackageMap(kPackagesFileName);
if (FileSystemEntity.isFileSync(_packagesFilePath)) {
PackageMap packageMap = new PackageMap(_packagesFilePath);
for (String packageName in packageMap.map.keys) {
Uri uri = packageMap.map[packageName];
......
......@@ -40,10 +40,12 @@ String getDevFSLoaderScript() {
class DartDependencySetBuilder {
DartDependencySetBuilder(this.mainScriptPath,
this.projectRootPath);
this.projectRootPath,
this.packagesFilePath);
final String mainScriptPath;
final String projectRootPath;
final String packagesFilePath;
Set<String> build() {
final String skySnapshotPath =
......@@ -51,7 +53,7 @@ class DartDependencySetBuilder {
final List<String> args = <String>[
skySnapshotPath,
'--packages=${path.absolute(PackageMap.globalPackagesPath)}',
'--packages=$packagesFilePath',
'--print-deps',
mainScriptPath
];
......@@ -120,16 +122,24 @@ class HotRunner extends ResidentRunner {
DebuggingOptions debuggingOptions,
bool usesTerminalUI: true,
this.benchmarkMode: false,
this.applicationBinary,
String projectRootPath,
String packagesFilePath,
}) : super(device,
target: target,
debuggingOptions: debuggingOptions,
usesTerminalUI: usesTerminalUI) {
_projectRootPath = Directory.current.path;
_projectRootPath = projectRootPath ?? Directory.current.path;
_packagesFilePath =
packagesFilePath ?? path.absolute(PackageMap.globalPackagesPath);
}
ApplicationPackage _package;
String _mainPath;
String _projectRootPath;
String _packagesFilePath;
final String applicationBinary;
bool get prebuiltMode => applicationBinary != null;
Set<String> _dartDependencies;
int _observatoryPort;
final AssetBundle bundle = new AssetBundle();
......@@ -144,6 +154,7 @@ class HotRunner extends ResidentRunner {
bool shouldBuild: true
}) {
// Don't let uncaught errors kill the process.
assert(shouldBuild == !prebuiltMode);
return Chain.capture(() {
return _run(
connectionInfoCompleter: connectionInfoCompleter,
......@@ -162,7 +173,8 @@ class HotRunner extends ResidentRunner {
return true;
}
DartDependencySetBuilder dartDependencySetBuilder =
new DartDependencySetBuilder(_mainPath, _projectRootPath);
new DartDependencySetBuilder(
_mainPath, _projectRootPath, _packagesFilePath);
try {
_dartDependencies = dartDependencySetBuilder.build();
} catch (error) {
......@@ -188,7 +200,7 @@ class HotRunner extends ResidentRunner {
return 1;
}
_package = getApplicationPackageForPlatform(device.platform);
_package = getApplicationPackageForPlatform(device.platform, applicationBinary: applicationBinary);
if (_package == null) {
String message = 'No application found for ${device.platform}.';
......@@ -222,15 +234,10 @@ class HotRunner extends ResidentRunner {
// TODO(devoncarew): Move this into the device.startApp() impls.
if (_package != null) {
printTrace("Stopping app '${_package.name}' on ${device.name}.");
// We don't wait for the stop command to complete.
device.stopApp(_package);
await device.stopApp(_package);
}
// Allow any stop commands from above to start work.
await new Future<Duration>.delayed(Duration.ZERO);
// TODO(devoncarew): This fails for ios devices - we haven't built yet.
if (device is AndroidDevice) {
if (prebuiltMode || device is AndroidDevice) {
printTrace('Running install command.');
if (!(installApp(device, _package, uninstall: false)))
return 1;
......@@ -249,7 +256,8 @@ class HotRunner extends ResidentRunner {
mainPath: getDevFSLoaderScript(),
debuggingOptions: debuggingOptions,
platformArgs: platformArgs,
route: route
route: route,
prebuiltApplication: prebuiltMode
);
LaunchResult result = await futureResult;
......@@ -369,7 +377,8 @@ class HotRunner extends ResidentRunner {
String fsName = path.basename(_projectRootPath);
_devFS = new DevFS(vmService,
fsName,
new Directory(_projectRootPath));
new Directory(_projectRootPath),
packagesFilePath: _packagesFilePath);
return _devFS.create();
}
......
......@@ -73,7 +73,10 @@ void testUsingContext(String description, dynamic testMethod(), {
if (bufferLogger.errorText.isNotEmpty)
print(bufferLogger.errorText);
}
throw error;
// Previously the following line read "throw error;". This is bad because
// it drops the error's actual stacktrace. Use 'rethrow' to preserve
// the stacktrace.
rethrow;
}
}, timeout: timeout);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment