Issue Description
When calling the Copy task, we now delete the destination file (if present) before copying the source file to that location:
#8275
That ensures that if the destination file is actually a symbolic link pointing to, say, the user's nuget cache, we don't write through the link and corrupt the file at the other end.
However, that causes a problem when the source file and destination file are the same. We delete the source file, and then there's no file to copy to the destination location!
Confusingly, this doesn't even throw an exception when the real problem occurs because we're already past the existence checks in Copy, and File.Copy doesn't know how to get its exception to MSBuild loggers. An exception is thrown on the second build when the Copy task is invoked with a file that never existed or during the first build if the copied file is subsequently used.
Steps to Reproduce
Create a new console app with dotnet new console. Add this target:
<Target Name="BadCopy">
<Copy SourceFiles=".\Program.cs" DestinationFiles="Program.cs" />
</Target>
Execute the target with msbuild <project> /t:BadCopy
Expected Behavior
Copies Program.cs on top of itself
Actual Behavior
Deletes Program.cs
Analysis
The .\ in the Target is intentional and necessary. We have a check earlier in Copy that the SourceFile and DestinationFile have different "Name"s. This is the path passed in, however, not the full path. This can also occur if someone wants to copy a relative path on top of a full path or vice versa.
Versions & Configurations
No response
Issue Description
When calling the Copy task, we now delete the destination file (if present) before copying the source file to that location:
#8275
That ensures that if the destination file is actually a symbolic link pointing to, say, the user's nuget cache, we don't write through the link and corrupt the file at the other end.
However, that causes a problem when the source file and destination file are the same. We delete the source file, and then there's no file to copy to the destination location!
Confusingly, this doesn't even throw an exception when the real problem occurs because we're already past the existence checks in Copy, and File.Copy doesn't know how to get its exception to MSBuild loggers. An exception is thrown on the second build when the Copy task is invoked with a file that never existed or during the first build if the copied file is subsequently used.
Steps to Reproduce
Create a new console app with
dotnet new console. Add this target:Execute the target with
msbuild <project> /t:BadCopyExpected Behavior
Copies Program.cs on top of itself
Actual Behavior
Deletes Program.cs
Analysis
The
.\in the Target is intentional and necessary. We have a check earlier in Copy that the SourceFile and DestinationFile have different "Name"s. This is the path passed in, however, not the full path. This can also occur if someone wants to copy a relative path on top of a full path or vice versa.Versions & Configurations
No response