2
2
// for details. All rights reserved. Use of this source code is governed by a
3
3
// BSD-style license that can be found in the LICENSE file.
4
4
5
- // ignore_for_file: lines_longer_than_80_chars
6
-
7
5
import 'dart:async' ;
8
6
import 'dart:collection' ;
9
7
import 'dart:convert' ;
@@ -110,8 +108,6 @@ class Build {
110
108
/// checked against the digest from the previous build.
111
109
final Set <AssetId > changedOutputs = {};
112
110
113
- static final debugging = true ;
114
-
115
111
Build ({
116
112
required this .environment,
117
113
required this .options,
@@ -127,13 +123,7 @@ class Build {
127
123
options.trackPerformance
128
124
? BuildPerformanceTracker ()
129
125
: BuildPerformanceTracker .noOp (),
130
- logFine = _logger.level <= Level .FINE || debugging {
131
- if (debugging) {
132
- Logger .root.level = Level .FINE ;
133
- /*Logger.root.onRecord.listen((record) {
134
- print('${record.message} ');
135
- });*/
136
- }
126
+ logFine = _logger.level <= Level .FINE {
137
127
hungActionsHeartbeat = HungActionsHeartbeat (() {
138
128
final message = StringBuffer ();
139
129
const actionsToLogMax = 5 ;
@@ -166,20 +156,10 @@ class Build {
166
156
buildPhases,
167
157
);
168
158
if (result.status == BuildStatus .success) {
169
- /*if (logFine) {
170
- _logger.fine('Failed? $processedAssets');
171
- _logger.fine(
172
- 'Failed?? ${processedAssets.map((id) => assetGraph.get(id)!).where((node) => node.type == NodeType.generated).map((node) => node.id)}',
173
- );
174
- _logger.fine(
175
- 'Failed??? ${processedAssets.map((id) => assetGraph.get(id)!).where((node) => node.type == NodeType.generated && node.generatedNodeState!.result == false).map((node) => node.id)}',
176
- );
177
- }*/
178
159
final failures = processedOutputs
179
160
.map ((id) => assetGraph.get (id)! )
180
161
.where ((node) => node.type == NodeType .generated)
181
- .where ((node) => node.generatedNodeState! .result == false )
182
- /*.where((node) => optionalOutputTracker.isRequired(node.id))*/ ;
162
+ .where ((node) => node.generatedNodeState! .result == false );
183
163
if (failures.isNotEmpty) {
184
164
await failureReporter.reportErrors (failures);
185
165
result = BuildResult (
@@ -235,7 +215,6 @@ class Build {
235
215
readerWriter,
236
216
);
237
217
deletedAssets.addAll (deleted);
238
- // if (debugging) print(assetGraph);
239
218
await readerWriter.cache.invalidate (changedInputs);
240
219
});
241
220
}
@@ -310,7 +289,6 @@ class Build {
310
289
},
311
290
(e, st) {
312
291
if (! done.isCompleted) {
313
- if (debugging) print ('Unhandled build failure! $e $st ' );
314
292
_logger.severe ('Unhandled build failure! $e $st ' , e, st);
315
293
done.complete (BuildResult (BuildStatus .failure, []));
316
294
}
@@ -504,22 +482,7 @@ class Build {
504
482
phase.builderLabel,
505
483
);
506
484
return tracker.track (() async {
507
- var builderOutputs = expectedOutputs (builder, input);
508
-
509
- // Add `builderOutputs` to the primary outputs of the input.
510
- var inputNode = assetGraph.get (input)! ;
511
- assert (
512
- inputNode.primaryOutputs.containsAll (builderOutputs),
513
- // ignore: prefer_interpolation_to_compose_strings
514
- 'input $input with builder $builder missing primary outputs: \n '
515
- 'Got ${inputNode .primaryOutputs .join (', ' )} '
516
- 'which was missing:\n ' +
517
- builderOutputs
518
- .where ((id) => ! inputNode.primaryOutputs.contains (id))
519
- .join (', ' ),
520
- );
521
-
522
- var readerWriter = SingleStepReaderWriter (
485
+ final readerWriter = SingleStepReaderWriter (
523
486
runningBuild: RunningBuild (
524
487
packageGraph: options.packageGraph,
525
488
targetGraph: options.targetGraph,
@@ -538,6 +501,7 @@ class Build {
538
501
assetsWritten: {},
539
502
);
540
503
504
+ final builderOutputs = expectedOutputs (builder, input);
541
505
if (! await tracker.trackStage (
542
506
'Setup' ,
543
507
() => _buildShouldRun (phaseNumber, input, builderOutputs, readerWriter),
@@ -551,19 +515,19 @@ class Build {
551
515
// Clear input tracking accumulated during `_buildShouldRun`.
552
516
readerWriter.inputTracker.clear ();
553
517
554
- var actionDescription = _actionLoggerName (
518
+ final actionDescription = _actionLoggerName (
555
519
phase,
556
520
input,
557
521
options.packageGraph.root.name,
558
522
);
559
- var logger = BuildForInputLogger (Logger (actionDescription));
523
+ final logger = BuildForInputLogger (Logger (actionDescription));
560
524
561
525
actionsStartedCount++ ;
562
526
pendingActions
563
527
.putIfAbsent (phaseNumber, () => < String > {})
564
528
.add (actionDescription);
565
529
566
- var unusedAssets = < AssetId > {};
530
+ final unusedAssets = < AssetId > {};
567
531
void reportUnusedAssetsForInput (AssetId input, Iterable <AssetId > assets) {
568
532
options.reportUnusedAssetsForInput? .call (input, assets);
569
533
unusedAssets.addAll (assets);
@@ -816,8 +780,8 @@ class Build {
816
780
if (primaryInputNode.type == NodeType .missingSource) {
817
781
if (logFine) {
818
782
_logger.fine (
819
- 'Skip ${renderer .build (primaryInput , outputs )} because $ primaryInput '
820
- ' was deleted.' ,
783
+ 'Skip ${renderer .build (primaryInput , outputs )} because '
784
+ '$ primaryInput was deleted.' ,
821
785
);
822
786
}
823
787
_markOutputsSkipped (outputs);
@@ -831,35 +795,36 @@ class Build {
831
795
if (primaryInputNode.generatedNodeState! .result == false ) {
832
796
if (logFine) {
833
797
_logger.fine (
834
- 'Skip ${renderer .build (primaryInput , outputs )} because $ primaryInput is '
835
- 'a generated file that failed.' ,
798
+ 'Skip ${renderer .build (primaryInput , outputs )} because '
799
+ '$ primaryInput is a generated file that failed.' ,
836
800
);
837
801
}
838
802
await _markOutputsTransitivelyFailed (outputs);
839
803
return false ;
840
804
}
841
805
842
- // If the primary input succeeded but was not output, this build is skipped.
806
+ // If the primary input succeeded but was not output, this build is
807
+ // skipped.
843
808
if (! primaryInputNode.wasOutput) {
844
809
if (logFine) {
845
810
_logger.fine (
846
- 'Skip ${renderer .build (primaryInput , outputs )} because $ primaryInput is a '
847
- ' generated file that was not output.' ,
811
+ 'Skip ${renderer .build (primaryInput , outputs )} because '
812
+ '$ primaryInput is a generated file that was not output.' ,
848
813
);
849
814
}
850
815
_markOutputsSkipped (outputs);
851
816
return false ;
852
817
}
853
818
}
854
819
855
- // The primary input has been checked and is valid, from here builds will run unless there
856
- // is valid output already on disk.
820
+ // The primary input has been checked and is valid, from here builds will
821
+ // run unless there is valid output already on disk.
857
822
858
823
if (assetGraph.cleanBuild) {
859
824
if (logFine) {
860
825
_logger.fine (
861
- 'Build ${renderer .build (primaryInput , outputs )} because this is a clean '
862
- 'build.' ,
826
+ 'Build ${renderer .build (primaryInput , outputs )} because this is a '
827
+ 'clean build.' ,
863
828
);
864
829
}
865
830
return true ;
@@ -869,8 +834,8 @@ class Build {
869
834
assetGraph.inBuildPhasesOptionsDigests[phaseNumber]) {
870
835
if (logFine) {
871
836
_logger.fine (
872
- 'Build ${renderer .build (primaryInput , outputs )} because builder options '
873
- 'changed.' ,
837
+ 'Build ${renderer .build (primaryInput , outputs )} because builder '
838
+ 'options changed.' ,
874
839
);
875
840
}
876
841
return true ;
@@ -879,8 +844,8 @@ class Build {
879
844
if (newPrimaryInputs.contains (primaryInput)) {
880
845
if (logFine) {
881
846
_logger.fine (
882
- 'Build ${renderer .build (primaryInput , outputs )} because $ primaryInput '
883
- 'was created.' ,
847
+ 'Build ${renderer .build (primaryInput , outputs )} because '
848
+ '$ primaryInput was created.' ,
884
849
);
885
850
}
886
851
return true ;
@@ -898,15 +863,16 @@ class Build {
898
863
}
899
864
}
900
865
901
- // Build results are the same across outputs, so just check the first output.
866
+ // Build results are the same across outputs, so just check the first
867
+ // output.
902
868
var firstOutput = assetGraph.get (outputs.first)! ;
903
869
final firstOutputState = firstOutput.generatedNodeState! ;
904
870
905
871
if (firstOutputState.result == null ) {
906
872
if (logFine) {
907
873
_logger.fine (
908
- 'Build ${renderer .build (primaryInput , outputs )} the outputs are optional outputs '
909
- 'than have become needed.' ,
874
+ 'Build ${renderer .build (primaryInput , outputs )} the outputs are '
875
+ 'optional outputs than have become needed.' ,
910
876
);
911
877
}
912
878
return true ;
@@ -1118,11 +1084,11 @@ class Build {
1118
1084
1119
1085
/// Sets the state for all [outputs] of a build step, by:
1120
1086
///
1121
- /// - Setting `needsUpdate` to `false` for each output
1122
- /// - Setting `wasOutput` based on `writer.assetsWritten` .
1123
- /// - Setting `isFailed` based on action success.
1124
- /// - Adding `outputs` as outputs to all `reader.assetsRead` .
1087
+ /// - Setting `digest` based on what was written.
1088
+ /// - Setting `result` based on action success.
1089
+ /// - Setting `inputs` based on `inputTracker` and `unusedAssets` .
1125
1090
/// - Storing the error message with the [failureReporter] .
1091
+ /// - Updating `newPrimaryInputs` and `changedOutputs` as needed.
1126
1092
Future <void > _setOutputsState (
1127
1093
AssetId input,
1128
1094
Iterable <AssetId > outputs,
@@ -1141,69 +1107,40 @@ class Build {
1141
1107
final result = errors.isEmpty;
1142
1108
1143
1109
await this .readerWriter.cache.invalidate (outputs);
1144
- for (var output in outputs) {
1145
- var wasOutput = readerWriter.assetsWritten.contains (output);
1146
- var digest = wasOutput ? await this .readerWriter.digest (output) : null ;
1110
+ for (final output in outputs) {
1111
+ final wasOutput = readerWriter.assetsWritten.contains (output);
1112
+ final digest = wasOutput ? await this .readerWriter.digest (output) : null ;
1113
+ var outputNode = assetGraph.get (output)! ;
1114
+
1115
+ // A transition from (missing or failed) to (written and not failed) is
1116
+ // a new primary input that triggers generation even if no content
1117
+ // changed.
1118
+ if ((outputNode.digest == null ||
1119
+ outputNode.generatedNodeState! .result == false ) &&
1120
+ (digest != null && result)) {
1121
+ newPrimaryInputs.add (output);
1122
+ }
1123
+ // Only a change to content matters for non-primary inputs.
1124
+ if (outputNode.digest != digest) {
1125
+ changedOutputs.add (output);
1126
+ }
1147
1127
1148
- processedOutputs.add (output);
1149
- assetGraph.updateNode (output, (nodeBuilder) {
1150
- /*_logger.fine(
1151
- 'Generated output $output, digest ${nodeBuilder.lastKnownDigest} '
1152
- '-> $digest',
1153
- );*/
1154
- // A transition from (missing or failed) to (written and not failed) is
1155
- // a new primary input that triggers generation even if no content changed.
1156
- if ((nodeBuilder.digest == null ||
1157
- nodeBuilder.generatedNodeState.result == false ) &&
1158
- (digest != null && result)) {
1159
- newPrimaryInputs.add (output);
1160
- }
1161
- if (nodeBuilder.digest != digest ||
1162
- nodeBuilder.generatedNodeState.result != result) {
1163
- _logger.fine ('Changed output $output ' );
1164
- changedOutputs.add (output);
1165
- } else {
1166
- _logger.fine ('Unchanged output $output ' );
1167
- }
1128
+ outputNode = assetGraph.updateNode (output, (nodeBuilder) {
1168
1129
nodeBuilder.generatedNodeState
1169
1130
..inputs.replace (usedInputs)
1170
1131
..result = result;
1171
1132
nodeBuilder.digest = digest;
1172
1133
});
1173
1134
1174
1135
if (! result) {
1175
- _logger.fine ('Failed: $input ->$output ' );
1136
+ await failureReporter.markReported (
1137
+ actionDescription,
1138
+ outputNode,
1139
+ errors,
1140
+ );
1176
1141
}
1177
1142
1178
- if (! result) {
1179
- final node = assetGraph.get (output)! ;
1180
- await failureReporter.markReported (actionDescription, node, errors);
1181
- } /*
1182
- var needsMarkAsFailure = Queue.of(node.primaryOutputs);
1183
- var allSkippedFailures = <AssetId>[];
1184
- while (needsMarkAsFailure.isNotEmpty) {
1185
- var output = needsMarkAsFailure.removeLast();
1186
- builtAssets.add(output);
1187
- assetGraph.updateNode(output, (nodeBuilder) {
1188
- if (nodeBuilder.digest != null) {
1189
- changedOutputs.add(output);
1190
- }
1191
- nodeBuilder.generatedNodeState.result = false;
1192
- nodeBuilder.digest = null;
1193
- });
1194
- allSkippedFailures.add(output);
1195
- needsMarkAsFailure.addAll(assetGraph.get(output)!.primaryOutputs);
1196
-
1197
- // Make sure output invalidation follows primary outputs for builds
1198
- // that won't run.
1199
- assetGraph.updateNode(output, (nodeBuilder) {
1200
- nodeBuilder.generatedNodeState.inputs.add(node.id);
1201
- });
1202
- }
1203
- await failureReporter.markSkipped(
1204
- allSkippedFailures.map((id) => assetGraph.get(id)!),
1205
- );
1206
- }*/
1143
+ processedOutputs.add (output);
1207
1144
}
1208
1145
}
1209
1146
0 commit comments