freshnessIssues method
Implementation
List<ZukeIndexFreshnessIssue> freshnessIssues({required String root}) {
final issues = <ZukeIndexFreshnessIssue>[];
final generatedManifest = File(_join(root, generatedManifestPath));
if (!generatedManifest.existsSync()) {
return [
ZukeIndexFreshnessIssue(
kind: ZukeIndexFreshnessIssueKind.generatedManifestMissing,
path: generatedManifestPath,
message: 'Generated manifest is missing: $generatedManifestPath',
),
];
}
if (_sha256(generatedManifest.readAsBytesSync()) !=
generatedManifestDigest) {
return [
ZukeIndexFreshnessIssue(
kind: ZukeIndexFreshnessIssueKind.generatedManifestDigestMismatch,
path: generatedManifestPath,
message: 'Generated manifest content changed: $generatedManifestPath',
),
];
}
issues.addAll(_generatedOutputIssues(root, generatedManifest));
final rootPath = Directory(root).absolute.path;
final currentPatternInputs = _matchedPatternInputs(rootPath, inputPatterns);
if (!_sameSet(currentPatternInputs, patternInputs)) {
final changed =
<String>{...currentPatternInputs, ...patternInputs}
.where(
(path) =>
!currentPatternInputs.contains(path) ||
!patternInputs.contains(path),
)
.toList()
..sort();
issues.add(
ZukeIndexFreshnessIssue(
kind: ZukeIndexFreshnessIssueKind.inputInventoryMismatch,
path: changed.isEmpty ? '.zuke/analyzer-index.json' : changed.first,
message:
'Configured specification inputs changed: '
'${changed.isEmpty ? '.zuke/analyzer-index.json' : changed.join(', ')}',
),
);
}
final current = <ZukeIndexInput>[];
for (final input in inputs) {
final file = File(_join(rootPath, input.path));
if (!file.existsSync()) {
issues.add(
ZukeIndexFreshnessIssue(
kind: ZukeIndexFreshnessIssueKind.inputMissing,
path: input.path,
message: 'Indexed input is missing: ${input.path}',
),
);
continue;
}
final currentInput = ZukeIndexInput(
path: input.path,
digest: _sha256(file.readAsBytesSync()),
);
current.add(currentInput);
if (currentInput.digest != input.digest) {
issues.add(
ZukeIndexFreshnessIssue(
kind: ZukeIndexFreshnessIssueKind.inputDigestMismatch,
path: input.path,
message: 'Indexed input content changed: ${input.path}',
),
);
}
}
final hasInputIssue = issues.any(
(issue) =>
issue.kind == ZukeIndexFreshnessIssueKind.inputMissing ||
issue.kind == ZukeIndexFreshnessIssueKind.inputDigestMismatch ||
issue.kind == ZukeIndexFreshnessIssueKind.inputInventoryMismatch,
);
if (!hasInputIssue &&
_inputDigest(
current,
requirementIds,
controlIds,
bindingIds,
inputPatterns,
patternInputs,
) !=
inputDigest) {
issues.add(
const ZukeIndexFreshnessIssue(
kind: ZukeIndexFreshnessIssueKind.inputSetDigestMismatch,
path: '.zuke/analyzer-index.json',
message:
'Analyzer index digest does not match its indexed inputs and IDs',
),
);
}
return List.unmodifiable(issues);
}