private async Task <Possible <Unit, Failure> > TryMaterializeCoreAsync(
            FileRealizationMode fileRealizationModes,
            ExpandedAbsolutePath path,
            ContentHash contentHash)
        {
            FileToDelete fileToDelete = FileToDelete.Create(path.ExpandedPath);

            string       pathForCache         = GetExpandedPathForCache(path);
            FileToDelete fileForCacheToDelete = (string.IsNullOrEmpty(pathForCache) ||
                                                 string.Equals(path.ExpandedPath, pathForCache, OperatingSystemHelper.PathComparison))
                        ? FileToDelete.Invalid
                        : FileToDelete.Create(pathForCache);

            if (!m_replaceExistingFileOnMaterialization)
            {
                // BuildXL controls the file deletion if the place file mode is FailIfExists.

                var mayBeDelete = fileToDelete.TryDelete();
                // The file materialization below can fail if fileToDelete and fileForCacheToDelete
                // point to different object files. One can think that fileForCacheToDelete should
                // be deleted as well by adding the following expression in the above statement:
                //
                //     .Then(r => fileForCacheToDelete.IsValid ? fileForCacheToDelete.TryDelete() : r);
                //
                // However, this deletion masks a possibly serious underlying issue because we expect
                // both fileToDelete and fileForCacheToDelete point to the same object file.

                if (!mayBeDelete.Succeeded)
                {
                    return(new FailToDeleteForMaterializationFailure(mayBeDelete.Failure));
                }
            }

            if (fileRealizationModes.AllowVirtualization)
            {
                pathForCache = AddVfsSuffix(pathForCache);
            }

            Possible <ICacheSession, Failure> maybeOpen   = m_cache.Get(nameof(TryMaterializeAsync));
            Possible <string, Failure>        maybePlaced = await PerformArtifactCacheOperationAsync(
                () => maybeOpen.ThenAsync(cache => cache.ProduceFileAsync(
                                              new CasHash(new global::BuildXL.Cache.Interfaces.Hash(contentHash)),
                                              pathForCache,
                                              GetFileStateForRealizationMode(fileRealizationModes))),
                nameof(TryMaterializeAsync));

            if (!maybePlaced.Succeeded && maybePlaced.Failure.DescribeIncludingInnerFailures().Contains("File exists at destination"))
            {
                string diagnostic = await fileToDelete.GetDiagnosticsAsync();

                diagnostic = fileForCacheToDelete.IsValid
                    ? diagnostic + Environment.NewLine + (await fileForCacheToDelete.GetDiagnosticsAsync())
                    : diagnostic;

                return(maybePlaced.Failure.Annotate(diagnostic));
            }

            return(maybePlaced.Then(p => Unit.Void));
        }
Пример #2
0
        public bool Run(out string ErrorMessage)
        {
            StringBuilder FailMessage = new StringBuilder();

            if (FilesToSync.Count > 0)
            {
                List <string> RevisionsToSync = new List <string>();
                foreach (FileInfo FileToSync in FilesToSync)
                {
                    RevisionsToSync.Add(String.Format("{0}#have", PerforceUtils.EscapePath(FileToSync.FullName)));
                }

                StringWriter Log = new StringWriter();
                if (!Perforce.Sync(RevisionsToSync, x => { }, new List <string>(), true, null, Log))
                {
                    FailMessage.Append(Log.ToString());
                }
            }

            foreach (FileInfo FileToDelete in FilesToDelete)
            {
                try
                {
                    FileToDelete.IsReadOnly = false;
                    FileToDelete.Delete();
                }
                catch (Exception Ex)
                {
                    FailMessage.AppendFormat("{0} ({1})\r\n", FileToDelete.FullName, Ex.Message.Trim());
                }
            }
            foreach (DirectoryInfo DirectoryToDelete in DirectoriesToDelete)
            {
                try
                {
                    DirectoryToDelete.Delete(true);
                }
                catch (Exception Ex)
                {
                    FailMessage.AppendFormat("{0} ({1})\r\n", DirectoryToDelete.FullName, Ex.Message.Trim());
                }
            }

            if (FailMessage.Length == 0)
            {
                ErrorMessage = null;
                return(true);
            }
            else
            {
                ErrorMessage = FailMessage.ToString();
                return(false);
            }
        }
Пример #3
0
        public bool Run(out string ErrorMessage)
        {
            StringBuilder FailMessage = new StringBuilder();

            foreach (FileInfo FileToSync in FilesToSync)
            {
                StringWriter Log = new StringWriter();
                if (!Perforce.ForceSync(String.Format("{0}#have", FileToSync.FullName), Log))
                {
                    FailMessage.AppendFormat("{0} ({1})\r\n", FileToSync.FullName, Log.ToString().Trim().Replace('\n', ' '));
                }
            }

            foreach (FileInfo FileToDelete in FilesToDelete)
            {
                try
                {
                    FileToDelete.IsReadOnly = false;
                    FileToDelete.Delete();
                }
                catch (Exception Ex)
                {
                    FailMessage.AppendFormat("{0} ({1})\r\n", FileToDelete.FullName, Ex.Message.Trim());
                }
            }
            foreach (DirectoryInfo DirectoryToDelete in DirectoriesToDelete)
            {
                try
                {
                    DirectoryToDelete.Delete(true);
                }
                catch (Exception Ex)
                {
                    FailMessage.AppendFormat("{0} ({1})\r\n", DirectoryToDelete.FullName, Ex.Message.Trim());
                }
            }

            if (FailMessage.Length == 0)
            {
                ErrorMessage = null;
                return(true);
            }
            else
            {
                ErrorMessage = FailMessage.ToString();
                return(false);
            }
        }
Пример #4
0
    public override void ExecuteBuild()
    {
        SetupStaticBuildEnvironment();

        bool bBuildSolutions = true;

        if (ParseParam("SkipBuildSolutions"))
        {
            bBuildSolutions = false;
        }

        bool bBuildLibraries = true;

        if (ParseParam("SkipBuild"))
        {
            bBuildLibraries = false;
        }

        bool bAutoCreateChangelist = true;

        if (ParseParam("SkipCreateChangelist"))
        {
            bAutoCreateChangelist = false;
        }

        bool bAutoSubmit = false;         // bAutoCreateChangelist;

        if (ParseParam("SkipSubmit"))
        {
            bAutoSubmit = false;
        }

        // if we don't pass anything, we'll just merge by default
        string RobomergeCommand = ParseParamValue("Robomerge", "").ToLower();

        if (!string.IsNullOrEmpty(RobomergeCommand))
        {
            // for merge default action, add flag to make sure buildmachine commit isn't skipped
            if (RobomergeCommand == "merge")
            {
                RobomergeCommand = "#robomerge[all] #DisregardExcludedAuthors";
            }
            // otherwise add hashtags
            else if (RobomergeCommand == "ignore")
            {
                RobomergeCommand = "#robomerge #ignore";
            }
            else if (RobomergeCommand == "null")
            {
                RobomergeCommand = "#robomerge #null";
            }
            // otherwise the submit will likely fail.
            else
            {
                throw new AutomationException("Invalid Robomerge param passed in {0}.  Must be \"merge\", \"null\", or \"ignore\"", RobomergeCommand);
            }
        }

        // get the platforms we want to build for
        List <TargetPlatformData> TargetPlatforms = GetTargetPlatforms();

        // get the platforms we want to build for
        List <WindowsCompiler> TargetWindowsCompilers = GetTargetWindowsCompilers();

        // get the configurations we want to build for
        List <string> TargetConfigurations = GetTargetConfigurations();

        if (bBuildSolutions)
        {
            // build target lib for all platforms
            foreach (TargetPlatformData TargetData in TargetPlatforms)
            {
                if (!PlatformSupportsTargetLib(TargetData))
                {
                    continue;
                }

                SetupBuildForTargetLibAndPlatform(TargetData, TargetConfigurations, TargetWindowsCompilers, false);
            }
        }

        HashSet <FileReference> FilesToReconcile = new HashSet <FileReference>();

        if (bBuildLibraries)
        {
            // build target lib for all platforms
            foreach (TargetPlatformData TargetData in TargetPlatforms)
            {
                if (!PlatformSupportsTargetLib(TargetData))
                {
                    continue;
                }

                HashSet <FileReference> FilesToDelete = new HashSet <FileReference>();
                foreach (string TargetConfiguration in TargetConfigurations)
                {
                    // Delete output files before building them
                    if (TargetData.Platform == UnrealTargetPlatform.Win64)
                    {
                        foreach (WindowsCompiler TargetCompiler in TargetWindowsCompilers)
                        {
                            FindOutputFiles(FilesToDelete, TargetData, TargetConfiguration, TargetCompiler);
                        }
                    }
                    else
                    {
                        FindOutputFiles(FilesToDelete, TargetData, TargetConfiguration);
                    }
                }
                foreach (FileReference FileToDelete in FilesToDelete)
                {
                    FilesToReconcile.Add(FileToDelete);
                    InternalUtils.SafeDeleteFile(FileToDelete.ToString());
                }

                BuildTargetLibForPlatform(TargetData, TargetConfigurations, TargetWindowsCompilers);

                if (DoesPlatformUseMSBuild(TargetData))
                {
                    foreach (WindowsCompiler TargetWindowsCompiler in TargetWindowsCompilers)
                    {
                        CopyLibsToFinalDestination(TargetData, TargetConfigurations, TargetWindowsCompiler);
                    }
                }
                else
                {
                    CopyLibsToFinalDestination(TargetData, TargetConfigurations);
                }
            }
        }

        int P4ChangeList = InvalidChangeList;

        if (bAutoCreateChangelist)
        {
            string RobomergeLine = string.Empty;
            if (!string.IsNullOrEmpty(RobomergeCommand))
            {
                RobomergeLine = Environment.NewLine + RobomergeCommand;
            }
            P4ChangeList = P4.CreateChange(P4Env.Client, "BuildHlslcc.Automation: Deploying hlslcc libs." + Environment.NewLine + "#rb none" + Environment.NewLine + "#lockdown Nick.Penwarden" + Environment.NewLine + "#tests none" + Environment.NewLine + "#jira none" + Environment.NewLine + "#okforgithub ignore" + RobomergeLine);
        }

        if (P4ChangeList != InvalidChangeList)
        {
            foreach (string TargetConfiguration in TargetConfigurations)
            {
                //Add any new files that p4 is not yet tracking.
                foreach (TargetPlatformData TargetData in TargetPlatforms)
                {
                    if (!PlatformSupportsTargetLib(TargetData))
                    {
                        continue;
                    }

                    if (TargetData.Platform == UnrealTargetPlatform.Win64)
                    {
                        foreach (WindowsCompiler TargetCompiler in TargetWindowsCompilers)
                        {
                            FindOutputFiles(FilesToReconcile, TargetData, TargetConfiguration, TargetCompiler);
                        }
                    }
                    else
                    {
                        FindOutputFiles(FilesToReconcile, TargetData, TargetConfiguration);
                    }
                }
            }

            foreach (FileReference FileToReconcile in FilesToReconcile)
            {
                P4.Reconcile(P4ChangeList, FileToReconcile.ToString());
            }
        }

        if (bAutoSubmit && (P4ChangeList != InvalidChangeList))
        {
            if (!P4.TryDeleteEmptyChange(P4ChangeList))
            {
                LogInformation("Submitting changelist " + P4ChangeList.ToString());
                int SubmittedChangeList = InvalidChangeList;
                P4.Submit(P4ChangeList, out SubmittedChangeList);
            }
            else
            {
                LogInformation("Nothing to submit!");
            }
        }
    }
Пример #5
0
        private void UpdateOpenHAB()
        {
            ResetSummary();

            string OpenHABUpdateFileWithPath;

            if (MainForm.UpdateTypeValue == 1)
            {
                UpdateDownloadComplete = false;

                Uri       UpdateFileURI;
                string    OpenHABUpdateFile;
                WebClient OpenHABDownload = new WebClient();

                WriteLog("Downloading OpenHAB update" + Environment.NewLine, true);

                Uri.TryCreate(MainForm.UpdateURL.Text.Trim(), UriKind.Absolute, out UpdateFileURI);
                OpenHABUpdateFile = Path.GetFileName(UpdateFileURI.LocalPath);

                OpenHABUpdateFileWithPath = new Uri(MainForm.UpdatePath.Text.Trim() + "\\" + OpenHABUpdateFile.Trim()).LocalPath;

                if (File.Exists(OpenHABUpdateFileWithPath))
                {
                    File.Delete(OpenHABUpdateFileWithPath);
                }

                OpenHABDownload.DownloadProgressChanged += new DownloadProgressChangedEventHandler(DownloadProgressCallback);
                OpenHABDownload.DownloadFileCompleted   += new AsyncCompletedEventHandler(DownloadFileCompletedCallback);

                try
                {
                    OpenHABDownload.DownloadFileAsync(new System.Uri(MainForm.UpdateURL.Text.Trim()), OpenHABUpdateFileWithPath.Trim());

                    while (!UpdateDownloadComplete)
                    {
                        Application.DoEvents();
                    }
                }
                catch (Exception DownloadException)
                {
                    WriteLog("An error occured while downloading OpenHAB update (" + DownloadException.Message + ")" + Environment.NewLine, true, true);

                    return;
                }

                TotalNumberOfItems = 0;
                CurrentItemNumber  = 0;
                bwrPerformUpdate.ReportProgress(0);
            }
            else
            {
                OpenHABUpdateFileWithPath = MainForm.UpdateFile.Text.Trim();
            }

            if (!StopOpenHABService())
            {
                return;
            }

            ZipArchive ZipFileToExtract = null;

            try
            {
                ZipFileToExtract = ZipFile.Open(OpenHABUpdateFileWithPath.Trim(), ZipArchiveMode.Read);
            }
            catch (Exception UpdateException)
            {
                WriteLog("Cannot update OpenHAB using update file: " + OpenHABUpdateFileWithPath.Trim() + " (" + UpdateException.Message + ")" + Environment.NewLine, true, true);

                return;
            }

            foreach (ZipArchiveEntry ZipEntryToCount in ZipFileToExtract.Entries)
            {
                if (!string.IsNullOrEmpty(ZipEntryToCount.FullName))
                {
                    TotalNumberOfItems++;
                }
            }

            if (MainForm.BeforeUpdatingValue == 2)
            {
                CreateFullBackup();
            }
            else if (MainForm.BeforeUpdatingValue == 3)
            {
                CreateConfigurationBackup();
            }

            WriteLog("Updating OpenHAB using update file: " + OpenHABUpdateFileWithPath.Trim() + Environment.NewLine, true);

            var FilesToDelete = File.ReadAllLines(AppDomain.CurrentDomain.BaseDirectory + "DeleteList.dat");

            foreach (var FileToDelete in FilesToDelete)
            {
                bool IsFolder = false;

                if ((!FileToDelete.ToString().Trim().Contains("*")) && (!FileToDelete.ToString().Trim().Contains("?")) && (Directory.Exists(new Uri(MainForm.OpenHABPath.Text.Trim() + "\\" + FileToDelete.ToString().Trim()).LocalPath)))
                {
                    if (File.GetAttributes(new Uri(MainForm.OpenHABPath.Text.Trim() + "\\" + FileToDelete.ToString().Trim()).LocalPath).HasFlag(FileAttributes.Directory))
                    {
                        IsFolder = true;
                    }
                }

                if (IsFolder)
                {
                    try
                    {
                        Directory.Delete(new Uri(MainForm.OpenHABPath.Text.Trim() + "\\" + FileToDelete.ToString().Trim()).LocalPath, true);

                        SummaryFoldersDeleteSucceeded++;

                        WriteLog("Deleting folder: " + new Uri(MainForm.OpenHABPath.Text.Trim() + "\\" + FileToDelete.ToString().Trim()).LocalPath);
                    }
                    catch (Exception DeleteException)
                    {
                        SummaryFoldersDeleteFailed++;

                        WriteLog("Cannot delete folder: " + new Uri(MainForm.OpenHABPath.Text.Trim() + "\\" + FileToDelete.ToString().Trim()).LocalPath + " (" + DeleteException.Message + ")", false, true);
                    }
                }
                else
                {
                    foreach (var SingleFile in Directory.GetFiles(new Uri(MainForm.OpenHABPath.Text.Trim() + "\\").LocalPath, FileToDelete))
                    {
                        try
                        {
                            File.Delete(SingleFile.ToString().Trim());

                            SummaryFilesDeleteSucceeded++;

                            WriteLog("Deleting file: " + SingleFile.ToString().Trim());
                        }
                        catch (Exception DeleteException)
                        {
                            SummaryFilesDeleteFailed++;

                            WriteLog("Cannot delete file: " + SingleFile.ToString().Trim() + " (" + DeleteException.Message + ")", false, true);
                        }
                    }
                }
            }

            foreach (ZipArchiveEntry ZipEntryToExtract in ZipFileToExtract.Entries)
            {
                CurrentItemNumber++;

                if (String.IsNullOrEmpty(ZipEntryToExtract.Name))
                {
                    if (!Directory.Exists(new Uri(Path.Combine(MainForm.OpenHABPath.Text.Trim(), ZipEntryToExtract.FullName)).LocalPath.Substring(0, new Uri(Path.Combine(MainForm.OpenHABPath.Text.Trim(), ZipEntryToExtract.FullName)).LocalPath.Length - ZipEntryToExtract.Name.Length)))
                    {
                        try
                        {
                            Directory.CreateDirectory(new Uri(Path.Combine(MainForm.OpenHABPath.Text.Trim(), ZipEntryToExtract.FullName)).LocalPath.Substring(0, new Uri(Path.Combine(MainForm.OpenHABPath.Text.Trim(), ZipEntryToExtract.FullName)).LocalPath.Length - ZipEntryToExtract.Name.Length));

                            bwrPerformUpdate.ReportProgress(CurrentItemNumber * 100 / TotalNumberOfItems);

                            SummaryFoldersCreateSucceeded++;

                            WriteLog("Creating folder: " + new Uri(Path.Combine(MainForm.OpenHABPath.Text.Trim(), ZipEntryToExtract.FullName)).LocalPath.Substring(0, new Uri(Path.Combine(MainForm.OpenHABPath.Text.Trim(), ZipEntryToExtract.FullName)).LocalPath.Length - ZipEntryToExtract.Name.Length));
                        }
                        catch (Exception UpdateException)
                        {
                            SummaryFoldersCreateFailed++;

                            WriteLog("Cannot create folder: " + new Uri(Path.Combine(MainForm.OpenHABPath.Text.Trim(), ZipEntryToExtract.FullName)).LocalPath.Substring(0, new Uri(Path.Combine(MainForm.OpenHABPath.Text.Trim(), ZipEntryToExtract.FullName)).LocalPath.Length - ZipEntryToExtract.Name.Length) + " (" + UpdateException.Message + ")", false, true);
                        }
                    }
                }
                else
                {
                    try
                    {
                        ZipEntryToExtract.ExtractToFile(new Uri(Path.Combine(MainForm.OpenHABPath.Text.Trim(), ZipEntryToExtract.FullName)).LocalPath, false);

                        bwrPerformUpdate.ReportProgress(CurrentItemNumber * 100 / TotalNumberOfItems);

                        SummaryFilesExtractSucceeded++;

                        WriteLog("Extracting file: " + ZipEntryToExtract.FullName);
                    }
                    catch (Exception UpdateException)
                    {
                        bwrPerformUpdate.ReportProgress(CurrentItemNumber * 100 / TotalNumberOfItems);

                        SummaryFilesExtractSkipped++;

                        WriteLog("Skipping file extraction: " + ZipEntryToExtract.FullName + " (" + UpdateException.Message.ToString() + ")");
                    }
                }
            }

            ZipFileToExtract.Dispose();

            WriteSummary("Update summary");

            WriteLog(Environment.NewLine + "Update complete" + Environment.NewLine, true);
        }
Пример #6
0
        private void CreateConfigurationBackup()
        {
            ResetSummary();

            int    NumberOfBackupsToDelete = 0;
            string BackupZipFileName       = "";

            TotalNumberOfItems += Directory.GetFiles(MainForm.OpenHABPath.Text.Trim() + "\\userdata", "*.*", SearchOption.AllDirectories).Length;
            TotalNumberOfItems += Directory.GetFiles(MainForm.OpenHABPath.Text.Trim() + "\\conf", "*.*", SearchOption.AllDirectories).Length;

            if (MainForm.DeleteOldConfigurationBackups.Checked)
            {
                NumberOfBackupsToDelete  = Directory.GetFiles(MainForm.BackupPath.Text.Trim(), "OpenHAB_Configuration*.zip", SearchOption.TopDirectoryOnly).Length;
                NumberOfBackupsToDelete -= Convert.ToInt16(MainForm.KeepLastConfigurationBackups.Value);
                NumberOfBackupsToDelete++;

                if (NumberOfBackupsToDelete > 0)
                {
                    TotalNumberOfItems += NumberOfBackupsToDelete;

                    var        BackupPathFolder = new DirectoryInfo(MainForm.BackupPath.Text.Trim());
                    FileInfo[] FilesToDelete    = BackupPathFolder.EnumerateFiles("OpenHAB_Configuration*.zip").Take(NumberOfBackupsToDelete).OrderBy(BackupWriteTime => BackupWriteTime.LastWriteTime).ToArray();

                    foreach (var FileToDelete in FilesToDelete)
                    {
                        try
                        {
                            CurrentItemNumber++;

                            FileToDelete.Delete();

                            SummaryBackupsDeleteSucceeded++;

                            WriteLog("Deleting configuration backup: " + FileToDelete.Name + Environment.NewLine, true);
                        }
                        catch (Exception DeleteException)
                        {
                            SummaryBackupsDeleteFailed++;

                            WriteLog("Cannot delete configuration backup: " + FileToDelete.Name + " (" + DeleteException.Message + ")" + Environment.NewLine, true, true);
                        }
                    }
                }
            }

            BackupZipFileName = MainForm.BackupPath.Text.Trim() + "\\OpenHAB_Configuration_" + DateTime.Now.ToString("yyyyMMddHHmmss") + ".zip";

            ZipArchive BackupZipFile = null;

            try
            {
                BackupZipFile = ZipFile.Open(BackupZipFileName, ZipArchiveMode.Create);

                WriteLog("Creating configuration backup archive: " + BackupZipFileName + Environment.NewLine, true);
            }
            catch (Exception CompressionException)
            {
                WriteLog("Cannot create configuration backup archive: " + BackupZipFileName + " (" + CompressionException.Message + ")", true, true);

                return;
            }

            foreach (string FileToBackup in Directory.GetFiles(MainForm.OpenHABPath.Text.Trim() + "\\userdata", "*.*", SearchOption.AllDirectories))
            {
                try
                {
                    CurrentItemNumber++;

                    BackupZipFile.CreateEntryFromFile(FileToBackup, FileToBackup.Substring(MainForm.OpenHABPath.Text.Trim().Length + 1));

                    if (OperationTypeId == OperationType.Update)
                    {
                        bwrPerformUpdate.ReportProgress(CurrentItemNumber * 100 / TotalNumberOfItems);
                    }
                    else
                    {
                        bwrCompressConfigurationBackup.ReportProgress(CurrentItemNumber * 100 / TotalNumberOfItems);
                    }

                    SummaryFilesCompressSucceeded++;

                    WriteLog("Compressing file: " + FileToBackup);
                }
                catch (Exception CompressionException)
                {
                    SummaryFilesCompressFailed++;

                    WriteLog("Cannot compress file: " + FileToBackup + " (" + CompressionException.Message + ")", false, true);
                }
            }

            foreach (string FileToBackup in Directory.GetFiles(MainForm.OpenHABPath.Text.Trim() + "\\conf", "*.*", SearchOption.AllDirectories))
            {
                try
                {
                    CurrentItemNumber++;

                    BackupZipFile.CreateEntryFromFile(FileToBackup, FileToBackup.Substring(MainForm.OpenHABPath.Text.Trim().Length + 1));

                    if (OperationTypeId == OperationType.Update)
                    {
                        bwrPerformUpdate.ReportProgress(CurrentItemNumber * 100 / TotalNumberOfItems);
                    }
                    else
                    {
                        bwrCompressConfigurationBackup.ReportProgress(CurrentItemNumber * 100 / TotalNumberOfItems);
                    }

                    SummaryFilesCompressSucceeded++;

                    WriteLog("Compressing file: " + FileToBackup);
                }
                catch (Exception CompressionException)
                {
                    SummaryFilesCompressFailed++;

                    WriteLog("Cannot compress file: " + FileToBackup + " (" + CompressionException.Message + ")", false, true);
                }
            }

            BackupZipFile.Dispose();

            WriteSummary("Configuration backup summary");

            WriteLog(Environment.NewLine + "Configuration backup complete" + Environment.NewLine, true);
        }
Пример #7
0
        private async Task <Possible <Unit, Failure> > TryMaterializeCoreAsync(
            FileRealizationMode fileRealizationModes,
            ExpandedAbsolutePath path,
            ContentHash contentHash)
        {
            FileToDelete fileToDelete = FileToDelete.Create(path.ExpandedPath);

            string       pathForCache         = GetExpandedPathForCache(path);
            FileToDelete fileForCacheToDelete = (string.IsNullOrEmpty(pathForCache) ||
                                                 string.Equals(path.ExpandedPath, pathForCache, OperatingSystemHelper.IsUnixOS
                            ? StringComparison.Ordinal
                            : StringComparison.OrdinalIgnoreCase))
                        ? FileToDelete.Invalid
                        : FileToDelete.Create(pathForCache);

            if (!m_replaceExistingFileOnMaterialization)
            {
                // BuildXL controls the file deletion if the place file mode is FailIfExists.

                var mayBeDelete = fileToDelete.TryDelete();
                // The file materialization below can fail if fileToDelete and fileForCacheToDelete
                // point to different object files. One can think that fileForCacheToDelete should
                // be deleted as well by adding the following expression in the above statement:
                //
                //     .Then(r => fileForCacheToDelete.IsValid ? fileForCacheToDelete.TryDelete() : r);
                //
                // However, this deletion masks a possibly serious underlying issue because we expect
                // both fileToDelete and fileForCacheToDelete point to the same object file.

                if (!mayBeDelete.Succeeded)
                {
                    return(mayBeDelete.Failure);
                }
            }

            Possible <ICacheSession, Failure> maybeOpen   = m_cache.Get(nameof(TryMaterializeAsync));
            Possible <string, Failure>        maybePlaced = await maybeOpen.ThenAsync(cache => cache.ProduceFileAsync(
                                                                                          new CasHash(new global::BuildXL.Cache.Interfaces.Hash(contentHash)),
                                                                                          pathForCache,
                                                                                          GetFileStateForRealizationMode(fileRealizationModes)));

            if (!maybePlaced.Succeeded && maybePlaced.Failure.DescribeIncludingInnerFailures().Contains("File exists at destination"))
            {
                string diagnostic = await fileToDelete.GetDiagnosticsAsync();

                diagnostic = fileForCacheToDelete.IsValid
                    ? diagnostic + Environment.NewLine + (await fileForCacheToDelete.GetDiagnosticsAsync())
                    : diagnostic;

                return(maybePlaced.Failure.Annotate(diagnostic));
            }

            return(maybePlaced.Then(p => {
                // TODO:58494: Occasionally we see odd behavior where materialization seems to succeed, but the file is not present in the file system
                //             layer. This check tries to see if the file exits after successful materialization and fails if it doesn't.
                if (!FileUtilities.FileExistsNoFollow(pathForCache))
                {
                    return new Failure <string>(string.Format(
                                                    CultureInfo.InvariantCulture,
                                                    "The file '{0}' with content hash '{1}' was materialzed successfully, but can't be found on disk",
                                                    pathForCache,
                                                    contentHash));
                }

                return new Possible <Unit, Failure>(Unit.Void);
            }));
        }