-
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
Issue8273 corrupt nu get cache #8275
Changes from all commits
359f511
864d5b7
cb5d0de
c21ac4d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -226,8 +226,6 @@ private void LogDiagnostic(string message, params object[] messageArgs) | |
FileState sourceFileState, // The source file | ||
FileState destinationFileState) // The destination file | ||
{ | ||
bool destinationFileExists = false; | ||
|
||
if (destinationFileState.DirectoryExists) | ||
{ | ||
Log.LogErrorWithCodeFromResources("Copy.DestinationIsDirectory", sourceFileState.Name, destinationFileState.Name); | ||
|
@@ -269,7 +267,14 @@ private void LogDiagnostic(string message, params object[] messageArgs) | |
if (OverwriteReadOnlyFiles) | ||
{ | ||
MakeFileWriteable(destinationFileState, true); | ||
destinationFileExists = destinationFileState.FileExists; | ||
} | ||
|
||
// If the destination file is a hard or symbolic link, File.Copy would overwrite the source. | ||
// To prevent this, we need to delete the existing entry before we Copy or create a link. | ||
// We could try to figure out if the file is a link, but I can't think of a reason to not simply delete it always. | ||
if (ChangeWaves.AreFeaturesEnabled(ChangeWaves.Wave17_6) && destinationFileState.FileExists && !destinationFileState.IsReadOnly) | ||
{ | ||
FileUtilities.DeleteNoThrow(destinationFileState.Name); | ||
} | ||
|
||
bool symbolicLinkCreated = false; | ||
|
@@ -279,7 +284,7 @@ private void LogDiagnostic(string message, params object[] messageArgs) | |
// Create hard links if UseHardlinksIfPossible is true | ||
if (UseHardlinksIfPossible) | ||
{ | ||
TryCopyViaLink(HardLinkComment, MessageImportance.Normal, sourceFileState, destinationFileState, ref destinationFileExists, out hardLinkCreated, ref errorMessage, (source, destination, errMessage) => NativeMethods.MakeHardLink(destination, source, ref errorMessage, Log)); | ||
TryCopyViaLink(HardLinkComment, MessageImportance.Normal, sourceFileState, destinationFileState, out hardLinkCreated, ref errorMessage, (source, destination, errMessage) => NativeMethods.MakeHardLink(destination, source, ref errorMessage, Log)); | ||
if (!hardLinkCreated) | ||
{ | ||
if (UseSymboliclinksIfPossible) | ||
|
@@ -297,13 +302,14 @@ private void LogDiagnostic(string message, params object[] messageArgs) | |
// Create symbolic link if UseSymboliclinksIfPossible is true and hard link is not created | ||
if (!hardLinkCreated && UseSymboliclinksIfPossible) | ||
{ | ||
TryCopyViaLink(SymbolicLinkComment, MessageImportance.Normal, sourceFileState, destinationFileState, ref destinationFileExists, out symbolicLinkCreated, ref errorMessage, (source, destination, errMessage) => NativeMethodsShared.MakeSymbolicLink(destination, source, ref errorMessage)); | ||
if (!NativeMethodsShared.IsWindows) | ||
{ | ||
errorMessage = Log.FormatResourceString("Copy.NonWindowsLinkErrorMessage", "symlink()", errorMessage); | ||
} | ||
TryCopyViaLink(SymbolicLinkComment, MessageImportance.Normal, sourceFileState, destinationFileState, out symbolicLinkCreated, ref errorMessage, (source, destination, errMessage) => NativeMethodsShared.MakeSymbolicLink(destination, source, ref errorMessage)); | ||
if (!symbolicLinkCreated) | ||
{ | ||
if (!NativeMethodsShared.IsWindows) | ||
{ | ||
errorMessage = Log.FormatResourceString("Copy.NonWindowsLinkErrorMessage", "symlink()", errorMessage); | ||
} | ||
|
||
Log.LogMessage(MessageImportance.Normal, RetryingAsFileCopy, sourceFileState.Name, destinationFileState.Name, errorMessage); | ||
} | ||
} | ||
|
@@ -324,41 +330,28 @@ private void LogDiagnostic(string message, params object[] messageArgs) | |
Log.LogMessage(MessageImportance.Normal, FileComment, sourceFilePath, destinationFilePath); | ||
|
||
File.Copy(sourceFileState.Name, destinationFileState.Name, true); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Given that the destination is always deleted, I think it would be a good idea to set the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, it is probably better to fail in case someone gets in between than overwriting a link. I will update the PR. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I do not believe it is necessary. Sometimes logic might change to not delete it, or new Copy task argument will be introduced, or some weird concurrent logic is relaying with last win. I would recommend to keep it as is, but if you decide to change it, it has to go under same ChangeWave or same conditions as deleting files. |
||
|
||
// If the destinationFile file exists, then make sure it's read-write. | ||
// The File.Copy command copies attributes, but our copy needs to | ||
// leave the file writeable. | ||
if (sourceFileState.IsReadOnly) | ||
{ | ||
destinationFileState.Reset(); | ||
MakeFileWriteable(destinationFileState, false); | ||
} | ||
} | ||
|
||
// Files were successfully copied or linked. Those are equivalent here. | ||
WroteAtLeastOneFile = true; | ||
|
||
destinationFileState.Reset(); | ||
|
||
// If the destinationFile file exists, then make sure it's read-write. | ||
// The File.Copy command copies attributes, but our copy needs to | ||
// leave the file writeable. | ||
if (sourceFileState.IsReadOnly) | ||
{ | ||
MakeFileWriteable(destinationFileState, false); | ||
} | ||
|
||
return true; | ||
} | ||
|
||
private void TryCopyViaLink(string linkComment, MessageImportance messageImportance, FileState sourceFileState, FileState destinationFileState, ref bool destinationFileExists, out bool linkCreated, ref string errorMessage, Func<string, string, string, bool> createLink) | ||
private void TryCopyViaLink(string linkComment, MessageImportance messageImportance, FileState sourceFileState, FileState destinationFileState, out bool linkCreated, ref string errorMessage, Func<string, string, string, bool> createLink) | ||
{ | ||
// Do not log a fake command line as well, as it's superfluous, and also potentially expensive | ||
Log.LogMessage(MessageImportance.Normal, linkComment, sourceFileState.Name, destinationFileState.Name); | ||
|
||
if (!OverwriteReadOnlyFiles) | ||
{ | ||
destinationFileExists = destinationFileState.FileExists; | ||
} | ||
|
||
// CreateHardLink and CreateSymbolicLink cannot overwrite an existing file or link | ||
// so we need to delete the existing entry before we create the hard or symbolic link. | ||
if (destinationFileExists) | ||
{ | ||
FileUtilities.DeleteNoThrow(destinationFileState.Name); | ||
} | ||
|
||
linkCreated = createLink(sourceFileState.Name, destinationFileState.Name, errorMessage); | ||
} | ||
|
||
|
@@ -826,6 +819,11 @@ private bool DoCopyWithRetries(FileState sourceFileState, FileState destinationF | |
LogDiagnostic("Retrying on ERROR_ACCESS_DENIED because MSBUILDALWAYSRETRY = 1"); | ||
} | ||
} | ||
else if (code == NativeMethods.ERROR_INVALID_FILENAME) | ||
{ | ||
// Invalid characters used in file name, no point retrying. | ||
throw; | ||
} | ||
|
||
if (e is UnauthorizedAccessException) | ||
{ | ||
|
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.
Should we also take into account OverwriteReadOnlyFiles and also delete them in that case?
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.
if
OverwriteReadOnlyFiles
is set, the file is made writable and hence deleted here.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.
...and now I see it 6 lines up. Stupid question, thanks!