| // Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file | |
| // for details. All rights reserved. Use of this source code is governed by a | |
| // BSD-style license that can be found in the LICENSE file. | |
| import 'package:collection/collection.dart'; | |
| import 'package:pub_semver/pub_semver.dart'; | |
| import 'package.dart'; | |
| import 'package_name.dart'; | |
| import 'pubspec.dart'; | |
| import 'source/hosted.dart'; | |
| import 'system_cache.dart'; | |
| /// Returns a new [Pubspec] without [original]'s dev_dependencies. | |
| Pubspec stripDevDependencies(Pubspec original) { | |
| return original.copyWith(devDependencies: []); | |
| } | |
| /// Returns a new [Pubspec] without [original]'s dependency_overrides. | |
| Pubspec stripDependencyOverrides(Pubspec original) { | |
| return original.copyWith(dependencyOverrides: []); | |
| } | |
| /// Returns new pubspec with the same dependencies as [original] but with the | |
| /// the bounds of the constraints removed. | |
| /// | |
| /// If [stripLowerBound] is `false` (the default) only the upper bound is | |
| /// removed. | |
| /// | |
| /// If [stripOnly] is provided, only the packages whose names are in [stripOnly] | |
| /// will have their bounds removed. If [stripOnly] is not specified or empty, | |
| /// then all packages will have their bounds removed. | |
| Pubspec stripVersionBounds( | |
| Pubspec original, { | |
| Iterable<String>? stripOnly, | |
| bool stripLowerBound = false, | |
| }) { | |
| stripOnly ??= []; | |
| List<PackageRange> stripBounds(Map<String, PackageRange> constrained) { | |
| final result = <PackageRange>[]; | |
| for (final name in constrained.keys) { | |
| final packageRange = constrained[name]!; | |
| var unconstrainedRange = packageRange; | |
| if (stripOnly!.isEmpty || stripOnly.contains(packageRange.name)) { | |
| unconstrainedRange = PackageRange( | |
| packageRange.toRef(), | |
| stripLowerBound | |
| ? VersionConstraint.any | |
| : stripUpperBound(packageRange.constraint), | |
| ); | |
| } | |
| result.add(unconstrainedRange); | |
| } | |
| return result; | |
| } | |
| return original.copyWith( | |
| dependencies: stripBounds(original.dependencies), | |
| devDependencies: stripBounds(original.devDependencies), | |
| ); | |
| } | |
| /// Returns a pubspec with the same dependencies as [original] but with all | |
| /// version constraints replaced by `>=c` where `c`, is the member of `current` | |
| /// that has same name as the dependency. | |
| Pubspec atLeastCurrent(Pubspec original, List<PackageId> current) { | |
| List<PackageRange> fixBounds(Map<String, PackageRange> constrained) { | |
| final result = <PackageRange>[]; | |
| for (final name in constrained.keys) { | |
| final packageRange = constrained[name]!; | |
| final currentVersion = current.firstWhereOrNull((id) => id.name == name); | |
| if (currentVersion == null) { | |
| result.add(packageRange); | |
| } else { | |
| result.add( | |
| packageRange.toRef().withConstraint( | |
| VersionRange(min: currentVersion.version, includeMin: true), | |
| ), | |
| ); | |
| } | |
| } | |
| return result; | |
| } | |
| return original.copyWith( | |
| dependencies: fixBounds(original.dependencies), | |
| devDependencies: fixBounds(original.devDependencies), | |
| ); | |
| } | |
| /// Removes the upper bound of [constraint]. If [constraint] is the | |
| /// empty version constraint, [VersionConstraint.empty] will be returned. | |
| VersionConstraint stripUpperBound(VersionConstraint constraint) { | |
| ArgumentError.checkNotNull(constraint, 'constraint'); | |
| /// A [VersionConstraint] has to either be a [VersionRange], [VersionUnion], | |
| /// or the empty [VersionConstraint]. | |
| if (constraint is VersionRange) { | |
| return VersionRange(min: constraint.min, includeMin: constraint.includeMin); | |
| } | |
| if (constraint is VersionUnion) { | |
| if (constraint.ranges.isEmpty) return VersionConstraint.empty; | |
| final firstRange = constraint.ranges.first; | |
| return VersionRange(min: firstRange.min, includeMin: firstRange.includeMin); | |
| } | |
| assert(constraint == VersionConstraint.empty, 'unknown constraint type'); | |
| /// If it gets here, [constraint] is the empty version constraint, so we | |
| /// just return an empty version constraint. | |
| return VersionConstraint.empty; | |
| } | |
| /// Returns a somewhat normalized version the description of a dependency with a | |
| /// version constraint (what comes after the version name in a dependencies | |
| /// section) as a json-style object. | |
| /// | |
| /// Will use just the constraint for dependencies hosted at the default host. | |
| /// | |
| /// Relative paths will be relative to the directory of [receivingPackage]. | |
| /// | |
| /// The syntax used for hosted will depend on the language version of | |
| /// [receivingPackage]. | |
| Object pubspecDescription( | |
| PackageRange range, | |
| SystemCache cache, | |
| Package receivingPackage, | |
| ) { | |
| final description = range.description; | |
| final constraint = range.constraint; | |
| if (description is HostedDescription && | |
| description.url == cache.hosted.defaultUrl) { | |
| return constraint.toString(); | |
| } else { | |
| return { | |
| range.source.name: description.serializeForPubspec( | |
| containingDir: receivingPackage.dir, | |
| languageVersion: receivingPackage.pubspec.languageVersion, | |
| ), | |
| if (!constraint.isAny) 'version': constraint.toString(), | |
| }; | |
| } | |
| } |