dotnet / dotnet/msbuild

Introduce concept of a non-file item

Open
#982 0 comments 4 reactions 0 assignees View on GitHub
Area: Language triaged
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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.