void _checkPackageConfigUpToDate()

in lib/src/entrypoint.dart [744:841]


  void _checkPackageConfigUpToDate() {
    void outOfDate() {
      dataError('The $lockFilePath file has changed since the '
          '$packageConfigFile file '
          'was generated, please run "$topLevelProgram pub get" again.');
    }

    void badPackageConfig() {
      dataError('The "$packageConfigFile" file is not recognized by '
          '"pub" version, please run "$topLevelProgram pub get".');
    }

    late String packageConfigRaw;
    try {
      packageConfigRaw = readTextFile(packageConfigFile);
    } on FileException {
      dataError(
          'The "$packageConfigFile" file does not exist, please run "$topLevelProgram pub get".');
    }

    late PackageConfig cfg;
    try {
      cfg = PackageConfig.fromJson(json.decode(packageConfigRaw));
    } on FormatException {
      badPackageConfig();
    }

    // Version 2 is the initial version number for `package_config.json`,
    // because `.packages` was version 1 (even if it was a different file).
    // If the version is different from 2, then it must be a newer incompatible
    // version, hence, the user should run `pub get` with the downgraded SDK.
    if (cfg.configVersion != 2) {
      badPackageConfig();
    }

    final packagePathsMapping = <String, String>{};

    // We allow the package called 'flutter_gen' to be injected into
    // package_config.
    //
    // This is somewhat a hack. But it allows flutter to generate code in a
    // package as it likes.
    //
    // See https://github.com/flutter/flutter/issues/73870 .
    final packagesToCheck =
        cfg.packages.where((package) => package.name != 'flutter_gen');
    for (final pkg in packagesToCheck) {
      // Pub always makes a packageUri of lib/
      if (pkg.packageUri == null || pkg.packageUri.toString() != 'lib/') {
        badPackageConfig();
      }
      packagePathsMapping[pkg.name] =
          root.path('.dart_tool', p.fromUri(pkg.rootUri));
    }
    if (!_isPackagePathsMappingUpToDateWithLockfile(packagePathsMapping)) {
      outOfDate();
    }

    // Check if language version specified in the `package_config.json` is
    // correct. This is important for path dependencies as these can mutate.
    for (final pkg in cfg.packages) {
      if (pkg.name == root.name || pkg.name == 'flutter_gen') continue;
      final id = lockFile.packages[pkg.name];
      if (id == null) {
        assert(
          false,
          'unnecessary package_config.json entries should be forbidden by '
          '_isPackagePathsMappingUpToDateWithLockfile',
        );
        continue;
      }

      // If a package is cached, then it's universally immutable and we need
      // not check if the language version is correct.
      final source = cache.source(id.source);
      if (source is CachedSource) {
        continue;
      }

      try {
        // Load `pubspec.yaml` and extract language version to compare with the
        // language version from `package_config.json`.
        final languageVersion = LanguageVersion.fromSdkConstraint(
          cache.load(id).pubspec.sdkConstraints[sdk.identifier],
        );
        if (pkg.languageVersion != languageVersion) {
          final relativePubspecPath = p.join(
              source.getDirectory(id, relativeFrom: '.'), 'pubspec.yaml');
          dataError('$relativePubspecPath has '
              'changed since the $lockFilePath file was generated, please run '
              '"$topLevelProgram pub get" again.');
        }
      } on FileException {
        dataError('Failed to read pubspec.yaml for "${pkg.name}", perhaps the '
            'entry is missing, please run "$topLevelProgram pub get".');
      }
    }
  }