Beispiel #1
0
 /// <summary>
 /// Converts the string to the equivalent version comparator.
 /// </summary>
 /// <param name="value">The string to convert.</param>
 /// <param name="comparator">The instance that will contain the parsed value. If the method returns <c>true</c>, result contains a valid version comparator. If the method returns <c>false</c>, result is null.</param>
 /// <returns><c>true</c> if the parse operation was successful; otherwise, <c>false</c>.</returns>
 public static bool TryParse(string value, out IVersionComparator comparator)
 {
     if (value == null)
     {
         throw new ArgumentNullException(nameof(value));
     }
     value      = value.Trim();
     comparator = null;
     if (string.IsNullOrEmpty(value))
     {
         return(false);
     }
     return(TryParseExpression(value, out comparator));
 }
Beispiel #2
0
        private static bool TryParseSection(string value, out IVersionComparator comparator)
        {
            comparator = null;
            if (string.IsNullOrEmpty(value))
            {
                return(false);
            }
            if (value == "*")
            {
                comparator = new VersionComparator(new Version(0, 0, 0), VersionFloatBehavior.Major, value);
                return(true);
            }
            VersionComparator lowerBound, upperBound;

            if (TryParseByBrakets(value, out lowerBound, out upperBound) || TryParseByHyphen(value, out lowerBound, out upperBound))
            {
                if (lowerBound == null && upperBound == null)
                {
                    return(false);
                }
                if (lowerBound == null || upperBound == null)
                {
                    comparator = lowerBound ?? upperBound;
                    return(true);
                }
                comparator = new VersionCompositeComparator(new IVersionComparator[] { lowerBound, upperBound }, VersionCompositor.And, value);
                return(true);
            }
            if (TryParseByTilde(value, out comparator) || TryParseByCaret(value, out comparator))
            {
                return(true);
            }
            VersionComparator versionComparator;

            if (VersionComparator.TryParse(value, out versionComparator))
            {
                comparator = versionComparator;
                return(true);
            }
            return(false);
        }
Beispiel #3
0
 private static bool TryParseExpression(string value, out IVersionComparator comparator)
 {
     value      = value.Trim();
     comparator = null;
     if (string.IsNullOrEmpty(value))
     {
         return(false);
     }
     if (TryParseCompositeExpression(value, "||", VersionCompositor.Or, out comparator))
     {
         return(true);
     }
     if (TryParseCompositeExpression(value, "&&", VersionCompositor.And, out comparator))
     {
         return(true);
     }
     if (TryParseSection(value, out comparator))
     {
         return(true);
     }
     return(false);
 }
Beispiel #4
0
        private static bool TryParseCompositeExpression(string value, string operatorString, VersionCompositor compositor, out IVersionComparator comparator)
        {
            comparator = null;
            if (value.IndexOf(operatorString, StringComparison.Ordinal) == -1)
            {
                return(false);
            }
            Func <bool, IVersionComparator> parse = ignoreParanthesis =>
            {
                string[] expressions;
                if (!SplitByOperator(value, operatorString, ignoreParanthesis, out expressions))
                {
                    return(null);
                }
                if (expressions.Length <= 1)
                {
                    return(null);
                }
                var  comparators = new List <IVersionComparator>();
                bool result      = true;
                foreach (var expression in expressions)
                {
                    IVersionComparator childComparator;
                    if (!TryParseExpression(expression, out childComparator))
                    {
                        result = false;
                        break;
                    }
                    comparators.Add(childComparator);
                }
                return(result ? new VersionCompositeComparator(comparators, compositor) : null);
            };

            comparator = parse(false) ?? parse(true);
            if (comparator != null)
            {
                return(true);
            }
            if (value[0] == '(')
            {
                if (value[value.Length - 1] != ')')
                {
                    return(false);
                }
                return(TryParseCompositeExpression(value.Substring(1, value.Length - 2).Trim(), operatorString, compositor, out comparator));
            }
            return(false);
        }
Beispiel #5
0
        private static bool TryParseByCaret(string value, out IVersionComparator comparator)
        {
            comparator = null;
            if (value[0] != '^')
            {
                return(false);
            }
            var versionString = value.Substring(1);

            if (string.IsNullOrEmpty(versionString))
            {
                return(false);
            }
            var hyphenIndex = versionString.IndexOf("-", StringComparison.Ordinal);
            var realVersion = hyphenIndex == -1 ? versionString : versionString.Substring(0, hyphenIndex);
            var parts       = realVersion.Split('.');
            var major       = parts.Length > 0 ? parts[0] : null;
            var minor       = parts.Length > 1 ? parts[1] : null;
            var patch       = parts.Length > 2 ? parts[2] : null;
            var revision    = parts.Length > 3 ? parts[3] : null;

            if (hyphenIndex == -1)
            {
                VersionComparator lowerBound, upperBound = null;
                if (!VersionComparator.TryParse(realVersion, VersionOperator.GreaterThanEqual, out lowerBound))
                {
                    return(false);
                }
                lowerBound._originalString = null;
                if (!string.IsNullOrEmpty(major) && (major != "0" || string.IsNullOrEmpty(minor) || minor == "x" || minor == "*"))
                {
                    upperBound = new VersionComparator(new Version(lowerBound.Version.Major, 0, 0), VersionFloatBehavior.Minor, VersionOperator.LessThanEqual);
                }
                else if (!string.IsNullOrEmpty(minor) && (minor != "0" || string.IsNullOrEmpty(patch) || patch == "x" || patch == "*"))
                {
                    upperBound = new VersionComparator(new Version(lowerBound.Version.Major, lowerBound.Version.Minor, 0), VersionFloatBehavior.Patch,
                                                       VersionOperator.LessThanEqual);
                }
                else if (!string.IsNullOrEmpty(patch) && (patch != "0" || string.IsNullOrEmpty(revision) || revision == "x" || revision == "*"))
                {
                    upperBound = new VersionComparator(new Version(lowerBound.Version.Major, lowerBound.Version.Minor, lowerBound.Version.Patch),
                                                       VersionFloatBehavior.Revision, VersionOperator.LessThanEqual);
                }
                else if (!string.IsNullOrEmpty(revision))
                {
                    comparator = new VersionComparator(lowerBound.Version);
                    return(true);
                }
                if (upperBound != null)
                {
                    comparator = new VersionCompositeComparator(lowerBound, upperBound);
                    return(true);
                }
            }
            else
            {
                Version version;
                if (!Version.TryParse(versionString, out version))
                {
                    return(false);
                }
                var releaseComparator = new VersionCompositeComparator(
                    new VersionComparator(version, VersionOperator.GreaterThanEqual),
                    new VersionComparator(new Version(version.Major, version.Minor, version.Patch, version.Revision),
                                          VersionOperator.LessThan));
                IVersionComparator versionComparator;
                if (TryParseByCaret("^" + realVersion, out versionComparator))
                {
                    comparator = new VersionCompositeComparator(new[] { releaseComparator, versionComparator }, VersionCompositor.Or, value);
                    return(true);
                }
            }
            return(false);
        }
Beispiel #6
0
        private static bool TryParseByTilde(string value, out IVersionComparator comparator)
        {
            comparator = null;
            if (value[0] != '~')
            {
                return(false);
            }
            var versionString = value.Substring(1);

            if (string.IsNullOrWhiteSpace(versionString))
            {
                return(false);
            }
            var hyphenIndex = versionString.IndexOf("-", StringComparison.Ordinal);
            var realVersion = hyphenIndex == -1 ? versionString : versionString.Substring(0, hyphenIndex);

            if (hyphenIndex == -1)
            {
                var parts = realVersion.Split('.');
                if (parts.Length >= 3)
                {
                    VersionComparator lowerBound;
                    if (!VersionComparator.TryParse(realVersion, VersionOperator.GreaterThanEqual, out lowerBound))
                    {
                        return(false);
                    }
                    lowerBound._originalString = null;
                    var upperBound = new VersionComparator(new Version(lowerBound.Version.Major, lowerBound.Version.Minor, 0), VersionFloatBehavior.Patch,
                                                           VersionOperator.LessThanEqual);
                    comparator = new VersionCompositeComparator(new IVersionComparator[] { lowerBound, upperBound }, VersionCompositor.And, value);
                }
                else
                {
                    VersionComparator versionComparator;
                    if (!VersionComparator.TryParse(realVersion + ".*", out versionComparator))
                    {
                        return(false);
                    }
                    versionComparator._originalString = value;
                    comparator = versionComparator;
                }
                return(true);
            }
            else
            {
                Version version;
                if (!Version.TryParse(versionString, out version))
                {
                    return(false);
                }
                var releaseComparator = new VersionCompositeComparator(
                    new VersionComparator(version, VersionOperator.GreaterThanEqual),
                    new VersionComparator(new Version(version.Major, version.Minor, version.Patch, version.Revision),
                                          VersionOperator.LessThan));
                IVersionComparator versionComparator;
                if (TryParseByTilde("~" + realVersion, out versionComparator))
                {
                    comparator = new VersionCompositeComparator(new[] { releaseComparator, versionComparator }, VersionCompositor.Or, value);
                    return(true);
                }
                return(false);
            }
        }