@@ -15,7 +15,6 @@ import 'package:path/path.dart' as p;
1515import  'package:watcher/watcher.dart' ;
1616
1717import  '../bootstrap/build_process_state.dart' ;
18- import  '../build_plan/build_directory.dart' ;
1918import  '../build_plan/build_options.dart' ;
2019import  '../build_plan/build_phases.dart' ;
2120import  '../build_plan/build_plan.dart' ;
@@ -24,6 +23,7 @@ import '../build_plan/phase.dart';
2423import  '../build_plan/target_graph.dart' ;
2524import  '../build_plan/testing_overrides.dart' ;
2625import  '../constants.dart' ;
26+ import  '../io/build_output_reader.dart' ;
2727import  '../io/create_merged_dir.dart' ;
2828import  '../io/reader_writer.dart' ;
2929import  '../logging/build_log.dart' ;
@@ -33,12 +33,10 @@ import 'asset_graph/node.dart';
3333import  'asset_graph/post_process_build_step_id.dart' ;
3434import  'build_dirs.dart' ;
3535import  'build_result.dart' ;
36- import  'finalized_assets_view.dart' ;
3736import  'input_tracker.dart' ;
3837import  'library_cycle_graph/asset_deps_loader.dart' ;
3938import  'library_cycle_graph/library_cycle_graph.dart' ;
4039import  'library_cycle_graph/library_cycle_graph_loader.dart' ;
41- import  'optional_output_tracker.dart' ;
4240import  'performance_tracker.dart' ;
4341import  'performance_tracking_resolvers.dart' ;
4442import  'resolver/analysis_driver_model.dart' ;
@@ -110,6 +108,9 @@ class Build {
110108  /// transitive source. 
111109final  Map <LibraryCycleGraph , bool > changedGraphs =  Map .identity ();
112110
111+   /// The build output. 
112+ final  BuildOutputReader  buildOutputReader;
113+ 
113114  Build ({
114115    required  this .buildPlan,
115116    required  this .readerWriter,
@@ -122,7 +123,12 @@ class Build {
122123       previousDepsLoader = 
123124           assetGraph.previousPhasedAssetDeps ==  null 
124125               ?  null 
125-                :  AssetDepsLoader .fromDeps (assetGraph.previousPhasedAssetDeps! );
126+                :  AssetDepsLoader .fromDeps (assetGraph.previousPhasedAssetDeps! ),
127+        buildOutputReader =  BuildOutputReader (
128+          buildPlan:  buildPlan,
129+          readerWriter:  readerWriter,
130+          assetGraph:  assetGraph,
131+        );
126132
127133  BuildOptions  get  buildOptions =>  buildPlan.buildOptions;
128134  TestingOverrides  get  testingOverrides =>  buildPlan.testingOverrides;
@@ -138,13 +144,6 @@ class Build {
138144      (b) =>  b..rootPackageName =  packageGraph.root.name,
139145    );
140146    var  result =  await  _safeBuild (updates);
141-     final  optionalOutputTracker =  OptionalOutputTracker (
142-       assetGraph,
143-       targetGraph,
144-       BuildDirectory .buildPaths (buildPlan.buildOptions.buildDirs),
145-       buildPlan.buildOptions.buildFilters,
146-       buildPhases,
147-     );
148147    if  (result.status ==  BuildStatus .success) {
149148      final  failures =  < AssetNode > [];
150149      for  (final  output in  processedOutputs) {
@@ -169,21 +168,31 @@ class Build {
169168            logger.severe (error);
170169          }
171170        }
172-         result =  BuildResult (
173-           BuildStatus .failure,
174-           result.outputs,
175-           performance:  result.performance,
176-         );
171+         result =  result.copyWith (status:  BuildStatus .failure);
177172      }
178173    }
179174    readerWriter.cache.flush ();
180175    await  resourceManager.disposeAll ();
181-     result =  await  _finalizeBuild (
182-       result,
183-       FinalizedAssetsView (assetGraph, packageGraph, optionalOutputTracker),
184-       readerWriter,
185-       buildPlan.buildOptions.buildDirs,
186-     );
176+ 
177+     // If requested, create output directories. If that fails, fail the build. 
178+     if  (buildPlan.buildOptions.buildDirs.any (
179+           (target) =>  target.outputLocation? .path.isNotEmpty ??  false ,
180+         ) && 
181+         result.status ==  BuildStatus .success) {
182+       if  (! await  createMergedOutputDirectories (
183+         packageGraph:  packageGraph,
184+         outputSymlinksOnly:  buildOptions.outputSymlinksOnly,
185+         buildDirs:  buildOptions.buildDirs,
186+         buildOutputReader:  buildOutputReader,
187+         readerWriter:  readerWriter,
188+       )) {
189+         result =  result.copyWith (
190+           status:  BuildStatus .failure,
191+           failureType:  FailureType .cantCreate,
192+         );
193+       }
194+     }
195+ 
187196    _resolvers.reset ();
188197    buildLog.finishBuild (
189198      result:  result.status ==  BuildStatus .success,
@@ -282,7 +291,13 @@ class Build {
282291          buildLog.error (
283292            buildLog.renderThrowable ('Unhandled build failure!' , e, st),
284293          );
285-           done.complete (BuildResult (BuildStatus .failure, []));
294+           done.complete (
295+             BuildResult (
296+               status:  BuildStatus .failure,
297+               outputs:  BuiltList (),
298+               buildOutputReader:  buildOutputReader,
299+             ),
300+           );
286301        }
287302      },
288303    );
@@ -372,9 +387,10 @@ class Build {
372387      );
373388      // Assume success, `_assetGraph.failedOutputs` will be checked later. 
374389      return  BuildResult (
375-         BuildStatus .success,
376-         outputs,
390+         status :   BuildStatus .success,
391+         outputs:  outputs. build () ,
377392        performance:  performanceTracker,
393+         buildOutputReader:  buildOutputReader,
378394      );
379395    });
380396  }
@@ -394,7 +410,7 @@ class Build {
394410        .toList (growable:  false )) {
395411      if  (! shouldBuildForDirs (
396412        node.id,
397-         buildDirs:  BuildDirectory . buildPaths ( buildPlan.buildOptions.buildDirs) ,
413+         buildDirs:  buildPlan.buildOptions.buildDirs,
398414        buildFilters:  buildPlan.buildOptions.buildFilters,
399415        phase:  phase,
400416        targetGraph:  targetGraph,
@@ -1211,60 +1227,6 @@ class Build {
12111227  }
12121228
12131229  Future  _delete (AssetId  id) =>  readerWriter.delete (id);
1214- 
1215-   /// Invoked after each build, can modify the [BuildResult]  in any way, even 
1216-   /// converting it to a failure. 
1217-   /// 
1218-   /// The [finalizedAssetsView]  can only be used until the returned [Future]  
1219-   /// completes, it will expire afterwords since it can no longer guarantee a 
1220-   /// consistent state. 
1221-   /// 
1222-   /// By default this returns the original result. 
1223-   /// 
1224-   /// Any operation may be performed, as determined by environment. 
1225- Future <BuildResult > _finalizeBuild (
1226-     BuildResult  buildResult,
1227-     FinalizedAssetsView  finalizedAssetsView,
1228-     ReaderWriter  readerWriter,
1229-     BuiltSet <BuildDirectory > buildDirs,
1230-   ) async  {
1231-     if  (testingOverrides.finalizeBuild !=  null ) {
1232-       return  testingOverrides.finalizeBuild !(
1233-         buildResult,
1234-         finalizedAssetsView,
1235-         readerWriter,
1236-         buildDirs,
1237-       );
1238-     }
1239-     if  (buildDirs.any (
1240-           (target) =>  target.outputLocation? .path.isNotEmpty ??  false ,
1241-         ) && 
1242-         buildResult.status ==  BuildStatus .success) {
1243-       if  (! await  createMergedOutputDirectories (
1244-         buildDirs,
1245-         packageGraph,
1246-         readerWriter,
1247-         finalizedAssetsView,
1248-         buildOptions.outputSymlinksOnly,
1249-       )) {
1250-         return  _convertToFailure (
1251-           buildResult,
1252-           failureType:  FailureType .cantCreate,
1253-         );
1254-       }
1255-     }
1256-     return  buildResult;
1257-   }
12581230}
12591231
12601232String  _twoDigits (int  n) =>  '$n ' .padLeft (2 , '0' );
1261- 
1262- BuildResult  _convertToFailure (
1263-   BuildResult  previous, {
1264-   FailureType ?  failureType,
1265- }) =>  BuildResult (
1266-   BuildStatus .failure,
1267-   previous.outputs,
1268-   performance:  previous.performance,
1269-   failureType:  failureType,
1270- );
0 commit comments