Future _runUpgradeMajorVersions()

in lib/src/command/upgrade.dart [175:275]


  Future<void> _runUpgradeMajorVersions() async {
    final toUpgrade = _directDependenciesToUpgrade();

    final resolvablePubspec = stripVersionUpperBounds(
      entrypoint.root.pubspec,
      stripOnly: toUpgrade,
    );

    // Solve [resolvablePubspec] in-memory and consolidate the resolved
    // versions of the packages into a map for quick searching.
    final resolvedPackages = <String, PackageId>{};
    final solveResult = await log.spinner('Resolving dependencies', () async {
      return await resolveVersions(
        SolveType.upgrade,
        cache,
        Package.inMemory(resolvablePubspec),
      );
    }, condition: _shouldShowSpinner);
    for (final resolvedPackage in solveResult.packages) {
      resolvedPackages[resolvedPackage.name] = resolvedPackage;
    }

    // Changes to be made to `pubspec.yaml`.
    // Mapping from original to changed value.
    final changes = <PackageRange, PackageRange>{};
    final declaredHostedDependencies = [
      ...entrypoint.root.pubspec.dependencies.values,
      ...entrypoint.root.pubspec.devDependencies.values,
    ].where((dep) => dep.source is HostedSource);
    for (final dep in declaredHostedDependencies) {
      final resolvedPackage = resolvedPackages[dep.name]!;
      if (!toUpgrade.contains(dep.name)) {
        // If we're not to upgrade this package, or it wasn't in the
        // resolution somehow, then we ignore it.
        continue;
      }

      // Skip [dep] if it has a dependency_override.
      if (entrypoint.root.dependencyOverrides.containsKey(dep.name)) {
        continue;
      }

      if (dep.constraint.allowsAll(resolvedPackage.version)) {
        // If constraint allows the resolvable version we found, then there is
        // no need to update the `pubspec.yaml`
        continue;
      }

      changes[dep] = dep.withConstraint(VersionConstraint.compatibleWith(
        resolvedPackage.version,
      ));
    }
    final newPubspecText = _updatePubspec(changes);

    if (_dryRun) {
      // Even if it is a dry run, run `acquireDependencies` so that the user
      // gets a report on changes.
      await Entrypoint.inMemory(
        Package.inMemory(
          Pubspec.parse(newPubspecText, cache.sources),
        ),
        cache,
        lockFile: entrypoint.lockFile,
        solveResult: solveResult,
      ).acquireDependencies(
        SolveType.get,
        dryRun: true,
        precompile: _precompile,
        analytics: null, // No analytics for dry-run
        generateDotPackages: false,
      );
    } else {
      if (changes.isNotEmpty) {
        writeTextFile(entrypoint.pubspecPath, newPubspecText);
      }
      // TODO: Allow Entrypoint to be created with in-memory pubspec, so that
      //       we can show the changes when not in --dry-run mode. For now we only show
      //       the changes made to pubspec.yaml in dry-run mode.
      await Entrypoint(directory, cache).acquireDependencies(
        SolveType.get,
        precompile: _precompile,
        analytics: analytics,
        generateDotPackages: argResults['legacy-packages-file'],
      );
    }

    _outputChangeSummary(changes);

    // If any of the packages to upgrade are dependency overrides, then we
    // show a warning.
    final toUpgradeOverrides =
        toUpgrade.where(entrypoint.root.dependencyOverrides.containsKey);
    if (toUpgradeOverrides.isNotEmpty) {
      log.warning(
        'Warning: dependency_overrides prevents upgrades for: '
        '${toUpgradeOverrides.join(', ')}',
      );
    }

    _showOfflineWarning();
  }