Skip to content

Commit 12704db

Browse files
committed
Add option to ignore baseline TFMs
Fixes #22901 Add frontend option to allow ignoring TFMs when performing baseline package validation.
1 parent 6710347 commit 12704db

File tree

7 files changed

+70
-21
lines changed

7 files changed

+70
-21
lines changed

src/Compatibility/ApiCompat/Microsoft.DotNet.ApiCompat.Shared/ValidatePackage.cs

+4-2
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ public static void Run(Func<ISuppressionEngine, ISuppressibleLog> logFactory,
3030
string? baselinePackagePath,
3131
string? runtimeGraph,
3232
IReadOnlyDictionary<NuGetFramework, IEnumerable<string>>? packageAssemblyReferences,
33-
IReadOnlyDictionary<NuGetFramework, IEnumerable<string>>? baselinePackageAssemblyReferences)
33+
IReadOnlyDictionary<NuGetFramework, IEnumerable<string>>? baselinePackageAssemblyReferences,
34+
string[]? baselinePackageFrameworksToIgnore)
3435
{
3536
// Initialize the service provider
3637
ApiCompatServiceProvider serviceProvider = new(logFactory,
@@ -70,7 +71,8 @@ public static void Run(Func<ISuppressionEngine, ISuppressibleLog> logFactory,
7071
enableStrictMode: enableStrictModeForBaselineValidation,
7172
enqueueApiCompatWorkItems: runApiCompat,
7273
executeApiCompatWorkItems: false,
73-
baselinePackage: Package.Create(baselinePackagePath, baselinePackageAssemblyReferences)));
74+
Package.Create(baselinePackagePath, baselinePackageAssemblyReferences),
75+
baselinePackageFrameworksToIgnore));
7476
}
7577

7678
if (runApiCompat)

src/Compatibility/ApiCompat/Microsoft.DotNet.ApiCompat.Task/ValidatePackageTask.cs

+9-3
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,11 @@ public class ValidatePackageTask : TaskBase
118118
/// </summary>
119119
public ITaskItem[]? BaselinePackageAssemblyReferences { get; set; }
120120

121+
/// <summary>
122+
/// A set of target frameworks to ignore from the baseline package.
123+
/// </summary>
124+
public string[]? BaselinePackageFrameworksToIgnore { get; set; }
125+
121126
public override bool Execute()
122127
{
123128
RoslynResolver roslynResolver = RoslynResolver.Register(RoslynAssembliesPath!);
@@ -153,15 +158,16 @@ protected override void ExecuteCore()
153158
BaselinePackageTargetPath,
154159
RuntimeGraph,
155160
ParsePackageAssemblyReferences(PackageAssemblyReferences),
156-
ParsePackageAssemblyReferences(BaselinePackageAssemblyReferences));
161+
ParsePackageAssemblyReferences(BaselinePackageAssemblyReferences),
162+
BaselinePackageFrameworksToIgnore);
157163
}
158164

159165
private static Dictionary<NuGetFramework, IEnumerable<string>>? ParsePackageAssemblyReferences(ITaskItem[]? packageAssemblyReferences)
160166
{
161-
if (packageAssemblyReferences == null || packageAssemblyReferences.Length == 0)
167+
if (packageAssemblyReferences is null || packageAssemblyReferences.Length == 0)
162168
return null;
163169

164-
Dictionary<NuGetFramework, IEnumerable<string>>? packageAssemblyReferencesDict = new(packageAssemblyReferences.Length);
170+
Dictionary<NuGetFramework, IEnumerable<string>> packageAssemblyReferencesDict = new(packageAssemblyReferences.Length);
165171
foreach (ITaskItem taskItem in packageAssemblyReferences)
166172
{
167173
string targetFrameworkMoniker = taskItem.GetMetadata("TargetFrameworkMoniker");

src/Compatibility/ApiCompat/Microsoft.DotNet.ApiCompat.Tool/Program.cs

+10-1
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,12 @@ static int Main(string[] args)
270270
Arity = ArgumentArity.ZeroOrMore,
271271
HelpName = "tfm=file1,file2,..."
272272
};
273+
CliOption<string[]?> baselinePackageFrameworksToIgnoreOption = new("--baseline-package-target-frameworks-to-ignore")
274+
{
275+
Description = "A set of target frameworks to ignore from the baseline package.",
276+
AllowMultipleArgumentsPerToken = true,
277+
Arity = ArgumentArity.ZeroOrMore,
278+
};
273279

274280
CliCommand packageCommand = new("package", "Validates the compatibility of package assets");
275281
packageCommand.Arguments.Add(packageArgument);
@@ -281,6 +287,7 @@ static int Main(string[] args)
281287
packageCommand.Options.Add(baselinePackageOption);
282288
packageCommand.Options.Add(packageAssemblyReferencesOption);
283289
packageCommand.Options.Add(baselinePackageAssemblyReferencesOption);
290+
packageCommand.Options.Add(baselinePackageFrameworksToIgnoreOption);
284291
packageCommand.SetAction((ParseResult parseResult) =>
285292
{
286293
// If a roslyn assemblies path isn't provided, use the compiled against version from a subfolder.
@@ -309,6 +316,7 @@ static int Main(string[] args)
309316
string? runtimeGraph = parseResult.GetValue(runtimeGraphOption);
310317
Dictionary<NuGetFramework, IEnumerable<string>>? packageAssemblyReferences = parseResult.GetValue(packageAssemblyReferencesOption);
311318
Dictionary<NuGetFramework, IEnumerable<string>>? baselinePackageAssemblyReferences = parseResult.GetValue(baselinePackageAssemblyReferencesOption);
319+
string[]? baselinePackageFrameworksToIgnore = parseResult.GetValue(baselinePackageFrameworksToIgnoreOption);
312320

313321
SuppressibleConsoleLog logFactory(ISuppressionEngine suppressionEngine) => new(suppressionEngine, verbosity);
314322
ValidatePackage.Run(logFactory,
@@ -330,7 +338,8 @@ static int Main(string[] args)
330338
baselinePackage,
331339
runtimeGraph,
332340
packageAssemblyReferences,
333-
baselinePackageAssemblyReferences);
341+
baselinePackageAssemblyReferences,
342+
baselinePackageFrameworksToIgnore);
334343

335344
roslynResolver.Unregister();
336345
});

src/Compatibility/ApiCompat/Microsoft.DotNet.PackageValidation/Validators/BaselinePackageValidator.cs

+7-1
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,15 @@ public void Validate(PackageValidatorOption options)
2828

2929
ApiCompatRunnerOptions apiCompatOptions = new(options.EnableStrictMode, isBaselineComparison: true);
3030

31-
// Iterate over all target frameworks in the package.
3231
foreach (NuGetFramework baselineTargetFramework in options.BaselinePackage.FrameworksInPackage)
3332
{
33+
// Skip target frameworks excluded from the baseline package.
34+
if (options.BaselinePackageFrameworksToIgnore is not null &&
35+
options.BaselinePackageFrameworksToIgnore.Contains(baselineTargetFramework.GetShortFolderName()))
36+
{
37+
continue;
38+
}
39+
3440
// Retrieve the compile time assets from the baseline package
3541
IReadOnlyList<ContentItem>? baselineCompileAssets = options.BaselinePackage.FindBestCompileAssetForFramework(baselineTargetFramework);
3642
if (baselineCompileAssets != null)

src/Compatibility/ApiCompat/Microsoft.DotNet.PackageValidation/Validators/PackageValidatorOption.cs

+10-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ public readonly struct PackageValidatorOption(Package package,
1313
bool enableStrictMode = false,
1414
bool enqueueApiCompatWorkItems = true,
1515
bool executeApiCompatWorkItems = true,
16-
Package? baselinePackage = null)
16+
Package? baselinePackage = null,
17+
string[]? baselinePackageFrameworksToIgnore = null)
1718
{
1819
/// <summary>
1920
/// The latest package that should be validated.
@@ -39,5 +40,13 @@ public readonly struct PackageValidatorOption(Package package,
3940
/// The baseline package to validate the latest package.
4041
/// </summary>
4142
public Package? BaselinePackage { get; } = baselinePackage;
43+
44+
/// <summary>
45+
/// A set of frameworks to ignore from the baseline package.
46+
/// </summary>
47+
public HashSet<string>? BaselinePackageFrameworksToIgnore { get; } =
48+
baselinePackageFrameworksToIgnore is not null ?
49+
new HashSet<string>(baselinePackageFrameworksToIgnore) :
50+
null;
4251
}
4352
}

src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.ApiCompat.ValidatePackage.targets

+2-1
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,8 @@ Copyright (c) .NET Foundation. All rights reserved.
5555
SuppressionOutputFile="$(ApiCompatSuppressionOutputFile)"
5656
BaselinePackageTargetPath="$(_packageValidationBaselinePath)"
5757
RoslynAssembliesPath="$(RoslynAssembliesPath)"
58-
PackageAssemblyReferences="@(PackageValidationReferencePath)" />
58+
PackageAssemblyReferences="@(PackageValidationReferencePath)"
59+
BaselinePackageFrameworksToIgnore="@(BaselinePackageFrameworkToIgnore)" />
5960

6061
<MakeDir Directories="$([System.IO.Path]::GetDirectoryName('$(ApiCompatValidatePackageSemaphoreFile)'))" />
6162
<Touch Files="$(ApiCompatValidatePackageSemaphoreFile)" AlwaysCreate="true" />

src/Tests/Microsoft.DotNet.PackageValidation.Tests/Validators/BaselinePackageValidatorTests.cs

+28-12
Original file line numberDiff line numberDiff line change
@@ -22,18 +22,13 @@ public class BaselinePackageValidatorTests
2222
[Fact]
2323
public void TfmDroppedInLatestVersion()
2424
{
25-
string[] previousFilePaths = new[]
26-
{
27-
@"ref/netcoreapp3.1/TestPackage.dll",
28-
@"ref/netstandard2.0/TestPackage.dll"
29-
};
30-
Package baselinePackage = new(string.Empty, "TestPackage", "1.0.0", previousFilePaths, null);
31-
32-
string[] currentFilePaths = new[]
33-
{
34-
@"ref/netcoreapp3.1/TestPackage.dll"
35-
};
36-
Package package = new(string.Empty, "TestPackage", "2.0.0", currentFilePaths, null);
25+
Package baselinePackage = new(string.Empty, "TestPackage", "1.0.0",
26+
[
27+
@"lib/netcoreapp3.1/TestPackage.dll",
28+
@"lib/netstandard2.0/TestPackage.dll"
29+
]);
30+
Package package = new(string.Empty, "TestPackage", "2.0.0", [ @"lib/netcoreapp3.1/TestPackage.dll" ]);
31+
3732
(SuppressibleTestLog log, BaselinePackageValidator validator) = CreateLoggerAndValidator();
3833

3934
validator.Validate(new PackageValidatorOption(package,
@@ -44,5 +39,26 @@ public void TfmDroppedInLatestVersion()
4439
Assert.NotEmpty(log.errors);
4540
Assert.Contains(DiagnosticIds.TargetFrameworkDropped + " " + string.Format(Resources.MissingTargetFramework, ".NETStandard,Version=v2.0"), log.errors);
4641
}
42+
43+
[Fact]
44+
public void BaselineFrameworksExcluded()
45+
{
46+
Package baselinePackage = new(string.Empty, "TestPackage", "1.0.0",
47+
[
48+
@"lib/netcoreapp3.1/TestPackage.dll",
49+
@"lib/netstandard2.0/TestPackage.dll"
50+
]);
51+
Package package = new(string.Empty, "TestPackage", "2.0.0", [ @"lib/netstandard2.0/TestPackage.dll" ]);
52+
53+
(SuppressibleTestLog log, BaselinePackageValidator validator) = CreateLoggerAndValidator();
54+
55+
validator.Validate(new PackageValidatorOption(package,
56+
enableStrictMode: false,
57+
enqueueApiCompatWorkItems: false,
58+
baselinePackage: baselinePackage,
59+
baselinePackageFrameworksToIgnore: [ "netcoreapp3.1" ]));
60+
61+
Assert.Empty(log.errors);
62+
}
4763
}
4864
}

0 commit comments

Comments
 (0)