22// for details. All rights reserved. Use of this source code is governed by a 
33// BSD-style license that can be found in the LICENSE file. 
44
5+ // ignore_for_file: lines_longer_than_80_chars 
6+ 
57import  'dart:async' ;
68import  'dart:collection' ;
79import  'dart:convert' ;
@@ -72,6 +74,13 @@ class Build {
7274  int  actionsStartedCount =  0 ;
7375  final  pendingActions =  SplayTreeMap <int , Set <String >>();
7476
77+   /// Glob assets and generated assets that have been processed. 
78+   /// 
79+   /// That means they have been checked to determine whether they 
80+   /// need building; if so, built; and the build state here and in the asset 
81+   /// graph have been updated accordingly. 
82+ final  Set <AssetId > processedAssets =  {};
83+ 
7584  /// Inputs that changed since the last build. 
7685  /// 
7786  /// Filled from the `updates`  passed in to the build. 
@@ -95,8 +104,6 @@ class Build {
95104  /// checked against the digest from the previous build. 
96105final  Set <AssetId > changedOutputs =  {};
97106
98-   final  Set <AssetId > builtAssets =  {};
99- 
100107  static  final  debugging =  false ;
101108
102109  Build ({
@@ -153,17 +160,16 @@ class Build {
153160      buildPhases,
154161    );
155162    if  (result.status ==  BuildStatus .success) {
156-       // ignore_for_file: lines_longer_than_80_chars 
157-       if  (logFine) {
158-         _logger.fine ('Failed? $builtAssets ' );
163+       /*if (logFine) { 
164+         _logger.fine('Failed? $processedAssets'); 
159165        _logger.fine( 
160-           'Failed?? ${builtAssets .map ((id ) => assetGraph .get (id )!).where ((node ) => node .type  == NodeType .generated ).map ((node ) => node .id )}' ,
166+           'Failed?? ${processedAssets .map((id) => assetGraph.get(id)!).where((node) => node.type == NodeType.generated).map((node) => node.id)}', 
161167        ); 
162168        _logger.fine( 
163-           'Failed??? ${builtAssets .map ((id ) => assetGraph .get (id )!).where ((node ) => node .type  == NodeType .generated  && node .generatedNodeState !.result  == false ).map ((node ) => node .id )}' ,
169+           'Failed??? ${processedAssets .map((id) => assetGraph.get(id)!).where((node) => node.type == NodeType.generated && node.generatedNodeState!.result == false).map((node) => node.id)}', 
164170        ); 
165-       }
166-       final  failures =  builtAssets 
171+       }*/  
172+       final  failures =  processedAssets 
167173          .map ((id) =>  assetGraph.get (id)! )
168174          .where ((node) =>  node.type ==  NodeType .generated)
169175          .where ((node) =>  node.generatedNodeState! .result ==  false )
@@ -192,34 +198,15 @@ class Build {
192198    if  (result.status ==  BuildStatus .success) {
193199      _logger.info (
194200        'Succeeded after ${humanReadable (watch .elapsed )} with ' 
195-         '${result .outputs .length } outputs, ($actionsCompletedCount  actions)\n ' ,
201+         '${result .outputs .length } outputs ' 
202+         '($actionsCompletedCount  actions)\n ' ,
196203      );
197204    } else  {
198205      _logger.severe ('Failed after ${humanReadable (watch .elapsed )}' );
199206    }
200207    return  result;
201208  }
202209
203-   bool  generatedNodeHasWorkToDo (AssetId  id) {
204-     if  (logFine) {
205-       _logger.fine (
206-         'work to do $id ? $builtAssets , at ${StackTrace .current .toString ().replaceAll ('\n ' , ' ' )}' ,
207-       );
208-     }
209-     return  ! builtAssets.contains (id);
210-   }
211- 
212-   bool  generatedNodeIsForcedBuild (AssetId  id) {
213-     return  deletedAssets.contains (id) || 
214-         newPrimaryInputs.contains (
215-           assetGraph.get (id)! .generatedNodeConfiguration! .primaryInput,
216-         );
217-   }
218- 
219-   bool  globNodeHasWorkToDo (AssetId  id) {
220-     return  ! builtAssets.contains (id);
221-   }
222- 
223210  Future <void > _updateAssetGraph (Map <AssetId , ChangeType > updates) async  {
224211    await  logTimedAsync (_logger, 'Updating asset graph' , () async  {
225212      changedInputs.clear ();
@@ -491,7 +478,7 @@ class Build {
491478
492479  Future <void > _buildAsset (AssetId  id) async  {
493480    final  node =  assetGraph.get (id)! ;
494-     if  (node.type ==  NodeType .generated &&  generatedNodeHasWorkToDo (id)) {
481+     if  (node.type ==  NodeType .generated &&  ! processedAssets. contains (id)) {
495482      final  nodeConfiguration =  node.generatedNodeConfiguration! ;
496483      await  _runLazyPhaseForInput (
497484        nodeConfiguration.phaseNumber,
@@ -782,24 +769,25 @@ class Build {
782769    Iterable <AssetId > outputs,
783770    AssetReader  reader,
784771  ) async  {
785-     if  (logFine) {
772+     /* if (logFine) {
786773      _logger.fine('_buildShouldRun $forInput'); 
787-     }
774+     }*/  
788775
789776    // _logger.fine('_buildShouldRun for $forInput'); 
790-     assert (
791-       outputs.every (assetGraph.contains),
792-       'Outputs should be known statically. Missing ' 
793-       '${outputs .where ((o ) => !assetGraph .contains (o )).toList ()}' ,
794-     );
795-     assert (outputs.isNotEmpty, 'Can\' t run a build with no outputs' );
796777
797778    var  inputNode =  assetGraph.get (forInput)! ;
779+     if  (inputNode.type ==  NodeType .generated) {
780+       if  (! processedAssets.contains (forInput)) {
781+         await  _buildAsset (forInput);
782+       }
783+     }
784+ 
798785    if  (deletedAssets.contains (forInput)) {
799786      if  (inputNode.type ==  NodeType .missingSource) {
800787        if  (logFine) {
801788          _logger.fine (
802-             'Skip ${renderer .build (forInput , outputs )} because input was deleted.' ,
789+             'Skip ${renderer .build (forInput , outputs )} because $forInput  ' 
790+             ' was deleted.' ,
803791          );
804792        }
805793        for  (final  output in  outputs) {
@@ -813,16 +801,18 @@ class Build {
813801        await  failureReporter.markSkipped (
814802          outputs.map ((id) =>  assetGraph.get (id)! ),
815803        );
804+         processedAssets.add (forInput);
816805        return  false ;
817806      } else  if  (inputNode.type ==  NodeType .generated) {
818807        _logger.fine (
819-           'Build ${renderer .build (forInput , outputs )} because it is a generated file that was deleted.' ,
808+           'Build ${renderer .build (forInput , outputs )} because $forInput  is a ' 
809+           'generated file that was deleted.' ,
820810        );
821811      }
822812    }
823813
824814    if  (inputNode.type ==  NodeType .generated) {
825-       if  (generatedNodeHasWorkToDo (forInput)) {
815+       if  (! processedAssets. contains (forInput)) {
826816        await  _buildAsset (forInput);
827817      }
828818      inputNode =  assetGraph.get (forInput)! ;
@@ -831,7 +821,8 @@ class Build {
831821          ! inputNode.wasOutput) {
832822        if  (logFine) {
833823          _logger.fine (
834-             'Skip ${renderer .build (forInput , outputs )} because input was not written.' ,
824+             'Skip ${renderer .build (forInput , outputs )} because $forInput  is a ' 
825+             ' generated file that was not output.' ,
835826          );
836827        }
837828        for  (final  output in  outputs) {
@@ -845,6 +836,7 @@ class Build {
845836        await  failureReporter.markSkipped (
846837          outputs.map ((id) =>  assetGraph.get (id)! ),
847838        );
839+         processedAssets.add (forInput);
848840        return  false ;
849841      }
850842
@@ -853,14 +845,14 @@ class Build {
853845        for  (final  output in  outputs) {
854846          if  (logFine) {
855847            _logger.fine (
856-               'Skip ${renderer .build (forInput , outputs )} because input failed.' ,
848+               'Skip ${renderer .build (forInput , outputs )} because $forInput  is ' 
849+               'a generated file that failed.' ,
857850            );
858851          }
859852          assetGraph.updateNode (output, (nodeBuilder) {
860853            if  (nodeBuilder.digest !=  null  || 
861854                nodeBuilder.generatedNodeState.result !=  false ) {
862-               _logger.fine ('Changed output due to skip: $output ' );
863-               changedOutputs.add (output);
855+               //changedOutputs.add(output); 
864856            }
865857
866858            // TODO(davidmorgan): deleting the file here may be the fix for 
@@ -872,6 +864,7 @@ class Build {
872864        await  failureReporter.markSkipped (
873865          outputs.map ((id) =>  assetGraph.get (id)! ),
874866        );
867+         processedAssets.add (forInput);
875868        return  false ;
876869      }
877870    }
@@ -884,9 +877,7 @@ class Build {
884877        );
885878      }
886879      return  true ;
887-     }
888- 
889-     if  (assetGraph.previousInBuildPhasesOptionsDigests! [phaseNumber] != 
880+     } else  if  (assetGraph.previousInBuildPhasesOptionsDigests! [phaseNumber] != 
890881        assetGraph.inBuildPhasesOptionsDigests[phaseNumber]) {
891882      if  (logFine) {
892883        _logger.fine (
@@ -897,71 +888,40 @@ class Build {
897888      return  true ;
898889    }
899890
900-     // We check if any output definitely needs an update - its possible during 
901-     // manual deletions that only one of the outputs would be marked. 
902-     for  (var  output in  outputs.skip (1 )) {
903-       if  (generatedNodeIsForcedBuild (output)) {
891+     if  (newPrimaryInputs.contains (forInput)) {
892+       if  (logFine) {
893+         _logger.fine (
894+           'Build ${renderer .build (forInput , outputs )} because $forInput  ' 
895+           'was created.' ,
896+         );
897+       }
898+       return  true ;
899+     }
900+ 
901+     for  (var  output in  outputs) {
902+       if  (deletedAssets.contains (output)) {
904903        if  (logFine) {
905904          _logger.fine (
906905            'Build ${renderer .build (forInput , outputs )} because ' 
907-             '${renderer .id (output )} was marked for build .' ,
906+             '${renderer .id (output )} was deleted .' ,
908907          );
909908        }
910909        return  true ;
911910      }
912911    }
913912
914-     // Otherwise, we only check the first output, because all outputs share the 
915-     // same inputs and invalidation state. 
916913    var  firstNode =  assetGraph.get (outputs.first)! ;
917-     assert (
918-       outputs
919-           .skip (1 )
920-           .every (
921-             (output) => 
922-                 assetGraph
923-                     .get (output)! 
924-                     .generatedNodeState! 
925-                     .inputs
926-                     .difference (firstNode.generatedNodeState! .inputs)
927-                     .isEmpty,
928-           ),
929-       'All outputs of a build action should share the same inputs.' ,
930-     );
931- 
932914    final  firstNodeState =  firstNode.generatedNodeState! ;
933915
934-     // No need to build an up to date output 
935-     if  (! generatedNodeHasWorkToDo (firstNode.id)) {
936-       if  (logFine) {
937-         _logger.fine (
938-           'Do not build ${renderer .build (forInput , outputs )} because ' 
939-           'it is marked as done.' ,
940-         );
941-       }
942-       return  false ;
943-     }
944- 
945-     // Early bail out condition, this is a forced update. 
946-     if  (generatedNodeIsForcedBuild (firstNode.id)) {
947-       if  (logFine) {
948-         _logger.fine (
949-           'Build ${renderer .build (forInput , outputs )} because ' 
950-           '${renderer .id (firstNode .id )} was marked for build.' ,
951-         );
952-       }
953-       return  true ;
954-     }
955- 
956-     if  (firstNodeState.result ==  null ) {
916+     /*if (firstNodeState.result == null) { 
957917      if (logFine) { 
958918        _logger.fine( 
959919          'Build ${renderer.build(forInput, outputs)} because ' 
960920          'it was skipped.', 
961921        ); 
962922      } 
963923      return true; 
964-     }
924+     }*/  
965925
966926    final  inputs =  firstNodeState.inputs;
967927    /*if (logFine) { 
@@ -977,7 +937,7 @@ class Build {
977937          continue ;
978938        }
979939        // Check that the input was built, so [changedOutputs] is updated. 
980-         if  (generatedNodeHasWorkToDo (input)) {
940+         if  (! processedAssets. contains (input)) {
981941          await  _buildAsset (node.id);
982942        }
983943        if  (changedOutputs.contains (input)) {
@@ -991,7 +951,7 @@ class Build {
991951        }
992952      } else  if  (node.type ==  NodeType .glob) {
993953        // Check that the glob was evaluated, so [changedOutputs] is updated. 
994-         if  (globNodeHasWorkToDo (input)) {
954+         if  (! processedAssets. contains (input)) {
995955          await  _buildGlobNode (input);
996956        }
997957        if  (changedOutputs.contains (input)) {
@@ -1026,30 +986,20 @@ class Build {
1026986      }
1027987    }
1028988
1029-     // Mark outputs as not needing building. 
1030-     /*for (var id in outputs) { 
1031-       assetGraph.updateNode(id, (nodeBuilder) { 
1032-         if (nodeBuilder.type == NodeType.generated) { 
1033-           builtAssets.add(id); 
1034-         } else if (nodeBuilder.type == NodeType.glob) { 
1035-           builtAssets.add(id); 
1036-         } 
1037-       }); 
1038-     }*/ 
1039-     builtAssets.add (forInput);
1040- 
1041-     _logger.fine (
989+     /*_logger.fine( 
1042990      'Do not build ${renderer.build(forInput, outputs)} because ' 
1043991      'there is no reason to build it.', 
1044-     );
992+     );*/  
1045993    // builtAssets.addAll(outputs); 
1046994
995+     // add so that the assets are "live" so they are considered as failures 
996+     // Is this sufficient for 'should fail if a severe was logged on a previous 
997+     // build' for a chain of deps? 
1047998    for  (final  output in  outputs) {
1048-       if  (! generatedNodeIsForcedBuild (output)) {
1049-         builtAssets.add (output);
1050-       }
999+       processedAssets.add (output);
10511000    }
10521001
1002+     processedAssets.add (forInput);
10531003    return  false ;
10541004  }
10551005
@@ -1075,7 +1025,7 @@ class Build {
10751025
10761026    if  (node.type ==  NodeType .generated) {
10771027      // Check that the input was built, so [changedOutputs] is updated. 
1078-       if  (generatedNodeHasWorkToDo (node.id)) {
1028+       if  (! processedAssets. contains (node.id)) {
10791029        await  _buildAsset (node.id);
10801030      }
10811031      if  (changedOutputs.contains (input)) {
@@ -1124,7 +1074,7 @@ class Build {
11241074  /// 
11251075  /// 
11261076Future <void > _buildGlobNode (AssetId  globId) async  {
1127-     if  (! globNodeHasWorkToDo (globId)) {
1077+     if  (processedAssets. contains (globId)) {
11281078      return ;
11291079    }
11301080
@@ -1176,7 +1126,7 @@ class Build {
11761126        if  (nodeBuilder.digest !=  digest) {
11771127          changedOutputs.add (globId);
11781128        }
1179-         builtAssets .add (globId);
1129+         processedAssets .add (globId);
11801130        nodeBuilder
11811131          ..globNodeState.results.replace (results)
11821132          ..globNodeState.inputs.replace (
@@ -1218,7 +1168,7 @@ class Build {
12181168      var  wasOutput =  readerWriter.assetsWritten.contains (output);
12191169      var  digest =  wasOutput ?  await  this .readerWriter.digest (output) :  null ;
12201170
1221-       builtAssets .add (output);
1171+       processedAssets .add (output);
12221172      assetGraph.updateNode (output, (nodeBuilder) {
12231173        /*_logger.fine( 
12241174          'Generated output $output, digest ${nodeBuilder.lastKnownDigest} ' 
0 commit comments