/// <summary> /// Parses a VersionRange from its string representation. /// </summary> public static bool TryParse(string value, bool allowFloating, out VersionRange versionRange) { if (value == null) { throw new ArgumentNullException("value"); } versionRange = null; value = value.Trim(); char[] charArray = value.ToCharArray(); // * is the only range below 3 chars if (allowFloating && charArray.Length == 1 && charArray[0] == '*') { versionRange = AllStableFloating; 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; bool isMinInclusive = false; bool 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 value = value.Substring(1, value.Length - 2); // Split by comma, and make sure we don't get more than two pieces string[] parts = value.Split(','); if (parts.Length > 2) { return(false); } else if (parts.All(String.IsNullOrEmpty)) { // If all parts are empty, then neither of upper or lower bounds were specified. Version spec is of the format (,] 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 = value; } 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); } } // Successful parse! versionRange = new VersionRange( minVersion: minVersion, includeMinVersion: isMinInclusive, maxVersion: maxVersion, includeMaxVersion: isMaxInclusive, includePrerelease: null, floatRange: floatRange); return(true); }
/// <summary> /// Parse a floating version into a FloatRange /// </summary> public static bool TryParse(string versionString, out FloatRange range) { range = null; if (versionString != null) { int starPos = versionString.IndexOf('*'); string actualVersion = versionString; string releasePrefix = string.Empty; if (versionString.Length == 1 && starPos == 0) { range = new FloatRange(NuGetVersionFloatBehavior.Major, new NuGetVersion(new Version(0, 0))); } else if (starPos == versionString.Length - 1) { var behavior = NuGetVersionFloatBehavior.None; actualVersion = versionString.Substring(0, versionString.Length - 1); if (versionString.IndexOf('-') == -1) { // replace the * with a 0 actualVersion += "0"; int versionParts = actualVersion.Split('.').Length; if (versionParts == 2) { behavior = NuGetVersionFloatBehavior.Minor; } else if (versionParts == 3) { behavior = NuGetVersionFloatBehavior.Patch; } else if (versionParts == 4) { behavior = NuGetVersionFloatBehavior.Revision; } } else { behavior = NuGetVersionFloatBehavior.Prerelease; // check for a prefix if (versionString.IndexOf('-') == versionString.LastIndexOf('-')) { releasePrefix = actualVersion.Substring(versionString.LastIndexOf('-') + 1); if (actualVersion.EndsWith("-")) { // remove the empty release label, the version will be release but // the behavior will have to account for this actualVersion += "-"; } else if (actualVersion.EndsWith(".")) { // ending with a . is not allowed // TODO: solve this better actualVersion += "0"; } } } NuGetVersion version = null; if (NuGetVersion.TryParse(actualVersion, out version)) { // there is no float range for this version range = new FloatRange(behavior, version, releasePrefix); } } else { // normal version parse NuGetVersion version = null; if (NuGetVersion.TryParse(versionString, out version)) { // there is no float range for this version range = new FloatRange(NuGetVersionFloatBehavior.None, version); } } } return(range != null); }