Fix mono/net403 framework assembly references (#3129)

* Add support for IncludeFramework for net403 and MonoAndroid (dotnet/cli#3128)

* Fallback mechanism for FrameworkList.xml from Mono/Xamarin that don't contain File elements (dotnet/cli#3128)

* Just using a foreach, as suggested by David Fowler (davidfowl)
This commit is contained in:
Mark Junker 2016-05-26 10:02:09 +02:00 committed by Piotr Puszkiewicz
parent e9e4427b42
commit 14e90f47b2

View file

@ -231,7 +231,7 @@ namespace Microsoft.DotNet.ProjectModel.Resolution
return null;
}
return GetFrameworkInformation(version, targetFramework);
return GetFrameworkInformation(version, targetFramework, referenceAssembliesPath);
}
private static FrameworkInformation GetLegacyFrameworkInformation(NuGetFramework targetFramework, string referenceAssembliesPath)
@ -294,7 +294,7 @@ namespace Microsoft.DotNet.ProjectModel.Resolution
var dir = new DirectoryInfo(searchPaths[i]);
if (dir.Exists)
{
PopulateFromRedistList(dir, frameworkInfo);
PopulateFromRedistList(dir, targetFramework, referenceAssembliesPath, frameworkInfo);
}
}
@ -323,7 +323,7 @@ namespace Microsoft.DotNet.ProjectModel.Resolution
return targetFramework.ToString();
}
private static FrameworkInformation GetFrameworkInformation(DirectoryInfo directory, NuGetFramework targetFramework)
private static FrameworkInformation GetFrameworkInformation(DirectoryInfo directory, NuGetFramework targetFramework, string referenceAssembliesPath)
{
var frameworkInfo = new FrameworkInformation();
frameworkInfo.Exists = true;
@ -333,7 +333,7 @@ namespace Microsoft.DotNet.ProjectModel.Resolution
Path.Combine(frameworkInfo.Path, "Facades")
};
PopulateFromRedistList(directory, frameworkInfo);
PopulateFromRedistList(directory, targetFramework, referenceAssembliesPath, frameworkInfo);
if (string.IsNullOrEmpty(frameworkInfo.Name))
{
frameworkInfo.Name = SynthesizeFrameworkFriendlyName(targetFramework);
@ -341,7 +341,7 @@ namespace Microsoft.DotNet.ProjectModel.Resolution
return frameworkInfo;
}
private static void PopulateFromRedistList(DirectoryInfo directory, FrameworkInformation frameworkInfo)
private static void PopulateFromRedistList(DirectoryInfo directory, NuGetFramework targetFramework, string referenceAssembliesPath, FrameworkInformation frameworkInfo)
{
// The redist list contains the list of assemblies for this target framework
string redistList = Path.Combine(directory.FullName, "RedistList", "FrameworkList.xml");
@ -354,11 +354,36 @@ namespace Microsoft.DotNet.ProjectModel.Resolution
{
var frameworkList = XDocument.Load(stream);
// Remember the original search paths, because we might need them later
var originalSearchPaths = frameworkInfo.SearchPaths;
// There are some frameworks, that "inherit" from a base framework, like
// e.g. .NET 4.0.3, and MonoAndroid.
var includeFrameworkVersion = frameworkList.Root.Attribute("IncludeFramework")?.Value;
if (includeFrameworkVersion != null)
{
// Get the NuGetFramework identifier for the framework to include
var includeFramework = NuGetFramework.Parse($"{targetFramework.Framework}, Version={includeFrameworkVersion}");
// Recursively call the code to get the framework information
var includeFrameworkInfo = GetFrameworkInformation(includeFramework, referenceAssembliesPath);
// Append the search paths of the included framework
frameworkInfo.SearchPaths = frameworkInfo.SearchPaths.Concat(includeFrameworkInfo.SearchPaths).ToArray();
// Add the assemblies of the included framework
foreach (var assemblyEntry in includeFrameworkInfo.Assemblies)
{
frameworkInfo.Assemblies[assemblyEntry.Key] = assemblyEntry.Value;
}
}
// On mono, the RedistList.xml has an entry pointing to the TargetFrameworkDirectory
// It basically uses the GAC as the reference assemblies for all .NET framework
// profiles
var targetFrameworkDirectory = frameworkList.Root.Attribute("TargetFrameworkDirectory")?.Value;
IEnumerable<string> populateFromPaths;
if (!string.IsNullOrEmpty(targetFrameworkDirectory))
{
// For some odd reason, the paths are actually listed as \ so normalize them here
@ -370,13 +395,20 @@ namespace Microsoft.DotNet.ProjectModel.Resolution
// Update the path to the framework
frameworkInfo.Path = resovledPath;
PopulateAssemblies(frameworkInfo.Assemblies, resovledPath);
PopulateAssemblies(frameworkInfo.Assemblies, Path.Combine(resovledPath, "Facades"));
populateFromPaths = new List<string>
{
resovledPath,
Path.Combine(resovledPath, "Facades")
};
}
else
{
var emptyFileElements = true;
foreach (var e in frameworkList.Root.Elements())
{
// Remember that we had at least one framework assembly
emptyFileElements = false;
var assemblyName = e.Attribute("AssemblyName").Value;
var version = e.Attribute("Version")?.Value;
@ -384,6 +416,27 @@ namespace Microsoft.DotNet.ProjectModel.Resolution
entry.Version = version != null ? Version.Parse(version) : null;
frameworkInfo.Assemblies[assemblyName] = entry;
}
if (emptyFileElements)
{
// When we haven't found any file elements, we probably processed a
// Mono/Xamarin FrameworkList.xml. That means, that we have to
// populate the assembly list from the files.
populateFromPaths = originalSearchPaths;
}
else
{
populateFromPaths = null;
}
}
// Do we need to populate from search paths?
if (populateFromPaths != null)
{
foreach (var populateFromPath in populateFromPaths)
{
PopulateAssemblies(frameworkInfo.Assemblies, populateFromPath);
}
}
var nameAttribute = frameworkList.Root.Attribute("Name");