Esempio n. 1
0
        /// <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)
        {
            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;
        }