Skip to content

invalidate the snapshot when build_runner or build_daemon are updated #2374

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jul 24, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions build_runner/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
## 1.6.3

- Pre-emptively re-snapshot when the `build_runner` or `build_daemon`
packages are updated.

## 1.6.2

- Support the latest `build_daemon` version.
Expand Down
57 changes: 49 additions & 8 deletions build_runner/lib/src/build_script_generate/bootstrap.dart
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ Future<int> generateAndRun(List<String> args, {Logger logger}) async {
return ExitCode.config.code;
}

scriptExitCode = await _createSnapshotIfMissing(logger);
scriptExitCode = await _createSnapshotIfNeeded(logger);
if (scriptExitCode != 0) return scriptExitCode;

exitPort = ReceivePort();
Expand Down Expand Up @@ -118,19 +118,30 @@ Future<int> generateAndRun(List<String> args, {Logger logger}) async {
return scriptExitCode;
}

/// Creates a script snapshot for the build script.
/// Creates a script snapshot for the build script in necessary.
///
/// A snapshot is generated if:
///
/// - It doesn't exist currently
/// - Either build_runner or build_daemon point at a different location than
/// they used to, see https://github.com/dart-lang/build/issues/1929.
///
/// Returns zero for success or a number for failure which should be set to the
/// exit code.
Future<int> _createSnapshotIfMissing(Logger logger) async {
Future<int> _createSnapshotIfNeeded(Logger logger) async {
var assetGraphFile = File(assetGraphPathFor(scriptSnapshotLocation));
var snapshotFile = File(scriptSnapshotLocation);

// If we failed to serialize an asset graph for the snapshot, then we don't
// want to re-use it because we can't check if it is up to date.
if (!await assetGraphFile.exists() && await snapshotFile.exists()) {
await snapshotFile.delete();
logger.warning('Deleted previous snapshot due to missing asset graph.');
if (await snapshotFile.exists()) {
// If we failed to serialize an asset graph for the snapshot, then we don't
// want to re-use it because we can't check if it is up to date.
if (!await assetGraphFile.exists()) {
await snapshotFile.delete();
logger.warning('Deleted previous snapshot due to missing asset graph.');
} else if (!await _checkImportantPackageDeps()) {
await snapshotFile.delete();
logger.warning('Deleted previous snapshot due to core package update');
}
}

String stderr;
Expand Down Expand Up @@ -159,3 +170,33 @@ Future<int> _createSnapshotIfMissing(Logger logger) async {
}
return 0;
}

const _importantPackages = [
'build_daemon',
'build_runner',
];
final _previousLocationsFile = File(
p.url.join(p.url.dirname(scriptSnapshotLocation), '.packageLocations'));

/// Returns whether the [_importantPackages] are all pointing at same locations
/// from the previous run.
///
/// Also updates the [_previousLocationsFile] with the new locations if not.
///
/// This is used to detect potential changes to the user facing api and
/// pre-emptively resolve them by resnapshotting, see
/// https://github.com/dart-lang/build/issues/1929.
Future<bool> _checkImportantPackageDeps() async {
var currentLocationsContent = _importantPackages
.map((pkg) => Isolate.resolvePackageUri(
Uri(scheme: 'package', path: '$pkg/fake.dart')))
.join('\n');

if (!_previousLocationsFile.existsSync() ||
currentLocationsContent != _previousLocationsFile.readAsStringSync()) {
_previousLocationsFile.writeAsStringSync(currentLocationsContent);
return false;
}

return true;
}
2 changes: 1 addition & 1 deletion build_runner/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: build_runner
version: 1.6.2
version: 1.6.3
description: Tools to write binaries that run builders.
author: Dart Team <[email protected]>
homepage: https://github.com/dart-lang/build/tree/master/build_runner
Expand Down