Bug 27171 - Add support for referencing item metadata within items
Summary: Add support for referencing item metadata within items
Status: RESOLVED DUPLICATE of bug 26350
Alias: None
Product: Tools
Classification: Mono
Component: xbuild ()
Version: unspecified
Hardware: PC All
: --- enhancement
Target Milestone: ---
Assignee: Bugzilla
Depends on:
Reported: 2015-02-18 01:16 UTC by Brendan Zagaeski (Xamarin Team, assistant)
Modified: 2015-05-27 19:09 UTC (History)
1 user (show)

Is this bug a regression?: ---
Last known good build:

Test case (4.54 KB, application/zip)
2015-02-18 01:16 UTC, Brendan Zagaeski (Xamarin Team, assistant)

Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.

Please create a new report on GitHub or Developer Community with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:

Description Brendan Zagaeski (Xamarin Team, assistant) 2015-02-18 01:16:06 UTC
Created attachment 9895 [details]
Test case

Add support for referencing item metadata within items.

`xbuild` currently supports `%()`-style item metadata references (such as the "well-known item metadata" [1]) within Targets, but it does not support those references within item metadata elements themselves (for example, within the Compile -> Link element). MSBuild on Windows _does_ support item metadata references within items. This might be a nice little feature to add to `xbuild`.

> [1] https://msdn.microsoft.com/en-us/library/ms164313.aspx

## Steps to reproduce

1. Build the attached test case using `xbuild` on Mac:
> $ xbuild /t:Build ContentLinkItemMetadata.sln

2. Run the resulting executable:
> mono ContentLinkItemMetadata/bin/Debug/ContentLinkItemMetadata.exe

The core of the test case is the following 4 lines in the `.csproj`:

> <Content Include="Subfolder1\**\*.*">
>   <Link>%(RecursiveDir)%(Filename)%(Extension)</Link>
>   <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
> </Content>

## Results

The app fails because it cannot locate the ".txt" resource files:
> System.IO.FileNotFoundException: Could not find file "/Users/macuser/Projects/ContentLinkItemMetadata/ContentLinkItemMetadata/bin/Debug/Subfolder2\Resource1.txt".

During the build, "Resource1.txt" is copied to the following path:
> ContentLinkItemMetadata/bin/Debug/%(RecursiveDir)%(Filename)%(Extension)

Note that the path contains literal %() expressions because they are not evaluated by `xbuild` during the build.

## Expected results

If you build and run the app on Windows using `msbuild`, the app runs successfully and outputs the contents of the 2 files:

> C:\Source\ContentLinkItemMetadata>ContentLinkItemMetadata\bin\Debug\ContentLinkItemMetadata.exe
> Hello from resource 1.
> Hello from resource 2.

The 2 files are copied to the "Subfolder2" subdirectory during the build:
> ContentLinkItemMetadata\bin\Debug\Subfolder2\Resource1.txt
> ContentLinkItemMetadata\bin\Debug\Subfolder2\Resource2.txt

## `xbuild` does already support item metadata references in _Targets_

Just to add a bit more context to the bug report, I'll note that although the 3 item metadata references used in the test case do not currently work within Items, they do work within Targets.

For example, you can add the following target at the bottom of the `.csproj`:

> <Target Name="ShowMessage">
>   <Message
>     Text = "%(Content.RecursiveDir)%(Content.Filename)%(Content.Extension)"/>
> </Target>

... and then build the ShowMessage target:
> $ xbuild /t:ShowMessage ContentLinkItemMetadata/ContentLinkItemMetadata.csproj

And the output is correct:
> Target ShowMessage:
> 	Subfolder2/Resource1.txt
> 	Subfolder2/Resource2.txt

## Version information

Mono 3.12.0 (detached/de2f33f)
Comment 1 Brendan Zagaeski (Xamarin Team, assistant) 2015-02-18 01:17:27 UTC
Here's another more concise example, in case it might be more convenient.

1. Paste the following text into a file (for example, `Test.csproj`).

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <MyItem Include="Foo">
  <Target Name="ShowMessages">
    <Message Text="MyItem.Metadata1=%(MyItem.Metadata1)" />
    <Message Text="MyItem.Metadata2=%(MyItem.Metadata2)" />

2. Run `xbuild /t:ShowMessages Test.csproj`.

## Result with `xbuild`
> MyItem.Metadata1=%(MyItem.Identity)
> MyItem.Metadata2=%(Metadata1)

## Result with `msbuild`
> MyItem.Metadata1=Foo
> MyItem.Metadata2=Foo
Comment 2 Brendan Zagaeski (Xamarin Team, assistant) 2015-05-27 19:09:49 UTC

*** This bug has been marked as a duplicate of bug 26350 ***