| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143 |
- // 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.Diagnostics;
- using System.IO;
- using System.Linq;
- using System.Xml.Linq;
- using Microsoft.Build.Framework;
- using Microsoft.Build.Utilities;
- namespace RepoTasks;
- public class CreateFrameworkListFile : Microsoft.Build.Utilities.Task
- {
- /// <summary>
- /// Files to extract basic information from and include in the list.
- /// </summary>
- [Required]
- public ITaskItem[] Files { get; set; }
- [Required]
- public string TargetFile { get; set; }
- /// <summary>
- /// Extra attributes to place on the root node.
- ///
- /// %(Identity): Attribute name.
- /// %(Value): Attribute value.
- /// </summary>
- public ITaskItem[] RootAttributes { get; set; }
- public override bool Execute()
- {
- XAttribute[] rootAttributes = RootAttributes
- ?.Select(item => new XAttribute(item.ItemSpec, item.GetMetadata("Value")))
- .ToArray();
- var frameworkManifest = new XElement("FileList", rootAttributes);
- var usedFileProfiles = new HashSet<string>();
- foreach (var f in Files
- .Select(item => new
- {
- Item = item,
- Filename = Path.GetFileName(item.ItemSpec),
- AssemblyName = FileUtilities.GetAssemblyName(item.ItemSpec),
- FileVersion = FileUtilities.GetFileVersion(item.ItemSpec),
- IsNative = item.GetMetadata("IsNativeImage") == "true",
- IsSymbolFile = item.GetMetadata("IsSymbolFile") == "true",
- PackagePath = GetPackagePath(item)
- })
- .Where(f =>
- !f.IsSymbolFile &&
- (f.Filename.EndsWith(".dll", StringComparison.OrdinalIgnoreCase) || f.IsNative))
- .OrderBy(f => f.Filename, StringComparer.Ordinal))
- {
- string path = Path.Combine(f.PackagePath, f.Filename).Replace('\\', '/');
- string type = f.IsNative ? "Native" : "Managed";
- var element = new XElement("File", new XAttribute("Path", path));
- if (path.StartsWith("analyzers/", StringComparison.Ordinal))
- {
- type = "Analyzer";
- if (path.EndsWith(".resources.dll", StringComparison.Ordinal))
- {
- // omit analyzer resources
- continue;
- }
- var pathParts = path.Split('/');
- if (pathParts.Length < 3 || !pathParts[1].Equals("dotnet", StringComparison.Ordinal) || pathParts.Length > 5)
- {
- Log.LogError($"Unexpected analyzer path format {path}. Expected 'analyzers/dotnet(/roslyn<version>)(/language)/analyzer.dll");
- }
- // Check if we have enough parts for language directory and include it.
- // There could be a roslyn<version> folder before the language folder. Check for it.
- bool hasRoslynVersion = pathParts[2].StartsWith("roslyn", StringComparison.Ordinal);
- int languageLengthCheck = hasRoslynVersion ? 4 : 3;
- int potentialLanguageIndex = hasRoslynVersion ? 3 : 2;
- if (pathParts.Length > languageLengthCheck)
- {
- element.Add(new XAttribute("Language", pathParts[potentialLanguageIndex]));
- }
- }
- element.Add(new XAttribute("Type", type));
- if (f.AssemblyName != null)
- {
- byte[] publicKeyToken = f.AssemblyName.GetPublicKeyToken();
- string publicKeyTokenHex;
- if (publicKeyToken != null)
- {
- publicKeyTokenHex = BitConverter.ToString(publicKeyToken)
- .ToLowerInvariant()
- .Replace("-", "");
- }
- else
- {
- Log.LogError($"No public key token found for assembly {f.Item.ItemSpec}");
- publicKeyTokenHex = "";
- }
- element.Add(
- new XAttribute("AssemblyName", f.AssemblyName.Name),
- new XAttribute("PublicKeyToken", publicKeyTokenHex),
- new XAttribute("AssemblyVersion", f.AssemblyName.Version));
- }
- else if (!f.IsNative)
- {
- // This file isn't managed and isn't native. Leave it off the list.
- continue;
- }
- element.Add(new XAttribute("FileVersion", f.FileVersion));
- frameworkManifest.Add(element);
- }
- Directory.CreateDirectory(Path.GetDirectoryName(TargetFile));
- File.WriteAllText(TargetFile, frameworkManifest.ToString());
- return !Log.HasLoggedErrors;
- }
- private static string GetPackagePath(ITaskItem item)
- {
- string packagePath = item.GetMetadata("PackagePath");
- // replicate the logic used by PackTask https://github.com/NuGet/NuGet.Client/blob/f24bad0668193ce21a1db8cabd1ce95ba509c7f0/src/NuGet.Core/NuGet.Build.Tasks.Pack/PackTaskLogic.cs#L644-L647
- string recursiveDir = item.GetMetadata("RecursiveDir");
- recursiveDir = string.IsNullOrEmpty(recursiveDir) ? item.GetMetadata("NuGetRecursiveDir") : recursiveDir;
- return string.IsNullOrEmpty(recursiveDir) ? packagePath :
- Path.Combine(packagePath, recursiveDir);
- }
- }
|