Skip to content

Commit f610222

Browse files
authored
invalidate the snapshot when build_runner or build_daemon are updated (#2374)
Related to #1929 I ended up going with the build_runner/build_daemon version check since the error handling was going to get pretty gnarly once I looked at what it would actually take. The check is done by examining where a fake uri resolves to for each package, since that actually catches some cases the version check alone wouldn't catch and it doesn't require reading/parsing any files. Note that this will not catch cases where you have a path override on these packages as that path won't ever change even if the packages do, but that should only affect us internally.
1 parent 0246ed2 commit f610222

File tree

3 files changed

+55
-9
lines changed

3 files changed

+55
-9
lines changed

build_runner/CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
## 1.6.3
2+
3+
- Pre-emptively re-snapshot when the `build_runner` or `build_daemon`
4+
packages are updated.
5+
16
## 1.6.2
27

38
- Support the latest `build_daemon` version.

build_runner/lib/src/build_script_generate/bootstrap.dart

Lines changed: 49 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ Future<int> generateAndRun(List<String> args, {Logger logger}) async {
5757
return ExitCode.config.code;
5858
}
5959

60-
scriptExitCode = await _createSnapshotIfMissing(logger);
60+
scriptExitCode = await _createSnapshotIfNeeded(logger);
6161
if (scriptExitCode != 0) return scriptExitCode;
6262

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

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

129-
// If we failed to serialize an asset graph for the snapshot, then we don't
130-
// want to re-use it because we can't check if it is up to date.
131-
if (!await assetGraphFile.exists() && await snapshotFile.exists()) {
132-
await snapshotFile.delete();
133-
logger.warning('Deleted previous snapshot due to missing asset graph.');
135+
if (await snapshotFile.exists()) {
136+
// If we failed to serialize an asset graph for the snapshot, then we don't
137+
// want to re-use it because we can't check if it is up to date.
138+
if (!await assetGraphFile.exists()) {
139+
await snapshotFile.delete();
140+
logger.warning('Deleted previous snapshot due to missing asset graph.');
141+
} else if (!await _checkImportantPackageDeps()) {
142+
await snapshotFile.delete();
143+
logger.warning('Deleted previous snapshot due to core package update');
144+
}
134145
}
135146

136147
String stderr;
@@ -159,3 +170,33 @@ Future<int> _createSnapshotIfMissing(Logger logger) async {
159170
}
160171
return 0;
161172
}
173+
174+
const _importantPackages = [
175+
'build_daemon',
176+
'build_runner',
177+
];
178+
final _previousLocationsFile = File(
179+
p.url.join(p.url.dirname(scriptSnapshotLocation), '.packageLocations'));
180+
181+
/// Returns whether the [_importantPackages] are all pointing at same locations
182+
/// from the previous run.
183+
///
184+
/// Also updates the [_previousLocationsFile] with the new locations if not.
185+
///
186+
/// This is used to detect potential changes to the user facing api and
187+
/// pre-emptively resolve them by resnapshotting, see
188+
/// https://github.com/dart-lang/build/issues/1929.
189+
Future<bool> _checkImportantPackageDeps() async {
190+
var currentLocationsContent = _importantPackages
191+
.map((pkg) => Isolate.resolvePackageUri(
192+
Uri(scheme: 'package', path: '$pkg/fake.dart')))
193+
.join('\n');
194+
195+
if (!_previousLocationsFile.existsSync() ||
196+
currentLocationsContent != _previousLocationsFile.readAsStringSync()) {
197+
_previousLocationsFile.writeAsStringSync(currentLocationsContent);
198+
return false;
199+
}
200+
201+
return true;
202+
}

build_runner/pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name: build_runner
2-
version: 1.6.2
2+
version: 1.6.3
33
description: Tools to write binaries that run builders.
44
author: Dart Team <[email protected]>
55
homepage: https://github.com/dart-lang/build/tree/master/build_runner

0 commit comments

Comments
 (0)