internal bool IsUpToDate(OutputWindowLogger logger, bool testing) { logger.WriteLine("Checking whether {0} needs to be rebuilt:", ProjectMgr.Caption); // in batch build it is possible that config is out of sync. // in this case, don't assume we are up to date ConfigCanonicalName activeConfig = default(ConfigCanonicalName); if(!Utilities.TryGetActiveConfigurationAndPlatform(ServiceProvider.GlobalProvider, this.project.ProjectIDGuid, out activeConfig) || activeConfig != this.ConfigCanonicalName) { logger.WriteLine("Not up to date: active confic does not match project config. Active: {0} Project: {1}", activeConfig, this.ConfigCanonicalName); if (!testing) return false; } var inputs = new HashSet<string>(StringComparer.OrdinalIgnoreCase); if (!GetUTDCheckInputs(inputs)) return false; var outputs = new HashSet<string>(StringComparer.OrdinalIgnoreCase); List<Tuple<string, string>> preserveNewestOutputs; GetUTDCheckOutputs(inputs, outputs, out preserveNewestOutputs); // determine the oldest output timestamp DateTime stalestOutputTime = DateTime.MaxValue.ToUniversalTime(); foreach (var output in outputs) { var timeStamp = TryGetLastWriteTimeUtc(output, logger); if (!timeStamp.HasValue) { logger.WriteLine("Declaring project NOT up to date, can't find expected output {0}", output); return false; } logger.WriteLine(" Output: {0} {1}", timeStamp.Value.ToLocalTime(), output); if (stalestOutputTime > timeStamp.Value) stalestOutputTime = timeStamp.Value; } // determine the newest input timestamp DateTime freshestInputTime = DateTime.MinValue.ToUniversalTime(); foreach (var input in inputs) { var timeStamp = TryGetLastWriteTimeUtc(input, logger); if (!timeStamp.HasValue) { logger.WriteLine("Declaring project NOT up to date, can't find expected input {0}", input); return false; } logger.WriteLine(" Input: {0} {1}", timeStamp.Value.ToLocalTime(), input); if (freshestInputTime < timeStamp.Value) freshestInputTime = timeStamp.Value; } // check 1-1 Preserve Newest mappings foreach (var kv in preserveNewestOutputs) { if (!IsUpToDatePreserveNewest(logger, TryGetLastWriteTimeUtc, kv.Item1, kv.Item2)) return false; } logger.WriteLine("Freshest input: {0}", freshestInputTime.ToLocalTime()); logger.WriteLine("Stalest output: {0}", stalestOutputTime.ToLocalTime()); logger.WriteLine("Up to date: {0}", freshestInputTime <= stalestOutputTime); // if all outputs are younger than all inputs, we are up to date return freshestInputTime <= stalestOutputTime; }
public static bool IsUpToDatePreserveNewest(OutputWindowLogger logger, Func<string, OutputWindowLogger, DateTime?> tryGetLastWriteTimeUtc, string input, string output) { var inputTime = tryGetLastWriteTimeUtc(input, logger); if (!inputTime.HasValue) { logger.WriteLine("Declaring project NOT up to date, can't find expected input {0}", input); return false; } var outputTime = tryGetLastWriteTimeUtc(output, logger); if (!outputTime.HasValue) { logger.WriteLine("Declaring project NOT up to date, can't find expected output {0}", output); return false; } var inputTimeValue = inputTime.Value; var outputTimeValue = outputTime.Value; if (outputTimeValue < inputTimeValue) { logger.WriteLine("Declaring project NOT up to date, ouput {0} is stale", output); return false; } return true; }
private static DateTime? TryGetLastWriteTimeUtc(string path, OutputWindowLogger logger) { Exception exn = null; try { if (File.Exists(path)) return File.GetLastWriteTimeUtc(path); } catch (Exception ex) { exn = ex; } if (exn != null) { logger.WriteLine("Failed to access {0}: {1}", path, exn.Message); logger.WriteLine(exn.ToString()); } return null; }