Skip to content

Instantly share code, notes, and snippets.

@khellang
Created October 23, 2014 17:33
Show Gist options
  • Save khellang/af53ef9991e8e31a6cc5 to your computer and use it in GitHub Desktop.
Save khellang/af53ef9991e8e31a6cc5 to your computer and use it in GitHub Desktop.
/// <summary>
/// This function tries to normalize a string that represents framework version names into
/// something a framework name that the package manager understands.
/// </summary>
public static FrameworkName ParseFrameworkName(string frameworkName)
{
if (frameworkName == null)
{
throw new ArgumentNullException("frameworkName");
}
// {Identifier}{Version}-{Profile}
// Split the framework name into 3 parts, identifier, version and profile.
string identifierPart = null;
string versionPart = null;
string[] parts = frameworkName.Split('-');
if (parts.Length > 2)
{
throw new ArgumentException(NuGetResources.InvalidFrameworkNameFormat, "frameworkName");
}
string frameworkNameAndVersion = parts.Length > 0 ? parts[0].Trim() : null;
string profilePart = parts.Length > 1 ? parts[1].Trim() : null;
if (String.IsNullOrEmpty(frameworkNameAndVersion))
{
throw new ArgumentException(NuGetResources.MissingFrameworkName, "frameworkName");
}
// If we find a version then we try to split the framework name into 2 parts
var versionMatch = Regex.Match(frameworkNameAndVersion, @"\d+");
if (versionMatch.Success)
{
identifierPart = frameworkNameAndVersion.Substring(0, versionMatch.Index).Trim();
versionPart = frameworkNameAndVersion.Substring(versionMatch.Index).Trim();
}
else
{
// Otherwise we take the whole name as an identifier
identifierPart = frameworkNameAndVersion.Trim();
}
if (!String.IsNullOrEmpty(identifierPart))
{
// Try to normalize the identifier to a known identifier
if (!_knownIdentifiers.TryGetValue(identifierPart, out identifierPart))
{
return UnsupportedFrameworkName;
}
}
if (!String.IsNullOrEmpty(profilePart))
{
string knownProfile;
if (_knownProfiles.TryGetValue(profilePart, out knownProfile))
{
profilePart = knownProfile;
}
}
Version version = null;
// We support version formats that are integers (40 becomes 4.0)
int versionNumber;
if (Int32.TryParse(versionPart, out versionNumber))
{
// Remove the extra numbers
if (versionPart.Length > 4)
{
versionPart = versionPart.Substring(0, 4);
}
// Make sure it has at least 2 digits so it parses as a valid version
versionPart = versionPart.PadRight(2, '0');
versionPart = String.Join(".", versionPart.ToCharArray());
}
// If we can't parse the version then use the default
if (!Version.TryParse(versionPart, out version))
{
// We failed to parse the version string once more. So we need to decide if this is unsupported or if we use the default version.
// This framework is unsupported if:
// 1. The identifier part of the framework name is null.
// 2. The version part is not null.
if (String.IsNullOrEmpty(identifierPart) || !String.IsNullOrEmpty(versionPart))
{
return UnsupportedFrameworkName;
}
version = _emptyVersion;
}
if (String.IsNullOrEmpty(identifierPart))
{
identifierPart = NetFrameworkIdentifier;
}
// if this is a .NET Portable framework name, validate the profile part to ensure it is valid
if (identifierPart.Equals(PortableFrameworkIdentifier, StringComparison.OrdinalIgnoreCase))
{
ValidatePortableFrameworkProfilePart(profilePart);
}
return new FrameworkName(identifierPart, version, profilePart);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment