using System;
using System.IO;
using System.Xml;
using System.Xml.Linq;
using System.Linq;
using System.Reflection;
using System.Collections.Generic;
using Microsoft.Build.Utilities; // Task
using Microsoft.Build.Framework; // MessageImportance
using Microsoft.NET.Build.Tasks; // LockFileCache
using NuGet.ProjectModel; // LockFileTargetLibrary
using NuGet.Frameworks; // NuGetFramework.Parse(targetframework)
namespace ILLink.Tasks
{
public class GetRuntimeLibraries : Task
{
///
/// Path to the assets file.
///
[Required]
public ITaskItem AssetsFilePath { get; set; }
///
/// Target framework for which to get the platform
/// libraries.
///
[Required]
public string TargetFramework { get; set; }
///
/// Runtime identifier for which to get the platform
/// libraries.
///
[Required]
public string RuntimeIdentifier { get; set; }
///
/// Name of the library to consider the "platform"
/// library.
///
[Required]
public string[] PackageNames { get; set; }
[Output]
public ITaskItem[] RuntimeLibraries { get; private set; }
public override bool Execute()
{
var lockFile = new LockFileCache(BuildEngine4).GetLockFile(AssetsFilePath.ItemSpec);
var lockFileTarget = lockFile.GetTarget(NuGetFramework.Parse(TargetFramework), RuntimeIdentifier);
if (lockFileTarget == null) {
var targetString = string.IsNullOrEmpty(RuntimeIdentifier) ? TargetFramework : $"{TargetFramework}/{RuntimeIdentifier}";
throw new Exception($"Missing target section {targetString} from assets file {AssetsFilePath}. Ensure you have restored this project previously.");
}
Dictionary packages = new Dictionary(lockFileTarget.Libraries.Count, StringComparer.OrdinalIgnoreCase);
foreach (var lib in lockFileTarget.Libraries) {
packages.Add(lib.Name, lib);
}
HashSet packageNames = new HashSet(PackageNames);
var rootPackages = lockFileTarget.Libraries.Where(l => packageNames.Contains(l.Name));
var packageQueue = new Queue(rootPackages);
var libraries = new List();
while (packageQueue.Count > 0) {
var package = packageQueue.Dequeue();
foreach (var lib in package.RuntimeAssemblies) {
libraries.Add(lib.ToString());
}
foreach (var dep in package.Dependencies.Select(d => d.Id)) {
packageQueue.Enqueue(packages[dep]);
}
}
RuntimeLibraries = libraries.Select(l => new TaskItem(l)).ToArray();
return true;
}
}
}