112 lines
4.8 KiB
C#
112 lines
4.8 KiB
C#
// Copyright (c) .NET Foundation. All rights reserved.
|
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.IO.Compression;
|
|
using System.Linq;
|
|
using System.Xml;
|
|
using System.Xml.Linq;
|
|
using Microsoft.Build.Framework;
|
|
using Microsoft.Build.Utilities;
|
|
using NuGet.Frameworks;
|
|
using NuGet.Packaging;
|
|
using NuGet.Packaging.Core;
|
|
|
|
namespace RepoTasks
|
|
{
|
|
// This is temporary until we can use FrameworkReference to build our own packages
|
|
public class RemoveSharedFrameworkDependencies : Task
|
|
{
|
|
[Required]
|
|
public ITaskItem[] Files { get; set; }
|
|
|
|
[Required]
|
|
public ITaskItem[] FrameworkOnlyPackages { get; set; }
|
|
|
|
[Required]
|
|
public string SharedFrameworkTargetFramework { get; set; }
|
|
|
|
public override bool Execute()
|
|
{
|
|
Log.LogMessage("NuGet version = " + typeof(PackageArchiveReader).Assembly.GetName().Version);
|
|
var dependencyToRemove = new HashSet<string>(FrameworkOnlyPackages.Select(p => p.ItemSpec), StringComparer.OrdinalIgnoreCase);
|
|
|
|
foreach (var file in Files)
|
|
{
|
|
FilterDependencies(file.ItemSpec, dependencyToRemove);
|
|
}
|
|
return !Log.HasLoggedErrors;
|
|
}
|
|
|
|
private void FilterDependencies(string targetPath, ISet<string> dependencyToRemove)
|
|
{
|
|
var fileName = Path.GetFileName(targetPath);
|
|
Log.LogMessage($"Updating {fileName}");
|
|
|
|
using (var fileStream = File.Open(targetPath, FileMode.Open))
|
|
using (var package = new ZipArchive(fileStream, ZipArchiveMode.Update))
|
|
using (var packageReader = new PackageArchiveReader(fileStream, leaveStreamOpen: true))
|
|
{
|
|
var referencesFrameworkOnlyAssembly = false;
|
|
var nuspecFile = packageReader.GetNuspecFile();
|
|
using (var stream = package.OpenFile(nuspecFile))
|
|
{
|
|
var reader = Manifest.ReadFrom(stream, validateSchema: true);
|
|
stream.Position = 0;
|
|
var packageBuilder = new PackageBuilder(stream, basePath: null);
|
|
var updatedGroups = new List<PackageDependencyGroup>();
|
|
|
|
foreach (var group in packageBuilder.DependencyGroups)
|
|
{
|
|
var packages = new List<PackageDependency>();
|
|
var updatedGroup = new PackageDependencyGroup(group.TargetFramework, packages);
|
|
foreach (var dependency in group.Packages)
|
|
{
|
|
if (dependencyToRemove.Contains(dependency.Id))
|
|
{
|
|
referencesFrameworkOnlyAssembly = true;
|
|
Log.LogMessage($" Remove dependency on '{dependency.Id}'");
|
|
continue;
|
|
}
|
|
|
|
packages.Add(dependency);
|
|
}
|
|
|
|
updatedGroups.Add(updatedGroup);
|
|
}
|
|
|
|
if (referencesFrameworkOnlyAssembly)
|
|
{
|
|
packageBuilder.DependencyGroups.Clear();
|
|
packageBuilder.DependencyGroups.AddRange(updatedGroups);
|
|
|
|
var updatedManifest = Manifest.Create(packageBuilder);
|
|
var inMemory = new MemoryStream();
|
|
updatedManifest.Save(inMemory);
|
|
inMemory.Position = 0;
|
|
// Hack the raw nuspec to add the <frameworkReference> dependency
|
|
var rawNuspec = XDocument.Load(inMemory, LoadOptions.PreserveWhitespace);
|
|
var ns = rawNuspec.Root.GetDefaultNamespace();
|
|
var metadata = rawNuspec.Root.Descendants(ns + "metadata").Single();
|
|
metadata.Add(
|
|
new XElement(ns + "frameworkReferences",
|
|
new XElement(ns + "group",
|
|
new XAttribute("targetFramework", NuGetFramework.Parse(SharedFrameworkTargetFramework).GetFrameworkString()),
|
|
new XElement(ns + "frameworkReference", new XAttribute("name", "Microsoft.AspNetCore.App")))));
|
|
stream.Position = 0;
|
|
stream.SetLength(0);
|
|
rawNuspec.Save(stream);
|
|
Log.LogMessage(MessageImportance.High, "Added <frameworkReference> to {0}", fileName);
|
|
}
|
|
else
|
|
{
|
|
Log.LogMessage($"No changes made to {fileName}");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|