tighten method

Map<Package, Map<PackageRange, PackageRange>> tighten({
  1. List<String> packagesToUpgrade = const [],
  2. Map<Package, Map<PackageRange, PackageRange>> existingChanges = const {},
  3. List<PackageId>? packageVersions,
})

Returns a list of changes to constraints of workspace pubspecs updated to have their lower bound match the version in packageVersions (or this.lockFile).

The return value for each workspace package is a mapping from the original package range to the updated.

If packages to update where given in packagesToUpgrade, only those are tightened. Otherwise all packages are tightened.

If a dependency has already been updated in existingChanges, the update will apply on top of that change (eg. preserving the new upper bound).

Implementation

Map<Package, Map<PackageRange, PackageRange>> tighten({
  List<String> packagesToUpgrade = const [],
  Map<Package, Map<PackageRange, PackageRange>> existingChanges = const {},
  List<PackageId>? packageVersions,
}) {
  final result = {...existingChanges};

  final toTighten = <(Package, PackageRange)>[];

  for (final package in workspaceRoot.transitiveWorkspace) {
    if (packagesToUpgrade.isEmpty) {
      for (final range in [
        ...package.dependencies.values,
        ...package.devDependencies.values,
      ]) {
        toTighten.add((package, range));
      }
    } else {
      for (final packageToUpgrade in packagesToUpgrade) {
        final range = package.dependencies[packageToUpgrade] ??
            package.devDependencies[packageToUpgrade];
        if (range != null) {
          toTighten.add((package, range));
        }
      }
    }
  }

  for (final (package, range) in toTighten) {
    final changesForPackage = result[package] ??= {};
    final constraint = (changesForPackage[range] ?? range).constraint;
    final resolvedVersion =
        (packageVersions?.firstWhere((p) => p.name == range.name) ??
                lockFile.packages[range.name])!
            .version;
    if (range.source is HostedSource && constraint.isAny) {
      changesForPackage[range] = range
          .toRef()
          .withConstraint(VersionConstraint.compatibleWith(resolvedVersion));
    } else if (constraint is VersionRange) {
      final min = constraint.min;
      if (min != null && min < resolvedVersion) {
        changesForPackage[range] = range.toRef().withConstraint(
              VersionRange(
                min: resolvedVersion,
                max: constraint.max,
                includeMin: true,
                includeMax: constraint.includeMax,
              ).asCompatibleWithIfPossible(),
            );
      }
    }
  }
  return result;
}