From 270dc59dad787165b3501aee7af4c38646d3dbe1 Mon Sep 17 00:00:00 2001 From: Alex S Date: Mon, 22 Sep 2025 15:19:02 -0700 Subject: [PATCH 1/2] Don't update the reference file if no changes were detected --- src/Shared/ReferenceItemExtensions.cs | 12 ++++++++++++ .../ReferenceProtector.Tasks.TestBase.cs | 2 +- .../ReferenceProtector.Tasks.Tests.cs | 19 +++++++++++++++++++ .../CollectAllReferences.cs | 4 +++- 4 files changed, 35 insertions(+), 2 deletions(-) diff --git a/src/Shared/ReferenceItemExtensions.cs b/src/Shared/ReferenceItemExtensions.cs index 5179bb8..183852a 100644 --- a/src/Shared/ReferenceItemExtensions.cs +++ b/src/Shared/ReferenceItemExtensions.cs @@ -14,6 +14,18 @@ public static string ToFileLine(this ReferenceItem item) public static void SaveToFile(this List items, string outputFile) { + if (File.Exists(outputFile)) + { + var currentContents = File.ReadAllLines(outputFile); + var newContents = items.Select(item => item.ToFileLine()).ToArray(); + // Assuming order is the same for incremental builds, no sorting needed + if (currentContents.SequenceEqual(newContents)) + { + // No changes, skip writing to avoid updating the timestamp, which will trigger unnecessary rebuilds + return; + } + } + File.WriteAllLines(outputFile, items.Select(item => item.ToFileLine())); } diff --git a/src/Tasks/ReferenceProtector.Tasks.IntegrationTests/ReferenceProtector.Tasks.TestBase.cs b/src/Tasks/ReferenceProtector.Tasks.IntegrationTests/ReferenceProtector.Tasks.TestBase.cs index 3b4d2f4..85a95c4 100644 --- a/src/Tasks/ReferenceProtector.Tasks.IntegrationTests/ReferenceProtector.Tasks.TestBase.cs +++ b/src/Tasks/ReferenceProtector.Tasks.IntegrationTests/ReferenceProtector.Tasks.TestBase.cs @@ -143,7 +143,7 @@ internal async Task Build(string additionalArgs = "") { string buildArgs = $"build dirs.proj " + - $"-m:1 -t:Rebuild -restore -nologo -nodeReuse:false -noAutoResponse " + + $"-m:1 -restore -nologo -nodeReuse:false -noAutoResponse " + $"/p:Configuration=Debug " + $"/p:ReferenceProtectorTaskAssembly={Path.Combine(Directory.GetCurrentDirectory(), "ReferenceProtector.Tasks.dll")} " + $"/v:m" + diff --git a/src/Tasks/ReferenceProtector.Tasks.IntegrationTests/ReferenceProtector.Tasks.Tests.cs b/src/Tasks/ReferenceProtector.Tasks.IntegrationTests/ReferenceProtector.Tasks.Tests.cs index 4dbe857..0130461 100644 --- a/src/Tasks/ReferenceProtector.Tasks.IntegrationTests/ReferenceProtector.Tasks.Tests.cs +++ b/src/Tasks/ReferenceProtector.Tasks.IntegrationTests/ReferenceProtector.Tasks.Tests.cs @@ -126,4 +126,23 @@ public async Task CollectAllReferences_PackageReferences_AreIncluded() Assert.Equal(expectedReferences, references); } + + [Fact] + public async Task CollectAllReferences_IncrememtalBuild_ReferenceTimestampIsNotUpdated() + { + CreateProject("A"); + CreateProject("B"); + await AddProjectReference("A", "B"); + await Build(); + + var generatedFiles = GetGeneratedReferencesFiles(); + + var timeStamps1 = generatedFiles.Select(File.GetLastWriteTimeUtc).ToList(); + + // Rebuild without any changes + await Build(); + + var timeStamps2 = generatedFiles.Select(File.GetLastWriteTimeUtc).ToList(); + Assert.Equal(timeStamps1, timeStamps2); + } } \ No newline at end of file diff --git a/src/Tasks/ReferenceProtector.Tasks/CollectAllReferences.cs b/src/Tasks/ReferenceProtector.Tasks/CollectAllReferences.cs index c48df6b..274bbfc 100644 --- a/src/Tasks/ReferenceProtector.Tasks/CollectAllReferences.cs +++ b/src/Tasks/ReferenceProtector.Tasks/CollectAllReferences.cs @@ -82,7 +82,9 @@ public override bool Execute() if (OutputFile is not null) { - references.SaveToFile(OutputFile); + // Is sorted to ensure consistent ordering for easier testing and to avoid unnecessary diffs + // May not needed, if msbuild guarantees a consistent order + references.OrderBy(x => (x.Source, x.Target, x.LinkType)).ToList().SaveToFile(OutputFile); return true; } From a1332899259dc6c04ac33191303d4316ddeb97c0 Mon Sep 17 00:00:00 2001 From: Alex S Date: Mon, 22 Sep 2025 15:28:24 -0700 Subject: [PATCH 2/2] Add xml to the test --- .../ReferenceProtector.Tasks.Tests.cs | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/Tasks/ReferenceProtector.Tasks.IntegrationTests/ReferenceProtector.Tasks.Tests.cs b/src/Tasks/ReferenceProtector.Tasks.IntegrationTests/ReferenceProtector.Tasks.Tests.cs index 0130461..7a6ea21 100644 --- a/src/Tasks/ReferenceProtector.Tasks.IntegrationTests/ReferenceProtector.Tasks.Tests.cs +++ b/src/Tasks/ReferenceProtector.Tasks.IntegrationTests/ReferenceProtector.Tasks.Tests.cs @@ -127,6 +127,9 @@ public async Task CollectAllReferences_PackageReferences_AreIncluded() Assert.Equal(expectedReferences, references); } + /// + /// Verifies that the CollectAllReferences task does not update the reference file timestamp if no changes were made. + /// [Fact] public async Task CollectAllReferences_IncrememtalBuild_ReferenceTimestampIsNotUpdated() { @@ -135,14 +138,16 @@ public async Task CollectAllReferences_IncrememtalBuild_ReferenceTimestampIsNotU await AddProjectReference("A", "B"); await Build(); - var generatedFiles = GetGeneratedReferencesFiles(); - - var timeStamps1 = generatedFiles.Select(File.GetLastWriteTimeUtc).ToList(); + var generatedFiles1 = GetGeneratedReferencesFiles(); + var timeStamps1 = generatedFiles1.Select(File.GetLastWriteTimeUtc).ToList(); // Rebuild without any changes await Build(); - var timeStamps2 = generatedFiles.Select(File.GetLastWriteTimeUtc).ToList(); + var generatedFiles2 = GetGeneratedReferencesFiles(); + var timeStamps2 = generatedFiles2.Select(File.GetLastWriteTimeUtc).ToList(); + + Assert.Equal(generatedFiles1, generatedFiles2); Assert.Equal(timeStamps1, timeStamps2); } } \ No newline at end of file