public static void FinalizeTLogs(bool trackedOperationsSucceeded, ITaskItem[] readTLogNames, ITaskItem[] writeTLogNames, ITaskItem[] trackedFilesToRemoveFromTLogs) { FlatTrackingData data = new FlatTrackingData(readTLogNames, true); FlatTrackingData data2 = new FlatTrackingData(writeTLogNames, true); if (!trackedOperationsSucceeded) { data.DependencyTable.Clear(); data.SaveTlog(); data2.DependencyTable.Clear(); data2.SaveTlog(); } else if ((trackedFilesToRemoveFromTLogs != null) && (trackedFilesToRemoveFromTLogs.Length > 0)) { IDictionary <string, ITaskItem> trackedFilesToRemove = new Dictionary <string, ITaskItem>(StringComparer.OrdinalIgnoreCase); foreach (ITaskItem item in trackedFilesToRemoveFromTLogs) { trackedFilesToRemove.Add(FileUtilities.NormalizePath(item.ItemSpec), item); } data2.SaveTlog(fullTrackedPath => !trackedFilesToRemove.ContainsKey(fullTrackedPath)); data.SaveTlog(fullTrackedPath => !trackedFilesToRemove.ContainsKey(fullTrackedPath)); } else { data2.SaveTlog(); data.SaveTlog(); } }
public static bool IsUpToDate(Task hostTask, UpToDateCheckType upToDateCheckType, ITaskItem[] readTLogNames, ITaskItem[] writeTLogNames) { bool isUpToDate; // Read the input graph (missing inputs are infinitely new - i.e. outputs are out of date) FlatTrackingData inputs = new FlatTrackingData(hostTask, readTLogNames, DateTime.MaxValue); // Read the output graph (missing outputs are infinitely old - i.e. outputs are out of date) FlatTrackingData outputs = new FlatTrackingData(hostTask, writeTLogNames, DateTime.MinValue); // Find out if we are up to date isUpToDate = IsUpToDate(hostTask.Log, upToDateCheckType, inputs, outputs); // We're going to execute, so clear out the tlogs so // the new execution will correctly populate the tlogs a-new if (!isUpToDate) { // Remove all from inputs tlog inputs.DependencyTable.Clear(); inputs.SaveTlog(); // Remove all from outputs tlog outputs.DependencyTable.Clear(); outputs.SaveTlog(); } return(isUpToDate); }
public static bool IsUpToDate(Task hostTask, UpToDateCheckType upToDateCheckType, ITaskItem[] readTLogNames, ITaskItem[] writeTLogNames) { FlatTrackingData inputs = new FlatTrackingData(hostTask, readTLogNames, DateTime.MaxValue); FlatTrackingData outputs = new FlatTrackingData(hostTask, writeTLogNames, DateTime.MinValue); bool flag = IsUpToDate(hostTask.Log, upToDateCheckType, inputs, outputs); if (!flag) { inputs.DependencyTable.Clear(); inputs.SaveTlog(); outputs.DependencyTable.Clear(); outputs.SaveTlog(); } return(flag); }
public void FlatTrackingExcludeDirectories() { Console.WriteLine("Test: FlatTrackingExcludeDirectories"); // Prepare files if (!Directory.Exists("TestFiles\\ToBeExcluded")) { Directory.CreateDirectory("TestFiles\\ToBeExcluded"); } DependencyTestHelper.WriteAll("TestFiles\\ToBeExcluded\\two.cpp", ""); DependencyTestHelper.WriteAll("TestFiles\\ToBeExcluded\\two.h", ""); DependencyTestHelper.WriteAll("TestFiles\\one.h", ""); DependencyTestHelper.WriteAll("TestFiles\\one.cpp", ""); File.WriteAllLines("TestFiles\\one.tlog", new string[] { "#Command some-command", Path.GetFullPath("TestFiles\\one.cpp"), Path.GetFullPath("TestFiles\\one1.h"), Path.GetFullPath("TestFiles\\ToBeExcluded\\two.cpp"), Path.GetFullPath("TestFiles\\ToBeExcluded\\two.h"), Path.GetFullPath("TestFiles\\SubdirectoryExcluded\\three.cpp"), Path.GetFullPath("TestFiles\\SubdirectoryExcluded\\three.h"), }); // Get the newest time w/o any exclude paths Dictionary<string, DateTime> sharedLastWriteTimeUtcCache = new Dictionary<string, DateTime>(StringComparer.OrdinalIgnoreCase); FlatTrackingData data = new FlatTrackingData ( DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\one.tlog")), null, DateTime.MinValue, null, sharedLastWriteTimeUtcCache ); DateTime originalNewest = data.NewestFileTimeUtc; // Force an update to the files we don't care about DependencyTestHelper.WriteAll("TestFiles\\ToBeExcluded\\two.cpp", ""); DependencyTestHelper.WriteAll("TestFiles\\ToBeExcluded\\two.h", ""); if (!Directory.Exists("TestFiles\\ToBeExcluded\\SubdirectoryExcluded")) { Directory.CreateDirectory("TestFiles\\ToBeExcluded\\SubdirectoryExcluded"); } DependencyTestHelper.WriteAll("TestFiles\\ToBeExcluded\\SubdirectoryExcluded\\three.cpp", ""); DependencyTestHelper.WriteAll("TestFiles\\ToBeExcluded\\SubdirectoryExcluded\\three.h", ""); // Now do a flat tracker ignoring the exclude directories and make sure the time didn't change data = new FlatTrackingData ( DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\one.tlog")), null, DateTime.MinValue, new string[] { Path.GetFullPath("TestFiles\\ToBeExcluded") }, sharedLastWriteTimeUtcCache ); Assert.Equal(originalNewest, data.NewestFileTimeUtc); // "Timestamp changed when no tracked files changed." }
public void FlatTrackingDataMissingOutputs() { Console.WriteLine("Test: FlatTrackingDataMissingOutputs"); // Prepare files DependencyTestHelper.WriteAll("TestFiles\\one1.h", ""); DependencyTestHelper.WriteAll("TestFiles\\one2.h", ""); DependencyTestHelper.WriteAll("TestFiles\\one3.h", ""); DependencyTestHelper.WriteAll("TestFiles\\one.cpp", ""); Thread.Sleep(sleepTimeMilliseconds); DependencyTestHelper.WriteAll("TestFiles\\one.obj", ""); Thread.Sleep(sleepTimeMilliseconds); // need to wait since the timestamp check needs some time to register File.WriteAllLines("TestFiles\\one.read.tlog", new string[] { "#Command some-command", "^" + Path.GetFullPath("TestFiles\\one.cpp"), Path.GetFullPath("TestFiles\\one1.h"), Path.GetFullPath("TestFiles\\one2.h"), Path.GetFullPath("TestFiles\\one3.h"), "^" + Path.GetFullPath("TestFiles\\two.cpp"), }); File.WriteAllLines("TestFiles\\one.write.tlog", new string[] { "#Command some-command", "^" + Path.GetFullPath("TestFiles\\one.cpp"), Path.GetFullPath("TestFiles\\one.obj"), Path.GetFullPath("TestFiles\\two.obj"), Path.GetFullPath("TestFiles\\sometempfile2.obj") }); FlatTrackingData outputs = new FlatTrackingData(DependencyTestHelper.MockTask, DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\one.write.tlog")), false); FlatTrackingData inputs = new FlatTrackingData(DependencyTestHelper.MockTask, DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\one.read.tlog")), false); // No matter which way you look at it, if we're missing outputs, we're out of date Assert.Equal(false, FlatTrackingData.IsUpToDate(DependencyTestHelper.MockTask.Log, UpToDateCheckType.InputNewerThanOutput, inputs, outputs)); Assert.Equal(false, FlatTrackingData.IsUpToDate(DependencyTestHelper.MockTask.Log, UpToDateCheckType.InputNewerThanTracking, inputs, outputs)); Assert.Equal(false, FlatTrackingData.IsUpToDate(DependencyTestHelper.MockTask.Log, UpToDateCheckType.InputOrOutputNewerThanTracking, inputs, outputs)); Assert.Equal(0, inputs.MissingFiles.Count); Assert.Equal(2, outputs.MissingFiles.Count); }
public void FlatTrackingDataInputOrOutputNewerThanTracking() { Console.WriteLine("Test: FlatTrackingDataInputOrOutputNewerThanTracking"); File.WriteAllLines("TestFiles\\one.read.tlog", new string[] { "#Command some-command", Path.GetFullPath("TestFiles\\one.cpp"), Path.GetFullPath("TestFiles\\one1.h"), Path.GetFullPath("TestFiles\\one2.h"), Path.GetFullPath("TestFiles\\one3.h"), }); File.WriteAllLines("TestFiles\\one.write.tlog", new string[] { "#Command some-command", "^" + Path.GetFullPath("TestFiles\\one.cpp"), Path.GetFullPath("TestFiles\\one.obj"), }); Thread.Sleep(sleepTimeMilliseconds); // Prepare files DependencyTestHelper.WriteAll("TestFiles\\one1.h", ""); DependencyTestHelper.WriteAll("TestFiles\\one2.h", ""); DependencyTestHelper.WriteAll("TestFiles\\one3.h", ""); DependencyTestHelper.WriteAll("TestFiles\\one.cpp", ""); Thread.Sleep(sleepTimeMilliseconds); DependencyTestHelper.WriteAll("TestFiles\\one.obj", ""); FlatTrackingData outputs = new FlatTrackingData(DependencyTestHelper.MockTask, DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\one.write.tlog")), false); // Compact the read tlog FlatTrackingData inputs = new FlatTrackingData(DependencyTestHelper.MockTask, DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\one.read.tlog")), false); // We should be up to date inputs vs outputs Assert.Equal(true, FlatTrackingData.IsUpToDate(DependencyTestHelper.MockTask.Log, UpToDateCheckType.InputNewerThanOutput, inputs, outputs)); // We should be out of date inputs & outputs vs tracking (since we wrote the files after the tracking logs) Assert.Equal(false, FlatTrackingData.IsUpToDate(DependencyTestHelper.MockTask.Log, UpToDateCheckType.InputOrOutputNewerThanTracking, inputs, outputs)); // Touch the tracking logs so that are more recent that any of the inputs Thread.Sleep(sleepTimeMilliseconds); File.SetLastWriteTime("TestFiles\\one.read.tlog", DateTime.Now); File.SetLastWriteTime("TestFiles\\one.write.tlog", DateTime.Now); Thread.Sleep(sleepTimeMilliseconds); outputs = new FlatTrackingData(DependencyTestHelper.MockTask, DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\one.write.tlog")), false); inputs = new FlatTrackingData(DependencyTestHelper.MockTask, DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\one.read.tlog")), false); // We should be up to date with respect to the tracking data Assert.Equal(true, FlatTrackingData.IsUpToDate(DependencyTestHelper.MockTask.Log, UpToDateCheckType.InputOrOutputNewerThanTracking, inputs, outputs)); // Touch the input so that we would be out of date with respect to the outputs, but up to date with respect to the tracking logs File.SetLastWriteTime(Path.GetFullPath("TestFiles\\one.cpp"), DateTime.Now); outputs = new FlatTrackingData(DependencyTestHelper.MockTask, DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\one.write.tlog")), false); inputs = new FlatTrackingData(DependencyTestHelper.MockTask, DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\one.read.tlog")), false); // We should be out of date with respect to the outputs Assert.Equal(false, FlatTrackingData.IsUpToDate(DependencyTestHelper.MockTask.Log, UpToDateCheckType.InputNewerThanOutput, inputs, outputs)); }
public void FlatTrackingDataInputNewerThanTrackingNoOutput() { Console.WriteLine("Test: FlatTrackingDataInputNewerThanTrackingNoOutput"); // Prepare files DependencyTestHelper.WriteAll("TestFiles\\one1.h", ""); DependencyTestHelper.WriteAll("TestFiles\\one2.h", ""); DependencyTestHelper.WriteAll("TestFiles\\one3.h", ""); DependencyTestHelper.WriteAll("TestFiles\\one.cpp", ""); Thread.Sleep(sleepTimeMilliseconds); File.WriteAllLines("TestFiles\\one.read.tlog", new string[] { "#Command some-command", "^" + Path.GetFullPath("TestFiles\\one.cpp"), Path.GetFullPath("TestFiles\\one1.h"), Path.GetFullPath("TestFiles\\one2.h"), Path.GetFullPath("TestFiles\\one3.h"), }); FlatTrackingData outputs = new FlatTrackingData(DependencyTestHelper.MockTask, DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\*-one.write.?.tlog")), false); // Compact the read tlog FlatTrackingData inputs = new FlatTrackingData(DependencyTestHelper.MockTask, DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\one.read.tlog")), false); inputs.SaveTlog(); outputs.SaveTlog(); outputs = new FlatTrackingData(DependencyTestHelper.MockTask, DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\*-one.write.?.tlog")), false); // Compact the read tlog inputs = new FlatTrackingData(DependencyTestHelper.MockTask, DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\one.read.tlog")), false); Assert.Equal(true, FlatTrackingData.IsUpToDate(DependencyTestHelper.MockTask.Log, UpToDateCheckType.InputNewerThanTracking, inputs, outputs)); }
public static bool IsUpToDate(TaskLoggingHelper Log, UpToDateCheckType upToDateCheckType, FlatTrackingData inputs, FlatTrackingData outputs) { bool isUpToDate = false; // Keep a record of the task resources that was in use before ResourceManager taskResources = Log.TaskResources; Log.TaskResources = AssemblyResources.PrimaryResources; inputs.UpdateFileEntryDetails(); outputs.UpdateFileEntryDetails(); if (!inputs.TlogsAvailable || !outputs.TlogsAvailable || inputs.DependencyTable.Count == 0) { // 1) The TLogs are somehow missing, which means we need to build // 2) Because we are flat tracking, there are no roots which means that all the input file information // comes from the input Tlogs, if they are empty then we must build. Log.LogMessageFromResources(MessageImportance.Low, "Tracking_LogFilesNotAvailable"); } else if (inputs.MissingFiles.Count > 0 || outputs.MissingFiles.Count > 0) { // Files are missing from either inputs or outputs, that means we need to build // Files are missing from inputs, that means we need to build if (inputs.MissingFiles.Count > 0) { Log.LogMessageFromResources(MessageImportance.Low, "Tracking_MissingInputs"); } // Too much logging leads to poor performance if (inputs.MissingFiles.Count > MaxLogCount) { FileTracker.LogMessageFromResources(Log, MessageImportance.Low, "Tracking_InputsNotShown", inputs.MissingFiles.Count); } else { // We have our set of inputs, log the details foreach (string input in inputs.MissingFiles) { FileTracker.LogMessage(Log, MessageImportance.Low, "\t" + input); } } // Files are missing from outputs, that means we need to build if (outputs.MissingFiles.Count > 0) { Log.LogMessageFromResources(MessageImportance.Low, "Tracking_MissingOutputs"); } // Too much logging leads to poor performance if (outputs.MissingFiles.Count > MaxLogCount) { FileTracker.LogMessageFromResources(Log, MessageImportance.Low, "Tracking_OutputsNotShown", outputs.MissingFiles.Count); } else { // We have our set of inputs, log the details foreach (string output in outputs.MissingFiles) { FileTracker.LogMessage(Log, MessageImportance.Low, "\t" + output); } } } else if (upToDateCheckType == UpToDateCheckType.InputOrOutputNewerThanTracking && (inputs.NewestFileTimeUtc > inputs.NewestTLogTimeUtc)) { // One of the inputs is newer than the input tlog Log.LogMessageFromResources(MessageImportance.Low, "Tracking_DependencyWasModifiedAt", inputs.NewestFileName, inputs.NewestFileTimeUtc, inputs.NewestTLogFileName, inputs.NewestTLogTimeUtc); } else if (upToDateCheckType == UpToDateCheckType.InputOrOutputNewerThanTracking && (outputs.NewestFileTimeUtc > outputs.NewestTLogTimeUtc)) { // one of the outputs is newer than the output tlog Log.LogMessageFromResources(MessageImportance.Low, "Tracking_DependencyWasModifiedAt", outputs.NewestFileName, outputs.NewestFileTimeUtc, outputs.NewestTLogFileName, outputs.NewestTLogTimeUtc); } else if (upToDateCheckType == UpToDateCheckType.InputNewerThanOutput && (inputs.NewestFileTimeUtc > outputs.NewestFileTimeUtc)) { // One of the inputs is newer than the outputs Log.LogMessageFromResources(MessageImportance.Low, "Tracking_DependencyWasModifiedAt", inputs.NewestFileName, inputs.NewestFileTimeUtc, outputs.NewestFileName, outputs.NewestFileTimeUtc); } else if (upToDateCheckType == UpToDateCheckType.InputNewerThanTracking && (inputs.NewestFileTimeUtc > inputs.NewestTLogTimeUtc)) { // One of the inputs is newer than the one of the TLogs Log.LogMessageFromResources(MessageImportance.Low, "Tracking_DependencyWasModifiedAt", inputs.NewestFileName, inputs.NewestFileTimeUtc, inputs.NewestTLogFileName, inputs.NewestTLogTimeUtc); } else if (upToDateCheckType == UpToDateCheckType.InputNewerThanTracking && (inputs.NewestFileTimeUtc > outputs.NewestTLogTimeUtc)) { // One of the inputs is newer than the one of the TLogs Log.LogMessageFromResources(MessageImportance.Low, "Tracking_DependencyWasModifiedAt", inputs.NewestFileName, inputs.NewestFileTimeUtc, outputs.NewestTLogFileName, outputs.NewestTLogTimeUtc); } else { // Nothing appears to have changed.. isUpToDate = true; Log.LogMessageFromResources(MessageImportance.Normal, "Tracking_UpToDate"); } // Set the task resources back now that we're done with it Log.TaskResources = taskResources; return(isUpToDate); }
public static bool IsUpToDate(Task hostTask, UpToDateCheckType upToDateCheckType, ITaskItem[] readTLogNames, ITaskItem[] writeTLogNames) { FlatTrackingData inputs = new FlatTrackingData(hostTask, readTLogNames, DateTime.MaxValue); FlatTrackingData outputs = new FlatTrackingData(hostTask, writeTLogNames, DateTime.MinValue); bool flag = IsUpToDate(hostTask.Log, upToDateCheckType, inputs, outputs); if (!flag) { inputs.DependencyTable.Clear(); inputs.SaveTlog(); outputs.DependencyTable.Clear(); outputs.SaveTlog(); } return flag; }
public void InvalidFlatTrackingTLogName() { Console.WriteLine("Test: InvalidFlatTrackingTLogName"); // Prepare files DependencyTestHelper.WriteAll("TestFiles\\one.h", ""); DependencyTestHelper.WriteAll("TestFiles\\one.cpp", ""); DependencyTestHelper.WriteAll("TestFiles\\one.obj", ""); DependencyTestHelper.WriteAll("TestFiles\\one.tlog", ""); MockTask task = DependencyTestHelper.MockTask; FlatTrackingData data = new FlatTrackingData ( task, DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\|one|.write.tlog")), false /* don't skip missing files */ ); Assert.Equal(1, ((task as ITask).BuildEngine as MockEngine).Warnings); // "Should have a warning." Assert.Equal(0, data.DependencyTable.Count); // "DependencyTable should be empty." }
public static void FinalizeTLogs(bool trackedOperationsSucceeded, ITaskItem[] readTLogNames, ITaskItem[] writeTLogNames, ITaskItem[] trackedFilesToRemoveFromTLogs) { // Read the input table, skipping missing files FlatTrackingData inputs = new FlatTrackingData(readTLogNames, true); // Read the output table, skipping missing files FlatTrackingData outputs = new FlatTrackingData(writeTLogNames, true); // If we failed we need to clean the Tlogs if (!trackedOperationsSucceeded) { // If the tool errors in some way, we assume that any and all inputs and outputs it wrote during // execution are wrong. So we compact the read and write tlogs to remove the entries for the // set of sources being compiled - the next incremental build will find no entries // and correctly cause the sources to be compiled // Remove all from inputs tlog inputs.DependencyTable.Clear(); inputs.SaveTlog(); // Remove all from outputs tlog outputs.DependencyTable.Clear(); outputs.SaveTlog(); } else { // If all went well with the tool execution, then compact the tlogs // to remove any files that are no longer on disk. // This removes any temporary files from the dependency graph // In addition to temporary file removal, an optional set of files to remove may be been supplied if (trackedFilesToRemoveFromTLogs != null && trackedFilesToRemoveFromTLogs.Length > 0) { IDictionary<string, ITaskItem> trackedFilesToRemove = new Dictionary<string, ITaskItem>(StringComparer.OrdinalIgnoreCase); foreach (ITaskItem removeFile in trackedFilesToRemoveFromTLogs) { trackedFilesToRemove.Add(FileUtilities.NormalizePath(removeFile.ItemSpec), removeFile); } // UNDONE: If necessary we could have two independent sets of "ignore" files, one for inputs and one for outputs // Use an anonymous method to encapsulate the contains check for the output tlogs outputs.SaveTlog(delegate (string fullTrackedPath) { // We need to answer the question "should fullTrackedPath be included in the TLog?" return (!trackedFilesToRemove.ContainsKey(fullTrackedPath)); } ); // Use an anonymous method to encapsulate the contains check for the input tlogs inputs.SaveTlog(delegate (string fullTrackedPath) { // We need to answer the question "should fullTrackedPath be included in the TLog?" return (!trackedFilesToRemove.ContainsKey(fullTrackedPath)); } ); } else { // Compact the write tlog outputs.SaveTlog(); // Compact the read tlog inputs.SaveTlog(); } } }
public static bool IsUpToDate(TaskLoggingHelper Log, UpToDateCheckType upToDateCheckType, FlatTrackingData inputs, FlatTrackingData outputs) { bool isUpToDate = false; // Keep a record of the task resources that was in use before ResourceManager taskResources = Log.TaskResources; Log.TaskResources = AssemblyResources.PrimaryResources; inputs.UpdateFileEntryDetails(); outputs.UpdateFileEntryDetails(); if (!inputs.TlogsAvailable || !outputs.TlogsAvailable || inputs.DependencyTable.Count == 0) { // 1) The TLogs are somehow missing, which means we need to build // 2) Because we are flat tracking, there are no roots which means that all the input file information // comes from the input Tlogs, if they are empty then we must build. Log.LogMessageFromResources(MessageImportance.Low, "Tracking_LogFilesNotAvailable"); } else if (inputs.MissingFiles.Count > 0 || outputs.MissingFiles.Count > 0) { // Files are missing from either inputs or outputs, that means we need to build // Files are missing from inputs, that means we need to build if (inputs.MissingFiles.Count > 0) { Log.LogMessageFromResources(MessageImportance.Low, "Tracking_MissingInputs"); } // Too much logging leads to poor performance if (inputs.MissingFiles.Count > MaxLogCount) { FileTracker.LogMessageFromResources(Log, MessageImportance.Low, "Tracking_InputsNotShown", inputs.MissingFiles.Count); } else { // We have our set of inputs, log the details foreach (string input in inputs.MissingFiles) { FileTracker.LogMessage(Log, MessageImportance.Low, "\t" + input); } } // Files are missing from outputs, that means we need to build if (outputs.MissingFiles.Count > 0) { Log.LogMessageFromResources(MessageImportance.Low, "Tracking_MissingOutputs"); } // Too much logging leads to poor performance if (outputs.MissingFiles.Count > MaxLogCount) { FileTracker.LogMessageFromResources(Log, MessageImportance.Low, "Tracking_OutputsNotShown", outputs.MissingFiles.Count); } else { // We have our set of inputs, log the details foreach (string output in outputs.MissingFiles) { FileTracker.LogMessage(Log, MessageImportance.Low, "\t" + output); } } } else if (upToDateCheckType == UpToDateCheckType.InputOrOutputNewerThanTracking && (inputs.NewestFileTimeUtc > inputs.NewestTLogTimeUtc)) { // One of the inputs is newer than the input tlog Log.LogMessageFromResources(MessageImportance.Low, "Tracking_DependencyWasModifiedAt", inputs.NewestFileName, inputs.NewestFileTimeUtc, inputs.NewestTLogFileName, inputs.NewestTLogTimeUtc); } else if (upToDateCheckType == UpToDateCheckType.InputOrOutputNewerThanTracking && (outputs.NewestFileTimeUtc > outputs.NewestTLogTimeUtc)) { // one of the outputs is newer than the output tlog Log.LogMessageFromResources(MessageImportance.Low, "Tracking_DependencyWasModifiedAt", outputs.NewestFileName, outputs.NewestFileTimeUtc, outputs.NewestTLogFileName, outputs.NewestTLogTimeUtc); } else if (upToDateCheckType == UpToDateCheckType.InputNewerThanOutput && (inputs.NewestFileTimeUtc > outputs.NewestFileTimeUtc)) { // One of the inputs is newer than the outputs Log.LogMessageFromResources(MessageImportance.Low, "Tracking_DependencyWasModifiedAt", inputs.NewestFileName, inputs.NewestFileTimeUtc, outputs.NewestFileName, outputs.NewestFileTimeUtc); } else if (upToDateCheckType == UpToDateCheckType.InputNewerThanTracking && (inputs.NewestFileTimeUtc > inputs.NewestTLogTimeUtc)) { // One of the inputs is newer than the one of the TLogs Log.LogMessageFromResources(MessageImportance.Low, "Tracking_DependencyWasModifiedAt", inputs.NewestFileName, inputs.NewestFileTimeUtc, inputs.NewestTLogFileName, inputs.NewestTLogTimeUtc); } else if (upToDateCheckType == UpToDateCheckType.InputNewerThanTracking && (inputs.NewestFileTimeUtc > outputs.NewestTLogTimeUtc)) { // One of the inputs is newer than the one of the TLogs Log.LogMessageFromResources(MessageImportance.Low, "Tracking_DependencyWasModifiedAt", inputs.NewestFileName, inputs.NewestFileTimeUtc, outputs.NewestTLogFileName, outputs.NewestTLogTimeUtc); } else { // Nothing appears to have changed.. isUpToDate = true; Log.LogMessageFromResources(MessageImportance.Normal, "Tracking_UpToDate"); } // Set the task resources back now that we're done with it Log.TaskResources = taskResources; return isUpToDate; }
public static bool IsUpToDate(Task hostTask, UpToDateCheckType upToDateCheckType, ITaskItem[] readTLogNames, ITaskItem[] writeTLogNames) { bool isUpToDate; // Read the input graph (missing inputs are infinitely new - i.e. outputs are out of date) FlatTrackingData inputs = new FlatTrackingData(hostTask, readTLogNames, DateTime.MaxValue); // Read the output graph (missing outputs are infinitely old - i.e. outputs are out of date) FlatTrackingData outputs = new FlatTrackingData(hostTask, writeTLogNames, DateTime.MinValue); // Find out if we are up to date isUpToDate = IsUpToDate(hostTask.Log, upToDateCheckType, inputs, outputs); // We're going to execute, so clear out the tlogs so // the new execution will correctly populate the tlogs a-new if (!isUpToDate) { // Remove all from inputs tlog inputs.DependencyTable.Clear(); inputs.SaveTlog(); // Remove all from outputs tlog outputs.DependencyTable.Clear(); outputs.SaveTlog(); } return isUpToDate; }
public static bool IsUpToDate(TaskLoggingHelper Log, UpToDateCheckType upToDateCheckType, FlatTrackingData inputs, FlatTrackingData outputs) { bool flag = false; ResourceManager taskResources = Log.TaskResources; Log.TaskResources = AssemblyResources.PrimaryResources; inputs.UpdateFileEntryDetails(); outputs.UpdateFileEntryDetails(); if ((!inputs.TlogsAvailable || !outputs.TlogsAvailable) || (inputs.DependencyTable.Count == 0)) { Log.LogMessageFromResources(MessageImportance.Low, "Tracking_LogFilesNotAvailable", new object[0]); } else if ((inputs.MissingFiles.Count > 0) || (outputs.MissingFiles.Count > 0)) { if (inputs.MissingFiles.Count > 0) { Log.LogMessageFromResources(MessageImportance.Low, "Tracking_MissingInputs", new object[0]); } if (inputs.MissingFiles.Count > 100) { FileTracker.LogMessageFromResources(Log, MessageImportance.Low, "Tracking_InputsNotShown", new object[] { inputs.MissingFiles.Count }); } else { foreach (string str in inputs.MissingFiles) { FileTracker.LogMessage(Log, MessageImportance.Low, "\t" + str, new object[0]); } } if (outputs.MissingFiles.Count > 0) { Log.LogMessageFromResources(MessageImportance.Low, "Tracking_MissingOutputs", new object[0]); } if (outputs.MissingFiles.Count > 100) { FileTracker.LogMessageFromResources(Log, MessageImportance.Low, "Tracking_OutputsNotShown", new object[] { outputs.MissingFiles.Count }); } else { foreach (string str2 in outputs.MissingFiles) { FileTracker.LogMessage(Log, MessageImportance.Low, "\t" + str2, new object[0]); } } } else if ((upToDateCheckType == UpToDateCheckType.InputOrOutputNewerThanTracking) && (inputs.NewestFileTimeUtc > inputs.NewestTLogTimeUtc)) { Log.LogMessageFromResources(MessageImportance.Low, "Tracking_DependencyWasModifiedAt", new object[] { inputs.NewestFileName, inputs.NewestFileTimeUtc }); } else if ((upToDateCheckType == UpToDateCheckType.InputOrOutputNewerThanTracking) && (outputs.NewestFileTimeUtc > outputs.NewestTLogTimeUtc)) { Log.LogMessage(MessageImportance.Low, "Tracking_DependencyWasModifiedAt", new object[] { outputs.NewestFileName, outputs.NewestFileTimeUtc }); } else if ((upToDateCheckType == UpToDateCheckType.InputNewerThanOutput) && (inputs.NewestFileTimeUtc > outputs.NewestFileTimeUtc)) { Log.LogMessageFromResources(MessageImportance.Low, "Tracking_DependencyWasModifiedAt", new object[] { inputs.NewestFileName, inputs.NewestFileTimeUtc }); } else if ((upToDateCheckType == UpToDateCheckType.InputNewerThanTracking) && (inputs.NewestFileTimeUtc > inputs.NewestTLogTimeUtc)) { Log.LogMessageFromResources(MessageImportance.Low, "Tracking_DependencyWasModifiedAt", new object[] { inputs.NewestFileName, inputs.NewestFileTimeUtc }); } else if ((upToDateCheckType == UpToDateCheckType.InputNewerThanTracking) && (inputs.NewestFileTimeUtc > outputs.NewestTLogTimeUtc)) { Log.LogMessageFromResources(MessageImportance.Low, "Tracking_DependencyWasModifiedAt", new object[] { inputs.NewestFileName, inputs.NewestFileTimeUtc }); } else { flag = true; Log.LogMessageFromResources(MessageImportance.Normal, "Tracking_UpToDate", new object[0]); } Log.TaskResources = taskResources; return(flag); }
public static void FinalizeTLogs(bool trackedOperationsSucceeded, ITaskItem[] readTLogNames, ITaskItem[] writeTLogNames, ITaskItem[] trackedFilesToRemoveFromTLogs) { // Read the input table, skipping missing files FlatTrackingData inputs = new FlatTrackingData(readTLogNames, true); // Read the output table, skipping missing files FlatTrackingData outputs = new FlatTrackingData(writeTLogNames, true); // If we failed we need to clean the Tlogs if (!trackedOperationsSucceeded) { // If the tool errors in some way, we assume that any and all inputs and outputs it wrote during // execution are wrong. So we compact the read and write tlogs to remove the entries for the // set of sources being compiled - the next incremental build will find no entries // and correctly cause the sources to be compiled // Remove all from inputs tlog inputs.DependencyTable.Clear(); inputs.SaveTlog(); // Remove all from outputs tlog outputs.DependencyTable.Clear(); outputs.SaveTlog(); } else { // If all went well with the tool execution, then compact the tlogs // to remove any files that are no longer on disk. // This removes any temporary files from the dependency graph // In addition to temporary file removal, an optional set of files to remove may be been supplied if (trackedFilesToRemoveFromTLogs != null && trackedFilesToRemoveFromTLogs.Length > 0) { IDictionary <string, ITaskItem> trackedFilesToRemove = new Dictionary <string, ITaskItem>(StringComparer.OrdinalIgnoreCase); foreach (ITaskItem removeFile in trackedFilesToRemoveFromTLogs) { trackedFilesToRemove.Add(FileUtilities.NormalizePath(removeFile.ItemSpec), removeFile); } // UNDONE: If necessary we could have two independent sets of "ignore" files, one for inputs and one for outputs // Use an anonymous method to encapsulate the contains check for the output tlogs outputs.SaveTlog(delegate(string fullTrackedPath) { // We need to answer the question "should fullTrackedPath be included in the TLog?" return(!trackedFilesToRemove.ContainsKey(fullTrackedPath)); } ); // Use an anonymous method to encapsulate the contains check for the input tlogs inputs.SaveTlog(delegate(string fullTrackedPath) { // We need to answer the question "should fullTrackedPath be included in the TLog?" return(!trackedFilesToRemove.ContainsKey(fullTrackedPath)); } ); } else { // Compact the write tlog outputs.SaveTlog(); // Compact the read tlog inputs.SaveTlog(); } } }
public void FlatTrackingTLogWithEmptyRoot() { Console.WriteLine("Test: FlatTrackingTLogWithEmptyRoot"); File.WriteAllLines("TestFiles\\one.tlog", new string[] { "^", "FOO" }); MockTask task = DependencyTestHelper.MockTask; FlatTrackingData data = new FlatTrackingData ( task, DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\one.tlog")), false /* don't skip missing files */ ); Assert.Equal(0, ((task as ITask).BuildEngine as MockEngine).Warnings); // "Should not warn -- root markers are ignored by default" Assert.Equal(1, data.DependencyTable.Count); // "DependencyTable should only contain one entry." Assert.NotNull(data.DependencyTable["FOO"]); // "FOO should be the only entry." }
public void FlatTrackingTLogWithInitialEmptyLine() { Console.WriteLine("Test: FlatTrackingTLogWithInitialEmptyLine"); File.WriteAllLines("TestFiles\\one.tlog", new string[] { "", "^FOO" }); MockTask task = DependencyTestHelper.MockTask; FlatTrackingData data = new FlatTrackingData ( task, DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\one.tlog")), false /* don't skip missing files */ ); Assert.Equal(1, ((task as ITask).BuildEngine as MockEngine).Warnings); // "Should have a warning." Assert.Equal(0, data.DependencyTable.Count); // "DependencyTable should be empty." }
public void FlatTrackingDataEmptyInputTLogs() { Console.WriteLine("Test: FlatTrackingDataEmptyInputTLogs"); // Prepare files File.WriteAllText("TestFiles\\one.read.tlog", String.Empty); File.WriteAllText("TestFiles\\one.write.tlog", String.Empty); FlatTrackingData outputs = new FlatTrackingData(DependencyTestHelper.MockTask, DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\one.write.tlog")), false); FlatTrackingData inputs = new FlatTrackingData(DependencyTestHelper.MockTask, DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\one.read.tlog")), false); // No matter which way you look at it, if we're missing inputs, we're out of date Assert.Equal(false, FlatTrackingData.IsUpToDate(DependencyTestHelper.MockTask.Log, UpToDateCheckType.InputNewerThanOutput, inputs, outputs)); Assert.Equal(false, FlatTrackingData.IsUpToDate(DependencyTestHelper.MockTask.Log, UpToDateCheckType.InputNewerThanTracking, inputs, outputs)); Assert.Equal(false, FlatTrackingData.IsUpToDate(DependencyTestHelper.MockTask.Log, UpToDateCheckType.InputOrOutputNewerThanTracking, inputs, outputs)); }
public static void FinalizeTLogs(bool trackedOperationsSucceeded, ITaskItem[] readTLogNames, ITaskItem[] writeTLogNames, ITaskItem[] trackedFilesToRemoveFromTLogs) { FlatTrackingData data = new FlatTrackingData(readTLogNames, true); FlatTrackingData data2 = new FlatTrackingData(writeTLogNames, true); if (!trackedOperationsSucceeded) { data.DependencyTable.Clear(); data.SaveTlog(); data2.DependencyTable.Clear(); data2.SaveTlog(); } else if ((trackedFilesToRemoveFromTLogs != null) && (trackedFilesToRemoveFromTLogs.Length > 0)) { IDictionary<string, ITaskItem> trackedFilesToRemove = new Dictionary<string, ITaskItem>(StringComparer.OrdinalIgnoreCase); foreach (ITaskItem item in trackedFilesToRemoveFromTLogs) { trackedFilesToRemove.Add(FileUtilities.NormalizePath(item.ItemSpec), item); } data2.SaveTlog(fullTrackedPath => !trackedFilesToRemove.ContainsKey(fullTrackedPath)); data.SaveTlog(fullTrackedPath => !trackedFilesToRemove.ContainsKey(fullTrackedPath)); } else { data2.SaveTlog(); data.SaveTlog(); } }
public void FlatTrackingDataEmptyOutputTLogs() { Console.WriteLine("Test: FlatTrackingDataEmptyOutputTLogs"); DependencyTestHelper.WriteAll("TestFiles\\one1.h", ""); DependencyTestHelper.WriteAll("TestFiles\\one2.h", ""); DependencyTestHelper.WriteAll("TestFiles\\one3.h", ""); DependencyTestHelper.WriteAll("TestFiles\\one.cpp", ""); Thread.Sleep(sleepTimeMilliseconds); // Prepare files File.WriteAllLines("TestFiles\\one.read.tlog", new string[] { "#Command some-command", "^" + Path.GetFullPath("TestFiles\\one.cpp"), Path.GetFullPath("TestFiles\\one1.h"), Path.GetFullPath("TestFiles\\one2.h"), Path.GetFullPath("TestFiles\\one3.h"), }); File.WriteAllText("TestFiles\\one.write.tlog", String.Empty); FlatTrackingData outputs = new FlatTrackingData(DependencyTestHelper.MockTask, DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\one.write.tlog")), false); FlatTrackingData inputs = new FlatTrackingData(DependencyTestHelper.MockTask, DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\one.read.tlog")), false); // Inputs newer than outputs - if there are no outputs, then we're out of date Assert.Equal(false, FlatTrackingData.IsUpToDate(DependencyTestHelper.MockTask.Log, UpToDateCheckType.InputNewerThanOutput, inputs, outputs)); // Inputs newer than tracking - if there are no outputs, then we don't care Assert.Equal(true, FlatTrackingData.IsUpToDate(DependencyTestHelper.MockTask.Log, UpToDateCheckType.InputNewerThanTracking, inputs, outputs)); // Inputs or Outputs newer than tracking - if there is an output tlog, even if there's no text written to it, we're not out of date Assert.Equal(true, FlatTrackingData.IsUpToDate(DependencyTestHelper.MockTask.Log, UpToDateCheckType.InputOrOutputNewerThanTracking, inputs, outputs)); }
public static bool IsUpToDate(TaskLoggingHelper Log, UpToDateCheckType upToDateCheckType, FlatTrackingData inputs, FlatTrackingData outputs) { bool flag = false; ResourceManager taskResources = Log.TaskResources; Log.TaskResources = AssemblyResources.PrimaryResources; inputs.UpdateFileEntryDetails(); outputs.UpdateFileEntryDetails(); if ((!inputs.TlogsAvailable || !outputs.TlogsAvailable) || (inputs.DependencyTable.Count == 0)) { Log.LogMessageFromResources(MessageImportance.Low, "Tracking_LogFilesNotAvailable", new object[0]); } else if ((inputs.MissingFiles.Count > 0) || (outputs.MissingFiles.Count > 0)) { if (inputs.MissingFiles.Count > 0) { Log.LogMessageFromResources(MessageImportance.Low, "Tracking_MissingInputs", new object[0]); } if (inputs.MissingFiles.Count > 100) { FileTracker.LogMessageFromResources(Log, MessageImportance.Low, "Tracking_InputsNotShown", new object[] { inputs.MissingFiles.Count }); } else { foreach (string str in inputs.MissingFiles) { FileTracker.LogMessage(Log, MessageImportance.Low, "\t" + str, new object[0]); } } if (outputs.MissingFiles.Count > 0) { Log.LogMessageFromResources(MessageImportance.Low, "Tracking_MissingOutputs", new object[0]); } if (outputs.MissingFiles.Count > 100) { FileTracker.LogMessageFromResources(Log, MessageImportance.Low, "Tracking_OutputsNotShown", new object[] { outputs.MissingFiles.Count }); } else { foreach (string str2 in outputs.MissingFiles) { FileTracker.LogMessage(Log, MessageImportance.Low, "\t" + str2, new object[0]); } } } else if ((upToDateCheckType == UpToDateCheckType.InputOrOutputNewerThanTracking) && (inputs.NewestFileTimeUtc > inputs.NewestTLogTimeUtc)) { Log.LogMessageFromResources(MessageImportance.Low, "Tracking_DependencyWasModifiedAt", new object[] { inputs.NewestFileName, inputs.NewestFileTimeUtc }); } else if ((upToDateCheckType == UpToDateCheckType.InputOrOutputNewerThanTracking) && (outputs.NewestFileTimeUtc > outputs.NewestTLogTimeUtc)) { Log.LogMessage(MessageImportance.Low, "Tracking_DependencyWasModifiedAt", new object[] { outputs.NewestFileName, outputs.NewestFileTimeUtc }); } else if ((upToDateCheckType == UpToDateCheckType.InputNewerThanOutput) && (inputs.NewestFileTimeUtc > outputs.NewestFileTimeUtc)) { Log.LogMessageFromResources(MessageImportance.Low, "Tracking_DependencyWasModifiedAt", new object[] { inputs.NewestFileName, inputs.NewestFileTimeUtc }); } else if ((upToDateCheckType == UpToDateCheckType.InputNewerThanTracking) && (inputs.NewestFileTimeUtc > inputs.NewestTLogTimeUtc)) { Log.LogMessageFromResources(MessageImportance.Low, "Tracking_DependencyWasModifiedAt", new object[] { inputs.NewestFileName, inputs.NewestFileTimeUtc }); } else if ((upToDateCheckType == UpToDateCheckType.InputNewerThanTracking) && (inputs.NewestFileTimeUtc > outputs.NewestTLogTimeUtc)) { Log.LogMessageFromResources(MessageImportance.Low, "Tracking_DependencyWasModifiedAt", new object[] { inputs.NewestFileName, inputs.NewestFileTimeUtc }); } else { flag = true; Log.LogMessageFromResources(MessageImportance.Normal, "Tracking_UpToDate", new object[0]); } Log.TaskResources = taskResources; return flag; }
public void TrackingDataCacheResetOnTlogChange() { Console.WriteLine("Test: FlatTrackingDataCacheResetOnTlogChange"); File.WriteAllLines("TestFiles\\one.write.tlog", new string[] { "#Command some-command", "^" + Path.GetFullPath("TestFiles\\one.cpp"), Path.GetFullPath("TestFiles\\one.obj"), }); FlatTrackingData outputs = new FlatTrackingData(DependencyTestHelper.MockTask, DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\one.write.tlog")), false); // Sleep once, so that NTFS has enough time to register a file modified time change Thread.Sleep(sleepTimeMilliseconds); File.WriteAllLines("TestFiles\\one.write.tlog", new string[] { "#Command some-command", "^" + Path.GetFullPath("TestFiles\\two.cpp"), Path.GetFullPath("TestFiles\\two.obj"), }); FlatTrackingData outputs2 = new FlatTrackingData(DependencyTestHelper.MockTask, DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\one.write.tlog")), false); // We should not use the cached dependency table, since it has been updated since it was last read from disk Assert.NotEqual(outputs.DependencyTable, outputs2.DependencyTable); }