/// <summary> /// Returns the smallest range that includes all given ranges. /// </summary> public static VersionRange Combine(IEnumerable <VersionRange> ranges, IVersionComparer comparer) { VersionRange result = VersionRange.None; if (ranges.Any()) { VersionRangeComparer rangeComparer = new VersionRangeComparer(comparer); // remove zero ranges ranges = ranges.Where(r => !rangeComparer.Equals(r, VersionRange.None)); var first = ranges.First(); NuGetVersion lowest = first.MinVersion; bool includeLowest = first.IsMinInclusive; NuGetVersion highest = first.MaxVersion; bool includeHighest = first.IsMaxInclusive; bool includePre = first.IncludePrerelease; foreach (var range in ranges.Skip(1)) { includePre |= range.IncludePrerelease; if (!range.HasLowerBound) { lowest = null; includeLowest |= range.IsMinInclusive; } else if (comparer.Compare(range.MinVersion, lowest) < 0) { lowest = range.MinVersion; includeLowest = range.IsMinInclusive; } if (!range.HasUpperBound) { highest = null; includeHighest |= range.IsMinInclusive; } else if (comparer.Compare(range.MinVersion, highest) > 0) { highest = range.MinVersion; includeHighest = range.IsMinInclusive; } } result = new VersionRange(lowest, includeLowest, highest, includeHighest, includePre); } return(result); }
/// <summary> /// Returns the smallest range that includes all given ranges. /// </summary> public static VersionRange Combine(IEnumerable<VersionRange> ranges, IVersionComparer comparer) { if (ranges == null) { throw new ArgumentNullException(nameof(ranges)); } if (comparer == null) { throw new ArgumentNullException(nameof(comparer)); } // Default to None for empty lists var result = None; // Remove zero width ranges. Ex: (1.0.0, 1.0.0) // This includes VersionRange.None and any other ranges that satisfy zero versions ranges = ranges.Where(range => HasValidRange(range)); if (ranges.Any()) { var rangeComparer = new VersionRangeComparer(comparer); // start with the first range in the list var first = ranges.First(); var lowest = first.MinVersion; var highest = first.MaxVersion; var includePre = first.IncludePrerelease; // To keep things consistent set min/max inclusive to false when there is no boundary // It is possible to denote an inclusive range with no bounds, but it has no useful meaning for combine var includeLowest = first.IsMinInclusive && first.HasLowerBound; var includeHighest = first.IsMaxInclusive && first.HasUpperBound; // expand the range to inclue all other ranges foreach (var range in ranges.Skip(1)) { // allow prerelease versions in the range if any range allows them includePre |= range.IncludePrerelease; // once we have an unbounded lower we can stop checking if (lowest != null) { if (range.HasLowerBound) { var lowerCompare = comparer.Compare(range.MinVersion, lowest); if (lowerCompare < 0) { // A new lowest was found lowest = range.MinVersion; includeLowest = range.IsMinInclusive; } else if (lowerCompare == 0) { // The lower ends are identical, update the inclusiveness includeLowest |= range.IsMinInclusive; } // lowerCompare > 0 falls into the current range, this is a no-op } else { // No lower bound lowest = null; includeLowest = false; } } // null is the highest we can get, stop checking once it is hit if (highest != null) { if (range.HasUpperBound) { var higherCompare = comparer.Compare(range.MaxVersion, highest); if (higherCompare > 0) { // A new highest was found highest = range.MaxVersion; includeHighest = range.IsMaxInclusive; } else if (higherCompare == 0) { // The higher ends are identical, update the inclusiveness includeHighest |= range.IsMaxInclusive; } // higherCompare < 0 falls into the current range, this is a no-op } else { // No higher bound highest = null; includeHighest = false; } } } // Create the new range using the maximums found result = new VersionRange(lowest, includeLowest, highest, includeHighest, includePre); } return result; }
/// <summary> /// Returns the smallest range that includes all given ranges. /// </summary> public static VersionRange Combine(IEnumerable <VersionRange> ranges, IVersionComparer comparer) { if (ranges == null) { throw new ArgumentNullException(nameof(ranges)); } if (comparer == null) { throw new ArgumentNullException(nameof(comparer)); } // Default to None for empty lists var result = None; // Remove zero width ranges. Ex: (1.0.0, 1.0.0) // This includes VersionRange.None and any other ranges that satisfy zero versions ranges = ranges.Where(range => HasValidRange(range)); if (ranges.Any()) { var rangeComparer = new VersionRangeComparer(comparer); // start with the first range in the list var first = ranges.First(); var lowest = first.MinVersion; var highest = first.MaxVersion; // To keep things consistent set min/max inclusive to false when there is no boundary // It is possible to denote an inclusive range with no bounds, but it has no useful meaning for combine var includeLowest = first.IsMinInclusive && first.HasLowerBound; var includeHighest = first.IsMaxInclusive && first.HasUpperBound; // expand the range to inclue all other ranges foreach (var range in ranges.Skip(1)) { // once we have an unbounded lower we can stop checking if (lowest != null) { if (range.HasLowerBound) { var lowerCompare = comparer.Compare(range.MinVersion, lowest); if (lowerCompare < 0) { // A new lowest was found lowest = range.MinVersion; includeLowest = range.IsMinInclusive; } else if (lowerCompare == 0) { // The lower ends are identical, update the inclusiveness includeLowest |= range.IsMinInclusive; } // lowerCompare > 0 falls into the current range, this is a no-op } else { // No lower bound lowest = null; includeLowest = false; } } // null is the highest we can get, stop checking once it is hit if (highest != null) { if (range.HasUpperBound) { var higherCompare = comparer.Compare(range.MaxVersion, highest); if (higherCompare > 0) { // A new highest was found highest = range.MaxVersion; includeHighest = range.IsMaxInclusive; } else if (higherCompare == 0) { // The higher ends are identical, update the inclusiveness includeHighest |= range.IsMaxInclusive; } // higherCompare < 0 falls into the current range, this is a no-op } else { // No higher bound highest = null; includeHighest = false; } } } // Create the new range using the maximums found result = new VersionRange(lowest, includeLowest, highest, includeHighest); } return(result); }
/// <summary> /// SubSet check /// </summary> public bool IsSubSetOrEqualTo(VersionRangeBase possibleSuperSet, IVersionComparer comparer) { var rangeComparer = new VersionRangeComparer(comparer); var possibleSubSet = this; var target = possibleSuperSet; if (rangeComparer.Equals(possibleSubSet, VersionRange.None)) { return(true); } if (rangeComparer.Equals(target, VersionRange.None)) { return(false); } if (target == null) { target = VersionRange.All; } if (possibleSubSet == null) { possibleSubSet = VersionRange.All; } var result = true; if (possibleSubSet.IncludePrerelease && !target.IncludePrerelease) { result = false; } if (possibleSubSet.HasLowerBound) { // normal check if (!target.Satisfies(possibleSubSet.MinVersion)) { // it's possible we didn't need that version, do a special non inclusive check if (!possibleSubSet.IsMinInclusive && !target.IsMinInclusive) { result &= comparer.Equals(target.MinVersion, possibleSubSet.MinVersion); } else { result = false; } } } else { result &= !target.HasLowerBound; } if (possibleSubSet.HasUpperBound) { // normal check if (!target.Satisfies(possibleSubSet.MaxVersion)) { // it's possible we didn't need that version, do a special non inclusive check if (!possibleSubSet.IsMaxInclusive && !target.IsMaxInclusive) { result &= comparer.Equals(target.MaxVersion, possibleSubSet.MaxVersion); } else { result = false; } } } else { result &= !target.HasUpperBound; } return(result); }
/// <summary> /// Use a specific IVersionComparer for comparison /// </summary> public bool Equals(VersionRangeBase other, IVersionComparer versionComparer) { IVersionRangeComparer comparer = new VersionRangeComparer(versionComparer); return(Equals(other, comparer)); }
/// <summary> /// Returns the smallest range that includes all given ranges. /// </summary> public static VersionRange Combine(IEnumerable<VersionRange> ranges, IVersionComparer comparer) { VersionRange result = VersionRange.None; if (ranges.Any()) { VersionRangeComparer rangeComparer = new VersionRangeComparer(comparer); // remove zero ranges ranges = ranges.Where(r => !rangeComparer.Equals(r, VersionRange.None)); var first = ranges.First(); NuGetVersion lowest = first.MinVersion; bool includeLowest = first.IsMinInclusive; NuGetVersion highest = first.MaxVersion; bool includeHighest = first.IsMaxInclusive; bool includePre = first.IncludePrerelease; foreach (var range in ranges.Skip(1)) { includePre |= range.IncludePrerelease; if (!range.HasLowerBound) { lowest = null; includeLowest |= range.IsMinInclusive; } else if (comparer.Compare(range.MinVersion, lowest) < 0) { lowest = range.MinVersion; includeLowest = range.IsMinInclusive; } if (!range.HasUpperBound) { highest = null; includeHighest |= range.IsMinInclusive; } else if (comparer.Compare(range.MinVersion, highest) > 0) { highest = range.MinVersion; includeHighest = range.IsMinInclusive; } } result = new VersionRange(lowest, includeLowest, highest, includeHighest, includePre); } return result; }