From ae61a1daf2042655e167874c3d70d04b8cb92a3c Mon Sep 17 00:00:00 2001 From: Viktor Hofer Date: Tue, 14 Jan 2025 10:49:14 +0100 Subject: [PATCH 1/4] Add Message to suppressions and simplify ISuppressibleLog --- .../SuppressibleMSBuildLog.cs | 8 +- .../SuppressibleConsoleLog.cs | 8 +- .../Logging/ISuppressibleLog.cs | 12 +-- .../Logging/Suppression.cs | 10 +++ .../Logging/SuppressionEngine.cs | 6 +- .../Runner/ApiCompatRunner.cs | 17 ++-- .../ApiCompatRunnerExtensions.cs | 6 +- .../Validators/BaselinePackageValidator.cs | 26 +++--- .../Validators/CompatibleTFMValidator.cs | 20 +++-- .../Logging/SuppressionEngineTests.cs | 79 +++++++++---------- .../Logging/SuppressionTests.cs | 44 +++++------ .../Logging/TestSuppressionEngine.cs | 9 +++ .../SuppressibleTestLog.cs | 8 +- 13 files changed, 129 insertions(+), 124 deletions(-) diff --git a/src/Compatibility/ApiCompat/Microsoft.DotNet.ApiCompat.Task/SuppressibleMSBuildLog.cs b/src/Compatibility/ApiCompat/Microsoft.DotNet.ApiCompat.Task/SuppressibleMSBuildLog.cs index 0dda7cfe46cc..749611577668 100644 --- a/src/Compatibility/ApiCompat/Microsoft.DotNet.ApiCompat.Task/SuppressibleMSBuildLog.cs +++ b/src/Compatibility/ApiCompat/Microsoft.DotNet.ApiCompat.Task/SuppressibleMSBuildLog.cs @@ -16,24 +16,24 @@ internal sealed class SuppressibleMSBuildLog(NET.Build.Tasks.Logger log, public bool HasLoggedErrorSuppressions { get; private set; } /// - public bool LogError(Suppression suppression, string code, string message) + public bool LogError(Suppression suppression) { if (suppressionEngine.IsErrorSuppressed(suppression)) return false; HasLoggedErrorSuppressions = true; - LogError(code, message); + LogError(suppression.DiagnosticId, suppression.Message); return true; } /// - public bool LogWarning(Suppression suppression, string code, string message) + public bool LogWarning(Suppression suppression) { if (suppressionEngine.IsErrorSuppressed(suppression)) return false; - LogWarning(code, message); + LogWarning(suppression.DiagnosticId, suppression.Message); return true; } diff --git a/src/Compatibility/ApiCompat/Microsoft.DotNet.ApiCompat.Tool/SuppressibleConsoleLog.cs b/src/Compatibility/ApiCompat/Microsoft.DotNet.ApiCompat.Tool/SuppressibleConsoleLog.cs index 4bda2be1f799..0ae477ad9c52 100644 --- a/src/Compatibility/ApiCompat/Microsoft.DotNet.ApiCompat.Tool/SuppressibleConsoleLog.cs +++ b/src/Compatibility/ApiCompat/Microsoft.DotNet.ApiCompat.Tool/SuppressibleConsoleLog.cs @@ -16,24 +16,24 @@ internal sealed class SuppressibleConsoleLog(ISuppressionEngine suppressionEngin public bool HasLoggedErrorSuppressions { get; private set; } /// - public bool LogError(Suppression suppression, string code, string message) + public bool LogError(Suppression suppression) { if (suppressionEngine.IsErrorSuppressed(suppression)) return false; HasLoggedErrorSuppressions = true; - LogError(code, message); + LogError(suppression.DiagnosticId, suppression.Message); return true; } /// - public bool LogWarning(Suppression suppression, string code, string message) + public bool LogWarning(Suppression suppression) { if (suppressionEngine.IsErrorSuppressed(suppression)) return false; - LogWarning(code, message); + LogWarning(suppression.DiagnosticId, suppression.Message); return true; } diff --git a/src/Compatibility/ApiCompat/Microsoft.DotNet.ApiCompatibility/Logging/ISuppressibleLog.cs b/src/Compatibility/ApiCompat/Microsoft.DotNet.ApiCompatibility/Logging/ISuppressibleLog.cs index c0236bc9c9f3..5dee962cd789 100644 --- a/src/Compatibility/ApiCompat/Microsoft.DotNet.ApiCompatibility/Logging/ISuppressibleLog.cs +++ b/src/Compatibility/ApiCompat/Microsoft.DotNet.ApiCompatibility/Logging/ISuppressibleLog.cs @@ -16,21 +16,17 @@ public interface ISuppressibleLog : ILog bool HasLoggedErrorSuppressions { get; } /// - /// Log an error based on a passed in suppression, code and message. + /// Log an error based on a passed in suppression. /// /// The suppression object which contains the rule information. - /// The suppression code - /// The message /// Returns true if the error is logged and not suppressed. - bool LogError(Suppression suppression, string code, string message); + bool LogError(Suppression suppression); /// - /// Log a warning based on the passed in suppression, code and message. + /// Log a warning based on the passed in suppression. /// /// The suppression object which contains the rule information. - /// The suppression code - /// The message /// Returns true if the warning is logged and not suppressed. - bool LogWarning(Suppression suppression, string code, string message); + bool LogWarning(Suppression suppression); } } diff --git a/src/Compatibility/ApiCompat/Microsoft.DotNet.ApiCompatibility/Logging/Suppression.cs b/src/Compatibility/ApiCompat/Microsoft.DotNet.ApiCompatibility/Logging/Suppression.cs index 1fe0ef1dd7e8..db3270b57ba3 100644 --- a/src/Compatibility/ApiCompat/Microsoft.DotNet.ApiCompatibility/Logging/Suppression.cs +++ b/src/Compatibility/ApiCompat/Microsoft.DotNet.ApiCompatibility/Logging/Suppression.cs @@ -13,6 +13,11 @@ public class Suppression : IEquatable /// public string DiagnosticId { get; set; } + /// + /// The diagnostic message describing the suppression. + /// + public string Message { get; set; } + /// /// The target of where to suppress the /// @@ -37,15 +42,18 @@ public class Suppression : IEquatable private Suppression() { DiagnosticId = string.Empty; + Message = string.Empty; } public Suppression(string diagnosticId, + string message, string? target = null, string? left = null, string? right = null, bool isBaselineSuppression = false) { DiagnosticId = diagnosticId; + Message = message; Target = target; Left = left; Right = right; @@ -74,6 +82,7 @@ public Suppression(string diagnosticId, /// public bool Equals(Suppression? other) { + // Message is intentionally not considered part of the unique object ID as it could contain language specific text. return other != null && AreEqual(DiagnosticId, other.DiagnosticId) && AreEqual(Target, other.Target) && @@ -106,6 +115,7 @@ public override string ToString() } stringBuilder.Append(DiagnosticId); + stringBuilder.Append(": " + Message); stringBuilder.Append(" ("); bool requiresDelimiter = false; diff --git a/src/Compatibility/ApiCompat/Microsoft.DotNet.ApiCompatibility/Logging/SuppressionEngine.cs b/src/Compatibility/ApiCompat/Microsoft.DotNet.ApiCompatibility/Logging/SuppressionEngine.cs index fef506d21bbf..a01b3db85934 100644 --- a/src/Compatibility/ApiCompat/Microsoft.DotNet.ApiCompatibility/Logging/SuppressionEngine.cs +++ b/src/Compatibility/ApiCompat/Microsoft.DotNet.ApiCompatibility/Logging/SuppressionEngine.cs @@ -67,13 +67,13 @@ public bool IsErrorSuppressed(Suppression error) if (error.DiagnosticId.StartsWith("cp", StringComparison.InvariantCultureIgnoreCase)) { // - DiagnosticId, Target, IsBaselineSuppression - Suppression globalTargetSuppression = new(error.DiagnosticId, error.Target, isBaselineSuppression: error.IsBaselineSuppression); + Suppression globalTargetSuppression = new(error.DiagnosticId, error.Message, error.Target, isBaselineSuppression: error.IsBaselineSuppression); // - Left, Right, IsBaselineSuppression - Suppression globalLeftRightSuppression = new(string.Empty, left: error.Left, right: error.Right, isBaselineSuppression: error.IsBaselineSuppression); + Suppression globalLeftRightSuppression = new(string.Empty, string.Empty, left: error.Left, right: error.Right, isBaselineSuppression: error.IsBaselineSuppression); // - DiagnosticId, Left, Right, IsBaselineSuppression - Suppression globalDiagnosticIdLeftRightSuppression = new(error.DiagnosticId, left: error.Left, right: error.Right, isBaselineSuppression: error.IsBaselineSuppression); + Suppression globalDiagnosticIdLeftRightSuppression = new(error.DiagnosticId, error.Message, left: error.Left, right: error.Right, isBaselineSuppression: error.IsBaselineSuppression); if (_suppressions.Contains(globalTargetSuppression) || _suppressions.Contains(globalLeftRightSuppression) || diff --git a/src/Compatibility/ApiCompat/Microsoft.DotNet.ApiCompatibility/Runner/ApiCompatRunner.cs b/src/Compatibility/ApiCompat/Microsoft.DotNet.ApiCompatibility/Runner/ApiCompatRunner.cs index ac567243dbf0..f160b5d03461 100644 --- a/src/Compatibility/ApiCompat/Microsoft.DotNet.ApiCompatibility/Runner/ApiCompatRunner.cs +++ b/src/Compatibility/ApiCompat/Microsoft.DotNet.ApiCompatibility/Runner/ApiCompatRunner.cs @@ -65,13 +65,12 @@ public void ExecuteWorkItems() foreach (CompatDifference difference in differenceGroup) { - Suppression suppression = new(difference.DiagnosticId) - { - Target = difference.ReferenceId, - Left = difference.Left.AssemblyId, - Right = difference.Right.AssemblyId, - IsBaselineSuppression = workItem.Options.IsBaselineComparison - }; + Suppression suppression = new(difference.DiagnosticId, + difference.Message, + difference.ReferenceId, + difference.Left.AssemblyId, + difference.Right.AssemblyId, + workItem.Options.IsBaselineComparison); // If the error is suppressed, don't log anything. if (suppressionEngine.IsErrorSuppressed(suppression)) @@ -87,9 +86,7 @@ public void ExecuteWorkItems() workItem.Options.IsBaselineComparison ? difference.Right.FullPath : "right")); } - log.LogError(suppression, - difference.DiagnosticId, - difference.Message); + log.LogError(suppression); } } } diff --git a/src/Compatibility/ApiCompat/Microsoft.DotNet.PackageValidation/ApiCompatRunnerExtensions.cs b/src/Compatibility/ApiCompat/Microsoft.DotNet.PackageValidation/ApiCompatRunnerExtensions.cs index cd716170e22f..7b78921787e4 100644 --- a/src/Compatibility/ApiCompat/Microsoft.DotNet.PackageValidation/ApiCompatRunnerExtensions.cs +++ b/src/Compatibility/ApiCompat/Microsoft.DotNet.PackageValidation/ApiCompatRunnerExtensions.cs @@ -82,11 +82,11 @@ private static MetadataInformation GetMetadataInformation(ISuppressibleLog log, // See if the package's assembly reference entries have the same target framework. if (!package.AssemblyReferences.TryGetValue(nuGetFramework, out assemblyReferences)) { - log.LogWarning(new Suppression(DiagnosticIds.SearchDirectoriesNotFoundForTfm) { Target = displayString }, - DiagnosticIds.SearchDirectoriesNotFoundForTfm, + log.LogWarning(new Suppression(DiagnosticIds.SearchDirectoriesNotFoundForTfm, string.Format(Resources.MissingSearchDirectory, nuGetFramework.GetShortFolderName(), - displayString)); + displayString), + displayString)); } } } diff --git a/src/Compatibility/ApiCompat/Microsoft.DotNet.PackageValidation/Validators/BaselinePackageValidator.cs b/src/Compatibility/ApiCompat/Microsoft.DotNet.PackageValidation/Validators/BaselinePackageValidator.cs index 4af23b918507..bbd7265ed470 100644 --- a/src/Compatibility/ApiCompat/Microsoft.DotNet.PackageValidation/Validators/BaselinePackageValidator.cs +++ b/src/Compatibility/ApiCompat/Microsoft.DotNet.PackageValidation/Validators/BaselinePackageValidator.cs @@ -45,10 +45,9 @@ public void Validate(PackageValidatorOption options) IReadOnlyList? latestCompileAssets = options.Package.FindBestCompileAssetForFramework(baselineTargetFramework); if (latestCompileAssets == null) { - log.LogError(new Suppression(DiagnosticIds.TargetFrameworkDropped) { Target = baselineTargetFramework.ToString() }, - DiagnosticIds.TargetFrameworkDropped, - string.Format(Resources.MissingTargetFramework, - baselineTargetFramework)); + log.LogError(new Suppression(DiagnosticIds.TargetFrameworkDropped, + string.Format(Resources.MissingTargetFramework, baselineTargetFramework), + baselineTargetFramework.ToString())); } else if (options.EnqueueApiCompatWorkItems) { @@ -69,10 +68,9 @@ public void Validate(PackageValidatorOption options) IReadOnlyList? latestRuntimeAssets = options.Package.FindBestRuntimeAssetForFramework(baselineTargetFramework); if (latestRuntimeAssets == null) { - log.LogError(new Suppression(DiagnosticIds.TargetFrameworkDropped) { Target = baselineTargetFramework.ToString() }, - DiagnosticIds.TargetFrameworkDropped, - string.Format(Resources.MissingTargetFramework, - baselineTargetFramework)); + log.LogError(new Suppression(DiagnosticIds.TargetFrameworkDropped, + string.Format(Resources.MissingTargetFramework, baselineTargetFramework), + baselineTargetFramework.ToString())); } else if (options.EnqueueApiCompatWorkItems) { @@ -98,11 +96,11 @@ public void Validate(PackageValidatorOption options) IReadOnlyList? latestRuntimeSpecificAssets = options.Package.FindBestRuntimeAssetForFrameworkAndRuntime(baselineTargetFramework, baselineRuntimeSpecificAssetsRidGroup.Key); if (latestRuntimeSpecificAssets == null) { - log.LogError(new Suppression(DiagnosticIds.TargetFrameworkAndRidPairDropped) { Target = baselineTargetFramework.ToString() + "-" + baselineRuntimeSpecificAssetsRidGroup.Key }, - DiagnosticIds.TargetFrameworkAndRidPairDropped, + log.LogError(new Suppression(DiagnosticIds.TargetFrameworkAndRidPairDropped, string.Format(Resources.MissingTargetFrameworkAndRid, baselineTargetFramework, - baselineRuntimeSpecificAssetsRidGroup.Key)); + baselineRuntimeSpecificAssetsRidGroup.Key), + baselineTargetFramework.ToString() + "-" + baselineRuntimeSpecificAssetsRidGroup.Key)); } else if (options.EnqueueApiCompatWorkItems) { @@ -134,10 +132,8 @@ public void Validate(PackageValidatorOption options) foreach (string baselineTargetFrameworkExcludedButPresentInCurrentPackage in baselineTargetFrameworksExcludedButPresentInCurrentPackage) { log.LogWarning(new Suppression(DiagnosticIds.BaselineTargetFrameworkIgnoredButPresentInCurrentPackage, - baselineTargetFrameworkExcludedButPresentInCurrentPackage), - DiagnosticIds.BaselineTargetFrameworkIgnoredButPresentInCurrentPackage, - string.Format(Resources.BaselineTargetFrameworkIgnoredButPresentInCurrentPackage, - baselineTargetFrameworkExcludedButPresentInCurrentPackage)); + string.Format(Resources.BaselineTargetFrameworkIgnoredButPresentInCurrentPackage, baselineTargetFrameworkExcludedButPresentInCurrentPackage), + baselineTargetFrameworkExcludedButPresentInCurrentPackage)); } } diff --git a/src/Compatibility/ApiCompat/Microsoft.DotNet.PackageValidation/Validators/CompatibleTFMValidator.cs b/src/Compatibility/ApiCompat/Microsoft.DotNet.PackageValidation/Validators/CompatibleTFMValidator.cs index 3082dea0317f..20e758b46c28 100644 --- a/src/Compatibility/ApiCompat/Microsoft.DotNet.PackageValidation/Validators/CompatibleTFMValidator.cs +++ b/src/Compatibility/ApiCompat/Microsoft.DotNet.PackageValidation/Validators/CompatibleTFMValidator.cs @@ -41,20 +41,18 @@ public void Validate(PackageValidatorOption options) IReadOnlyList? compileTimeAsset = options.Package.FindBestCompileAssetForFramework(framework); if (compileTimeAsset == null) { - log.LogError(new Suppression(DiagnosticIds.ApplicableCompileTimeAsset) { Target = framework.ToString() }, - DiagnosticIds.ApplicableCompileTimeAsset, - string.Format(Resources.NoCompatibleCompileTimeAsset, - framework)); + log.LogError(new Suppression(DiagnosticIds.ApplicableCompileTimeAsset, + string.Format(Resources.NoCompatibleCompileTimeAsset, framework), + target: framework.ToString())); break; } IReadOnlyList? runtimeAsset = options.Package.FindBestRuntimeAssetForFramework(framework); if (runtimeAsset == null) { - log.LogError(new Suppression(DiagnosticIds.CompatibleRuntimeRidLessAsset) { Target = framework.ToString() }, - DiagnosticIds.CompatibleRuntimeRidLessAsset, - string.Format(Resources.NoCompatibleRuntimeAsset, - framework)); + log.LogError(new Suppression(DiagnosticIds.CompatibleRuntimeRidLessAsset, + string.Format(Resources.NoCompatibleRuntimeAsset, framework), + framework.ToString())); } // Invoke ApiCompat to compare the compile time asset with the runtime asset if they are not the same assembly. else if (options.EnqueueApiCompatWorkItems) @@ -71,11 +69,11 @@ public void Validate(PackageValidatorOption options) IReadOnlyList? runtimeRidSpecificAsset = options.Package.FindBestRuntimeAssetForFrameworkAndRuntime(framework, rid); if (runtimeRidSpecificAsset == null) { - log.LogError(new Suppression(DiagnosticIds.CompatibleRuntimeRidSpecificAsset) { Target = framework.ToString() + "-" + rid }, - DiagnosticIds.CompatibleRuntimeRidSpecificAsset, + log.LogError(new Suppression(DiagnosticIds.CompatibleRuntimeRidSpecificAsset, string.Format(Resources.NoCompatibleRidSpecificRuntimeAsset, framework, - rid)); + rid), + framework.ToString() + "-" + rid)); } // Invoke ApiCompat to compare the compile time asset with the runtime specific asset if they are not the same and // if the comparison hasn't already happened (when the runtime asset is the same as the runtime specific asset). diff --git a/test/Microsoft.DotNet.ApiCompatibility.Tests/Logging/SuppressionEngineTests.cs b/test/Microsoft.DotNet.ApiCompatibility.Tests/Logging/SuppressionEngineTests.cs index 0ec716d1095f..b24e5d0d6f9e 100644 --- a/test/Microsoft.DotNet.ApiCompatibility.Tests/Logging/SuppressionEngineTests.cs +++ b/test/Microsoft.DotNet.ApiCompatibility.Tests/Logging/SuppressionEngineTests.cs @@ -13,7 +13,7 @@ public class SuppressionEngineTests public void SuppressionEngine_AddSuppression_AddingTwiceDoesntThrow() { SuppressionEngine suppressionEngine = new(); - Suppression suppression = new("PKG004", "A.B()", "ref/net6.0/mylib.dll", "lib/net6.0/mylib.dll"); + Suppression suppression = new("PKG004", string.Empty, "A.B()", "ref/net6.0/mylib.dll", "lib/net6.0/mylib.dll"); suppressionEngine.AddSuppression(suppression); suppressionEngine.AddSuppression(suppression); @@ -30,16 +30,16 @@ public void SuppressionEngine_IsErrorSuppressed_CanParseInputSuppressionFile() // Parsed the right amount of suppressions Assert.Equal(9, suppressionEngine.BaselineSuppressions.Count); - Assert.True(suppressionEngine.IsErrorSuppressed(new Suppression("CP0001", "T:A.B", "ref/netstandard2.0/tempValidation.dll", "lib/net6.0/tempValidation.dll"))); - Assert.False(suppressionEngine.IsErrorSuppressed(new Suppression("CP0001", "T:A.C", "ref/netstandard2.0/tempValidation.dll", "lib/net6.0/tempValidation.dll"))); - Assert.False(suppressionEngine.IsErrorSuppressed(new Suppression("CP0001", "T:A.B", "lib/netstandard2.0/tempValidation.dll", "lib/net6.0/tempValidation.dll"))); - Assert.True(suppressionEngine.IsErrorSuppressed(new Suppression("PKV004", ".netframework,Version=v4.8"))); - Assert.False(suppressionEngine.IsErrorSuppressed(new Suppression(string.Empty, string.Empty))); - Assert.False(suppressionEngine.IsErrorSuppressed(new Suppression("PKV004", ".netframework,Version=v4.8", "lib/net6.0/mylib.dll"))); - Assert.False(suppressionEngine.IsErrorSuppressed(new Suppression("PKV004", ".NETStandard,Version=v2.0"))); - Assert.True(suppressionEngine.IsErrorSuppressed(new Suppression("CP123", "T:myValidation.Class1", isBaselineSuppression: true))); - Assert.False(suppressionEngine.IsErrorSuppressed(new Suppression("CP123", "T:myValidation.Class1", isBaselineSuppression: false))); - Assert.True(suppressionEngine.IsErrorSuppressed(new Suppression("CP0001", "T:A.B", "ref/netstandard2.0/tempValidation.dll", "lib/net6.0/tempValidation.dll"))); + Assert.True(suppressionEngine.IsErrorSuppressed(new Suppression("CP0001", string.Empty, "T:A.B", "ref/netstandard2.0/tempValidation.dll", "lib/net6.0/tempValidation.dll"))); + Assert.False(suppressionEngine.IsErrorSuppressed(new Suppression("CP0001", string.Empty, "T:A.C", "ref/netstandard2.0/tempValidation.dll", "lib/net6.0/tempValidation.dll"))); + Assert.False(suppressionEngine.IsErrorSuppressed(new Suppression("CP0001", string.Empty, "T:A.B", "lib/netstandard2.0/tempValidation.dll", "lib/net6.0/tempValidation.dll"))); + Assert.True(suppressionEngine.IsErrorSuppressed(new Suppression("PKV004", string.Empty, ".netframework,Version=v4.8"))); + Assert.False(suppressionEngine.IsErrorSuppressed(new Suppression(string.Empty, string.Empty, string.Empty))); + Assert.False(suppressionEngine.IsErrorSuppressed(new Suppression("PKV004", string.Empty, ".netframework,Version=v4.8", "lib/net6.0/mylib.dll"))); + Assert.False(suppressionEngine.IsErrorSuppressed(new Suppression("PKV004", string.Empty, ".NETStandard,Version=v2.0"))); + Assert.True(suppressionEngine.IsErrorSuppressed(new Suppression("CP123", string.Empty, "T:myValidation.Class1", isBaselineSuppression: true))); + Assert.False(suppressionEngine.IsErrorSuppressed(new Suppression("CP123", string.Empty, "T:myValidation.Class1", isBaselineSuppression: false))); + Assert.True(suppressionEngine.IsErrorSuppressed(new Suppression("CP0001", string.Empty, "T:A.B", "ref/netstandard2.0/tempValidation.dll", "lib/net6.0/tempValidation.dll"))); } [Fact] @@ -156,29 +156,29 @@ public void SuppressionEngine_IsErrorSuppressed_SupportsGlobalSuppressions() SuppressionEngine engine = new(); // Engine has a suppression with no left and no right. This should be treated global for any left and any right. - engine.AddSuppression(new Suppression("CP0001", "T:A.B", isBaselineSuppression: true)); - engine.AddSuppression(new Suppression("CP0001", "T:A.C")); + engine.AddSuppression(new Suppression("CP0001", string.Empty, "T:A.B", isBaselineSuppression: true)); + engine.AddSuppression(new Suppression("CP0001", string.Empty, "T:A.C")); - Assert.True(engine.IsErrorSuppressed(new Suppression("CP0001", "T:A.B", "ref/net6.0/myLib.dll", "lib/net6.0/myLib.dll", isBaselineSuppression: true))); - Assert.False(engine.IsErrorSuppressed(new Suppression("CP0001", "T:A.B", "ref/net6.0/myLib.dll", "lib/net6.0/myLib.dll", isBaselineSuppression: false))); + Assert.True(engine.IsErrorSuppressed(new Suppression("CP0001", string.Empty, "T:A.B", "ref/net6.0/myLib.dll", "lib/net6.0/myLib.dll", isBaselineSuppression: true))); + Assert.False(engine.IsErrorSuppressed(new Suppression("CP0001", string.Empty, "T:A.B", "ref/net6.0/myLib.dll", "lib/net6.0/myLib.dll", isBaselineSuppression: false))); - Assert.True(engine.IsErrorSuppressed(new Suppression("CP0001", "T:A.C", "ref/net6.0/myLib.dll", "lib/net6.0/myLib.dll", isBaselineSuppression: false))); - Assert.False(engine.IsErrorSuppressed(new Suppression("CP0001", "T:A.C", "ref/net6.0/myLib.dll", "lib/net6.0/myLib.dll", isBaselineSuppression: true))); + Assert.True(engine.IsErrorSuppressed(new Suppression("CP0001", string.Empty, "T:A.C", "ref/net6.0/myLib.dll", "lib/net6.0/myLib.dll", isBaselineSuppression: false))); + Assert.False(engine.IsErrorSuppressed(new Suppression("CP0001", string.Empty, "T:A.C", "ref/net6.0/myLib.dll", "lib/net6.0/myLib.dll", isBaselineSuppression: true))); // Engine has a suppression with no target. Should be treated globally for any target with that left and right. - engine.AddSuppression(new Suppression("CP0003", null, "ref/net6.0/myleft.dll", "lib/net6.0/myright.dll", isBaselineSuppression: false)); + engine.AddSuppression(new Suppression("CP0003", string.Empty, null, "ref/net6.0/myleft.dll", "lib/net6.0/myright.dll", isBaselineSuppression: false)); - Assert.True(engine.IsErrorSuppressed(new Suppression("CP0003", "T:A.B", "ref/net6.0/myLeft.dll", "lib/net6.0/myRight.dll"))); - Assert.True(engine.IsErrorSuppressed(new Suppression("CP0003", "T:A.C", "ref/net6.0/myLeft.dll", "lib/net6.0/myRight.dll"))); - Assert.True(engine.IsErrorSuppressed(new Suppression("CP0003", "T:A.D", "ref/net6.0/myLeft.dll", "lib/net6.0/myRight.dll"))); - Assert.False(engine.IsErrorSuppressed(new Suppression("CP0003", "T:A.D", "ref/net6.0/myLeft.dll", "lib/net6.0/myRight.dll", isBaselineSuppression: true))); + Assert.True(engine.IsErrorSuppressed(new Suppression("CP0003", string.Empty, "T:A.B", "ref/net6.0/myLeft.dll", "lib/net6.0/myRight.dll"))); + Assert.True(engine.IsErrorSuppressed(new Suppression("CP0003", string.Empty, "T:A.C", "ref/net6.0/myLeft.dll", "lib/net6.0/myRight.dll"))); + Assert.True(engine.IsErrorSuppressed(new Suppression("CP0003", string.Empty, "T:A.D", "ref/net6.0/myLeft.dll", "lib/net6.0/myRight.dll"))); + Assert.False(engine.IsErrorSuppressed(new Suppression("CP0003", string.Empty, "T:A.D", "ref/net6.0/myLeft.dll", "lib/net6.0/myRight.dll", isBaselineSuppression: true))); // Engine has a suppression with no diagnostic id and target. Should be treated globally for any diagnostic id and target with that left and right. - engine.AddSuppression(new Suppression(string.Empty, null, "ref/net8.0/left.dll", "lib/net8.0/left.dll", isBaselineSuppression: false)); - engine.AddSuppression(new Suppression(string.Empty, null, "ref/net8.0/left.dll", "lib/net8.0/left.dll", isBaselineSuppression: true)); + engine.AddSuppression(new Suppression(string.Empty, string.Empty, null, "ref/net8.0/left.dll", "lib/net8.0/left.dll", isBaselineSuppression: false)); + engine.AddSuppression(new Suppression(string.Empty, string.Empty, null, "ref/net8.0/left.dll", "lib/net8.0/left.dll", isBaselineSuppression: true)); - Assert.True(engine.IsErrorSuppressed(new Suppression("CP0009", "T:A.B.C.D.E", "ref/net8.0/left.dll", "lib/net8.0/left.dll", isBaselineSuppression: false))); - Assert.True(engine.IsErrorSuppressed(new Suppression("CP0009", "T:A.B.C.D.E", "ref/net8.0/left.dll", "lib/net8.0/left.dll", isBaselineSuppression: true))); + Assert.True(engine.IsErrorSuppressed(new Suppression("CP0009", string.Empty, "T:A.B.C.D.E", "ref/net8.0/left.dll", "lib/net8.0/left.dll", isBaselineSuppression: false))); + Assert.True(engine.IsErrorSuppressed(new Suppression("CP0009", string.Empty, "T:A.B.C.D.E", "ref/net8.0/left.dll", "lib/net8.0/left.dll", isBaselineSuppression: true))); } [Fact] @@ -209,12 +209,11 @@ public void SuppressionEngine_BaseliningNewErrorsDoesNotOverrideSuppressions() Suppression[] deserializedSuppressions = xmlSerializer.Deserialize(stream) as Suppression[]; Assert.Equal(10, deserializedSuppressions.Length); - Assert.Equal(new Suppression("CP0001") - { - Target = "T:A", - Left = "lib/netstandard1.3/tempValidation.dll", - Right = "lib/netstandard1.3/tempValidation.dll" - }, deserializedSuppressions[0]); + Assert.Equal(new Suppression("CP0001", + string.Empty, + "T:A", + "lib/netstandard1.3/tempValidation.dll", + "lib/netstandard1.3/tempValidation.dll"), deserializedSuppressions[0]); Assert.Equal(newSuppression, deserializedSuppressions[4]); } @@ -224,16 +223,16 @@ public void SuppressionEngine_IsErrorSuppressed_NoWarnIsHonored() { SuppressionEngine engine = new(noWarn: "CP0001;CP0003;CP1111"); - Assert.True(engine.IsErrorSuppressed(new Suppression("CP0001", "T:A.B", "ref/net6.0/myLib.dll", "lib/net6.0/myLib.dll", isBaselineSuppression: true))); - Assert.False(engine.IsErrorSuppressed(new Suppression("CP1110", "T:A.B", "ref/net6.0/myLib.dll", "lib/net6.0/myLib.dll", isBaselineSuppression: false))); + Assert.True(engine.IsErrorSuppressed(new Suppression("CP0001", string.Empty, "T:A.B", "ref/net6.0/myLib.dll", "lib/net6.0/myLib.dll", isBaselineSuppression: true))); + Assert.False(engine.IsErrorSuppressed(new Suppression("CP1110", string.Empty, "T:A.B", "ref/net6.0/myLib.dll", "lib/net6.0/myLib.dll", isBaselineSuppression: false))); - Assert.True(engine.IsErrorSuppressed(new Suppression("CP0001", "T:A.C", "ref/net6.0/myLib.dll", "lib/net6.0/myLib.dll", isBaselineSuppression: false))); - Assert.False(engine.IsErrorSuppressed(new Suppression("CP1000", "T:A.C", "ref/net6.0/myLib.dll", "lib/net6.0/myLib.dll", isBaselineSuppression: true))); + Assert.True(engine.IsErrorSuppressed(new Suppression("CP0001", string.Empty, "T:A.C", "ref/net6.0/myLib.dll", "lib/net6.0/myLib.dll", isBaselineSuppression: false))); + Assert.False(engine.IsErrorSuppressed(new Suppression("CP1000", string.Empty, "T:A.C", "ref/net6.0/myLib.dll", "lib/net6.0/myLib.dll", isBaselineSuppression: true))); - Assert.True(engine.IsErrorSuppressed(new Suppression("CP0003", "T:A.B", "ref/net6.0/myLeft.dll", "lib/net6.0/myRight.dll"))); - Assert.True(engine.IsErrorSuppressed(new Suppression("CP0003", "T:A.C", "ref/net6.0/myLeft.dll", "lib/net6.0/myRight.dll"))); - Assert.True(engine.IsErrorSuppressed(new Suppression("CP0003", "T:A.D", "ref/net6.0/myLeft.dll", "lib/net6.0/myRight.dll"))); - Assert.False(engine.IsErrorSuppressed(new Suppression("CP1232", "T:A.D", "ref/net6.0/myLeft.dll", "lib/net6.0/myRight.dll", isBaselineSuppression: true))); + Assert.True(engine.IsErrorSuppressed(new Suppression("CP0003", string.Empty, "T:A.B", "ref/net6.0/myLeft.dll", "lib/net6.0/myRight.dll"))); + Assert.True(engine.IsErrorSuppressed(new Suppression("CP0003", string.Empty, "T:A.C", "ref/net6.0/myLeft.dll", "lib/net6.0/myRight.dll"))); + Assert.True(engine.IsErrorSuppressed(new Suppression("CP0003", string.Empty, "T:A.D", "ref/net6.0/myLeft.dll", "lib/net6.0/myRight.dll"))); + Assert.False(engine.IsErrorSuppressed(new Suppression("CP1232", string.Empty, "T:A.D", "ref/net6.0/myLeft.dll", "lib/net6.0/myRight.dll", isBaselineSuppression: true))); } } } diff --git a/test/Microsoft.DotNet.ApiCompatibility.Tests/Logging/SuppressionTests.cs b/test/Microsoft.DotNet.ApiCompatibility.Tests/Logging/SuppressionTests.cs index f2257347f464..39d75f7bed1b 100644 --- a/test/Microsoft.DotNet.ApiCompatibility.Tests/Logging/SuppressionTests.cs +++ b/test/Microsoft.DotNet.ApiCompatibility.Tests/Logging/SuppressionTests.cs @@ -7,31 +7,31 @@ public class SuppressionTests { public static IEnumerable GetEqualData() { - yield return new object[] { new Suppression(string.Empty), new Suppression(string.Empty) { Left = null, Right = null, Target = null } }; - yield return new object[] { new Suppression(string.Empty), new Suppression(string.Empty) { Left = string.Empty, Right = string.Empty, Target = string.Empty } }; - yield return new object[] { new Suppression("PK004"), new Suppression("pk004") }; - yield return new object[] { new Suppression("PK004"), new Suppression(" pk004 ") }; - yield return new object[] { new Suppression("PK004") { Target = "A.B" }, new Suppression(" pk004 ") { Target = "A.b " } }; - yield return new object[] { new Suppression("PK004") { Target = "A.B", Left = "ref/net6.0/myLib.dll" }, new Suppression(" pk004 ") { Target = "A.B", Left = "ref/net6.0/mylib.dll" } }; - yield return new object[] { new Suppression("PK004") { Target = "A.B", Left = "ref/net6.0/myLib.dll", Right = "lib/net6.0/myLib.dll" }, new Suppression("PK004") { Target = "A.B", Left = "ref/net6.0/myLib.dll", Right = "lib/net6.0/myLib.dll", IsBaselineSuppression = false } }; - yield return new object[] { new Suppression("PK004") { Target = "A.B", Left = "ref/net6.0/myLib.dll", Right = "lib/net6.0/myLib.dll", IsBaselineSuppression = false }, new Suppression("PK004") { Target = "A.B", Left = "ref/net6.0/myLib.dll", Right = "lib/net6.0/myLib.dll", IsBaselineSuppression = false } }; - yield return new object[] { new Suppression("PK004") { Target = "A.B", Left = "ref/net6.0/myLib.dll", Right = "lib/net6.0/myLib.dll", IsBaselineSuppression = true }, new Suppression("PK004") { Target = "A.B", Left = "ref/net6.0/myLib.dll", Right = "lib/net6.0/myLib.dll", IsBaselineSuppression = true } }; + yield return new object[] { new Suppression(string.Empty, string.Empty), new Suppression(string.Empty, string.Empty, target:null, left: null, right: null) }; + yield return new object[] { new Suppression(string.Empty, string.Empty), new Suppression(string.Empty, string.Empty, target: string.Empty, left: string.Empty, right: string.Empty) }; + yield return new object[] { new Suppression("PK004", string.Empty), new Suppression("pk004", string.Empty) }; + yield return new object[] { new Suppression("PK004", string.Empty), new Suppression(" pk004 ", string.Empty) }; + yield return new object[] { new Suppression("PK004", string.Empty, "A.B"), new Suppression(" pk004 ", string.Empty, "A.b ") }; + yield return new object[] { new Suppression("PK004", string.Empty, "A.B", "ref/net6.0/myLib.dll"), new Suppression(" pk004 ", string.Empty, "A.B", "ref/net6.0/mylib.dll") }; + yield return new object[] { new Suppression("PK004", string.Empty, "A.B", "ref/net6.0/myLib.dll", "lib/net6.0/myLib.dll"), new Suppression("PK004", string.Empty, "A.B", "ref/net6.0/myLib.dll", "lib/net6.0/myLib.dll", isBaselineSuppression: false) }; + yield return new object[] { new Suppression("PK004", string.Empty, "A.B", "ref/net6.0/myLib.dll", "lib/net6.0/myLib.dll", isBaselineSuppression: false), new Suppression("PK004", string.Empty, "A.B", "ref/net6.0/myLib.dll", "lib/net6.0/myLib.dll", isBaselineSuppression: false) }; + yield return new object[] { new Suppression("PK004", string.Empty, "A.B", "ref/net6.0/myLib.dll", "lib/net6.0/myLib.dll", isBaselineSuppression: true), new Suppression("PK004", string.Empty, "A.B", "ref/net6.0/myLib.dll", "lib/net6.0/myLib.dll", isBaselineSuppression: true) }; } public static IEnumerable GetDifferentData() { - yield return new object[] { new Suppression(string.Empty), new Suppression("PK005") }; - yield return new object[] { new Suppression("PK004"), new Suppression("PK005") }; - yield return new object[] { new Suppression("PK004"), new Suppression("PK004") { Target = "A.B()" } }; - yield return new object[] { new Suppression("PK004") { Target = "A.B" }, new Suppression("PK004") { Target = "A.B()" } }; - yield return new object[] { new Suppression("PK004") { Target = "A.C" }, new Suppression("PK004") { Target = "A.B()" } }; - yield return new object[] { new Suppression("PK004") { Target = "A.B()", Left = "ref/net6.0/myLib.dll" }, new Suppression("PK004") { Target = "A.B()" } }; - yield return new object[] { new Suppression("PK004") { Target = "A.B()", Left = "ref/net6.0/myLib.dll" }, new Suppression("PK004") { Target = "A.B()", Left = "lib/net6.0/myLib.dll" } }; - yield return new object[] { new Suppression("PK004") { Target = "A.B()", Right = "ref/net6.0/myLib.dll" }, new Suppression("PK004") { Target = "A.B()" } }; - yield return new object[] { new Suppression("PK004") { Target = "A.B()", Right = "ref/net6.0/myLib.dll" }, new Suppression("PK004") { Target = "A.B()", Right = "lib/net6.0/myLib.dll" } }; - yield return new object[] { new Suppression("PK004") { Target = "A.B()", Left = "ref/net6.0/mylib.dll", Right = "lib/net6.0/myLib.dll" }, new Suppression("PK004") { Target = "A.B()", Left = "ref/netstandard2.0/mylib.dll", Right = "lib/net6.0/myLib.dll" } }; - yield return new object[] { new Suppression("PK004") { Target = "A.B", Left = "ref/net6.0/myLib.dll", Right = "lib/net6.0/myLib.dll", IsBaselineSuppression = true }, new Suppression("PK004") { Target = "A.B", Left = "ref/net6.0/myLib.dll", Right = "lib/net6.0/myLib.dll", IsBaselineSuppression = false } }; - yield return new object[] { new Suppression("PK004") { Target = "A.B", Left = "ref/net6.0/myLib.dll", Right = "lib/net6.0/myLib.dll" }, new Suppression("PK004") { Target = "A.B", Left = "ref/net6.0/myLib.dll", Right = "lib/net6.0/myLib.dll", IsBaselineSuppression = true } }; + yield return new object[] { new Suppression(string.Empty, string.Empty), new Suppression("PK005", string.Empty) }; + yield return new object[] { new Suppression("PK004", string.Empty), new Suppression("PK005", string.Empty) }; + yield return new object[] { new Suppression("PK004", string.Empty), new Suppression("PK004", string.Empty, "A.B()") }; + yield return new object[] { new Suppression("PK004", string.Empty, "A.B"), new Suppression("PK004", string.Empty, "A.B()") }; + yield return new object[] { new Suppression("PK004", string.Empty, "A.C"), new Suppression("PK004", string.Empty, "A.B()") }; + yield return new object[] { new Suppression("PK004", string.Empty, "A.B()", "ref/net6.0/myLib.dll"), new Suppression("PK004", string.Empty, "A.B()") }; + yield return new object[] { new Suppression("PK004", string.Empty, "A.B()", "ref/net6.0/myLib.dll"), new Suppression("PK004", string.Empty, "A.B()", "lib/net6.0/myLib.dll") }; + yield return new object[] { new Suppression("PK004", string.Empty, "A.B()", "ref/net6.0/myLib.dll"), new Suppression("PK004", string.Empty, "A.B()") }; + yield return new object[] { new Suppression("PK004", string.Empty, "A.B()", "ref/net6.0/myLib.dll"), new Suppression("PK004", string.Empty, "A.B()", "lib/net6.0/myLib.dll") }; + yield return new object[] { new Suppression("PK004", string.Empty, "A.B()", "ref/net6.0/mylib.dll", "lib/net6.0/myLib.dll"), new Suppression("PK004", string.Empty, "A.B()", "ref/netstandard2.0/mylib.dll", "lib/net6.0/myLib.dll") }; + yield return new object[] { new Suppression("PK004", string.Empty, "A.B", "ref/net6.0/myLib.dll", "lib/net6.0/myLib.dll", isBaselineSuppression: true), new Suppression("PK004", string.Empty, "A.B", "ref/net6.0/myLib.dll", "lib/net6.0/myLib.dll", isBaselineSuppression: false) }; + yield return new object[] { new Suppression("PK004", string.Empty, "A.B", "ref/net6.0/myLib.dll", "lib/net6.0/myLib.dll"), new Suppression("PK004", string.Empty, "A.B", "ref/net6.0/myLib.dll", "lib/net6.0/myLib.dll", isBaselineSuppression: true) }; } [Theory] @@ -53,7 +53,7 @@ public void CheckSuppressionsAreNotEqual(Suppression suppression, Suppression ot [Fact] public void CheckSuppressionIsNotEqualWithNull() { - Assert.False(new Suppression("PK0004").Equals(null)); + Assert.False(new Suppression("PK0004", string.Empty).Equals(null)); } } } diff --git a/test/Microsoft.DotNet.ApiCompatibility.Tests/Logging/TestSuppressionEngine.cs b/test/Microsoft.DotNet.ApiCompatibility.Tests/Logging/TestSuppressionEngine.cs index 7d844d258d0d..68840a19747a 100644 --- a/test/Microsoft.DotNet.ApiCompatibility.Tests/Logging/TestSuppressionEngine.cs +++ b/test/Microsoft.DotNet.ApiCompatibility.Tests/Logging/TestSuppressionEngine.cs @@ -27,12 +27,14 @@ internal class TestSuppressionEngine : SuppressionEngine public static readonly string DefaultSuppressionFile = SuppressionFileHeader + @$" CP0001 + MessageForCP0001 T:A lib/netstandard1.3/tempValidation.dll lib/netstandard1.3/tempValidation.dll {SuppressionFileComment} CP0001 + MessageForCP0001 T:tempValidation.Class1 lib/netstandard1.3/tempValidation.dll lib/netstandard1.3/tempValidation.dll @@ -40,41 +42,48 @@ internal class TestSuppressionEngine : SuppressionEngine CP0001 + MessageForCP0001 T:A.B ref/netstandard2.0/tempValidation.dll lib/net6.0/tempValidation.dll CP0001 + MessageForCP0001 T:tempValidation.SomeGenericType`1 ref/netstandard2.0/tempValidation.dll lib/net6.0/tempValidation.dll CP0002 + MessageForCP0002 M:tempValidation.Class1.Bar(System.Int32) ref/netstandard2.0/tempValidation.dll lib/net6.0/tempValidation.dll CP0002 + MessageForCP0002 M:tempValidation.Class1.SomeNewBreakingChange ref/netstandard2.0/tempValidation.dll lib/net6.0/tempValidation.dll CP0002 + MessageForCP0002 M:tempValidation.Class1.SomeOtherGenericMethod``1(``0) ref/netstandard2.0/tempValidation.dll lib/net6.0/tempValidation.dll CP123 + MessageForCP123 T:myValidation.Class1 true PKV004 + MessageForPKV004 .NETFramework,Version=v4.8 " + SuppressionFileFooter; diff --git a/test/Microsoft.DotNet.ApiCompatibility.Tests/SuppressibleTestLog.cs b/test/Microsoft.DotNet.ApiCompatibility.Tests/SuppressibleTestLog.cs index 798c8c32adda..c64f59100741 100644 --- a/test/Microsoft.DotNet.ApiCompatibility.Tests/SuppressibleTestLog.cs +++ b/test/Microsoft.DotNet.ApiCompatibility.Tests/SuppressibleTestLog.cs @@ -15,19 +15,19 @@ internal class SuppressibleTestLog : ISuppressibleLog public bool HasLoggedErrors => errors.Count != 0; public bool HasLoggedErrorSuppressions { get; private set; } - public bool LogError(Suppression suppression, string code, string message) + public bool LogError(Suppression suppression) { HasLoggedErrorSuppressions = true; - errors.Add($"{code} {message}"); + errors.Add($"{suppression.DiagnosticId} {suppression.Message}"); return true; } public void LogError(string message) => errors.Add(message); public void LogError(string code, string message) => errors.Add($"{code} {message}"); - public bool LogWarning(Suppression suppression, string code, string message) + public bool LogWarning(Suppression suppression) { - warnings.Add($"{code} {message}"); + warnings.Add($"{suppression.DiagnosticId} {suppression.Message}"); return true; } From cbb1c00087880e6c6ef568b33846406f4d95d0f4 Mon Sep 17 00:00:00 2001 From: Viktor Hofer Date: Tue, 14 Jan 2025 15:01:42 +0100 Subject: [PATCH 2/4] Allow specifying a neutral language when generating suppression files --- .../ValidateAssemblies.cs | 12 ++++++++++ .../ValidatePackage.cs | 24 ++++++++++++++----- .../ValidateAssembliesTask.cs | 6 +++++ .../ValidatePackageTask.cs | 6 +++++ ...piCompat.ValidateAssemblies.Common.targets | 1 + .../Program.cs | 11 +++++++++ .../ResourceSingleton.cs | 15 ++++++++++++ .../ResourceSingleton.cs | 19 +++++++++++++++ ...soft.NET.ApiCompat.ValidatePackage.targets | 1 + 9 files changed, 89 insertions(+), 6 deletions(-) create mode 100644 src/Compatibility/ApiCompat/Microsoft.DotNet.ApiCompatibility/ResourceSingleton.cs create mode 100644 src/Compatibility/ApiCompat/Microsoft.DotNet.PackageValidation/ResourceSingleton.cs diff --git a/src/Compatibility/ApiCompat/Microsoft.DotNet.ApiCompat.Shared/ValidateAssemblies.cs b/src/Compatibility/ApiCompat/Microsoft.DotNet.ApiCompat.Shared/ValidateAssemblies.cs index 5ca7266c730c..b5725ed6a4ab 100644 --- a/src/Compatibility/ApiCompat/Microsoft.DotNet.ApiCompat.Shared/ValidateAssemblies.cs +++ b/src/Compatibility/ApiCompat/Microsoft.DotNet.ApiCompat.Shared/ValidateAssemblies.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Globalization; using Microsoft.DotNet.ApiCompatibility; using Microsoft.DotNet.ApiCompatibility.Logging; using Microsoft.DotNet.ApiCompatibility.Rules; @@ -21,6 +22,7 @@ public static int Run(Func logFactory, bool enableRuleAttributesMustMatch, string[]? excludeAttributesFiles, bool enableRuleCannotChangeParameterName, + string neutralLanguage, string[] leftAssemblies, string[] rightAssemblies, bool enableStrictMode, @@ -30,6 +32,16 @@ public static int Run(Func logFactory, (string CaptureGroupPattern, string ReplacementString)[]? leftAssembliesTransformationPatterns, (string CaptureGroupPattern, string ReplacementString)[]? rightAssembliesTransformationPatterns) { + // When generating the suppression file and baselining all errors, change the resource language + // to neutral. This guarantees that suppression files aren't language specific. + if (generateSuppressionFile) + { + CultureInfo neutralLanguageCultureInfo = new(neutralLanguage); + Resources.Culture = neutralLanguageCultureInfo; + CommonResources.Culture = neutralLanguageCultureInfo; + ApiCompatibility.ResourceSingleton.ChangeCulture(neutralLanguageCultureInfo); + } + // Initialize the service provider ApiCompatServiceProvider serviceProvider = new(logFactory, () => SuppressionFileHelper.CreateSuppressionEngine(suppressionFiles, noWarn, generateSuppressionFile), diff --git a/src/Compatibility/ApiCompat/Microsoft.DotNet.ApiCompat.Shared/ValidatePackage.cs b/src/Compatibility/ApiCompat/Microsoft.DotNet.ApiCompat.Shared/ValidatePackage.cs index 1b82442c985d..113de3d55cfe 100644 --- a/src/Compatibility/ApiCompat/Microsoft.DotNet.ApiCompat.Shared/ValidatePackage.cs +++ b/src/Compatibility/ApiCompat/Microsoft.DotNet.ApiCompat.Shared/ValidatePackage.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Globalization; using Microsoft.DotNet.ApiCompatibility.Logging; using Microsoft.DotNet.ApiCompatibility.Rules; using Microsoft.DotNet.PackageValidation; @@ -23,6 +24,7 @@ public static int Run(Func logFactory, bool enableRuleAttributesMustMatch, string[]? excludeAttributesFiles, bool enableRuleCannotChangeParameterName, + string neutralLanguage, string? packagePath, bool runApiCompat, bool enableStrictModeForCompatibleTfms, @@ -34,6 +36,22 @@ public static int Run(Func logFactory, IReadOnlyDictionary>? baselinePackageAssemblyReferences, string[]? baselinePackageFrameworksToIgnore) { + // When generating the suppression file and baselining all errors, change the resource language + // to neutral. This guarantees that suppression files aren't language specific. + if (generateSuppressionFile) + { + CultureInfo neutralLanguageCultureInfo = new(neutralLanguage); + Resources.Culture = neutralLanguageCultureInfo; + CommonResources.Culture = neutralLanguageCultureInfo; + PackageValidation.ResourceSingleton.ChangeCulture(neutralLanguageCultureInfo); + } + + // If a runtime graph is provided, parse and use it for asset selection during the in-memory package construction. + if (runtimeGraph != null) + { + Package.InitializeRuntimeGraph(runtimeGraph); + } + // Initialize the service provider ApiCompatServiceProvider serviceProvider = new(logFactory, () => SuppressionFileHelper.CreateSuppressionEngine(suppressionFiles, noWarn, generateSuppressionFile), @@ -43,12 +61,6 @@ public static int Run(Func logFactory, respectInternals, excludeAttributesFiles); - // If a runtime graph is provided, parse and use it for asset selection during the in-memory package construction. - if (runtimeGraph != null) - { - Package.InitializeRuntimeGraph(runtimeGraph); - } - // Create the in-memory representation of the passed in package path Package package = Package.Create(packagePath, packageAssemblyReferences); diff --git a/src/Compatibility/ApiCompat/Microsoft.DotNet.ApiCompat.Task/ValidateAssembliesTask.cs b/src/Compatibility/ApiCompat/Microsoft.DotNet.ApiCompat.Task/ValidateAssembliesTask.cs index 650245dae575..4452120dceda 100644 --- a/src/Compatibility/ApiCompat/Microsoft.DotNet.ApiCompat.Task/ValidateAssembliesTask.cs +++ b/src/Compatibility/ApiCompat/Microsoft.DotNet.ApiCompat.Task/ValidateAssembliesTask.cs @@ -82,6 +82,11 @@ public class ValidateAssembliesTask : TaskBase /// public bool EnableRuleCannotChangeParameterName { get; set; } + /// + /// The neutral language to use when generating suppression files. Defaults to en-US. + /// + public string NeutralLanguage { get; set; } = "en-US"; + /// /// Performs api comparison checks in strict mode. /// @@ -144,6 +149,7 @@ protected override void ExecuteCore() EnableRuleAttributesMustMatch, ExcludeAttributesFiles, EnableRuleCannotChangeParameterName, + NeutralLanguage, LeftAssemblies!, RightAssemblies!, EnableStrictMode, diff --git a/src/Compatibility/ApiCompat/Microsoft.DotNet.ApiCompat.Task/ValidatePackageTask.cs b/src/Compatibility/ApiCompat/Microsoft.DotNet.ApiCompat.Task/ValidatePackageTask.cs index b839ca1d4325..e1663fa6380a 100644 --- a/src/Compatibility/ApiCompat/Microsoft.DotNet.ApiCompat.Task/ValidatePackageTask.cs +++ b/src/Compatibility/ApiCompat/Microsoft.DotNet.ApiCompat.Task/ValidatePackageTask.cs @@ -108,6 +108,11 @@ public class ValidatePackageTask : TaskBase /// public string? NoWarn { get; set; } + /// + /// The neutral language to use when generating suppression files. Defaults to en-US. + /// + public string NeutralLanguage { get; set; } = "en-US"; + /// /// Assembly references grouped by target framework, for the assets inside the package. /// @@ -152,6 +157,7 @@ protected override void ExecuteCore() EnableRuleAttributesMustMatch, ExcludeAttributesFiles, EnableRuleCannotChangeParameterName, + NeutralLanguage, PackageTargetPath!, RunApiCompat, EnableStrictModeForCompatibleTfms, diff --git a/src/Compatibility/ApiCompat/Microsoft.DotNet.ApiCompat.Task/build/Microsoft.DotNet.ApiCompat.ValidateAssemblies.Common.targets b/src/Compatibility/ApiCompat/Microsoft.DotNet.ApiCompat.Task/build/Microsoft.DotNet.ApiCompat.ValidateAssemblies.Common.targets index b784c4c4e4a4..a0b4277352d7 100644 --- a/src/Compatibility/ApiCompat/Microsoft.DotNet.ApiCompat.Task/build/Microsoft.DotNet.ApiCompat.ValidateAssemblies.Common.targets +++ b/src/Compatibility/ApiCompat/Microsoft.DotNet.ApiCompat.Task/build/Microsoft.DotNet.ApiCompat.ValidateAssemblies.Common.targets @@ -27,6 +27,7 @@ EnableRuleAttributesMustMatch="$(ApiCompatEnableRuleAttributesMustMatch)" ExcludeAttributesFiles="@(ApiCompatExcludeAttributesFile)" EnableRuleCannotChangeParameterName="$(ApiCompatEnableRuleCannotChangeParameterName)" + NeutralLanguage="$(ApiCompatNeutralLanguage)" EnableStrictMode="$(ApiCompatStrictMode)" LeftAssembliesReferences="@(ApiCompatLeftAssembliesReferences)" RightAssembliesReferences="@(ApiCompatRightAssembliesReferences)" diff --git a/src/Compatibility/ApiCompat/Microsoft.DotNet.ApiCompat.Tool/Program.cs b/src/Compatibility/ApiCompat/Microsoft.DotNet.ApiCompat.Tool/Program.cs index cb248930e153..dfe888c5598f 100644 --- a/src/Compatibility/ApiCompat/Microsoft.DotNet.ApiCompat.Tool/Program.cs +++ b/src/Compatibility/ApiCompat/Microsoft.DotNet.ApiCompat.Tool/Program.cs @@ -84,6 +84,12 @@ static int Main(string[] args) Description = "If true, enables rule to check that the parameter names between public methods do not change.", Recursive = true }; + CliOption neutralLanguageOption = new("--neutral-language") + { + Description = "The neutral language to use when generating suppression files. Defaults to en-US.", + Recursive = true, + DefaultValueFactory = _ => "en-US" + }; // Root command CliOption leftAssembliesOption = new("--left-assembly", "--left", "-l") @@ -158,6 +164,7 @@ static int Main(string[] args) rootCommand.Options.Add(enableRuleAttributesMustMatchOption); rootCommand.Options.Add(excludeAttributesFilesOption); rootCommand.Options.Add(enableRuleCannotChangeParameterNameOption); + rootCommand.Options.Add(neutralLanguageOption); rootCommand.Options.Add(leftAssembliesOption); rootCommand.Options.Add(rightAssembliesOption); @@ -186,6 +193,7 @@ static int Main(string[] args) bool enableRuleAttributesMustMatch = parseResult.GetValue(enableRuleAttributesMustMatchOption); string[]? excludeAttributesFiles = parseResult.GetValue(excludeAttributesFilesOption); bool enableRuleCannotChangeParameterName = parseResult.GetValue(enableRuleCannotChangeParameterNameOption); + string neutralLanguage = parseResult.GetValue(neutralLanguageOption)!; string[] leftAssemblies = parseResult.GetValue(leftAssembliesOption)!; string[] rightAssemblies = parseResult.GetValue(rightAssembliesOption)!; @@ -208,6 +216,7 @@ static int Main(string[] args) enableRuleAttributesMustMatch, excludeAttributesFiles, enableRuleCannotChangeParameterName, + neutralLanguage, leftAssemblies, rightAssemblies, strictMode, @@ -308,6 +317,7 @@ static int Main(string[] args) bool enableRuleAttributesMustMatch = parseResult.GetValue(enableRuleAttributesMustMatchOption); string[]? excludeAttributesFiles = parseResult.GetValue(excludeAttributesFilesOption); bool enableRuleCannotChangeParameterName = parseResult.GetValue(enableRuleCannotChangeParameterNameOption); + string neutralLanguage = parseResult.GetValue(neutralLanguageOption)!; string? package = parseResult.GetValue(packageArgument); bool runApiCompat = parseResult.GetValue(runApiCompatOption); @@ -332,6 +342,7 @@ static int Main(string[] args) enableRuleAttributesMustMatch, excludeAttributesFiles, enableRuleCannotChangeParameterName, + neutralLanguage, package, runApiCompat, enableStrictModeForCompatibleTfms, diff --git a/src/Compatibility/ApiCompat/Microsoft.DotNet.ApiCompatibility/ResourceSingleton.cs b/src/Compatibility/ApiCompat/Microsoft.DotNet.ApiCompatibility/ResourceSingleton.cs new file mode 100644 index 000000000000..b7e4188ac716 --- /dev/null +++ b/src/Compatibility/ApiCompat/Microsoft.DotNet.ApiCompatibility/ResourceSingleton.cs @@ -0,0 +1,15 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Globalization; + +namespace Microsoft.DotNet.ApiCompatibility +{ + public static class ResourceSingleton + { + /// + /// Change the embedded resources culture. + /// + public static void ChangeCulture(CultureInfo culture) => Resources.Culture = culture; + } +} diff --git a/src/Compatibility/ApiCompat/Microsoft.DotNet.PackageValidation/ResourceSingleton.cs b/src/Compatibility/ApiCompat/Microsoft.DotNet.PackageValidation/ResourceSingleton.cs new file mode 100644 index 000000000000..8cbf57bc9781 --- /dev/null +++ b/src/Compatibility/ApiCompat/Microsoft.DotNet.PackageValidation/ResourceSingleton.cs @@ -0,0 +1,19 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Globalization; + +namespace Microsoft.DotNet.PackageValidation +{ + public static class ResourceSingleton + { + /// + /// Change the embedded resources culture. + /// s + public static void ChangeCulture(CultureInfo culture) + { + Resources.Culture = culture; + ApiCompatibility.ResourceSingleton.ChangeCulture(culture); + } + } +} diff --git a/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.ApiCompat.ValidatePackage.targets b/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.ApiCompat.ValidatePackage.targets index 0a1efbdccdfd..8e8c95e40c6e 100644 --- a/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.ApiCompat.ValidatePackage.targets +++ b/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.ApiCompat.ValidatePackage.targets @@ -44,6 +44,7 @@ Copyright (c) .NET Foundation. All rights reserved. EnableRuleAttributesMustMatch="$(ApiCompatEnableRuleAttributesMustMatch)" ExcludeAttributesFiles="@(ApiCompatExcludeAttributesFile)" EnableRuleCannotChangeParameterName="$(ApiCompatEnableRuleCannotChangeParameterName)" + NeutralLanguage="$(ApiCompatNeutralLanguage)" RunApiCompat="$(RunApiCompat)" EnableStrictModeForCompatibleTfms="$(EnableStrictModeForCompatibleTfms)" EnableStrictModeForCompatibleFrameworksInPackage="$(EnableStrictModeForCompatibleFrameworksInPackage)" From e23343ba5bfb4e89a36e9c1e0c93a02a14eb4c90 Mon Sep 17 00:00:00 2001 From: Viktor Hofer Date: Mon, 20 Jan 2025 18:24:03 +0100 Subject: [PATCH 3/4] Rename option to --suppressions-culture --- .../ValidateAssemblies.cs | 10 +++++----- .../ValidatePackage.cs | 10 +++++----- .../ValidateAssembliesTask.cs | 6 +++--- .../ValidatePackageTask.cs | 6 +++--- ...Net.ApiCompat.ValidateAssemblies.Common.targets | 2 +- .../Microsoft.DotNet.ApiCompat.Tool/Program.cs | 14 +++++++------- ...Microsoft.NET.ApiCompat.ValidatePackage.targets | 2 +- 7 files changed, 25 insertions(+), 25 deletions(-) diff --git a/src/Compatibility/ApiCompat/Microsoft.DotNet.ApiCompat.Shared/ValidateAssemblies.cs b/src/Compatibility/ApiCompat/Microsoft.DotNet.ApiCompat.Shared/ValidateAssemblies.cs index b5725ed6a4ab..953c561fb405 100644 --- a/src/Compatibility/ApiCompat/Microsoft.DotNet.ApiCompat.Shared/ValidateAssemblies.cs +++ b/src/Compatibility/ApiCompat/Microsoft.DotNet.ApiCompat.Shared/ValidateAssemblies.cs @@ -22,7 +22,7 @@ public static int Run(Func logFactory, bool enableRuleAttributesMustMatch, string[]? excludeAttributesFiles, bool enableRuleCannotChangeParameterName, - string neutralLanguage, + string suppressionsCulture, string[] leftAssemblies, string[] rightAssemblies, bool enableStrictMode, @@ -36,10 +36,10 @@ public static int Run(Func logFactory, // to neutral. This guarantees that suppression files aren't language specific. if (generateSuppressionFile) { - CultureInfo neutralLanguageCultureInfo = new(neutralLanguage); - Resources.Culture = neutralLanguageCultureInfo; - CommonResources.Culture = neutralLanguageCultureInfo; - ApiCompatibility.ResourceSingleton.ChangeCulture(neutralLanguageCultureInfo); + CultureInfo suppressionsCultureInfo = new(suppressionsCulture); + Resources.Culture = suppressionsCultureInfo; + CommonResources.Culture = suppressionsCultureInfo; + ApiCompatibility.ResourceSingleton.ChangeCulture(suppressionsCultureInfo); } // Initialize the service provider diff --git a/src/Compatibility/ApiCompat/Microsoft.DotNet.ApiCompat.Shared/ValidatePackage.cs b/src/Compatibility/ApiCompat/Microsoft.DotNet.ApiCompat.Shared/ValidatePackage.cs index 113de3d55cfe..4a62781c47ea 100644 --- a/src/Compatibility/ApiCompat/Microsoft.DotNet.ApiCompat.Shared/ValidatePackage.cs +++ b/src/Compatibility/ApiCompat/Microsoft.DotNet.ApiCompat.Shared/ValidatePackage.cs @@ -24,7 +24,7 @@ public static int Run(Func logFactory, bool enableRuleAttributesMustMatch, string[]? excludeAttributesFiles, bool enableRuleCannotChangeParameterName, - string neutralLanguage, + string suppressionsCulture, string? packagePath, bool runApiCompat, bool enableStrictModeForCompatibleTfms, @@ -40,10 +40,10 @@ public static int Run(Func logFactory, // to neutral. This guarantees that suppression files aren't language specific. if (generateSuppressionFile) { - CultureInfo neutralLanguageCultureInfo = new(neutralLanguage); - Resources.Culture = neutralLanguageCultureInfo; - CommonResources.Culture = neutralLanguageCultureInfo; - PackageValidation.ResourceSingleton.ChangeCulture(neutralLanguageCultureInfo); + CultureInfo suppressionsCultureInfo = new(suppressionsCulture); + Resources.Culture = suppressionsCultureInfo; + CommonResources.Culture = suppressionsCultureInfo; + PackageValidation.ResourceSingleton.ChangeCulture(suppressionsCultureInfo); } // If a runtime graph is provided, parse and use it for asset selection during the in-memory package construction. diff --git a/src/Compatibility/ApiCompat/Microsoft.DotNet.ApiCompat.Task/ValidateAssembliesTask.cs b/src/Compatibility/ApiCompat/Microsoft.DotNet.ApiCompat.Task/ValidateAssembliesTask.cs index 910a267fefa3..84e479359fa9 100644 --- a/src/Compatibility/ApiCompat/Microsoft.DotNet.ApiCompat.Task/ValidateAssembliesTask.cs +++ b/src/Compatibility/ApiCompat/Microsoft.DotNet.ApiCompat.Task/ValidateAssembliesTask.cs @@ -83,9 +83,9 @@ public class ValidateAssembliesTask : TaskBase public bool EnableRuleCannotChangeParameterName { get; set; } /// - /// The neutral language to use when generating suppression files. Defaults to en-US. + /// The culture to use in suppressions when is true. Defaults to en-US. /// - public string NeutralLanguage { get; set; } = "en-US"; + public string SuppressionsCulture { get; set; } = "en-US"; /// /// Performs api comparison checks in strict mode. @@ -149,7 +149,7 @@ protected override void ExecuteCore() EnableRuleAttributesMustMatch, ExcludeAttributesFiles, EnableRuleCannotChangeParameterName, - NeutralLanguage, + SuppressionsCulture, LeftAssemblies!, RightAssemblies!, EnableStrictMode, diff --git a/src/Compatibility/ApiCompat/Microsoft.DotNet.ApiCompat.Task/ValidatePackageTask.cs b/src/Compatibility/ApiCompat/Microsoft.DotNet.ApiCompat.Task/ValidatePackageTask.cs index 77d2c4046fe6..7c65363cfa64 100644 --- a/src/Compatibility/ApiCompat/Microsoft.DotNet.ApiCompat.Task/ValidatePackageTask.cs +++ b/src/Compatibility/ApiCompat/Microsoft.DotNet.ApiCompat.Task/ValidatePackageTask.cs @@ -109,9 +109,9 @@ public class ValidatePackageTask : TaskBase public string? NoWarn { get; set; } /// - /// The neutral language to use when generating suppression files. Defaults to en-US. + /// The culture to use in suppressions when is true. Defaults to en-US. /// - public string NeutralLanguage { get; set; } = "en-US"; + public string SuppressionsCulture { get; set; } = "en-US"; /// /// Assembly references grouped by target framework, for the assets inside the package. @@ -157,7 +157,7 @@ protected override void ExecuteCore() EnableRuleAttributesMustMatch, ExcludeAttributesFiles, EnableRuleCannotChangeParameterName, - NeutralLanguage, + SuppressionsCulture, PackageTargetPath!, RunApiCompat, EnableStrictModeForCompatibleTfms, diff --git a/src/Compatibility/ApiCompat/Microsoft.DotNet.ApiCompat.Task/build/Microsoft.DotNet.ApiCompat.ValidateAssemblies.Common.targets b/src/Compatibility/ApiCompat/Microsoft.DotNet.ApiCompat.Task/build/Microsoft.DotNet.ApiCompat.ValidateAssemblies.Common.targets index a0b4277352d7..2a95e0a11bb7 100644 --- a/src/Compatibility/ApiCompat/Microsoft.DotNet.ApiCompat.Task/build/Microsoft.DotNet.ApiCompat.ValidateAssemblies.Common.targets +++ b/src/Compatibility/ApiCompat/Microsoft.DotNet.ApiCompat.Task/build/Microsoft.DotNet.ApiCompat.ValidateAssemblies.Common.targets @@ -27,7 +27,7 @@ EnableRuleAttributesMustMatch="$(ApiCompatEnableRuleAttributesMustMatch)" ExcludeAttributesFiles="@(ApiCompatExcludeAttributesFile)" EnableRuleCannotChangeParameterName="$(ApiCompatEnableRuleCannotChangeParameterName)" - NeutralLanguage="$(ApiCompatNeutralLanguage)" + SuppressionsCulture="$(ApiCompatSuppressionsCulture)" EnableStrictMode="$(ApiCompatStrictMode)" LeftAssembliesReferences="@(ApiCompatLeftAssembliesReferences)" RightAssembliesReferences="@(ApiCompatRightAssembliesReferences)" diff --git a/src/Compatibility/ApiCompat/Microsoft.DotNet.ApiCompat.Tool/Program.cs b/src/Compatibility/ApiCompat/Microsoft.DotNet.ApiCompat.Tool/Program.cs index b2d7587f634d..8086a64d2195 100644 --- a/src/Compatibility/ApiCompat/Microsoft.DotNet.ApiCompat.Tool/Program.cs +++ b/src/Compatibility/ApiCompat/Microsoft.DotNet.ApiCompat.Tool/Program.cs @@ -84,9 +84,9 @@ static int Main(string[] args) Description = "If true, enables rule to check that the parameter names between public methods do not change.", Recursive = true }; - CliOption neutralLanguageOption = new("--neutral-language") + CliOption suppressionsCultureOption = new("--suppressions-culture") { - Description = "The neutral language to use when generating suppression files. Defaults to en-US.", + Description = "The culture to use in suppressions when the '--generate-suppression-file' argument is supplied. Defaults to en-US.", Recursive = true, DefaultValueFactory = _ => "en-US" }; @@ -164,7 +164,7 @@ static int Main(string[] args) rootCommand.Options.Add(enableRuleAttributesMustMatchOption); rootCommand.Options.Add(excludeAttributesFilesOption); rootCommand.Options.Add(enableRuleCannotChangeParameterNameOption); - rootCommand.Options.Add(neutralLanguageOption); + rootCommand.Options.Add(suppressionsCultureOption); rootCommand.Options.Add(leftAssembliesOption); rootCommand.Options.Add(rightAssembliesOption); @@ -193,7 +193,7 @@ static int Main(string[] args) bool enableRuleAttributesMustMatch = parseResult.GetValue(enableRuleAttributesMustMatchOption); string[]? excludeAttributesFiles = parseResult.GetValue(excludeAttributesFilesOption); bool enableRuleCannotChangeParameterName = parseResult.GetValue(enableRuleCannotChangeParameterNameOption); - string neutralLanguage = parseResult.GetValue(neutralLanguageOption)!; + string suppressionsCulture = parseResult.GetValue(suppressionsCultureOption)!; string[] leftAssemblies = parseResult.GetValue(leftAssembliesOption)!; string[] rightAssemblies = parseResult.GetValue(rightAssembliesOption)!; @@ -216,7 +216,7 @@ static int Main(string[] args) enableRuleAttributesMustMatch, excludeAttributesFiles, enableRuleCannotChangeParameterName, - neutralLanguage, + suppressionsCulture, leftAssemblies, rightAssemblies, strictMode, @@ -317,7 +317,7 @@ static int Main(string[] args) bool enableRuleAttributesMustMatch = parseResult.GetValue(enableRuleAttributesMustMatchOption); string[]? excludeAttributesFiles = parseResult.GetValue(excludeAttributesFilesOption); bool enableRuleCannotChangeParameterName = parseResult.GetValue(enableRuleCannotChangeParameterNameOption); - string neutralLanguage = parseResult.GetValue(neutralLanguageOption)!; + string suppressionsCulture = parseResult.GetValue(suppressionsCultureOption)!; string? package = parseResult.GetValue(packageArgument); bool runApiCompat = parseResult.GetValue(runApiCompatOption); @@ -342,7 +342,7 @@ static int Main(string[] args) enableRuleAttributesMustMatch, excludeAttributesFiles, enableRuleCannotChangeParameterName, - neutralLanguage, + suppressionsCulture, package, runApiCompat, enableStrictModeForCompatibleTfms, diff --git a/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.ApiCompat.ValidatePackage.targets b/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.ApiCompat.ValidatePackage.targets index 8e8c95e40c6e..53c7ab85666c 100644 --- a/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.ApiCompat.ValidatePackage.targets +++ b/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.ApiCompat.ValidatePackage.targets @@ -44,7 +44,7 @@ Copyright (c) .NET Foundation. All rights reserved. EnableRuleAttributesMustMatch="$(ApiCompatEnableRuleAttributesMustMatch)" ExcludeAttributesFiles="@(ApiCompatExcludeAttributesFile)" EnableRuleCannotChangeParameterName="$(ApiCompatEnableRuleCannotChangeParameterName)" - NeutralLanguage="$(ApiCompatNeutralLanguage)" + SuppressionsCulture="$(ApiCompatSuppressionsCulture)" RunApiCompat="$(RunApiCompat)" EnableStrictModeForCompatibleTfms="$(EnableStrictModeForCompatibleTfms)" EnableStrictModeForCompatibleFrameworksInPackage="$(EnableStrictModeForCompatibleFrameworksInPackage)" From 1531368792d98b4cb81e5a10f5259e8685752314 Mon Sep 17 00:00:00 2001 From: Viktor Hofer Date: Mon, 20 Jan 2025 20:02:37 +0100 Subject: [PATCH 4/4] Rename option again --- .../ValidateAssemblies.cs | 10 +++++----- .../ValidatePackage.cs | 10 +++++----- .../ValidateAssembliesTask.cs | 4 ++-- .../ValidatePackageTask.cs | 4 ++-- ...otNet.ApiCompat.ValidateAssemblies.Common.targets | 2 +- .../Microsoft.DotNet.ApiCompat.Tool/Program.cs | 12 ++++++------ .../Microsoft.NET.ApiCompat.ValidatePackage.targets | 2 +- 7 files changed, 22 insertions(+), 22 deletions(-) diff --git a/src/Compatibility/ApiCompat/Microsoft.DotNet.ApiCompat.Shared/ValidateAssemblies.cs b/src/Compatibility/ApiCompat/Microsoft.DotNet.ApiCompat.Shared/ValidateAssemblies.cs index 953c561fb405..6457d0a54554 100644 --- a/src/Compatibility/ApiCompat/Microsoft.DotNet.ApiCompat.Shared/ValidateAssemblies.cs +++ b/src/Compatibility/ApiCompat/Microsoft.DotNet.ApiCompat.Shared/ValidateAssemblies.cs @@ -22,7 +22,7 @@ public static int Run(Func logFactory, bool enableRuleAttributesMustMatch, string[]? excludeAttributesFiles, bool enableRuleCannotChangeParameterName, - string suppressionsCulture, + string suppressionCulture, string[] leftAssemblies, string[] rightAssemblies, bool enableStrictMode, @@ -36,10 +36,10 @@ public static int Run(Func logFactory, // to neutral. This guarantees that suppression files aren't language specific. if (generateSuppressionFile) { - CultureInfo suppressionsCultureInfo = new(suppressionsCulture); - Resources.Culture = suppressionsCultureInfo; - CommonResources.Culture = suppressionsCultureInfo; - ApiCompatibility.ResourceSingleton.ChangeCulture(suppressionsCultureInfo); + CultureInfo suppressionCultureInfo = new(suppressionCulture); + Resources.Culture = suppressionCultureInfo; + CommonResources.Culture = suppressionCultureInfo; + ApiCompatibility.ResourceSingleton.ChangeCulture(suppressionCultureInfo); } // Initialize the service provider diff --git a/src/Compatibility/ApiCompat/Microsoft.DotNet.ApiCompat.Shared/ValidatePackage.cs b/src/Compatibility/ApiCompat/Microsoft.DotNet.ApiCompat.Shared/ValidatePackage.cs index 4a62781c47ea..816835752ddf 100644 --- a/src/Compatibility/ApiCompat/Microsoft.DotNet.ApiCompat.Shared/ValidatePackage.cs +++ b/src/Compatibility/ApiCompat/Microsoft.DotNet.ApiCompat.Shared/ValidatePackage.cs @@ -24,7 +24,7 @@ public static int Run(Func logFactory, bool enableRuleAttributesMustMatch, string[]? excludeAttributesFiles, bool enableRuleCannotChangeParameterName, - string suppressionsCulture, + string suppressionCulture, string? packagePath, bool runApiCompat, bool enableStrictModeForCompatibleTfms, @@ -40,10 +40,10 @@ public static int Run(Func logFactory, // to neutral. This guarantees that suppression files aren't language specific. if (generateSuppressionFile) { - CultureInfo suppressionsCultureInfo = new(suppressionsCulture); - Resources.Culture = suppressionsCultureInfo; - CommonResources.Culture = suppressionsCultureInfo; - PackageValidation.ResourceSingleton.ChangeCulture(suppressionsCultureInfo); + CultureInfo suppressionCultureInfo = new(suppressionCulture); + Resources.Culture = suppressionCultureInfo; + CommonResources.Culture = suppressionCultureInfo; + PackageValidation.ResourceSingleton.ChangeCulture(suppressionCultureInfo); } // If a runtime graph is provided, parse and use it for asset selection during the in-memory package construction. diff --git a/src/Compatibility/ApiCompat/Microsoft.DotNet.ApiCompat.Task/ValidateAssembliesTask.cs b/src/Compatibility/ApiCompat/Microsoft.DotNet.ApiCompat.Task/ValidateAssembliesTask.cs index 84e479359fa9..cb3ab94afae3 100644 --- a/src/Compatibility/ApiCompat/Microsoft.DotNet.ApiCompat.Task/ValidateAssembliesTask.cs +++ b/src/Compatibility/ApiCompat/Microsoft.DotNet.ApiCompat.Task/ValidateAssembliesTask.cs @@ -85,7 +85,7 @@ public class ValidateAssembliesTask : TaskBase /// /// The culture to use in suppressions when is true. Defaults to en-US. /// - public string SuppressionsCulture { get; set; } = "en-US"; + public string SuppressionCulture { get; set; } = "en-US"; /// /// Performs api comparison checks in strict mode. @@ -149,7 +149,7 @@ protected override void ExecuteCore() EnableRuleAttributesMustMatch, ExcludeAttributesFiles, EnableRuleCannotChangeParameterName, - SuppressionsCulture, + SuppressionCulture, LeftAssemblies!, RightAssemblies!, EnableStrictMode, diff --git a/src/Compatibility/ApiCompat/Microsoft.DotNet.ApiCompat.Task/ValidatePackageTask.cs b/src/Compatibility/ApiCompat/Microsoft.DotNet.ApiCompat.Task/ValidatePackageTask.cs index 7c65363cfa64..614ffa404df9 100644 --- a/src/Compatibility/ApiCompat/Microsoft.DotNet.ApiCompat.Task/ValidatePackageTask.cs +++ b/src/Compatibility/ApiCompat/Microsoft.DotNet.ApiCompat.Task/ValidatePackageTask.cs @@ -111,7 +111,7 @@ public class ValidatePackageTask : TaskBase /// /// The culture to use in suppressions when is true. Defaults to en-US. /// - public string SuppressionsCulture { get; set; } = "en-US"; + public string SuppressionCulture { get; set; } = "en-US"; /// /// Assembly references grouped by target framework, for the assets inside the package. @@ -157,7 +157,7 @@ protected override void ExecuteCore() EnableRuleAttributesMustMatch, ExcludeAttributesFiles, EnableRuleCannotChangeParameterName, - SuppressionsCulture, + SuppressionCulture, PackageTargetPath!, RunApiCompat, EnableStrictModeForCompatibleTfms, diff --git a/src/Compatibility/ApiCompat/Microsoft.DotNet.ApiCompat.Task/build/Microsoft.DotNet.ApiCompat.ValidateAssemblies.Common.targets b/src/Compatibility/ApiCompat/Microsoft.DotNet.ApiCompat.Task/build/Microsoft.DotNet.ApiCompat.ValidateAssemblies.Common.targets index 2a95e0a11bb7..e0ec1aa4dd8e 100644 --- a/src/Compatibility/ApiCompat/Microsoft.DotNet.ApiCompat.Task/build/Microsoft.DotNet.ApiCompat.ValidateAssemblies.Common.targets +++ b/src/Compatibility/ApiCompat/Microsoft.DotNet.ApiCompat.Task/build/Microsoft.DotNet.ApiCompat.ValidateAssemblies.Common.targets @@ -27,7 +27,7 @@ EnableRuleAttributesMustMatch="$(ApiCompatEnableRuleAttributesMustMatch)" ExcludeAttributesFiles="@(ApiCompatExcludeAttributesFile)" EnableRuleCannotChangeParameterName="$(ApiCompatEnableRuleCannotChangeParameterName)" - SuppressionsCulture="$(ApiCompatSuppressionsCulture)" + SuppressionCulture="$(ApiCompatSuppressionCulture)" EnableStrictMode="$(ApiCompatStrictMode)" LeftAssembliesReferences="@(ApiCompatLeftAssembliesReferences)" RightAssembliesReferences="@(ApiCompatRightAssembliesReferences)" diff --git a/src/Compatibility/ApiCompat/Microsoft.DotNet.ApiCompat.Tool/Program.cs b/src/Compatibility/ApiCompat/Microsoft.DotNet.ApiCompat.Tool/Program.cs index 8086a64d2195..f7d0913fab9d 100644 --- a/src/Compatibility/ApiCompat/Microsoft.DotNet.ApiCompat.Tool/Program.cs +++ b/src/Compatibility/ApiCompat/Microsoft.DotNet.ApiCompat.Tool/Program.cs @@ -84,7 +84,7 @@ static int Main(string[] args) Description = "If true, enables rule to check that the parameter names between public methods do not change.", Recursive = true }; - CliOption suppressionsCultureOption = new("--suppressions-culture") + CliOption suppressionCultureOption = new("--suppression-culture") { Description = "The culture to use in suppressions when the '--generate-suppression-file' argument is supplied. Defaults to en-US.", Recursive = true, @@ -164,7 +164,7 @@ static int Main(string[] args) rootCommand.Options.Add(enableRuleAttributesMustMatchOption); rootCommand.Options.Add(excludeAttributesFilesOption); rootCommand.Options.Add(enableRuleCannotChangeParameterNameOption); - rootCommand.Options.Add(suppressionsCultureOption); + rootCommand.Options.Add(suppressionCultureOption); rootCommand.Options.Add(leftAssembliesOption); rootCommand.Options.Add(rightAssembliesOption); @@ -193,7 +193,7 @@ static int Main(string[] args) bool enableRuleAttributesMustMatch = parseResult.GetValue(enableRuleAttributesMustMatchOption); string[]? excludeAttributesFiles = parseResult.GetValue(excludeAttributesFilesOption); bool enableRuleCannotChangeParameterName = parseResult.GetValue(enableRuleCannotChangeParameterNameOption); - string suppressionsCulture = parseResult.GetValue(suppressionsCultureOption)!; + string suppressionCulture = parseResult.GetValue(suppressionCultureOption)!; string[] leftAssemblies = parseResult.GetValue(leftAssembliesOption)!; string[] rightAssemblies = parseResult.GetValue(rightAssembliesOption)!; @@ -216,7 +216,7 @@ static int Main(string[] args) enableRuleAttributesMustMatch, excludeAttributesFiles, enableRuleCannotChangeParameterName, - suppressionsCulture, + suppressionCulture, leftAssemblies, rightAssemblies, strictMode, @@ -317,7 +317,7 @@ static int Main(string[] args) bool enableRuleAttributesMustMatch = parseResult.GetValue(enableRuleAttributesMustMatchOption); string[]? excludeAttributesFiles = parseResult.GetValue(excludeAttributesFilesOption); bool enableRuleCannotChangeParameterName = parseResult.GetValue(enableRuleCannotChangeParameterNameOption); - string suppressionsCulture = parseResult.GetValue(suppressionsCultureOption)!; + string suppressionCulture = parseResult.GetValue(suppressionCultureOption)!; string? package = parseResult.GetValue(packageArgument); bool runApiCompat = parseResult.GetValue(runApiCompatOption); @@ -342,7 +342,7 @@ static int Main(string[] args) enableRuleAttributesMustMatch, excludeAttributesFiles, enableRuleCannotChangeParameterName, - suppressionsCulture, + suppressionCulture, package, runApiCompat, enableStrictModeForCompatibleTfms, diff --git a/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.ApiCompat.ValidatePackage.targets b/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.ApiCompat.ValidatePackage.targets index 53c7ab85666c..5e70c2a5ef93 100644 --- a/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.ApiCompat.ValidatePackage.targets +++ b/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.ApiCompat.ValidatePackage.targets @@ -44,7 +44,7 @@ Copyright (c) .NET Foundation. All rights reserved. EnableRuleAttributesMustMatch="$(ApiCompatEnableRuleAttributesMustMatch)" ExcludeAttributesFiles="@(ApiCompatExcludeAttributesFile)" EnableRuleCannotChangeParameterName="$(ApiCompatEnableRuleCannotChangeParameterName)" - SuppressionsCulture="$(ApiCompatSuppressionsCulture)" + SuppressionCulture="$(ApiCompatSuppressionCulture)" RunApiCompat="$(RunApiCompat)" EnableStrictModeForCompatibleTfms="$(EnableStrictModeForCompatibleTfms)" EnableStrictModeForCompatibleFrameworksInPackage="$(EnableStrictModeForCompatibleFrameworksInPackage)"