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

Update construct seems to update all items regardless of match when run in target #1618

Closed
nguerrera opened this issue Jan 27, 2017 · 10 comments

Comments

@nguerrera
Copy link
Contributor

<Project>
  <ItemGroup>
     <X Include="A;B;C" />
     <X Update="B" Metadata="Just on B" />
     <X Update="NonExistent" Metadata="Useless" />
  </ItemGroup>

  <Target Name="Build">
    <Warning Text="Before in-target update: %(X.Identity) %(X.Metadata)" />
    
   <ItemGroup>
      <X Update="A" Metadata="Just on A" />
      <X Update="NonExistent" Metadata="Huh" />
   </ItemGroup>
      
   <Warning Text="After in-target update: %(X.Identity) %(X.Metadata)" />
 </Target>
</Project>

Expected after target runs:

  • A has Metadata= "Just on A" and B has Metadata "Just on B", C has no Metadata=""

Actual:

  • They all have Metadata="Huh"
C:\temp\test.proj(10,5): warning : Before in-target update: A
C:\temp\test.proj(10,5): warning : Before in-target update: B Just on B
C:\temp\test.proj(10,5): warning : Before in-target update: C
C:\temp\test.proj(17,4): warning : After in-target update: A Huh
C:\temp\test.proj(17,4): warning : After in-target update: B Huh
C:\temp\test.proj(17,4): warning : After in-target update: C Huh

@AndyGerlicher @rainersigwald

@davkean
Copy link
Member

davkean commented Jan 27, 2017

tag @cdmihai

@rainersigwald
Copy link
Member

I think this is a bad interaction between metadata-as-attributes and the fact that items are handled differently in targets.

Update was possible before the Update attribute, but only in targets. Inside a target you can use the old form (set metadata as though in an ItemDefinitionGroup, batching over the items with conditions).

      <X Metadata="Just on A" Condition="'%(X.Identity)' == 'A'" />
      <X Metadata="Huh" Condition="'%(X.Identity)' == 'NonExistent'" />

That's the best workaround for this.

Surprising things:

  • This isn't an error. We didn't implement Update attributes inside targets, and I would have expected this to report "invalid syntax". I suspect it's not because of metadata-as-attributes, but
  • Update doesn't appear to actually be getting set as metadata. Maybe we're correctly rejecting it as a reserved not-eligible-for-as-attribute metadata name, but not pushing up an error?

@nguerrera
Copy link
Contributor Author

nguerrera commented Jan 27, 2017

This needs to at least be an error for RTW.

I have a case (investigating perf issue with GetTargetFrameworkProperties) where it is very difficult to express as a condition.

Basically, I get a item group back from <MSBuild> task where the items have OriginalItemSpec pointing back to the project items and I want to update the project items passed in with metadata returned.

I imagined something like this would work and read nicely:

<MSBuild Projects="@(X)">
   <Output TaskParameter="TargetOutputs" ItemName="Y" />
</MSBuild>
<ItemGroup>
    <X Update="%(Y.OriginalItemSpec)">
        <Metadata>%(Y.Metadata)</Metadata>
   </X>
</ItemGroup>

Variants using conditions did not work out either:

<X  Metadata="%(Y.Metadata)" Condition="%(X.Identity) == %(Y.OriginalItemSpec)" />

I'm still trying to wrap my head around #1018 (comment) and I can't get it to work. I'd love to find a readable expression of this pattern.

@nguerrera nguerrera added the bug label Jan 27, 2017
@nguerrera
Copy link
Contributor Author

Btw, it does error out if I use Update="" saying Update can't be empty so it partially knows this is special and not metadata.

@rainersigwald
Copy link
Member

Beat my head against this for quite a while. I think you should just write a Task to do this. The syntax you want wouldn't do what you expect either due to the vagaries of batching rules.

@nguerrera
Copy link
Contributor Author

OK. I'll write a task. :) Still pushing for that error in RTW.

@cdmihai
Copy link
Contributor

cdmihai commented Mar 8, 2017

Included in #1124

@nguerrera
Copy link
Contributor Author

NOTE: This was closed because it's a subset of #1124, not because it was fixed.

@jimitndiaye
Copy link

This needs to at least be an error for RTW.

I have a case (investigating perf issue with GetTargetFrameworkProperties) where it is very difficult to express as a condition.

Basically, I get a item group back from <MSBuild> task where the items have OriginalItemSpec pointing back to the project items and I want to update the project items passed in with metadata returned.

I imagined something like this would work and read nicely:

<MSBuild Projects="@(X)">
   <Output TaskParameter="TargetOutputs" ItemName="Y" />
</MSBuild>
<ItemGroup>
    <X Update="%(Y.OriginalItemSpec)">
        <Metadata>%(Y.Metadata)</Metadata>
   </X>
</ItemGroup>

Variants using conditions did not work out either:

<X  Metadata="%(Y.Metadata)" Condition="%(X.Identity) == %(Y.OriginalItemSpec)" />

I'm still trying to wrap my head around #1018 (comment) and I can't get it to work. I'd love to find a readable expression of this pattern.

I'm trying to do exactly what @nguerrera is trying to do here with similar results.

@gulbanana
Copy link

I've just run across this and it was extremely confusing.

@AR-May AR-May added the triaged label Feb 21, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants