Skip to content

[New MSBuild Task] Allow filtering a set of Items by matching on compatible RuntimeIdentifier #50614

@baronfel

Description

@baronfel

Is your feature request related to a problem? Please describe.

While working on the container incrementality I kept running into the problem of wanting to gather a bunch of assets at one time, but filter down to the subset of that list that were compatible with a specific Runtime Identifier. Note this is not equality - we could do that in raw MSbuild. Checking for RID compatibility is a more complex task, so we should provide a primitive for it.

Describe the solution you'd like

We should provide a Task that filters an Item list by those items that contain a specific Metadata that is compatible with a specified Runtime Identifier, according to a given RuntimeIdentifierGraph file.

Given

  • a required path to a RuntimeIdentifierGraph
  • a required list of candidate Items
  • an optional string that is the name of the MSBuild metadata to check on each of those items, defaulting to "RuntimeIdentifier"
  • a required target Runtime Identifier

The task would load the RID graph and iterate over each of the given items, yielding those that matched the candidate RID according to the given metadata and RID graph.

A sample implementation might look like:

public class SelectRuntimeIdentifierSpecificItems : Microsoft.Build.Utilities.Task
{
    [Required]
    public string TargetRuntimeIdentifier { get; set; } = string.Empty;

    [Required]
    public ITaskItem[] Items { get; set; } = [];
    
    public string RuntimeIdentifierItemMetadata { get; set; } = "RuntimeIdentifier"

    [Required]
    public string RuntimeIdentifierGraphPath { get; set; } = string.Empty;

    [Output]
    public ITaskItem[] SelectedItems { get; set; } = [];

    public void Cancel() => _cts.Cancel();

    public override bool Execute()
    {
        var graph = NuGet.RuntimeModel.JsonRuntimeFormat.ReadRuntimeGraph(RuntimeIdentifierGraphPath);

        var selectedItems = new List<ITaskItem>(Items.Length);
        foreach (var item in Items)
        {
            if (item.GetMetadata(RuntimeIdentifierItemMetadata) is string ridValue &&
                !string.IsNullOrEmpty(ridValue) &&
                graph.AreCompatible(TargetRuntimeIdentifier, ridValue))
            {
                selectedItems.Add(item);
            }
        }

        SelectedItems = selectedItems.ToArray();
        return true;
    }
}

Metadata

Metadata

Assignees

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions