From 493c6287a2bd54c41a71cc88cbfb7c8ee06ee812 Mon Sep 17 00:00:00 2001 From: Davis Goodin Date: Thu, 14 Feb 2019 11:12:56 -0600 Subject: [PATCH] Create framework assembly list file in .NET Core targeting pack (#5168) * Create framework assembly list file * Fix FileUtilities private static style * Remove package ID prefix from PlatformManifest.txt * Proactively detect/report missing public key token --- dir.props | 7 +- .../Microsoft.NETCore.App.Ref.pkgproj | 3 +- src/pkg/projects/dir.props | 7 ++ src/pkg/projects/dir.targets | 20 +++++ tools-local/tasks/CreateFrameworkListFile.cs | 82 +++++++++++++++++++ tools-local/tasks/FileUtilities.cs | 21 +++-- tools-local/tasks/GenerateFileVersionProps.cs | 2 +- 7 files changed, 129 insertions(+), 13 deletions(-) create mode 100644 tools-local/tasks/CreateFrameworkListFile.cs diff --git a/dir.props b/dir.props index 751ec7ca..20b23c00 100644 --- a/dir.props +++ b/dir.props @@ -33,8 +33,11 @@ Microsoft.NETCore.App - .NETCoreApp,Version=v$(MajorVersion).$(MinorVersion) - netcoreapp$(MajorVersion).$(MinorVersion) + .NETCoreApp + $(MajorVersion).$(MinorVersion) + $(NETCoreAppFrameworkIdentifier),Version=v$(NETCoreAppFrameworkVersion) + netcoreapp$(NETCoreAppFrameworkVersion) + .NET Core $(NETCoreAppFrameworkVersion) - data/ + data/PlatformManifest.txt + data/ false diff --git a/src/pkg/projects/dir.props b/src/pkg/projects/dir.props index b240b5b5..723bca6c 100644 --- a/src/pkg/projects/dir.props +++ b/src/pkg/projects/dir.props @@ -20,6 +20,13 @@ true + + + + + + + true true diff --git a/src/pkg/projects/dir.targets b/src/pkg/projects/dir.targets index 03da4f32..80333f3f 100644 --- a/src/pkg/projects/dir.targets +++ b/src/pkg/projects/dir.targets @@ -1,6 +1,7 @@ + @@ -180,4 +181,23 @@ + + + $(IntermediateOutputPath)FrameworkList.xml + + + + + + + $(FrameworkListTargetPath) + + + + \ No newline at end of file diff --git a/tools-local/tasks/CreateFrameworkListFile.cs b/tools-local/tasks/CreateFrameworkListFile.cs new file mode 100644 index 00000000..37e5affb --- /dev/null +++ b/tools-local/tasks/CreateFrameworkListFile.cs @@ -0,0 +1,82 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Microsoft.Build.Framework; +using System; +using System.IO; +using System.Linq; +using System.Xml.Linq; + +namespace Microsoft.DotNet.Build.Tasks +{ + public class CreateFrameworkListFile : BuildTask + { + /// + /// Files to extract basic information from and include in the list. + /// + [Required] + public ITaskItem[] Files { get; set; } + + [Required] + public string TargetFile { get; set; } + + /// + /// Extra attributes to place on the root node. + /// + /// %(Identity): Attribute name. + /// %(Value): Attribute value. + /// + 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); + + foreach (var f in Files + .Where(item => + item.GetMetadata("TargetPath")?.StartsWith("data/") == true && + item.ItemSpec.EndsWith(".dll", StringComparison.OrdinalIgnoreCase)) + .Select(item => new + { + Item = item, + AssemblyName = FileUtilities.GetAssemblyName(item.ItemSpec), + FileVersion = FileUtilities.GetFileVersion(item.ItemSpec) + }) + .Where(f => f.AssemblyName != null) + .OrderBy(f => f.Item.ItemSpec, StringComparer.OrdinalIgnoreCase)) + { + 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 = ""; + } + + frameworkManifest.Add(new XElement( + "File", + new XAttribute("AssemblyName", f.AssemblyName.Name), + new XAttribute("PublicKeyToken", publicKeyTokenHex), + new XAttribute("AssemblyVersion", f.AssemblyName.Version), + new XAttribute("FileVersion", f.FileVersion))); + } + + Directory.CreateDirectory(Path.GetDirectoryName(TargetFile)); + File.WriteAllText(TargetFile, frameworkManifest.ToString()); + + return !Log.HasLoggedErrors; + } + } +} diff --git a/tools-local/tasks/FileUtilities.cs b/tools-local/tasks/FileUtilities.cs index e1f04613..40691aeb 100644 --- a/tools-local/tasks/FileUtilities.cs +++ b/tools-local/tasks/FileUtilities.cs @@ -10,8 +10,12 @@ using System.Reflection; namespace Microsoft.DotNet.Build.Tasks { - static partial class FileUtilities + internal static partial class FileUtilities { + private static readonly HashSet s_assemblyExtensions = new HashSet( + new[] { ".dll", ".exe", ".winmd" }, + StringComparer.OrdinalIgnoreCase); + public static Version GetFileVersion(string sourcePath) { var fvi = FileVersionInfo.GetVersionInfo(sourcePath); @@ -24,21 +28,20 @@ namespace Microsoft.DotNet.Build.Tasks return null; } - static readonly HashSet s_assemblyExtensions = new HashSet(new[] { ".dll", ".exe", ".winmd" }, StringComparer.OrdinalIgnoreCase); - public static Version TryGetAssemblyVersion(string sourcePath) + public static AssemblyName GetAssemblyName(string path) { - var extension = Path.GetExtension(sourcePath); + if (!s_assemblyExtensions.Contains(Path.GetExtension(path))) + { + return null; + } - return s_assemblyExtensions.Contains(extension) ? GetAssemblyVersion(sourcePath) : null; - } - private static Version GetAssemblyVersion(string sourcePath) - { try { - return AssemblyName.GetAssemblyName(sourcePath)?.Version; + return AssemblyName.GetAssemblyName(path); } catch (BadImageFormatException) { + // Not a valid assembly. return null; } } diff --git a/tools-local/tasks/GenerateFileVersionProps.cs b/tools-local/tasks/GenerateFileVersionProps.cs index 7e89cf6e..b306d4d3 100644 --- a/tools-local/tasks/GenerateFileVersionProps.cs +++ b/tools-local/tasks/GenerateFileVersionProps.cs @@ -131,7 +131,7 @@ namespace Microsoft.DotNet.Build.Tasks { return new FileVersionData() { - AssemblyVersion = FileUtilities.TryGetAssemblyVersion(filePath), + AssemblyVersion = FileUtilities.GetAssemblyName(filePath)?.Version, FileVersion = FileUtilities.GetFileVersion(filePath) }; }