| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110 |
- // Licensed to the .NET Foundation under one or more agreements.
- // The .NET Foundation licenses this file to you under the MIT license.
- 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 : Microsoft.Build.Utilities.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}");
- }
- }
- }
- }
- }
|