parseLockfile method

Future<LockfileData> parseLockfile(
  1. File file
)

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