@@ -8,15 +8,16 @@ import 'package:build/build.dart';
88import 'package:built_collection/built_collection.dart' ;
99import 'package:watcher/watcher.dart' ;
1010
11+ import '../bootstrap/build_script_generate.dart' ;
1112import '../build_plan/build_directory.dart' ;
1213import '../build_plan/build_filter.dart' ;
1314import '../build_plan/build_plan.dart' ;
1415import '../commands/watch/asset_change.dart' ;
1516import '../constants.dart' ;
1617import '../io/asset_tracker.dart' ;
17- import '../io/build_output_reader.dart' ;
1818import '../io/filesystem_cache.dart' ;
1919import '../io/reader_writer.dart' ;
20+ import '../logging/build_log.dart' ;
2021import 'asset_graph/graph.dart' ;
2122import 'asset_graph/node.dart' ;
2223import 'build.dart' ;
@@ -35,11 +36,10 @@ import 'build_result.dart';
3536/// this serialized state is not actually used: the `AssetGraph` instance
3637/// already in memory is used directly.
3738class BuildSeries {
38- final BuildPlan _buildPlan;
39+ BuildPlan _buildPlan;
40+ AssetGraph _assetGraph;
41+ ReaderWriter _readerWriter;
3942
40- final AssetGraph _assetGraph;
41-
42- final ReaderWriter _readerWriter;
4343 final ResourceManager _resourceManager = ResourceManager ();
4444
4545 /// For the first build only, updates from the previous serialized build
@@ -105,19 +105,21 @@ class BuildSeries {
105105 return false ;
106106 }
107107
108- final node =
109- _assetGraph.contains (change.id) ? _assetGraph.get (change.id) : null ;
108+ final id = change.id;
109+ if (_isBuildConfiguration (id)) return true ;
110+
111+ final node = _assetGraph.contains (id) ? _assetGraph.get (id) : null ;
110112
111113 // Changes to files that are not currently part of the build.
112114 if (node == null ) {
113115 // Ignore under `.dart_tool/build`.
114- if (change. id.path.startsWith (cacheDir)) return false ;
116+ if (id.path.startsWith (cacheDir)) return false ;
115117
116118 // Ignore modifications and deletes.
117119 if (change.type != ChangeType .ADD ) return false ;
118120
119121 // It's an add: return whether it's a new input.
120- return _buildPlan.targetGraph.anyMatchesAsset (change. id);
122+ return _buildPlan.targetGraph.anyMatchesAsset (id);
121123 }
122124
123125 // Changes to files that are part of the build.
@@ -136,15 +138,21 @@ class BuildSeries {
136138
137139 // For modifications, confirm that the content actually changed.
138140 if (change.type == ChangeType .MODIFY ) {
139- _readerWriter.cache.invalidate ([change. id]);
140- final newDigest = await _readerWriter.digest (change. id);
141+ _readerWriter.cache.invalidate ([id]);
142+ final newDigest = await _readerWriter.digest (id);
141143 return node.digest != newDigest;
142144 }
143145
144146 // It's an add of "missing source" node or a deletion of an input.
145147 return true ;
146148 }
147149
150+ bool _isBuildConfiguration (AssetId id) =>
151+ id.path == 'build.yaml' ||
152+ id.path.endsWith ('.build.yaml' ) ||
153+ (id.package == _buildPlan.packageGraph.root.name &&
154+ id.path == 'build.${_buildPlan .buildOptions .configKey }.yaml' );
155+
148156 Future <List <WatchEvent >> checkForChanges () async {
149157 final updates = await AssetTracker (
150158 _buildPlan.readerWriter,
@@ -178,14 +186,29 @@ class BuildSeries {
178186 BuiltSet <BuildFilter >? buildFilters,
179187 }) async {
180188 if (_hasBuildScriptChanged (updates.keys.toSet ())) {
181- return BuildResult (
182- status: BuildStatus .failure,
183- failureType: FailureType .buildScriptChanged,
184- buildOutputReader: BuildOutputReader (
185- buildPlan: _buildPlan,
186- readerWriter: _readerWriter,
187- assetGraph: _assetGraph,
188- ),
189+ return BuildResult .buildScriptChanged ();
190+ }
191+
192+ if (updates.keys.any (_isBuildConfiguration)) {
193+ _buildPlan = await _buildPlan.reload ();
194+ await _buildPlan.deleteFilesAndFolders ();
195+ // A config change might have caused new builders to be needed, which
196+ // needs a restart to change the build script.
197+ if (_buildPlan.restartIsNeeded) {
198+ return BuildResult .buildScriptChanged ();
199+ }
200+ // A config change might have changed builder factories, which needs a
201+ // restart to change the build script.
202+ if (await hasGeneratedBuildScriptChanged ()) {
203+ return BuildResult .buildScriptChanged ();
204+ }
205+ _assetGraph = _buildPlan.takeAssetGraph ();
206+ _readerWriter = _buildPlan.readerWriter.copyWith (
207+ generatedAssetHider: _assetGraph,
208+ cache:
209+ _buildPlan.buildOptions.enableLowResourcesMode
210+ ? const PassthroughFilesystemCache ()
211+ : InMemoryFilesystemCache (),
189212 );
190213 }
191214
@@ -202,6 +225,7 @@ class BuildSeries {
202225 }
203226 }
204227
228+ if (! firstBuild) buildLog.nextBuild ();
205229 final build = Build (
206230 buildPlan: _buildPlan.copyWith (
207231 buildDirs: buildDirs,
0 commit comments