Create framework assembly list file in .NET Core targeting pack (dotnet/core-setup...
authorDavis Goodin <dagood@users.noreply.github.com>
Thu, 14 Feb 2019 17:12:56 +0000 (11:12 -0600)
committerGitHub <noreply@github.com>
Thu, 14 Feb 2019 17:12:56 +0000 (11:12 -0600)
* Create framework assembly list file

* Fix FileUtilities private static style

* Remove package ID prefix from PlatformManifest.txt

* Proactively detect/report missing public key token

Commit migrated from https://github.com/dotnet/core-setup/commit/493c6287a2bd54c41a71cc88cbfb7c8ee06ee812

src/installer/pkg/projects/Microsoft.NETCore.App.Ref/Microsoft.NETCore.App.Ref.pkgproj
src/installer/pkg/projects/dir.props
src/installer/pkg/projects/dir.targets
tools-local/tasks/CreateFrameworkListFile.cs [new file with mode: 0644]
tools-local/tasks/FileUtilities.cs
tools-local/tasks/GenerateFileVersionProps.cs

index f61dce0..d53fc43 100644 (file)
@@ -9,7 +9,8 @@
     <SkipValidatePackage>true</SkipValidatePackage>
 
     <!-- Include the platform manifest in the data dir. -->
-    <PlatformManifestTargetPath>data/</PlatformManifestTargetPath>
+    <PlatformManifestTargetPath>data/PlatformManifest.txt</PlatformManifestTargetPath>
+    <FrameworkListTargetPath>data/</FrameworkListTargetPath>
 
     <!-- Exclude runtime.json from the package. -->
     <IncludeRuntimeJson>false</IncludeRuntimeJson>
index b240b5b..723bca6 100644 (file)
     <PackProjectDependencies>true</PackProjectDependencies>
   </PropertyGroup>
 
+  <ItemGroup>
+    <FrameworkListRootAttributes Include="Name" Value="$(NETCoreAppFrameworkBrandName)" />
+    <FrameworkListRootAttributes Include="TargetFrameworkIdentifier" Value="$(NETCoreAppFrameworkIdentifier)" />
+    <FrameworkListRootAttributes Include="TargetFrameworkVersion" Value="$(NETCoreAppFrameworkVersion)" />
+    <FrameworkListRootAttributes Include="FrameworkName" Value="$(SharedFrameworkName)" />
+  </ItemGroup>
+
   <PropertyGroup Condition="'$(PackageTargetRuntime)' == ''">
     <SkipValidatePackage>true</SkipValidatePackage>
     <IncludeRuntimeJson>true</IncludeRuntimeJson>
index 03da4f3..80333f3 100644 (file)
@@ -1,6 +1,7 @@
 <Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <Import Project="..\dir.targets" />
 
+  <UsingTask TaskName="CreateFrameworkListFile" AssemblyFile="$(LocalBuildToolsTaskDir)core-setup.tasks.dll"/>
   <UsingTask TaskName="GenerateFileVersionProps" AssemblyFile="$(LocalBuildToolsTaskDir)core-setup.tasks.dll"/>
 
   <PropertyGroup>
     </ItemGroup>
   </Target>
 
+  <Target Name="IncludeFrameworkListFile"
+          BeforeTargets="GetFiles"
+          Condition="'$(PackageTargetRuntime)' == '' AND '$(FrameworkListTargetPath)' != ''">
+    <PropertyGroup>
+      <FrameworkListFile>$(IntermediateOutputPath)FrameworkList.xml</FrameworkListFile>
+    </PropertyGroup>
+
+    <CreateFrameworkListFile
+      Files="@(File)"
+      TargetFile="$(FrameworkListFile)"
+      RootAttributes="@(FrameworkListRootAttributes)" />
+
+    <ItemGroup>
+      <File Include="$(FrameworkListFile)">
+        <TargetPath>$(FrameworkListTargetPath)</TargetPath>
+      </File>
+    </ItemGroup>
+  </Target>
+
 </Project>
\ No newline at end of file
diff --git a/tools-local/tasks/CreateFrameworkListFile.cs b/tools-local/tasks/CreateFrameworkListFile.cs
new file mode 100644 (file)
index 0000000..37e5aff
--- /dev/null
@@ -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
+    {
+        /// <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);
+
+            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;
+        }
+    }
+}
index e1f0461..40691ae 100644 (file)
@@ -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<string> s_assemblyExtensions = new HashSet<string>(
+            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<string> s_assemblyExtensions = new HashSet<string>(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;
             }
         }
index 7e89cf6..b306d4d 100644 (file)
@@ -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)
                 };
             }