Skip to content

Commit 09b4534

Browse files
committed
Properly evaluate PackInference.PackExclude
We were previously assuming Exclude was a valuated while doing the Include for entire item groups, while this is not the case. We need instead to evaluate using the same MSBuild syntax (we use minimatch for this) so we can properly exclude items. Fixes #128 and #122.
1 parent 35b0a51 commit 09b4534

File tree

5 files changed

+111
-4
lines changed

5 files changed

+111
-4
lines changed
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.IO;
4+
using System.Linq;
5+
using Microsoft.Build.Framework;
6+
using Microsoft.Build.Utilities;
7+
using Minimatch;
8+
9+
namespace NuGetizer.Tasks
10+
{
11+
/// <summary>
12+
/// Evaluates one or more minimatch expressions against a set of
13+
/// items and returns two lists: those that matched and those that
14+
/// didn't.
15+
/// </summary>
16+
public class EvaluateWildcards : Task
17+
{
18+
[Required]
19+
public ITaskItem[] Items { get; set; }
20+
21+
[Required]
22+
public string Wildcards { get; set; }
23+
24+
[Output]
25+
public ITaskItem[] MatchingItems { get; set; }
26+
27+
[Output]
28+
public ITaskItem[] NonMatchingItems { get; set; }
29+
30+
public override bool Execute()
31+
{
32+
var matching = new List<ITaskItem>();
33+
var nonMatching = new List<ITaskItem>();
34+
35+
var options = new Options
36+
{
37+
AllowWindowsPaths = true,
38+
Dot = true,
39+
IgnoreCase = true
40+
};
41+
42+
var matchers = Wildcards
43+
.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries)
44+
.Select(wildcard => new Minimatcher(wildcard.Trim(), options))
45+
.ToList();
46+
47+
foreach (var item in Items)
48+
{
49+
if (matchers.Any(matcher => matcher.IsMatch(item.ItemSpec)) ||
50+
matchers.Any(matcher => matcher.IsMatch(item.GetMetadata("Fullpath"))))
51+
matching.Add(item);
52+
else
53+
nonMatching.Add(item);
54+
}
55+
56+
MatchingItems = matching.ToArray();
57+
NonMatchingItems = nonMatching.ToArray();
58+
59+
return true;
60+
}
61+
}
62+
}

src/NuGetizer.Tasks/Extensions.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ public static string GetShortFrameworkName(this FrameworkName frameworkName)
139139
public static void LogErrorCode(this TaskLoggingHelper log, string code, string message, params object[] messageArgs) =>
140140
log.LogError(string.Empty, code, string.Empty, string.Empty, 0, 0, 0, 0, message, messageArgs);
141141

142-
public static void LogWarningCode(this TaskLoggingHelper log, string code, string file, string message, params object[] messageArgs) =>
143-
log.LogWarning(string.Empty, code, string.Empty, file, 0, 0, 0, 0, message, messageArgs);
142+
public static void LogWarningCode(this TaskLoggingHelper log, string code, string message, params object[] messageArgs) =>
143+
log.LogWarning(string.Empty, code, string.Empty, string.Empty, 0, 0, 0, 0, message, messageArgs);
144144
}
145145
}

src/NuGetizer.Tasks/NuGetizer.Inference.targets

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ Copyright (c) .NET Foundation. All rights reserved.
1111
-->
1212
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
1313
<UsingTask TaskName="NuGetizer.Tasks.InferImplicitPackageReference" AssemblyFile="NuGetizer.Tasks.dll" />
14+
<UsingTask TaskName="NuGetizer.Tasks.EvaluateWildcards" AssemblyFile="NuGetizer.Tasks.dll" />
1415

1516
<PropertyGroup>
1617
<!-- The PackFolder of primary output (build, symbols, doc and satellite assemblies) set if PackBuildOutput = true -->
@@ -177,9 +178,22 @@ Copyright (c) .NET Foundation. All rights reserved.
177178
</ItemGroup>
178179
</Target>
179180

180-
<Target Name="InferPackageContents" DependsOnTargets="$(InferPackageContentsDependsOn)" Returns="@(PackageFile)">
181+
<Target Name="_CollectInferenceCandidates" Inputs="@(PackInference)" Outputs="%(PackInference.Identity)-BATCH">
182+
<PropertyGroup>
183+
<PackExclude>%(PackInference.PackExclude)</PackExclude>
184+
</PropertyGroup>
185+
<!-- If we have an exclude wildcard to evaluate, do so and keep only non-matching items -->
186+
<EvaluateWildcards Condition="'$(PackExclude)' != ''" Items="@(%(PackInference.Identity))" Wildcards="$(PackExclude)">
187+
<Output TaskParameter="NonMatchingItems" ItemName="InferenceCandidate" />
188+
</EvaluateWildcards>
189+
<!-- Otherwise, just include all items as candidates -->
190+
<ItemGroup Condition="'$(PackExclude)' == ''">
191+
<InferenceCandidate Include="@(%(PackInference.Identity))" />
192+
</ItemGroup>
193+
</Target>
194+
195+
<Target Name="InferPackageContents" DependsOnTargets="$(InferPackageContentsDependsOn);_CollectInferenceCandidates" Returns="@(PackageFile)">
181196
<ItemGroup>
182-
<InferenceCandidate Include="@(%(PackInference.Identity))" Exclude="@(%(PackInference.Identity) -> '%(PackExclude)')"/>
183197
<InferenceCandidate>
184198
<ShouldPack Condition="('%(Pack)' == 'true' or '%(PackagePath)' != '' or '%(PackFolder)' != '' or '%(PackageReference)' != '') and '%(Pack)' != 'false'">true</ShouldPack>
185199
</InferenceCandidate>

src/NuGetizer.Tasks/NuGetizer.Tasks.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
<PackageReference Include="NuGet.Packaging" Version="5.10.0" PrivateAssets="all" />
1515
<PackageReference Include="NuGet.ProjectManagement" Version="4.2.0" PrivateAssets="all" />
1616
<PackageReference Include="ThisAssembly" Version="1.0.8" PrivateAssets="all" />
17+
<PackageReference Include="Minimatch" Version="2.0.0" PrivateAssets="all" />
1718
</ItemGroup>
1819

1920
<ItemGroup>

src/NuGetizer.Tests/given_packinference.cs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -541,6 +541,36 @@ public void when_adding_new_inference_then_can_change_defaults()
541541
}));
542542
}
543543

544+
[Fact]
545+
public void when_updating_inference_then_can_exclude_by_wildcard()
546+
{
547+
var result = Builder.BuildProject(@"
548+
<Project Sdk='Microsoft.NET.Sdk'>
549+
<PropertyGroup>
550+
<PackageId>Library</PackageId>
551+
<TargetFramework>netstandard2.0</TargetFramework>
552+
<PackNone>true</PackNone>
553+
</PropertyGroup>
554+
<ItemGroup>
555+
<PackInference Update='Content' PackExclude='**/*grpc*.*' />
556+
<Content Include='C:\Users\myuser\.nuget\packages\grpc.core\2.38.1\runtimes\win-x86\native\grpc_csharp_ext.x86.dll' />
557+
<Content Include='C:\Users\danie\.nuget\packages\grpc.core\2.38.1\build\net45\..\..\runtimes\win-x86\native\grpc_csharp_ext.x86.dll' />
558+
<Content Include='.\..\..\runtimes\win-x86\native\grpc_csharp_ext.x86.dll' />
559+
560+
<PackInference Update='None' PackExclude='**\*grpc*.*' />
561+
<None Include='C:\Users\myuser\.nuget\packages\grpc.core\2.38.1\runtimes\win-x86\native\grpc_csharp_ext.x86.dll' />
562+
<None Include='C:/Users/myuser/.nuget/packages/grpc.core/2.38.1/runtimes/win-x86/native/grpc_csharp_ext.x86.dll' />
563+
</ItemGroup>
564+
</Project>",
565+
"GetPackageContents", output);
566+
567+
result.AssertSuccess(output);
568+
Assert.DoesNotContain(result.Items, item => item.Matches(new
569+
{
570+
Filename = "grpc_csharp_ext.x86",
571+
}));
572+
}
573+
544574
[Fact]
545575
public void when_direct_and_indirect_packagereference_then_packs_once()
546576
{

0 commit comments

Comments
 (0)