-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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
Allow Custom CopyToOutputDirectory Location With TargetPath #6237
Conversation
src/Tasks/AssignTargetPath.cs
Outdated
// https://github.com/dotnet/msbuild/issues/2795 | ||
if (!string.IsNullOrEmpty(targetPath)) | ||
{ | ||
AssignedFiles[i].SetMetadata(ItemMetadataNames.targetPath, EscapingUtilities.Escape(targetPath)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: Instead of the continue and duplication you could let it fall through. First try TargetPath. If null or empty try Link. If null or empty run that if block. Then set the escaped value and return.
|
||
Assert.True(success); | ||
[Theory] | ||
[InlineData("test/output/file.txt")] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also add a fully qualified path to sanity ensure the task preserves those.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Even though this seems the better way of doing it, I assume there might be people whose builds might start copying files to different places. Add an escape hatch / change wave . On the other hand if they take the time to investigate and learn about the escape hatch, they might as well fix it :)
src/Tasks/AssignTargetPath.cs
Outdated
// https://github.com/dotnet/msbuild/issues/2795 | ||
if (!string.IsNullOrEmpty(targetPath)) | ||
{ | ||
AssignedFiles[i].SetMetadata(ItemMetadataNames.targetPath, EscapingUtilities.Escape(targetPath)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider using some new variable ("targetPathOverride"? "targetPath2"? Choose a good name) to allow users to provide a custom targetPath while maintaining that this task can be called twice without adverse consequences. (Escaping seems necessary as part of what TaskItem requires for all its metadata.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Going with TargetPathOverride
for clarity.
@cdmihai No longer needed as discussed in the PR review. Users now set |
@dsplaisted before we get this merged, could I have your take on this? /cc: @KathleenDollard To quickly summarize what the goal is:
This change simply allows a |
@benvillalobos In addition to your goals, I would also add:
|
friendly reminder. @dsplaisted |
@dsplaisted I'm not sure how this change could impact the rest of the build. Do TargetPath and Link need to stay in sync for any reason? |
I'm pretty sure my worries about this were unfounded. What I was thinking of is specifying
|
@dsplaisted That was exclusively the reason. We figured that changing what Note that the change doesn't set I'm open to placing this under a changewave if you think it's the better long term solution than having a separate metadata controlling this behavior. |
Pushed up changes that use |
Isn't the point of the method to set the TargetPath property if it isn't already set? It doesn't seem helpful to set the TargetPath property if it isn't already set using the TargetPath property, since that's guaranteed to not be set... |
@Forgind There's no guarantee that TargetPath isn't set when this task runs (no conditions on the targer or tasks), so I think it's reasonable to skip over it if it's already set. |
Does the |
As far as I can tell it only looks to be used when defining where files will be placed, which reinforces that we should be using TargetPath instead of TargetPathOverride. |
@dsplaisted ping for an approving review or feedback 🙂 |
Hello @benvillalobos. Now that version 16.10 has been released, I am able to test. Unfortunately, I think this change exchanged one problem for another. <Content Include="Files\**">
<Link>Files\%(Filename)%(Extension)</Link>
<TargetPath>%(Filename)%(Extension)</TargetPath>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content> I have verified the correctness of the first two lines (i.e. the I tested by modifying the MWE I provided in my original VSDC isssue. |
@TysonMN I created https://github.com/dotnet/msbuild/issues/6496 to track this |
Fixes #2795
and indirectly fixes https://developercommunity.visualstudio.com/t/copytooutputdirectorypreservenewest-ignored-inside/1332219?from=email&viewtype=all#T-ND1363347
Context
There's currently no way to include items in a project such that:
<Link>
).<Link>
)Changes Made
Modify the
AssignTargetPath
task to return early ifTargetPath
metadata is already set on a particular item.Testing
Here's the repro I'm using:
Notes
The other way of solving this problem has to do with
Microsoft.Common.CurrentVersion.targets
. We modify it so that theAssignTargetPath
task look something like this:This seems less efficient to me. AssignTargetPath is also called for all
None
,Content
, andEmbeddedResource
files. So if we go this batching route and wantNone
orEmbeddedResource
to have this feature, we'd need to batch those as well.