parseLockfile function
Implementation
Lockfile parseLockfile(String content, {required String path}) {
final root = _loadYaml(content, path);
if (root is! Map) {
throw LockfileUnreadable(path, 'the top level is not a map');
}
final packages = root['packages'] ?? const {};
if (packages is! Map) {
throw LockfileUnreadable(path, '`packages:` is not a map',
line: _lineOf(packages));
}
final hosted = <PackageRef>[];
final skipped = <SkippedPackage>[];
final counts = <PackageSource, int>{};
for (final entry in packages.entries) {
final name = '${entry.key}';
final value = entry.value;
if (value is! Map) {
throw LockfileUnreadable(path, 'package $name is malformed',
line: _lineOf(value));
}
final source = PackageSource.parse(value['source']);
counts[source] = (counts[source] ?? 0) + 1;
if (source != PackageSource.hosted) {
skipped.add(NotHosted(name, source));
continue;
}
final Version version;
try {
version = Version.parse('${value['version']}');
} on FormatException {
skipped.add(InvalidVersion(name, '${value['version']}'));
continue;
}
final description = value['description'];
Uri? url;
if (description is Map && description['url'] is String) {
url = Uri.tryParse(description['url'] as String);
}
// description.name, not the map key: they can differ, and advisories
// use the published name.
final hostedName = description is Map && description['name'] is String
? description['name'] as String
: name;
hosted.add(PackageRef(
name: hostedName,
version: version,
source: source,
dependency: Dependency.parse(value['dependency']),
hostedUrl: url,
));
}
final sdks = root['sdks'];
return Lockfile(
path: path,
hosted: hosted,
skipped: skipped,
countBySource: counts,
sdkKeys: sdks is Map ? {for (final k in sdks.keys) '$k'} : const {},
);
}