From edabe4e093be07d9abd62270e1c1dfbb7fd4f707 Mon Sep 17 00:00:00 2001 From: Davis Goodin Date: Fri, 5 Apr 2019 12:06:18 -0500 Subject: [PATCH] Enforce that DLL/EXEs in platform manifest have a FileVersion (dotnet/core-setup#5682) * Enforce DLL/EXEs in platform manifest have version * Allow zero/missing versions on non-Windows Commit migrated from https://github.com/dotnet/core-setup/commit/851859e9e07eda7adb2dcf129b0d6fb3cab411e3 --- src/installer/pkg/projects/dir.targets | 11 ++++- .../pkg/projects/windowsdesktop/dir.props | 11 +++++ tools-local/tasks/GenerateFileVersionProps.cs | 50 ++++++++++++++++++---- 3 files changed, 63 insertions(+), 9 deletions(-) diff --git a/src/installer/pkg/projects/dir.targets b/src/installer/pkg/projects/dir.targets index f8ca13a..3719ef4 100644 --- a/src/installer/pkg/projects/dir.targets +++ b/src/installer/pkg/projects/dir.targets @@ -158,12 +158,21 @@ + + + true + + + PreferredPackages="$(Id);@(RuntimeDependency)" + PermitDllAndExeFilesLackingFileVersion="$(PermitDllAndExeFilesLackingFileVersion)" /> Microsoft.WindowsDesktop.App + + + true diff --git a/tools-local/tasks/GenerateFileVersionProps.cs b/tools-local/tasks/GenerateFileVersionProps.cs index b306d4d..a8cfdb8 100644 --- a/tools-local/tasks/GenerateFileVersionProps.cs +++ b/tools-local/tasks/GenerateFileVersionProps.cs @@ -2,18 +2,21 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System; +using Microsoft.Build.Construction; using Microsoft.Build.Framework; -using System.IO; +using System; using System.Collections.Generic; -using Microsoft.Build.Construction; +using System.IO; +using System.Linq; namespace Microsoft.DotNet.Build.Tasks { public partial class GenerateFileVersionProps : BuildTask { - const string PlatformManifestsItem = "PackageConflictPlatformManifests"; - const string PreferredPackagesProperty = "PackageConflictPreferredPackages"; + private const string PlatformManifestsItem = "PackageConflictPlatformManifests"; + private const string PreferredPackagesProperty = "PackageConflictPreferredPackages"; + private static readonly Version ZeroVersion = new Version(0, 0, 0, 0); + [Required] public ITaskItem[] Files { get; set; } @@ -33,6 +36,12 @@ namespace Microsoft.DotNet.Build.Tasks [Required] public string PreferredPackages { get; set; } + /// + /// The task normally enforces that all DLL and EXE files have a non-0.0.0.0 FileVersion. + /// This flag disables the check. + /// + public bool PermitDllAndExeFilesLackingFileVersion { get; set; } + public override bool Execute() { var fileVersions = new Dictionary(StringComparer.OrdinalIgnoreCase); @@ -90,6 +99,28 @@ namespace Microsoft.DotNet.Build.Tasks } } + // Check for versionless files after all duplicate filenames are resolved, rather than + // logging errors immediately upon encountering a versionless file. There may be + // duplicate filenames where only one has a version, and this is ok. The highest version + // is used. + if (!PermitDllAndExeFilesLackingFileVersion) + { + var versionlessFiles = fileVersions + .Where(p => + p.Key.EndsWith(".exe", StringComparison.OrdinalIgnoreCase) || + p.Key.EndsWith(".dll", StringComparison.OrdinalIgnoreCase)) + .Where(p => (p.Value.FileVersion ?? ZeroVersion) == ZeroVersion) + .Select(p => p.Value.File.ItemSpec) + .ToArray(); + + if (versionlessFiles.Any()) + { + Log.LogError( + $"Missing FileVersion in {versionlessFiles.Length} shared framework files:" + + string.Concat(versionlessFiles.Select(f => Environment.NewLine + f))); + } + } + var props = ProjectRootElement.Create(); var itemGroup = props.AddItemGroup(); // set the platform manifest when the platform is not being published as part of the app @@ -132,7 +163,8 @@ namespace Microsoft.DotNet.Build.Tasks return new FileVersionData() { AssemblyVersion = FileUtilities.GetAssemblyName(filePath)?.Version, - FileVersion = FileUtilities.GetFileVersion(filePath) + FileVersion = FileUtilities.GetFileVersion(filePath), + File = file }; } else @@ -147,13 +179,14 @@ namespace Microsoft.DotNet.Build.Tasks { // FileVersionInfo will return 0.0.0.0 if a file doesn't have a version. // match that behavior - fileVersion = new Version(0, 0, 0, 0); + fileVersion = ZeroVersion; } return new FileVersionData() { AssemblyVersion = assemblyVersion, - FileVersion = fileVersion + FileVersion = fileVersion, + File = file }; } } @@ -162,6 +195,7 @@ namespace Microsoft.DotNet.Build.Tasks { public Version AssemblyVersion { get; set; } public Version FileVersion { get; set; } + public ITaskItem File { get; set; } } } } -- 2.7.4