parseLockfile function

Lockfile parseLockfile(
  1. String content, {
  2. required String path,
})

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 {},
  );
}