execute method
Optimizes assets identified in the analysis.
Creates backups before modifying files and restores on failure.
Implementation
Future<List<OptimizationResult>> execute(
AnalysisResult analysis,
OptimizationConfig config,
) async {
try {
_state.startOptimization();
final results = <OptimizationResult>[];
final total = analysis.assets.length;
if (total == 0) {
_state.updateProgress(1.0);
_state.completeOptimization();
return results;
}
var processed = 0;
for (final asset in analysis.assets) {
_state.updateProgress(processed / total);
if (!_cacheService.shouldOptimize(
asset.info.path,
asset.info.size,
asset.info.lastModified,
)) {
processed++;
continue;
}
try {
final file = File(asset.info.path);
await _fileService.backupFile(file);
final optimizedFile = await _imageService.optimizeImage(
file,
config,
hasAlpha: asset.imageInfo?.hasAlpha,
);
if (optimizedFile != null) {
final optimizedSize = await optimizedFile.length();
final savedBytes = asset.info.size - optimizedSize;
if (savedBytes > 0) {
await optimizedFile.copy(asset.info.path);
final result = OptimizationResult(
originalAsset: asset.info,
optimizedSize: optimizedSize,
savedBytes: savedBytes,
optimizedAt: DateTime.now(),
);
results.add(result);
_cacheService.updateEntry(
asset.info.path,
optimizedSize,
DateTime.now(),
);
_state.addResult(result);
}
await optimizedFile.delete();
}
await _fileService.cleanupBackups([asset.info.path]);
} on OptimizationSkippedException catch (e) {
await _fileService.cleanupBackups([asset.info.path]);
_state.addError(asset.info.path, e.message);
} catch (e) {
await _fileService.restoreBackup(asset.info.path);
_state.addError(asset.info.path, e.toString());
}
processed++;
}
await _cacheService.save();
_state.completeOptimization();
return results;
} catch (e) {
_state.failOptimization(e.toString());
rethrow;
}
}