public static TryParseVersionSpec ( string value, IVersionSpec &result ) : bool | ||
value | string | |
result | IVersionSpec | |
return | bool |
public static bool TryParseVersionSpec(string value, out IVersionSpec result)
{
if (value == null)
{
throw new ArgumentNullException("value");
}
var versionSpec = new VersionSpec();
value = value.Trim();
// First, try to parse it as a plain version string
SemanticVersion version;
if (SemanticVersion.TryParse(value, out version))
{
// A plain version is treated as an inclusive minimum range
result = new VersionSpec
{
MinVersion = version,
IsMinInclusive = true
};
return true;
}
// It's not a plain version, so it must be using the bracket arithmetic range syntax
result = null;
// Fail early if the string is too short to be valid
if (value.Length < 3)
{
return false;
}
// The first character must be [ ot (
switch (value.First())
{
case '[':
versionSpec.IsMinInclusive = true;
break;
case '(':
versionSpec.IsMinInclusive = false;
break;
default:
return false;
}
// The last character must be ] ot )
switch (value.Last())
{
case ']':
versionSpec.IsMaxInclusive = true;
break;
case ')':
versionSpec.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
string minVersionString = parts[0];
string maxVersionString = (parts.Length == 2) ? parts[1] : parts[0];
// Only parse the min version if it's non-empty
if (!String.IsNullOrWhiteSpace(minVersionString))
{
if (!TryParseVersion(minVersionString, out version))
{
return false;
}
versionSpec.MinVersion = version;
}
// Same deal for max
if (!String.IsNullOrWhiteSpace(maxVersionString))
{
if (!TryParseVersion(maxVersionString, out version))
{
return false;
}
versionSpec.MaxVersion = version;
}
// Successful parse!
result = versionSpec;
return true;
}
/// <summary> /// Parses a dependency from the feed in the format: /// id or id:versionSpec, or id:versionSpec:targetFramework /// </summary> private static Tuple <string, IVersionSpec, FrameworkName> ParseDependency(string value) { if (String.IsNullOrWhiteSpace(value)) { return(null); } // IMPORTANT: Do not pass StringSplitOptions.RemoveEmptyEntries to this method, because it will break // if the version spec is null, for in that case, the Dependencies string sent down is "<id>::<target framework>". // We do want to preserve the second empty element after the split. string[] tokens = value.Trim().Split(new[] { ':' }); if (tokens.Length == 0) { return(null); } // Trim the id string id = tokens[0].Trim(); IVersionSpec versionSpec = null; if (tokens.Length > 1) { // Attempt to parse the version VersionUtility.TryParseVersionSpec(tokens[1], out versionSpec); } var targetFramework = (tokens.Length > 2 && !String.IsNullOrEmpty(tokens[2])) ? VersionUtility.ParseFrameworkName(tokens[2]) : null; return(Tuple.Create(id, versionSpec, targetFramework)); }