Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Automatic Link generation from LinkBase does not work for Page, Resource items #2697

Closed
nguerrera opened this issue Nov 27, 2018 · 2 comments · Fixed by #3390
Closed

Automatic Link generation from LinkBase does not work for Page, Resource items #2697

nguerrera opened this issue Nov 27, 2018 · 2 comments · Fixed by #3390
Assignees
Milestone

Comments

@nguerrera
Copy link
Contributor

(Filing bugs from my notes after customer visit exploring porting large WPF app to .NET core 3)

This:

<ItemGroup>
  <Page Include="..\X\**\*.xaml"  LinkBase="Y" />
</ItemGroup>

Does not work as it does for Compile, EmbeddedResource, AdditionalFiles, EmbeddedResource:

<!--
Automatically add Link metadata to items of specific types if they are outside of the project folder and don't already have the Link metadata set.
This will cause them to be shown in the Solution Explorer. If an item has LinkBase metadata, the automatic Link will start with that value, and
the items will appear in the Solution Explorer under the folder specified by LinkBase.
-->
<ItemGroup Condition="'$(SetLinkMetadataAutomatically)' != 'false'">
<Compile Update="@(Compile)">
<!-- First, add a trailing slash to the LinkBase metadata if necessary. This allows us to use the same value
for the Link metadata whether or not LinkBase metadata is set: %(LinkBase)%(RecursiveDir)%(Filename)%(Extension)
Note that RecursiveDir already includes the trailing slash.
-->
<LinkBase Condition="'%(LinkBase)' != ''">$([MSBuild]::EnsureTrailingSlash(%(LinkBase)))</LinkBase>
<!-- Set the Link metadata if it's not already set, if the item wasn't defined in a shared project, and the item is outside of the project directory.
Check whether the item was defined in a shared project by checking whether the extension of the defining project was .projitems.
Check whether an item is inside the project directory by seeing if the FullPath starts with EnsureTrailingSlash(MSBuildProjectDirectory)
The FullPath and the MSBuildProjectDirectory will both already be normalized full paths.
The call to [MSBuild]::ValueOrDefault() is there in order to allow calling StartsWith on the FullPath value, since it's
not possible to call a string method on a metadata item directly. The intrinsic ValueOrDefault() will be more
performant than calling String.Copy(), which has been used for this in other contexts, but actually makes a copy
of the string data.
-->
<Link Condition="'%(Link)' == '' And '%(DefiningProjectExtension)' != '.projitems' And !$([MSBuild]::ValueOrDefault('%(FullPath)', '').StartsWith($([MSBuild]::EnsureTrailingSlash($(MSBuildProjectDirectory)))))">%(LinkBase)%(RecursiveDir)%(Filename)%(Extension)</Link>
</Compile>
<AdditionalFiles Update="@(AdditionalFiles)">
<LinkBase Condition="'%(LinkBase)' != ''">$([MSBuild]::EnsureTrailingSlash(%(LinkBase)))</LinkBase>
<Link Condition="'%(Link)' == '' And '%(DefiningProjectExtension)' != '.projitems' And !$([MSBuild]::ValueOrDefault('%(FullPath)', '').StartsWith($([MSBuild]::EnsureTrailingSlash($(MSBuildProjectDirectory)))))">%(LinkBase)%(RecursiveDir)%(Filename)%(Extension)</Link>
</AdditionalFiles>
<None Update="@(None)">
<LinkBase Condition="'%(LinkBase)' != ''">$([MSBuild]::EnsureTrailingSlash(%(LinkBase)))</LinkBase>
<Link Condition="'%(Link)' == '' And '%(DefiningProjectExtension)' != '.projitems' And !$([MSBuild]::ValueOrDefault('%(FullPath)', '').StartsWith($([MSBuild]::EnsureTrailingSlash($(MSBuildProjectDirectory)))))">%(LinkBase)%(RecursiveDir)%(Filename)%(Extension)</Link>
</None>
<Content Update="@(Content)">
<LinkBase Condition="'%(LinkBase)' != ''">$([MSBuild]::EnsureTrailingSlash(%(LinkBase)))</LinkBase>
<Link Condition="'%(Link)' == '' And '%(DefiningProjectExtension)' != '.projitems' And !$([MSBuild]::ValueOrDefault('%(FullPath)', '').StartsWith($([MSBuild]::EnsureTrailingSlash($(MSBuildProjectDirectory)))))">%(LinkBase)%(RecursiveDir)%(Filename)%(Extension)</Link>
</Content>
<EmbeddedResource Update="@(EmbeddedResource)">
<LinkBase Condition="'%(LinkBase)' != ''">$([MSBuild]::EnsureTrailingSlash(%(LinkBase)))</LinkBase>
<Link Condition="'%(Link)' == '' And '%(DefiningProjectExtension)' != '.projitems' And !$([MSBuild]::ValueOrDefault('%(FullPath)', '').StartsWith($([MSBuild]::EnsureTrailingSlash($(MSBuildProjectDirectory)))))">%(LinkBase)%(RecursiveDir)%(Filename)%(Extension)</Link>
</EmbeddedResource>
</ItemGroup>

This has two consequences:

  1. It prevents the easy way of getting these files outside project cone to show in sln explorer
  2. Xaml interpretation can actually change based on the Link so the impact of not generating a Link as expected can change the application behavior. I forget the details here, but I observed this in customer app.

I'm unsure if the WindowsDesktop SDK should be handling it or if we should add to above. We probably need to do this for Resource items as well.

cc @dsplaisted @vatsan-madhavan

@nguerrera nguerrera added this to the 3.0.1xx milestone Nov 27, 2018
@mjrousos
Copy link
Member

mjrousos commented Feb 27, 2019

Regarding consequence number 2 above, I've seen this cause functional differences when trying to load XAML as a resource. The resource path changes based on the link path of the XAML so previously working code can break without <Link>.

@vatsan-madhavan
Copy link
Member

vatsan-madhavan commented Feb 27, 2019

Is there documentation for LinkBase besides #1246?

When EnableDefaultItems=false, does it imply SetLinkMetadataAutomatically==false ?

What about when EnableDefaultCompileItems=false, EnableDefaultPageItems=false etc. hold - do they imply that SetLinkMetadataAutomatically==false for the corresponding ItemGroup elements?

@dsplaisted dsplaisted self-assigned this Feb 27, 2019
wli3 pushed a commit that referenced this issue Feb 7, 2020
* Update dependencies from https://github.com/dotnet/cli build 20190907.5

- Microsoft.DotNet.Cli.Runtime - 5.0.100-alpha1.19457.5

* Update dependencies from https://github.com/dotnet/cli build 20190907.10

- Microsoft.DotNet.Cli.Runtime - 5.0.100-alpha1.19457.10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants