Introduce concept of a non-file item
- Dominant language
- C#
- Stars
- 5.5k
- Forks
- 1.5k
- Avg merge
- 1d 13h
- Merged PRs (30d)
- 133
Description
## Problem
While MSBuild items are designed to be a list of named things and not necessarily files, there are two things that get in the way to make this actually work successfully:
### "*" in Include has meaning
If your non-file item's identity includes a wild card, such as:
``` XML
```
Then this is interpreted as wild card pattern, causing MSBuild to not only hit the disk on expansion but resulting in a list of zero items (assuming no files match the pattern).
This restricts the allowable values inside an Include[1] and greatly hinders the design of new things that we would like to bring forward into MSBuild (such as a PackageReference).
[1] Note, you can can escape the character, but do so you need to use the ASCII sequence; %2A, which is not very user readable/writable.
### Retrieving built-in metadata throws
If you ask an non-file item that contains invalid path characters for a list of its metadata via ITaskItem.Metadata, it includes built-in metadata such as %(FullPath) and %(Filename), but throws (InvalidOperationException) when you attempt to retrieve said metadata via ITaskItem.GetMetadata.
There's no way to figure out up-front if this is going to succeed, which can be problematic for a system that sits on top of MSBuild like the Common Project System (CPS). CPS takes snapshots (including built-in metadata) of items between evaluations and design-time builds, so that it can expose a diff of what's changed from evaluation to evaluation or from design-time build to design-time build. If those consumers are interested in non-file items (such as the new C#/VB project system's representation of Csc/Vbc's command-line arguments) - these exceptions need to be handled, ruining debugability due to the large number of first-chance exceptions.
With the new project system, in a standard .NET Core project, **_there's over >2200 (2 per built-in metadata item x 11 metadata items x ~100 items) first-chance exceptions alone for every design-time build**_.
## Proposal
To resolve the above problems, I'd like to introduce the concept of a non-file item. This will be indicated by a new attribute an ItemDefinitionGroup called _IsFile_:
``` XML
```
By default, not specifying IsFile will be the same as setting it to _true_ and will cause MSBuild to treat items exactly the same way as it treats them today.
When _false_, MSBuild will:
1) Not treat \* as a wild card in the Include attribute for an item of that type, instead it will be treated as a literal (as if you'd specified the escape sequence %2A) .
2) ITaskItem.Metadata will not contain the following built-in metadata for a non-file item:
| Name |
| --- |
| FullPath |
| RootDir |
| Filename |
| Extension |
| RelativeDir |
| Directory |
| ModifiedTime |
| CreatedTime |
| AccessedTime |
Contributor guide
No contributing guide indexed for this repository
Research direction
Use the proposal as the starting point: review ItemDefinitionGroup, the IsFile attribute, wildcard handling in Include, and ITaskItem.Metadata behavior. The work is done when non-file items preserve literal wildcards and omit the listed file metadata while existing file-item behavior remains unchanged.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- csharp
- Domain
- build-system
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 25/100