Skip to content

Commit

Permalink
Properly evaluate PackInference.PackExclude
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
kzu committed Jul 19, 2021
1 parent 35b0a51 commit d62ddfe
Show file tree
Hide file tree
Showing 5 changed files with 111 additions and 4 deletions.
62 changes: 62 additions & 0 deletions src/NuGetizer.Tasks/EvaluateWildcards.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
using Minimatch;

namespace NuGetizer.Tasks
{
/// <summary>
/// Evaluates one or more minimatch expressions against a set of
/// items and returns two lists: those that matched and those that
/// didn't.
/// </summary>
public class EvaluateWildcards : Task
{
[Required]
public ITaskItem[] Items { get; set; }

[Required]
public string Wildcards { get; set; }

[Output]
public ITaskItem[] MatchingItems { get; set; }

[Output]
public ITaskItem[] NonMatchingItems { get; set; }

public override bool Execute()
{
var matching = new List<ITaskItem>();
var nonMatching = new List<ITaskItem>();

var options = new Options
{
AllowWindowsPaths = true,
Dot = true,
IgnoreCase = true
};

var matchers = Wildcards
.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries)
.Select(wildcard => new Minimatcher(wildcard.Trim(), options))
.ToList();

foreach (var item in Items)
{
if (matchers.Any(matcher => matcher.IsMatch(item.ItemSpec)) ||
matchers.Any(matcher => matcher.IsMatch(item.GetMetadata("Fullpath"))))
matching.Add(item);
else
nonMatching.Add(item);
}

MatchingItems = matching.ToArray();
NonMatchingItems = nonMatching.ToArray();

return true;
}
}
}
4 changes: 2 additions & 2 deletions src/NuGetizer.Tasks/Extensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ public static string GetShortFrameworkName(this FrameworkName frameworkName)
public static void LogErrorCode(this TaskLoggingHelper log, string code, string message, params object[] messageArgs) =>
log.LogError(string.Empty, code, string.Empty, string.Empty, 0, 0, 0, 0, message, messageArgs);

public static void LogWarningCode(this TaskLoggingHelper log, string code, string file, string message, params object[] messageArgs) =>
log.LogWarning(string.Empty, code, string.Empty, file, 0, 0, 0, 0, message, messageArgs);
public static void LogWarningCode(this TaskLoggingHelper log, string code, string message, params object[] messageArgs) =>
log.LogWarning(string.Empty, code, string.Empty, string.Empty, 0, 0, 0, 0, message, messageArgs);
}
}
18 changes: 16 additions & 2 deletions src/NuGetizer.Tasks/NuGetizer.Inference.targets
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ Copyright (c) .NET Foundation. All rights reserved.
-->
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<UsingTask TaskName="NuGetizer.Tasks.InferImplicitPackageReference" AssemblyFile="NuGetizer.Tasks.dll" />
<UsingTask TaskName="NuGetizer.Tasks.EvaluateWildcards" AssemblyFile="NuGetizer.Tasks.dll" />

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

<Target Name="InferPackageContents" DependsOnTargets="$(InferPackageContentsDependsOn)" Returns="@(PackageFile)">
<Target Name="_CollectInferenceCandidates" Inputs="@(PackInference)" Outputs="%(PackInference.Identity)-BATCH">
<PropertyGroup>
<PackExclude>%(PackInference.PackExclude)</PackExclude>
</PropertyGroup>
<!-- If we have an exclude wildcard to evaluate, do so and keep only non-matching items -->
<EvaluateWildcards Condition="'$(PackExclude)' != ''" Items="@(%(PackInference.Identity))" Wildcards="$(PackExclude)">
<Output TaskParameter="NonMatchingItems" ItemName="InferenceCandidate" />
</EvaluateWildcards>
<!-- Otherwise, just include all items as candidates -->
<ItemGroup Condition="'$(PackExclude)' == ''">
<InferenceCandidate Include="@(%(PackInference.Identity))" />
</ItemGroup>
</Target>

<Target Name="InferPackageContents" DependsOnTargets="$(InferPackageContentsDependsOn);_CollectInferenceCandidates" Returns="@(PackageFile)">
<ItemGroup>
<InferenceCandidate Include="@(%(PackInference.Identity))" Exclude="@(%(PackInference.Identity) -> '%(PackExclude)')"/>
<InferenceCandidate>
<ShouldPack Condition="('%(Pack)' == 'true' or '%(PackagePath)' != '' or '%(PackFolder)' != '' or '%(PackageReference)' != '') and '%(Pack)' != 'false'">true</ShouldPack>
</InferenceCandidate>
Expand Down
1 change: 1 addition & 0 deletions src/NuGetizer.Tasks/NuGetizer.Tasks.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
<PackageReference Include="NuGet.Packaging" Version="5.10.0" PrivateAssets="all" />
<PackageReference Include="NuGet.ProjectManagement" Version="4.2.0" PrivateAssets="all" />
<PackageReference Include="ThisAssembly" Version="1.0.8" PrivateAssets="all" />
<PackageReference Include="Minimatch" Version="2.0.0" PrivateAssets="all" />
</ItemGroup>

<ItemGroup>
Expand Down
30 changes: 30 additions & 0 deletions src/NuGetizer.Tests/given_packinference.cs
Original file line number Diff line number Diff line change
Expand Up @@ -541,6 +541,36 @@ public void when_adding_new_inference_then_can_change_defaults()
}));
}

[Fact]
public void when_updating_inference_then_can_exclude_by_wildcard()
{
var result = Builder.BuildProject(@"
<Project Sdk='Microsoft.NET.Sdk'>
<PropertyGroup>
<PackageId>Library</PackageId>
<TargetFramework>netstandard2.0</TargetFramework>
<PackNone>true</PackNone>
</PropertyGroup>
<ItemGroup>
<PackInference Update='Content' PackExclude='**/*grpc*.*' />
<Content Include='C:\Users\myuser\.nuget\packages\grpc.core\2.38.1\runtimes\win-x86\native\grpc_csharp_ext.x86.dll' />
<Content Include='C:\Users\danie\.nuget\packages\grpc.core\2.38.1\build\net45\..\..\runtimes\win-x86\native\grpc_csharp_ext.x86.dll' />
<Content Include='.\..\..\runtimes\win-x86\native\grpc_csharp_ext.x86.dll' />
<PackInference Update='None' PackExclude='**\*grpc*.*' />
<None Include='C:\Users\myuser\.nuget\packages\grpc.core\2.38.1\runtimes\win-x86\native\grpc_csharp_ext.x86.dll' />
<None Include='C:/Users/myuser/.nuget/packages/grpc.core/2.38.1/runtimes/win-x86/native/grpc_csharp_ext.x86.dll' />
</ItemGroup>
</Project>",
"GetPackageContents", output);

result.AssertSuccess(output);
Assert.DoesNotContain(result.Items, item => item.Matches(new
{
Filename = "grpc_csharp_ext.x86",
}));
}

[Fact]
public void when_direct_and_indirect_packagereference_then_packs_once()
{
Expand Down

0 comments on commit d62ddfe

Please sign in to comment.