Пример #1
0
        /// <summary>
        /// Parses a VersionRange from its string representation.
        /// </summary>
        public static bool TryParse(string value, bool allowFloating, out VersionRange versionRange)
        {
            versionRange = null;

            if (value == null)
            {
                return(false);
            }

            var trimmedValue = value.Trim();

            var charArray = trimmedValue.ToCharArray();

            // * is the only 1 char range
            if (allowFloating &&
                charArray.Length == 1 &&
                charArray[0] == '*')
            {
                versionRange = new VersionRange(new NuGetVersion(0, 0, 0), true, null, true, FloatRange.Parse(trimmedValue), originalString: value);
                return(true);
            }

            // Fail early if the string is too short to be valid
            if (charArray.Length < 3)
            {
                return(false);
            }

            string       minVersionString = null;
            string       maxVersionString = null;
            var          isMinInclusive   = false;
            var          isMaxInclusive   = false;
            NuGetVersion minVersion       = null;
            NuGetVersion maxVersion       = null;
            FloatRange   floatRange       = null;

            if (charArray[0] == '(' ||
                charArray[0] == '[')
            {
                // The first character must be [ to (
                switch (charArray[0])
                {
                case '[':
                    isMinInclusive = true;
                    break;

                case '(':
                    isMinInclusive = false;
                    break;

                default:
                    return(false);
                }

                // The last character must be ] ot )
                switch (charArray[charArray.Length - 1])
                {
                case ']':
                    isMaxInclusive = true;
                    break;

                case ')':
                    isMaxInclusive = false;
                    break;

                default:
                    return(false);
                }

                // Get rid of the two brackets
                trimmedValue = trimmedValue.Substring(1, trimmedValue.Length - 2);

                // Split by comma, and make sure we don't get more than two pieces
                var parts = trimmedValue.Split(',');

                if (parts.Length > 2)
                {
                    return(false);
                }
                else
                {
                    var allEmpty = true;

                    for (int i = 0; i < parts.Length; i++)
                    {
                        if (!string.IsNullOrEmpty(parts[i]))
                        {
                            allEmpty = false;
                            break;
                        }
                    }

                    // If all parts are empty, then neither of upper or lower bounds were specified. Version spec is of the format (,]
                    if (allEmpty)
                    {
                        return(false);
                    }
                }

                // (1.0.0] and [1.0.0),(1.0.0) are invalid.
                if (parts.Length == 1 &&
                    !(isMinInclusive && isMaxInclusive))
                {
                    return(false);
                }

                // If there is only one piece, we use it for both min and max
                minVersionString = parts[0];
                maxVersionString = (parts.Length == 2) ? parts[1] : parts[0];
            }
            else
            {
                // default to min inclusive when there are no braces
                isMinInclusive = true;

                // use the entire value as the version
                minVersionString = trimmedValue;
            }

            if (!string.IsNullOrWhiteSpace(minVersionString))
            {
                // parse the min version string
                if (allowFloating && minVersionString.Contains("*"))
                {
                    // single floating version
                    if (FloatRange.TryParse(minVersionString, out floatRange) &&
                        floatRange.HasMinVersion)
                    {
                        minVersion = floatRange.MinVersion;
                    }
                    else
                    {
                        // invalid float
                        return(false);
                    }
                }
                else
                {
                    // single non-floating version
                    if (!NuGetVersion.TryParse(minVersionString, out minVersion))
                    {
                        // invalid version
                        return(false);
                    }
                }
            }

            // parse the max version string, the max cannot float
            if (!string.IsNullOrWhiteSpace(maxVersionString))
            {
                if (!NuGetVersion.TryParse(maxVersionString, out maxVersion))
                {
                    // invalid version
                    return(false);
                }
            }

            if (minVersion != null && maxVersion != null)
            {
                int result = minVersion.CompareTo(maxVersion);

                // minVersion > maxVersion
                if (result > 0)
                {
                    return(false);
                }

                // minVersion is equal to maxVersion (1.0.0, 1.0.0], [1.0.0, 1.0.0)
                if (result == 0 &&
                    (isMinInclusive ^ isMaxInclusive))
                {
                    return(false);
                }
            }

            // Successful parse!
            versionRange = new VersionRange(
                minVersion: minVersion,
                includeMinVersion: isMinInclusive,
                maxVersion: maxVersion,
                includeMaxVersion: isMaxInclusive,
                floatRange: floatRange,
                originalString: value);

            return(true);
        }