Make a way for Target authors to easily clean up unused/intermediate Items after Target invocation
- Dominant language
- C#
- Stars
- 5.5k
- Forks
- 1.5k
- Avg merge
- 1d 8h
- Merged PRs (30d)
- 141
Description
### Summary
Today it's common for authors of MSBuild Target logic to create Items in Targets for many reasons:
* need to store per-item metadata/computed values
* incrementally build up to a solution
* track specific steps through a complex filtering/sorting workflow
An example of this is the following code from MSBuildLocator:
```xml
<_MSBuildAssembliesCopyLocalItems Include="@(RuntimeCopyLocalItems->WithMetadataValue('NuGetPackageId', 'Microsoft.Build'))" />
<_MSBuildAssembliesCopyLocalItems Include="@(RuntimeCopyLocalItems->WithMetadataValue('NuGetPackageId', 'Microsoft.Build.Framework'))" />
<_MSBuildAssembliesCopyLocalItems Include="@(RuntimeCopyLocalItems->WithMetadataValue('NuGetPackageId', 'Microsoft.Build.Utilities.Core'))" />
<_MSBuildAssembliesCopyLocalItems Include="@(RuntimeCopyLocalItems->WithMetadataValue('NuGetPackageId', 'Microsoft.Build.Tasks.Core'))" />
<_MSBuildAssembliesCopyLocalItems Include="@(RuntimeCopyLocalItems->WithMetadataValue('NuGetPackageId', 'Microsoft.Build.Engine'))" />
<_MSBuildAssembliesCopyLocalItems Include="@(RuntimeCopyLocalItems->WithMetadataValue('NuGetPackageId', 'Microsoft.Build.Conversion.Core'))" />
<_MSBuildAssembliesCopyLocalItems Include="@(RuntimeCopyLocalItems->WithMetadataValue('NuGetPackageId', 'Microsoft.Build.Runtime'))" />
<_MSBuildAssembliesCopyLocalItems Include="@(RuntimeCopyLocalItems->WithMetadataValue('NuGetPackageId', 'Microsoft.Build.Localization'))" />
<_MSBuildAssembliesCopyLocalItems Include="@(RuntimeCopyLocalItems->WithMetadataValue('NuGetPackageId', 'Microsoft.Build.Engine'))" />
<_MSBuildAssembliesCopyLocalItems Include="@(RuntimeCopyLocalItems->WithMetadataValue('NuGetPackageId', 'Microsoft.NET.StringTools'))" />
<_MSBuildAssembliesCopyLocalItems Include="@(RuntimeCopyLocalItems->WithMetadataValue('NuGetPackageId', 'NuGet.Frameworks'))" />
<_DistinctMSBuildPackagesReferencedPoorly Include="@(MSBuildAssembliesCopyLocalItems->Metadata('NuGetPackageId')->Distinct())" />
```
Where a list of candidates is built up over time in progressive steps, then used to compute a list of PackageReferences that violate the MSBuild Locator packaging rules. In projects with many references this intermediate list can represent hundreds of Items.
These Items often represent discrete steps towards a final goal, but one that goal is accomplished they remain in the engine because there's no clear indicator in the engine if something is actually _consuming_ those items or not.
Today, users must remember to manually clean up these lists (which we haven't done at time of writing in Locator!).
While we can add [tooling](https://github.com/dotnet/msbuild/pull/12887) that warns users when this happens, we should have a more first-class way to annotate that items can be automatically cleaned up by the engine after Target invocation.
### Background and Motivation
* Improved memory usage of the build
* Reduced developer cognitive load
### Proposed Feature
There are a few ways of approaching this, I'll highlight a few in brief:
* The engine could track usage itself and have some logic for when to clean up Items
* Difficult to know for certain because Inputs and Outputs of Targets aren't comprehensive today - could lead to premature deletions
* The individual Items could support a metadata that signaled that they could be deleted after Target Invocation
* `<_MyThing Include="..." AutoRemove="true" />`
* Annoying because it's a bit manual, it makes the 'easy' thing the non-performant thing
* Metadata name is subject to collisions - if we choose a common name we alter semantics for existing code, if we choose an ugly-but-unique name it's hard for users to remember and use
* The Target could support declaring names of Item lists to remove after execution
* `...`
* semi-declarative, shows intent, relatively easily tool-able?
### Alternative Designs
_No response_
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.