-
Notifications
You must be signed in to change notification settings - Fork 359
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add generate shared framework manifest target, inverse xunit analyzer…
…, reference Test SDK correctly (#3139) * Inverse xunit analyzer, ref vstest correctly * Add generate framework manifest target * Code cleanup in uap * Use a higher version of Newtonsoft.Json * Hide RemoteExecutor include files in VS
- Loading branch information
1 parent
e350d32
commit d412d2b
Showing
9 changed files
with
308 additions
and
56 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
// 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. | ||
|
||
// Copied from https://github.com/dotnet/core-setup/blob/b73c0af268be449db317a7c0718012027cd8b173/tools-local/tasks/FileUtilities.cs | ||
|
||
using System; | ||
using System.Collections.Generic; | ||
using System.Diagnostics; | ||
using System.IO; | ||
using System.Reflection; | ||
|
||
namespace Microsoft.DotNet.Build.Tasks | ||
{ | ||
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); | ||
|
||
if (fvi != null) | ||
{ | ||
return new Version(fvi.FileMajorPart, fvi.FileMinorPart, fvi.FileBuildPart, fvi.FilePrivatePart); | ||
} | ||
|
||
return null; | ||
} | ||
|
||
public static AssemblyName GetAssemblyName(string path) | ||
{ | ||
if (!s_assemblyExtensions.Contains(Path.GetExtension(path))) | ||
{ | ||
return null; | ||
} | ||
|
||
try | ||
{ | ||
return AssemblyName.GetAssemblyName(path); | ||
} | ||
catch (BadImageFormatException) | ||
{ | ||
// Not a valid assembly. | ||
return null; | ||
} | ||
} | ||
} | ||
} |
210 changes: 210 additions & 0 deletions
210
src/Microsoft.DotNet.CoreFxTesting/GenerateFileVersionProps.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,210 @@ | ||
// 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. | ||
|
||
// Copied and slightly modified from https://github.com/dotnet/core-setup/blob/b73c0af268be449db317a7c0718012027cd8b173/tools-local/tasks/GenerateFileVersionProps.cs | ||
|
||
using Microsoft.Build.Construction; | ||
using Microsoft.Build.Framework; | ||
using System; | ||
using System.Collections.Generic; | ||
using System.IO; | ||
using System.Linq; | ||
|
||
namespace Microsoft.DotNet.Build.Tasks | ||
{ | ||
public partial class GenerateFileVersionProps : BuildTask | ||
{ | ||
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; } | ||
|
||
[Required] | ||
public string PackageId { get; set; } | ||
|
||
[Required] | ||
public string PackageVersion { get; set; } | ||
|
||
[Required] | ||
public string PlatformManifestFile { get; set; } | ||
|
||
public string PropsFile { get; set; } | ||
|
||
[Required] | ||
public string PreferredPackages { get; set; } | ||
|
||
/// <summary> | ||
/// The task normally enforces that all DLL and EXE files have a non-0.0.0.0 FileVersion. | ||
/// This flag disables the check. | ||
/// </summary> | ||
public bool PermitDllAndExeFilesLackingFileVersion { get; set; } | ||
|
||
public override bool Execute() | ||
{ | ||
var fileVersions = new Dictionary<string, FileVersionData>(StringComparer.OrdinalIgnoreCase); | ||
foreach(var file in Files) | ||
{ | ||
var targetPath = file.GetMetadata("TargetPath"); | ||
|
||
if (!targetPath.StartsWith("runtimes/")) | ||
{ | ||
continue; | ||
} | ||
|
||
if (file.GetMetadata("IsSymbolFile").Equals("true", StringComparison.OrdinalIgnoreCase)) | ||
{ | ||
continue; | ||
} | ||
|
||
var fileName = Path.GetFileName(file.ItemSpec); | ||
|
||
var current = GetFileVersionData(file); | ||
|
||
FileVersionData existing; | ||
|
||
if (fileVersions.TryGetValue(fileName, out existing)) | ||
{ | ||
if (current.AssemblyVersion != null) | ||
{ | ||
if (existing.AssemblyVersion == null) | ||
{ | ||
fileVersions[fileName] = current; | ||
continue; | ||
} | ||
else if (current.AssemblyVersion != existing.AssemblyVersion) | ||
{ | ||
if (current.AssemblyVersion > existing.AssemblyVersion) | ||
{ | ||
fileVersions[fileName] = current; | ||
} | ||
continue; | ||
} | ||
} | ||
|
||
if (current.FileVersion != null && | ||
existing.FileVersion != null) | ||
{ | ||
if (current.FileVersion > existing.FileVersion) | ||
{ | ||
fileVersions[fileName] = current; | ||
} | ||
} | ||
} | ||
else | ||
{ | ||
fileVersions[fileName] = current; | ||
} | ||
} | ||
|
||
// 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))); | ||
} | ||
} | ||
|
||
bool generatePropsFile = !string.IsNullOrWhiteSpace(PropsFile); | ||
ProjectRootElement props = null; | ||
|
||
if (generatePropsFile) | ||
{ | ||
props = ProjectRootElement.Create(); | ||
var itemGroup = props.AddItemGroup(); | ||
// set the platform manifest when the platform is not being published as part of the app | ||
itemGroup.Condition = "'$(RuntimeIdentifier)' == '' or '$(SelfContained)' != 'true'"; | ||
|
||
var manifestFileName = Path.GetFileName(PlatformManifestFile); | ||
itemGroup.AddItem(PlatformManifestsItem, $"$(MSBuildThisFileDirectory){manifestFileName}"); | ||
} | ||
|
||
Directory.CreateDirectory(Path.GetDirectoryName(PlatformManifestFile)); | ||
using (var manifestWriter = File.CreateText(PlatformManifestFile)) | ||
{ | ||
foreach (var fileData in fileVersions) | ||
{ | ||
var name = fileData.Key; | ||
var versions = fileData.Value; | ||
var assemblyVersion = versions.AssemblyVersion?.ToString() ?? String.Empty; | ||
var fileVersion = versions.FileVersion?.ToString() ?? String.Empty; | ||
|
||
manifestWriter.WriteLine($"{name}|{PackageId}|{assemblyVersion}|{fileVersion}"); | ||
} | ||
} | ||
|
||
if (!string.IsNullOrWhiteSpace(PropsFile)) | ||
{ | ||
var propertyGroup = props.AddPropertyGroup(); | ||
propertyGroup.AddProperty(PreferredPackagesProperty, PreferredPackages); | ||
|
||
var versionPropertyName = $"_{PackageId.Replace(".", "_")}_Version"; | ||
propertyGroup.AddProperty(versionPropertyName, PackageVersion); | ||
|
||
props.Save(PropsFile); | ||
} | ||
|
||
return !Log.HasLoggedErrors; | ||
} | ||
|
||
FileVersionData GetFileVersionData(ITaskItem file) | ||
{ | ||
var filePath = file.GetMetadata("FullPath"); | ||
|
||
if (File.Exists(filePath)) | ||
{ | ||
return new FileVersionData() | ||
{ | ||
AssemblyVersion = FileUtilities.GetAssemblyName(filePath)?.Version, | ||
FileVersion = FileUtilities.GetFileVersion(filePath), | ||
File = file | ||
}; | ||
} | ||
else | ||
{ | ||
// allow for the item to specify version directly | ||
Version assemblyVersion, fileVersion; | ||
|
||
Version.TryParse(file.GetMetadata("AssemblyVersion"), out assemblyVersion); | ||
Version.TryParse(file.GetMetadata("FileVersion"), out fileVersion); | ||
|
||
if (fileVersion == null) | ||
{ | ||
// FileVersionInfo will return 0.0.0.0 if a file doesn't have a version. | ||
// match that behavior | ||
fileVersion = ZeroVersion; | ||
} | ||
|
||
return new FileVersionData() | ||
{ | ||
AssemblyVersion = assemblyVersion, | ||
FileVersion = fileVersion, | ||
File = file | ||
}; | ||
} | ||
} | ||
|
||
class FileVersionData | ||
{ | ||
public Version AssemblyVersion { get; set; } | ||
public Version FileVersion { get; set; } | ||
public ITaskItem File { get; set; } | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.