parseLockfile method
Parse a pubspec.lock file into a LockfileData model.
The lockfile YAML structure looks like:
packages:
provider:
dependency: "direct main"
description:
name: provider
sha256: ...
url: "https://pub.dev"
source: hosted
version: "6.1.1"
Implementation
Future<LockfileData> parseLockfile(File file) async {
final content = await file.readAsString();
final yaml = loadYaml(content) as YamlMap;
final packagesYaml = yaml['packages'] as YamlMap?;
if (packagesYaml == null) {
Logger.warn('Lockfile contains no "packages" key.');
return const LockfileData(packages: {});
}
final packages = <String, LockfilePackage>{};
for (final entry in packagesYaml.entries) {
final name = entry.key.toString();
final value = entry.value as YamlMap?;
if (value == null) continue;
final dependencyRaw = value['dependency'];
final dependency = <String, String>{};
if (dependencyRaw is YamlMap) {
for (final d in dependencyRaw.entries) {
dependency[d.key.toString()] = d.value?.toString() ?? '';
}
} else if (dependencyRaw is String) {
// The common case: e.g. "direct main", "direct dev", "transitive"
dependency['type'] = dependencyRaw;
}
// Description can be a map (hosted packages) or a simple string (sdk).
String? descriptionStr;
final descriptionRaw = value['description'];
if (descriptionRaw is YamlMap) {
// Build a human-readable representation while keeping the URL accessible.
descriptionStr = _descriptionMapToString(descriptionRaw);
} else if (descriptionRaw != null) {
descriptionStr = descriptionRaw.toString();
}
packages[name] = LockfilePackage(
name: name,
version: value['version']?.toString() ?? '0.0.0',
source: value['source']?.toString() ?? 'unknown',
description: descriptionStr,
dependency: dependency,
);
}
Logger.debug('Parsed ${packages.length} packages from lockfile.');
return LockfileData(packages: packages);
}