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

Apply DependentUpon Convention Only to .resx Files #4764

Merged
merged 4 commits into from
Oct 2, 2019

Conversation

benvillalobos
Copy link
Member

@benvillalobos benvillalobos commented Sep 26, 2019

Description

Fix #4740, build or runtime failures that arise because non-resx resources get embedded with an unexpected name.

Customer Impact

Builds fail with CS1508 or applications fail to extract a resource at runtime. Roadblock to adopting the final 3.0 SDK and to migrating to .NET Core 3.0 for applications with embedded resources (UI applications in particular).

Reported by multiple internal partners (CoreFX, EF) and customers.

Workaround

Users can explicitly opt out of the new behavior back into preview8 behavior with a property

<EmbeddedResourceUseDependentUponConvention>false</EmbeddedResourceUseDependentUponConvention>

Regression?

Yes, builds fail in cases that passed before. Introduced with #4597, a new feature to support (resx) resources without project-file impact.

Testing

Automated tests, including a new one for this specific case. e2e validation in failing scenarios using privates.

Risk

Low. Targeted fix in a conditioned codepath, so the existing workarounds will continue to work and can mitigate any problems.


Taking the suggestion made by @nguerrera to restrict dependentupon convention to .resx files.
#4740 (comment)

Restricting to resx makes sense because that is the case that would have been persisted with DependentUpon in a classic project. I'm not aware of anything that would have put DependentUpon for non-resx in your project unless you did it manually so I don't think it should have been part of the convention to do so.

Added a check on the Type metadata and file extension to prevent dependent upon convention from being used on non-resx files.

Users can manually assign the Type metadata when including embedded resources in their projects like so:
<EmbeddedResource Include="MyResource.txt" WithCulture="false" Type="Non-Resx" />

If the metadata isn't set, it should automatically be populated by the time the task runs.

In case the Type metadata is missing for whatever reason when the task runs, a check on the file's extension will be made to determine whether or not it's a resx file.

// If it has a file type metadata is "Resx"
bool isResxFile = (!string.IsNullOrEmpty(fileType) && fileType == "Resx");

//fall back onto the extension
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not familiar with when Type=Resx is set, is that up to the user or to targets that precede this do it?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, please document the current state at least in the PR and maybe in the comment here.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Users can manually set the Type metadata to Resx or Non-Resx. If that metadata isn't set, it is automatically populated by the time the task runs. Currently trying to track down when it gets set.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's set through the SplitResourcesByCulture target here

      <EmbeddedResource Include="@(_MixedResourceWithNoCulture);@(_MixedResourceWithCulture)" Condition="'%(Extension)'=='.resx' or '%(Extension)'=='.restext'">
        <Type Condition="'%(_MixedResourceWithNoCulture.Type)'=='' and '%(_MixedResourceWithCulture.Type)'==''">Resx</Type>
      </EmbeddedResource>
      <EmbeddedResource Include="@(_MixedResourceWithNoCulture);@(_MixedResourceWithCulture)" Condition="'%(Extension)'!='.resx' and '%(Extension)'!='.restext'">
        <Type Condition="'%(_MixedResourceWithNoCulture.Type)'=='' and '%(_MixedResourceWithCulture.Type)'==''">Non-Resx</Type>
      </EmbeddedResource>

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My follow up here is do we need this fallback to extension, then? It seems like we should expect Type to be set?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I think I now lean toward "assume it's set and if it's not, no convention" as well. I'll push that.

@nguerrera
Copy link
Contributor

Tests for the convention are failing. I assume they are test defects at this point?

@rainersigwald
Copy link
Member

They are failing because the tests don't set the Type metadata, yes. Unfortunately, that metadata isn't documented in the CreateCSharpManifestResourceName docs, so I'm wavering in my commitment to relying on it. Are our tests representative of real-world calls, or special?

I am seeing some third-party calls to the task: https://github.com/search?l=XML&q=CreateCSharpManifestResourceName&type=Code

@rainersigwald rainersigwald added this to the MSBuild 16.3 milestone Sep 30, 2019
@rainersigwald rainersigwald added Area: Tasks Issues impacting the tasks shipped in Microsoft.Build.Tasks.Core.dll. ask-mode labels Sep 30, 2019
rynowak added a commit to dotnet/razor that referenced this pull request Oct 1, 2019
Without this change we get lots of errors related to duplicate resource
ids.
rynowak added a commit to dotnet/razor that referenced this pull request Oct 2, 2019
Without this change we get lots of errors related to duplicate resource
ids.
rynowak added a commit to dotnet/razor that referenced this pull request Oct 2, 2019
Without this change we get lots of errors related to duplicate resource
ids.
@rainersigwald
Copy link
Member

Two relevant offline conversations yesterday:

  • @nguerrera is now willing to take the double-checked extension as a belt-and-suspenders approach to direct callers of the task that don't use the usual common.targets flow to assign Type for inputs.
  • Bar check for 16.3.x passed, so we need a build.

I'm going to merge.

@rainersigwald rainersigwald merged commit 0e1b800 into dotnet:vs16.3 Oct 2, 2019
rynowak added a commit to dotnet/razor that referenced this pull request Oct 4, 2019
Without this change we get lots of errors related to duplicate resource
ids.
rynowak added a commit to dotnet/razor that referenced this pull request Oct 4, 2019
Without this change we get lots of errors related to duplicate resource
ids.
rynowak added a commit to dotnet/razor that referenced this pull request Oct 4, 2019
Without this change we get lots of errors related to duplicate resource
ids.
@benvillalobos
Copy link
Member Author

Now that the rules for manifest resource name selection have changed, refer to this dotnet docs issue for a detailed explanation on how this selection works now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area: Tasks Issues impacting the tasks shipped in Microsoft.Build.Tasks.Core.dll. ask-mode
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants