From b1c14ff273031f86e1df23a5fddc5d47842066ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20Strandg=C3=A5rd?= Date: Thu, 24 Jul 2025 13:56:44 +0200 Subject: [PATCH 1/4] Fix moving file detection --- src/ProjectDiff.Core/BuildGraphDiff.cs | 4 +- src/ProjectDiff.Core/BuildGraphFactory.cs | 29 +++- src/ProjectDiff.Core/BuildGraphProject.cs | 5 - src/ProjectDiff.Core/DiffProject.cs | 4 +- .../DirectoryScanEntrypointProvider.cs | 6 +- src/ProjectDiff.Core/ProjectDiffExecutor.cs | 13 +- src/dotnet-proj-diff/ProjectDiffCommand.cs | 2 - test/ProjectDiff.Tests/Core/MoveFileTests.cs | 143 ++++++++++++++++++ ...tputsJson_absolutePaths=False.verified.txt | 2 + ...utputsJson_absolutePaths=True.verified.txt | 2 + ...ctDiffTests.DetectsAddedFiles.verified.txt | 1 + ...iffTests.DetectsAddedProjects.verified.txt | 1 + ...ddedProjectsWithDirectoryScan.verified.txt | 1 + ...gesInNestedReferencedProjects.verified.txt | 3 + ...tsChangesInReferencedProjects.verified.txt | 2 + ...DiffTests.DetectsDeletedFiles.verified.txt | 1 + ...eletedProjectsWhenOptionIsSet.verified.txt | 1 + ...iffTests.DetectsModifiedFiles.verified.txt | 1 + 18 files changed, 199 insertions(+), 22 deletions(-) create mode 100644 test/ProjectDiff.Tests/Core/MoveFileTests.cs diff --git a/src/ProjectDiff.Core/BuildGraphDiff.cs b/src/ProjectDiff.Core/BuildGraphDiff.cs index ebe8c19..2065612 100644 --- a/src/ProjectDiff.Core/BuildGraphDiff.cs +++ b/src/ProjectDiff.Core/BuildGraphDiff.cs @@ -30,7 +30,7 @@ public IEnumerable Execute(BuildGraph previous, FrozenSet m { foreach (var currentProject in _graph.Projects) { - var previousProject = previous.Projects.FirstOrDefault(it => it.Matches(currentProject)); + var previousProject = previous.Projects.FirstOrDefault(it => it.FullPath == currentProject.FullPath); if (previousProject is null) { yield return new DiffProject @@ -62,7 +62,7 @@ public IEnumerable Execute(BuildGraph previous, FrozenSet m foreach (var previousProject in previous.Projects) { - var existsInCurrent = _graph.Projects.Any(it => it.Matches(previousProject)); + var existsInCurrent = _graph.Projects.Any(it => it.FullPath == previousProject.FullPath); if (!existsInCurrent) { yield return new DiffProject diff --git a/src/ProjectDiff.Core/BuildGraphFactory.cs b/src/ProjectDiff.Core/BuildGraphFactory.cs index 00be02a..83ee308 100644 --- a/src/ProjectDiff.Core/BuildGraphFactory.cs +++ b/src/ProjectDiff.Core/BuildGraphFactory.cs @@ -1,4 +1,5 @@ using System.Diagnostics; +using LibGit2Sharp; using Microsoft.Build.Execution; using Microsoft.Build.Graph; using Microsoft.Build.Prediction; @@ -16,7 +17,8 @@ public static class BuildGraphFactory public static BuildGraph CreateForProjectGraph( ProjectGraph graph, - IReadOnlyCollection changedFiles + Repository repository, + IReadOnlyCollection ignoredFiles ) { var executor = new ProjectGraphPredictionExecutor( @@ -24,7 +26,7 @@ IReadOnlyCollection changedFiles ProjectPredictors.AllProjectPredictors ); - var collector = new BuildGraphPredictionCollector(graph, changedFiles); + var collector = new BuildGraphPredictionCollector(graph, repository, ignoredFiles); executor.PredictInputsAndOutputs(graph, collector); @@ -34,13 +36,19 @@ IReadOnlyCollection changedFiles private sealed class BuildGraphPredictionCollector : IProjectPredictionCollector { private readonly ProjectGraph _projectGraph; + private readonly Repository _repository; + private readonly IReadOnlyCollection _ignoredFiles; private readonly Dictionary _collectors; - private readonly IReadOnlyCollection _changedFiles; - public BuildGraphPredictionCollector(ProjectGraph projectGraph, IReadOnlyCollection changedFiles) + public BuildGraphPredictionCollector( + ProjectGraph projectGraph, + Repository repository, + IReadOnlyCollection ignoredFiles + ) { _projectGraph = projectGraph; - _changedFiles = changedFiles; + _repository = repository; + _ignoredFiles = ignoredFiles; _collectors = new Dictionary(_projectGraph.ProjectNodes.Count); foreach (var node in _projectGraph.ProjectNodes) { @@ -51,6 +59,7 @@ public BuildGraphPredictionCollector(ProjectGraph projectGraph, IReadOnlyCollect } } + public void AddInputFile(string path, ProjectInstance projectInstance, string predictorName) { if (!Path.IsPathRooted(path)) @@ -58,11 +67,19 @@ public void AddInputFile(string path, ProjectInstance projectInstance, string pr path = Path.GetFullPath(path, projectInstance.Directory); } - if (!_changedFiles.Contains(path)) + // Only include files that are part of this repository + if (!path.StartsWith(_repository.Info.WorkingDirectory)) + { + return; + } + + // Ignore files that are in the ignored files list + if (_ignoredFiles.Count > 0 && _ignoredFiles.Any(it => it.FullName == path)) { return; } + if (!_collectors.TryGetValue(projectInstance.FullPath, out var collector)) { Debug.Fail($"Failed to get collector for project {projectInstance.FullPath}"); diff --git a/src/ProjectDiff.Core/BuildGraphProject.cs b/src/ProjectDiff.Core/BuildGraphProject.cs index 1b5d1e0..297ed7d 100644 --- a/src/ProjectDiff.Core/BuildGraphProject.cs +++ b/src/ProjectDiff.Core/BuildGraphProject.cs @@ -16,9 +16,4 @@ IReadOnlyCollection references public string FullPath { get; } public IReadOnlyCollection InputFiles { get; } public IReadOnlyCollection References { get; } - - public bool Matches(BuildGraphProject other) - { - return FullPath == other.FullPath; - } } \ No newline at end of file diff --git a/src/ProjectDiff.Core/DiffProject.cs b/src/ProjectDiff.Core/DiffProject.cs index 5e459a4..f545991 100644 --- a/src/ProjectDiff.Core/DiffProject.cs +++ b/src/ProjectDiff.Core/DiffProject.cs @@ -3,8 +3,8 @@ public sealed record DiffProject { public required string Path { get; init; } + public string Name => System.IO.Path.GetFileNameWithoutExtension(Path); public required DiffStatus Status { get; init; } - - + public required IReadOnlyCollection ReferencedProjects { get; init; } = []; } \ No newline at end of file diff --git a/src/ProjectDiff.Core/Entrypoints/DirectoryScanEntrypointProvider.cs b/src/ProjectDiff.Core/Entrypoints/DirectoryScanEntrypointProvider.cs index e0c7db4..dd2128b 100644 --- a/src/ProjectDiff.Core/Entrypoints/DirectoryScanEntrypointProvider.cs +++ b/src/ProjectDiff.Core/Entrypoints/DirectoryScanEntrypointProvider.cs @@ -1,6 +1,7 @@ using Microsoft.Build.FileSystem; using Microsoft.Build.Graph; using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Abstractions; namespace ProjectDiff.Core.Entrypoints; @@ -8,9 +9,10 @@ public sealed class DirectoryScanEntrypointProvider : IEntrypointProvider { private readonly ILogger _logger; - public DirectoryScanEntrypointProvider(ILogger logger) + + public DirectoryScanEntrypointProvider(ILogger? logger = null) { - _logger = logger; + _logger = logger ?? NullLogger.Instance; } public Task> GetEntrypoints( diff --git a/src/ProjectDiff.Core/ProjectDiffExecutor.cs b/src/ProjectDiff.Core/ProjectDiffExecutor.cs index df49d71..238ed14 100644 --- a/src/ProjectDiff.Core/ProjectDiffExecutor.cs +++ b/src/ProjectDiff.Core/ProjectDiffExecutor.cs @@ -176,14 +176,17 @@ public async Task GetProjectDiff( _logger.LogDebug("Head project graph construction metrics: {Metrics}", headGraph.ConstructionMetrics); - var headBuildGraph = BuildGraphFactory.CreateForProjectGraph(headGraph, changedFiles); - var baseBuildGraph = BuildGraphFactory.CreateForProjectGraph(baseGraph, changedFiles); + var headBuildGraph = BuildGraphFactory.CreateForProjectGraph(headGraph, repo, _options.IgnoreChangedFiles); + var baseBuildGraph = BuildGraphFactory.CreateForProjectGraph(baseGraph, repo, _options.IgnoreChangedFiles); + var projects = BuildGraphDiff.Diff(baseBuildGraph, headBuildGraph, changedFiles) + .OrderBy(it => it.ReferencedProjects.Count) + .ThenBy(it => it.Name); return new ProjectDiffResult { Status = ProjectDiffExecutionStatus.Success, ChangedFiles = changedFiles, - Projects = BuildGraphDiff.Diff(baseBuildGraph, headBuildGraph, changedFiles), + Projects = projects, }; bool ShouldIncludeFile(string file) => @@ -205,6 +208,10 @@ private static IEnumerable GetGitModifiedFiles( : repository.Diff.Compare(baseCommit.Tree, headCommit.Tree); foreach (var change in changes) { + // if (change.Path != change.OldPath) + // { + // yield return Path.GetFullPath(change.OldPath, repository.Info.WorkingDirectory); + // } yield return Path.GetFullPath(change.Path, repository.Info.WorkingDirectory); } } diff --git a/src/dotnet-proj-diff/ProjectDiffCommand.cs b/src/dotnet-proj-diff/ProjectDiffCommand.cs index b49d7ee..8d72ed6 100644 --- a/src/dotnet-proj-diff/ProjectDiffCommand.cs +++ b/src/dotnet-proj-diff/ProjectDiffCommand.cs @@ -246,8 +246,6 @@ CancellationToken cancellationToken var projects = result.Projects .Where(ShouldInclude) - .OrderBy(it => it.ReferencedProjects.Count) - .ThenBy(it => it.Path) .ToList(); logger.LogInformation("Found {Count} projects in diff", projects.Count); diff --git a/test/ProjectDiff.Tests/Core/MoveFileTests.cs b/test/ProjectDiff.Tests/Core/MoveFileTests.cs new file mode 100644 index 0000000..9cdac33 --- /dev/null +++ b/test/ProjectDiff.Tests/Core/MoveFileTests.cs @@ -0,0 +1,143 @@ +using LibGit2Sharp; +using ProjectDiff.Core; +using ProjectDiff.Core.Entrypoints; +using ProjectDiff.Tests.Utils; + +namespace ProjectDiff.Tests.Core; + +public sealed class MoveFileTests +{ + [Fact] + public async Task MoveFileToReferencedProject() + { + using var repo = await TestRepository.SetupAsync(async r => + { + r.CreateDirectory("ProjectA"); + r.CreateProject("ProjectA/ProjectA.csproj"); + + r.CreateDirectory("ProjectB"); + r.CreateProject( + "ProjectB/ProjectB.csproj", + p => p.AddItem("ProjectReference", "../ProjectA/ProjectA.csproj") + ); + + await r.WriteAllTextAsync("ProjectB/FileA.cs", "File A content"); + } + ); + Commands.Move( + repo.Repository, + "ProjectB/FileA.cs", + "ProjectA/FileA.cs" + ); + var projects = await GetDiffProjects(repo); + + Assert.Collection( + projects, + p => + { + Assert.Equal("ProjectA", p.Name); + Assert.Equal(DiffStatus.Modified, p.Status); + }, + p => + { + Assert.Equal("ProjectB", p.Name); + Assert.Equal(DiffStatus.Modified, p.Status); + } + ); + } + + [Fact] + public async Task MoveFileFromReferencedProjects() + { + using var repo = await TestRepository.SetupAsync(async r => + { + r.CreateDirectory("ProjectA"); + r.CreateProject("ProjectA/ProjectA.csproj"); + await r.WriteAllTextAsync("ProjectA/FileA.cs", "File A content"); + + r.CreateDirectory("ProjectB"); + r.CreateProject( + "ProjectB/ProjectB.csproj", + p => p.AddItem("ProjectReference", "../ProjectA/ProjectA.csproj") + ); + } + ); + Commands.Move( + repo.Repository, + "ProjectA/FileA.cs", + "ProjectB/FileA.cs" + ); + var projects = await GetDiffProjects(repo); + + Assert.Collection( + projects, + p => + { + Assert.Equal("ProjectA", p.Name); + Assert.Equal(DiffStatus.Modified, p.Status); + }, + p => + { + Assert.Equal("ProjectB", p.Name); + Assert.Equal(DiffStatus.Modified, p.Status); + } + ); + } + + + [Fact] + public async Task MovingFileBetweenTwoUnreleatedProjects() + { + using var repo = await TestRepository.SetupAsync(async r => + { + r.CreateDirectory("ProjectA"); + r.CreateProject("ProjectA/ProjectA.csproj"); + await r.WriteAllTextAsync("ProjectA/FileA.cs", "File A content"); + + r.CreateDirectory("ProjectB"); + r.CreateProject("ProjectB/ProjectB.csproj"); + } + ); + + Commands.Move( + repo.Repository, + "ProjectA/FileA.cs", + "ProjectB/FileA.cs" + ); + var projects = await GetDiffProjects(repo); + Assert.Collection( + projects, + p => + { + Assert.Equal("ProjectA", p.Name); + Assert.Equal(DiffStatus.Modified, p.Status); + }, + p => + { + Assert.Equal("ProjectB", p.Name); + Assert.Equal(DiffStatus.Modified, p.Status); + } + ); + } + + private static async Task> GetDiffProjects(TestRepository repo) + { + var options = new ProjectDiffExecutorOptions + { + FindMergeBase = false, + IgnoreChangedFiles = [] + }; + + + var executor = new ProjectDiffExecutor(options); + var result = await executor.GetProjectDiff( + repo.WorkingDirectory, + new DirectoryScanEntrypointProvider(), + cancellationToken: TestContext.Current.CancellationToken + ); + + Assert.Equal(ProjectDiffExecutionStatus.Success, result.Status); + + return result.Projects; + } +} \ No newline at end of file diff --git a/test/ProjectDiff.Tests/Tool/OutputFormatters/JsonOutputFormatterTests.WriteAsync_OutputsJson_absolutePaths=False.verified.txt b/test/ProjectDiff.Tests/Tool/OutputFormatters/JsonOutputFormatterTests.WriteAsync_OutputsJson_absolutePaths=False.verified.txt index e9c28a2..5c32d5b 100644 --- a/test/ProjectDiff.Tests/Tool/OutputFormatters/JsonOutputFormatterTests.WriteAsync_OutputsJson_absolutePaths=False.verified.txt +++ b/test/ProjectDiff.Tests/Tool/OutputFormatters/JsonOutputFormatterTests.WriteAsync_OutputsJson_absolutePaths=False.verified.txt @@ -1,10 +1,12 @@ [ { path: ProjectA, + name: ProjectA, status: Added }, { path: ProjectB, + name: ProjectB, status: ReferenceChanged, referencedProjects: [ ProjectA diff --git a/test/ProjectDiff.Tests/Tool/OutputFormatters/JsonOutputFormatterTests.WriteAsync_OutputsJson_absolutePaths=True.verified.txt b/test/ProjectDiff.Tests/Tool/OutputFormatters/JsonOutputFormatterTests.WriteAsync_OutputsJson_absolutePaths=True.verified.txt index b90471c..1a058c3 100644 --- a/test/ProjectDiff.Tests/Tool/OutputFormatters/JsonOutputFormatterTests.WriteAsync_OutputsJson_absolutePaths=True.verified.txt +++ b/test/ProjectDiff.Tests/Tool/OutputFormatters/JsonOutputFormatterTests.WriteAsync_OutputsJson_absolutePaths=True.verified.txt @@ -1,10 +1,12 @@ [ { path: {TempPath}ProjectA, + name: ProjectA, status: Added }, { path: {TempPath}ProjectB, + name: ProjectB, status: ReferenceChanged, referencedProjects: [ {TempPath}ProjectA diff --git a/test/ProjectDiff.Tests/Tool/ProjectDiffTests.DetectsAddedFiles.verified.txt b/test/ProjectDiff.Tests/Tool/ProjectDiffTests.DetectsAddedFiles.verified.txt index 4362c65..619a1e6 100644 --- a/test/ProjectDiff.Tests/Tool/ProjectDiffTests.DetectsAddedFiles.verified.txt +++ b/test/ProjectDiff.Tests/Tool/ProjectDiffTests.DetectsAddedFiles.verified.txt @@ -1,6 +1,7 @@ [ { path: Sample/Sample.csproj, + name: Sample, status: Modified } ] \ No newline at end of file diff --git a/test/ProjectDiff.Tests/Tool/ProjectDiffTests.DetectsAddedProjects.verified.txt b/test/ProjectDiff.Tests/Tool/ProjectDiffTests.DetectsAddedProjects.verified.txt index ccc0ca6..dd6492a 100644 --- a/test/ProjectDiff.Tests/Tool/ProjectDiffTests.DetectsAddedProjects.verified.txt +++ b/test/ProjectDiff.Tests/Tool/ProjectDiffTests.DetectsAddedProjects.verified.txt @@ -1,6 +1,7 @@ [ { path: Added/Added.csproj, + name: Added, status: Added } ] \ No newline at end of file diff --git a/test/ProjectDiff.Tests/Tool/ProjectDiffTests.DetectsAddedProjectsWithDirectoryScan.verified.txt b/test/ProjectDiff.Tests/Tool/ProjectDiffTests.DetectsAddedProjectsWithDirectoryScan.verified.txt index ccc0ca6..dd6492a 100644 --- a/test/ProjectDiff.Tests/Tool/ProjectDiffTests.DetectsAddedProjectsWithDirectoryScan.verified.txt +++ b/test/ProjectDiff.Tests/Tool/ProjectDiffTests.DetectsAddedProjectsWithDirectoryScan.verified.txt @@ -1,6 +1,7 @@ [ { path: Added/Added.csproj, + name: Added, status: Added } ] \ No newline at end of file diff --git a/test/ProjectDiff.Tests/Tool/ProjectDiffTests.DetectsChangesInNestedReferencedProjects.verified.txt b/test/ProjectDiff.Tests/Tool/ProjectDiffTests.DetectsChangesInNestedReferencedProjects.verified.txt index ca07d4f..edf7b6a 100644 --- a/test/ProjectDiff.Tests/Tool/ProjectDiffTests.DetectsChangesInNestedReferencedProjects.verified.txt +++ b/test/ProjectDiff.Tests/Tool/ProjectDiffTests.DetectsChangesInNestedReferencedProjects.verified.txt @@ -1,10 +1,12 @@ [ { path: Sample/Sample.csproj, + name: Sample, status: Modified }, { path: Application/Application.csproj, + name: Application, status: ReferenceChanged, referencedProjects: [ Sample/Sample.csproj @@ -12,6 +14,7 @@ }, { path: Tests/Tests.csproj, + name: Tests, status: ReferenceChanged, referencedProjects: [ Application/Application.csproj, diff --git a/test/ProjectDiff.Tests/Tool/ProjectDiffTests.DetectsChangesInReferencedProjects.verified.txt b/test/ProjectDiff.Tests/Tool/ProjectDiffTests.DetectsChangesInReferencedProjects.verified.txt index d17975d..bb01156 100644 --- a/test/ProjectDiff.Tests/Tool/ProjectDiffTests.DetectsChangesInReferencedProjects.verified.txt +++ b/test/ProjectDiff.Tests/Tool/ProjectDiffTests.DetectsChangesInReferencedProjects.verified.txt @@ -1,10 +1,12 @@ [ { path: Sample/Sample.csproj, + name: Sample, status: Modified }, { path: Tests/Tests.csproj, + name: Tests, status: ReferenceChanged, referencedProjects: [ Sample/Sample.csproj diff --git a/test/ProjectDiff.Tests/Tool/ProjectDiffTests.DetectsDeletedFiles.verified.txt b/test/ProjectDiff.Tests/Tool/ProjectDiffTests.DetectsDeletedFiles.verified.txt index 4362c65..619a1e6 100644 --- a/test/ProjectDiff.Tests/Tool/ProjectDiffTests.DetectsDeletedFiles.verified.txt +++ b/test/ProjectDiff.Tests/Tool/ProjectDiffTests.DetectsDeletedFiles.verified.txt @@ -1,6 +1,7 @@ [ { path: Sample/Sample.csproj, + name: Sample, status: Modified } ] \ No newline at end of file diff --git a/test/ProjectDiff.Tests/Tool/ProjectDiffTests.DetectsDeletedProjectsWhenOptionIsSet.verified.txt b/test/ProjectDiff.Tests/Tool/ProjectDiffTests.DetectsDeletedProjectsWhenOptionIsSet.verified.txt index fe7bd9a..cdbabb4 100644 --- a/test/ProjectDiff.Tests/Tool/ProjectDiffTests.DetectsDeletedProjectsWhenOptionIsSet.verified.txt +++ b/test/ProjectDiff.Tests/Tool/ProjectDiffTests.DetectsDeletedProjectsWhenOptionIsSet.verified.txt @@ -1,6 +1,7 @@ [ { path: Tests/Tests.csproj, + name: Tests, status: Removed } ] \ No newline at end of file diff --git a/test/ProjectDiff.Tests/Tool/ProjectDiffTests.DetectsModifiedFiles.verified.txt b/test/ProjectDiff.Tests/Tool/ProjectDiffTests.DetectsModifiedFiles.verified.txt index 4362c65..619a1e6 100644 --- a/test/ProjectDiff.Tests/Tool/ProjectDiffTests.DetectsModifiedFiles.verified.txt +++ b/test/ProjectDiff.Tests/Tool/ProjectDiffTests.DetectsModifiedFiles.verified.txt @@ -1,6 +1,7 @@ [ { path: Sample/Sample.csproj, + name: Sample, status: Modified } ] \ No newline at end of file From 53bddf7217f03524d8891d1e0796a982a1144ff5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20Strandg=C3=A5rd?= Date: Thu, 24 Jul 2025 14:29:41 +0200 Subject: [PATCH 2/4] Exclude git-ignored when building project graph for working directory --- src/ProjectDiff.Core/BuildGraphFactory.cs | 21 +++++++++++++++++---- src/ProjectDiff.Core/ProjectDiffExecutor.cs | 14 ++++++++++++-- src/dotnet-proj-diff/SystemConsole.cs | 1 - 3 files changed, 29 insertions(+), 7 deletions(-) diff --git a/src/ProjectDiff.Core/BuildGraphFactory.cs b/src/ProjectDiff.Core/BuildGraphFactory.cs index 83ee308..2261cfb 100644 --- a/src/ProjectDiff.Core/BuildGraphFactory.cs +++ b/src/ProjectDiff.Core/BuildGraphFactory.cs @@ -11,14 +11,15 @@ public static class BuildGraphFactory { private static readonly IProjectGraphPredictor[] ProjectGraphPredictors = ProjectPredictors .AllProjectGraphPredictors + // We create the build graph ourselves, we don't want referenced csproj files to be part of the input files .Where(it => it is not ProjectFileAndImportsGraphPredictor) .ToArray(); - public static BuildGraph CreateForProjectGraph( ProjectGraph graph, Repository repository, - IReadOnlyCollection ignoredFiles + IReadOnlyCollection ignoredFiles, + bool checkGitIgnore ) { var executor = new ProjectGraphPredictionExecutor( @@ -26,7 +27,7 @@ IReadOnlyCollection ignoredFiles ProjectPredictors.AllProjectPredictors ); - var collector = new BuildGraphPredictionCollector(graph, repository, ignoredFiles); + var collector = new BuildGraphPredictionCollector(graph, repository, ignoredFiles, checkGitIgnore); executor.PredictInputsAndOutputs(graph, collector); @@ -38,17 +39,20 @@ private sealed class BuildGraphPredictionCollector : IProjectPredictionCollector private readonly ProjectGraph _projectGraph; private readonly Repository _repository; private readonly IReadOnlyCollection _ignoredFiles; + private readonly bool _checkGitIgnore; private readonly Dictionary _collectors; public BuildGraphPredictionCollector( ProjectGraph projectGraph, Repository repository, - IReadOnlyCollection ignoredFiles + IReadOnlyCollection ignoredFiles, + bool checkGitIgnore ) { _projectGraph = projectGraph; _repository = repository; _ignoredFiles = ignoredFiles; + _checkGitIgnore = checkGitIgnore; _collectors = new Dictionary(_projectGraph.ProjectNodes.Count); foreach (var node in _projectGraph.ProjectNodes) { @@ -79,6 +83,15 @@ public void AddInputFile(string path, ProjectInstance projectInstance, string pr return; } + if (_checkGitIgnore) + { + // Ignore files that are ignored by .gitignore, this does not take + var relativePath = Path.GetRelativePath(_repository.Info.WorkingDirectory, path).Replace('\\', '/'); + if (_repository.Ignore.IsPathIgnored(relativePath)) + { + return; + } + } if (!_collectors.TryGetValue(projectInstance.FullPath, out var collector)) { diff --git a/src/ProjectDiff.Core/ProjectDiffExecutor.cs b/src/ProjectDiff.Core/ProjectDiffExecutor.cs index 238ed14..e2b6c44 100644 --- a/src/ProjectDiff.Core/ProjectDiffExecutor.cs +++ b/src/ProjectDiff.Core/ProjectDiffExecutor.cs @@ -176,8 +176,18 @@ public async Task GetProjectDiff( _logger.LogDebug("Head project graph construction metrics: {Metrics}", headGraph.ConstructionMetrics); - var headBuildGraph = BuildGraphFactory.CreateForProjectGraph(headGraph, repo, _options.IgnoreChangedFiles); - var baseBuildGraph = BuildGraphFactory.CreateForProjectGraph(baseGraph, repo, _options.IgnoreChangedFiles); + var headBuildGraph = BuildGraphFactory.CreateForProjectGraph( + headGraph, + repo, + _options.IgnoreChangedFiles, + checkGitIgnore: headCommit is null // If we are using the working directory, we need to check .gitignore to avoid adding files that are ignored + ); + var baseBuildGraph = BuildGraphFactory.CreateForProjectGraph( + baseGraph, + repo, + _options.IgnoreChangedFiles, + checkGitIgnore: false // We don't need to check .gitignore for the base graph, as it is always based on a commit + ); var projects = BuildGraphDiff.Diff(baseBuildGraph, headBuildGraph, changedFiles) .OrderBy(it => it.ReferencedProjects.Count) diff --git a/src/dotnet-proj-diff/SystemConsole.cs b/src/dotnet-proj-diff/SystemConsole.cs index 674b9fb..a2df364 100644 --- a/src/dotnet-proj-diff/SystemConsole.cs +++ b/src/dotnet-proj-diff/SystemConsole.cs @@ -6,6 +6,5 @@ public sealed class SystemConsole : IConsole public TextWriter Out { get; } = Console.Out; public Stream OpenStandardOutput() => Console.OpenStandardOutput(); - public string WorkingDirectory { get; } = Directory.GetCurrentDirectory(); } \ No newline at end of file From 34cd9917dfc76ca6561be75dc11a95c06f4983bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20Strandg=C3=A5rd?= Date: Thu, 24 Jul 2025 14:53:51 +0200 Subject: [PATCH 3/4] Always check .gitignore when building BuildGraph --- src/ProjectDiff.Core/BuildGraphDiff.cs | 35 ++++++++++++++++++--- src/ProjectDiff.Core/BuildGraphFactory.cs | 21 +++++-------- src/ProjectDiff.Core/ProjectDiffExecutor.cs | 18 +++++------ src/dotnet-proj-diff/ProjectDiffCommand.cs | 3 +- 4 files changed, 47 insertions(+), 30 deletions(-) diff --git a/src/ProjectDiff.Core/BuildGraphDiff.cs b/src/ProjectDiff.Core/BuildGraphDiff.cs index 2065612..d5ed033 100644 --- a/src/ProjectDiff.Core/BuildGraphDiff.cs +++ b/src/ProjectDiff.Core/BuildGraphDiff.cs @@ -1,4 +1,6 @@ using System.Collections.Frozen; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Abstractions; namespace ProjectDiff.Core; @@ -7,10 +9,12 @@ public static class BuildGraphDiff public static IEnumerable Diff( BuildGraph previous, BuildGraph current, - IEnumerable modifiedFiles + IEnumerable modifiedFiles, + ILoggerFactory? loggerFactory = null ) { - var instance = new GraphDiffInstance(current); + loggerFactory ??= NullLoggerFactory.Instance; + var instance = new GraphDiffInstance(current, loggerFactory.CreateLogger()); return instance.Execute(previous, modifiedFiles.ToFrozenSet()); } @@ -19,20 +23,24 @@ private sealed class GraphDiffInstance { private readonly BuildGraph _graph; private readonly Dictionary _modifiedProjects; + private readonly ILogger _logger; - public GraphDiffInstance(BuildGraph graph) + public GraphDiffInstance(BuildGraph graph, ILogger logger) { _modifiedProjects = new Dictionary(graph.Projects.Count); _graph = graph; + _logger = logger; } public IEnumerable Execute(BuildGraph previous, FrozenSet modifiedFiles) { foreach (var currentProject in _graph.Projects) { + using var scope = _logger.BeginScope(currentProject.FullPath); var previousProject = previous.Projects.FirstOrDefault(it => it.FullPath == currentProject.FullPath); if (previousProject is null) { + _logger.LogDebug("Project not found in previous graph, marking as added"); yield return new DiffProject { Path = currentProject.FullPath, @@ -42,6 +50,7 @@ public IEnumerable Execute(BuildGraph previous, FrozenSet m } else if (HasProjectChanged(previousProject, currentProject, modifiedFiles)) { + _logger.LogDebug("Project has changed, marking as modified"); yield return new DiffProject { Path = currentProject.FullPath, @@ -51,6 +60,7 @@ public IEnumerable Execute(BuildGraph previous, FrozenSet m } else if (HasProjectReferencesChanged(previousProject, currentProject, modifiedFiles)) { + _logger.LogDebug("Project references have changed, marking as reference changed" ); yield return new DiffProject { Path = currentProject.FullPath, @@ -65,6 +75,7 @@ public IEnumerable Execute(BuildGraph previous, FrozenSet m var existsInCurrent = _graph.Projects.Any(it => it.FullPath == previousProject.FullPath); if (!existsInCurrent) { + _logger.LogDebug("Project {Path} not found in current graph, marking as removed", previousProject.FullPath); yield return new DiffProject { Path = previousProject.FullPath, @@ -96,7 +107,7 @@ FrozenSet modifiedFiles return false; } - private static bool HasProjectInputFilesChanged( + private bool HasProjectInputFilesChanged( IReadOnlyCollection previous, IReadOnlyCollection current, FrozenSet modifiedFiles @@ -104,6 +115,11 @@ FrozenSet modifiedFiles { if (previous.Count != current.Count) { + _logger.LogDebug( + "Input files count changed: {PreviousCount} -> {CurrentCount}", + previous.Count, + current.Count + ); return true; } @@ -111,11 +127,13 @@ FrozenSet modifiedFiles { if (!previous.Contains(file)) { + _logger.LogInformation("Input file {File} added", file); return true; } if (modifiedFiles.Contains(file)) { + _logger.LogInformation("Input file {File} modified", file); return true; } } @@ -124,6 +142,7 @@ FrozenSet modifiedFiles { if (!current.Contains(file)) { + _logger.LogInformation("Input file {File} removed", file); return true; } } @@ -140,6 +159,11 @@ FrozenSet modifiedFiles { if (previous.References.Count != current.References.Count) { + _logger.LogDebug( + "References count changed: {PreviousCount} -> {CurrentCount}", + previous.References.Count, + current.References.Count + ); return true; } @@ -147,6 +171,7 @@ FrozenSet modifiedFiles { if (!previous.References.Contains(reference)) { + _logger.LogInformation("Reference {Reference} added", reference); return true; } @@ -155,6 +180,7 @@ FrozenSet modifiedFiles if (HasProjectChanged(previousReference, currentReference, modifiedFiles)) { + _logger.LogInformation("Referenced project {Reference} modified", reference); return true; } } @@ -163,6 +189,7 @@ FrozenSet modifiedFiles { if (!current.References.Contains(reference)) { + _logger.LogInformation("Referenced project {Reference} removed", reference); return true; } } diff --git a/src/ProjectDiff.Core/BuildGraphFactory.cs b/src/ProjectDiff.Core/BuildGraphFactory.cs index 2261cfb..6c724d7 100644 --- a/src/ProjectDiff.Core/BuildGraphFactory.cs +++ b/src/ProjectDiff.Core/BuildGraphFactory.cs @@ -18,8 +18,7 @@ public static class BuildGraphFactory public static BuildGraph CreateForProjectGraph( ProjectGraph graph, Repository repository, - IReadOnlyCollection ignoredFiles, - bool checkGitIgnore + IReadOnlyCollection ignoredFiles ) { var executor = new ProjectGraphPredictionExecutor( @@ -27,7 +26,7 @@ bool checkGitIgnore ProjectPredictors.AllProjectPredictors ); - var collector = new BuildGraphPredictionCollector(graph, repository, ignoredFiles, checkGitIgnore); + var collector = new BuildGraphPredictionCollector(graph, repository, ignoredFiles); executor.PredictInputsAndOutputs(graph, collector); @@ -39,20 +38,17 @@ private sealed class BuildGraphPredictionCollector : IProjectPredictionCollector private readonly ProjectGraph _projectGraph; private readonly Repository _repository; private readonly IReadOnlyCollection _ignoredFiles; - private readonly bool _checkGitIgnore; private readonly Dictionary _collectors; public BuildGraphPredictionCollector( ProjectGraph projectGraph, Repository repository, - IReadOnlyCollection ignoredFiles, - bool checkGitIgnore + IReadOnlyCollection ignoredFiles ) { _projectGraph = projectGraph; _repository = repository; _ignoredFiles = ignoredFiles; - _checkGitIgnore = checkGitIgnore; _collectors = new Dictionary(_projectGraph.ProjectNodes.Count); foreach (var node in _projectGraph.ProjectNodes) { @@ -83,14 +79,11 @@ public void AddInputFile(string path, ProjectInstance projectInstance, string pr return; } - if (_checkGitIgnore) + // Ignore any files that are ignored by .gitignore + var relativePath = Path.GetRelativePath(_repository.Info.WorkingDirectory, path).Replace('\\', '/'); + if (_repository.Ignore.IsPathIgnored(relativePath)) { - // Ignore files that are ignored by .gitignore, this does not take - var relativePath = Path.GetRelativePath(_repository.Info.WorkingDirectory, path).Replace('\\', '/'); - if (_repository.Ignore.IsPathIgnored(relativePath)) - { - return; - } + return; } if (!_collectors.TryGetValue(projectInstance.FullPath, out var collector)) diff --git a/src/ProjectDiff.Core/ProjectDiffExecutor.cs b/src/ProjectDiff.Core/ProjectDiffExecutor.cs index e2b6c44..d03932d 100644 --- a/src/ProjectDiff.Core/ProjectDiffExecutor.cs +++ b/src/ProjectDiff.Core/ProjectDiffExecutor.cs @@ -42,6 +42,10 @@ public async Task GetProjectDiff( _logger.LogDebug("Found repository at '{RepoPath}'", repoPath); using var repo = new Repository(repoPath); + if (repo.Info.IsShallow) + { + _logger.LogWarning("Repository at is shallow, some operations may not work as expected"); + } _logger.LogDebug("Looking up base commit '{BaseCommitRef}'", baseCommitRef); var baseCommit = repo.Lookup(baseCommitRef); @@ -148,7 +152,6 @@ public async Task GetProjectDiff( "Base project graph built with {NumProjects} projects", baseGraph.ProjectNodes.Count ); - _logger.LogDebug("Base project graph construction metrics: {Metrics}", baseGraph.ConstructionMetrics); ProjectGraph headGraph; if (headCommit is null) @@ -173,23 +176,20 @@ public async Task GetProjectDiff( "Head project graph built with {NumProjects} projects", headGraph.ProjectNodes.Count ); - _logger.LogDebug("Head project graph construction metrics: {Metrics}", headGraph.ConstructionMetrics); var headBuildGraph = BuildGraphFactory.CreateForProjectGraph( headGraph, repo, - _options.IgnoreChangedFiles, - checkGitIgnore: headCommit is null // If we are using the working directory, we need to check .gitignore to avoid adding files that are ignored + _options.IgnoreChangedFiles ); var baseBuildGraph = BuildGraphFactory.CreateForProjectGraph( baseGraph, repo, - _options.IgnoreChangedFiles, - checkGitIgnore: false // We don't need to check .gitignore for the base graph, as it is always based on a commit + _options.IgnoreChangedFiles ); - var projects = BuildGraphDiff.Diff(baseBuildGraph, headBuildGraph, changedFiles) + var projects = BuildGraphDiff.Diff(baseBuildGraph, headBuildGraph, changedFiles, _loggerFactory) .OrderBy(it => it.ReferencedProjects.Count) .ThenBy(it => it.Name); return new ProjectDiffResult @@ -218,10 +218,6 @@ private static IEnumerable GetGitModifiedFiles( : repository.Diff.Compare(baseCommit.Tree, headCommit.Tree); foreach (var change in changes) { - // if (change.Path != change.OldPath) - // { - // yield return Path.GetFullPath(change.OldPath, repository.Info.WorkingDirectory); - // } yield return Path.GetFullPath(change.Path, repository.Info.WorkingDirectory); } } diff --git a/src/dotnet-proj-diff/ProjectDiffCommand.cs b/src/dotnet-proj-diff/ProjectDiffCommand.cs index 8d72ed6..957e284 100644 --- a/src/dotnet-proj-diff/ProjectDiffCommand.cs +++ b/src/dotnet-proj-diff/ProjectDiffCommand.cs @@ -119,7 +119,7 @@ public sealed class ProjectDiffCommand : RootCommand private static readonly Option LogLevelOption = new("--log-level") { - DefaultValueFactory = _ => LogLevel.Information, + DefaultValueFactory = _ => LogLevel.Warning, Description = "Set the log level for the command", }; @@ -183,6 +183,7 @@ CancellationToken cancellationToken using var loggerFactory = LoggerFactory.Create(x => { x.AddConsole(c => c.LogToStandardErrorThreshold = LogLevel.Trace); // Log everything to stderr + x.AddSimpleConsole(x => x.IncludeScopes = true); x.SetMinimumLevel(settings.LogLevel); } ); From 9bf49de9d6f531798c05b5a85a359253a9783b01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20Strandg=C3=A5rd?= Date: Thu, 24 Jul 2025 15:07:46 +0200 Subject: [PATCH 4/4] Reformat code using .editorconfig settings --- .editorconfig | 18 +++++- src/ProjectDiff.Core/BuildGraph.cs | 6 +- src/ProjectDiff.Core/BuildGraphDiff.cs | 6 +- src/ProjectDiff.Core/BuildGraphFactory.cs | 4 +- src/ProjectDiff.Core/BuildGraphProject.cs | 4 +- src/ProjectDiff.Core/DiffProject.cs | 4 +- src/ProjectDiff.Core/DiffStatus.cs | 4 +- .../DirectoryScanEntrypointProvider.cs | 4 +- .../Entrypoints/IEntrypointProvider.cs | 4 +- .../Entrypoints/SolutionEntrypointProvider.cs | 57 ++++--------------- src/ProjectDiff.Core/GitTreeFileSystem.cs | 4 +- .../ProjectDiffExecutionStatus.cs | 4 +- src/ProjectDiff.Core/ProjectDiffExecutor.cs | 4 +- .../ProjectDiffExecutorOptions.cs | 4 +- src/ProjectDiff.Core/ProjectDiffResult.cs | 4 +- src/ProjectDiff.Core/ProjectGraphFactory.cs | 4 +- src/dotnet-proj-diff/IConsole.cs | 4 +- src/dotnet-proj-diff/Output.cs | 4 +- src/dotnet-proj-diff/OutputFormat.cs | 4 +- .../OutputFormatters/IOutputFormatter.cs | 4 +- .../OutputFormatters/JsonOutputFormatter.cs | 12 ++-- .../OutputFormatters/PlainOutputFormatter.cs | 4 +- .../OutputFormatters/SlnfOutputFormatter.cs | 4 +- .../TraversalOutputFormatter.cs | 4 +- src/dotnet-proj-diff/Program.cs | 4 +- src/dotnet-proj-diff/ProjectDiffCommand.cs | 6 +- src/dotnet-proj-diff/ProjectDiffSettings.cs | 4 +- src/dotnet-proj-diff/ProjectDiffTool.cs | 4 +- src/dotnet-proj-diff/SystemConsole.cs | 4 +- test/ProjectDiff.Tests/Core/BranchTests.cs | 4 +- .../Core/BuildGraphDiffTests.cs | 10 ++-- .../Core/DirectoryBuildPropsTests.cs | 4 +- test/ProjectDiff.Tests/Core/ErrorTests.cs | 4 +- .../Core/GitTreeFileSystemTests.cs | 4 +- .../Core/IgnoreChangesTests.cs | 4 +- test/ProjectDiff.Tests/Core/MoveFileTests.cs | 10 ++-- .../Core/MultiFrameworkTests.cs | 4 +- test/ProjectDiff.Tests/ModuleInit.cs | 4 +- .../JsonOutputFormatterTests.cs | 4 +- .../PlainOutputFormatterTests.cs | 4 +- .../SlnfOutputFormatterTests.cs | 6 +- .../TraversalOutputFormatterTests.cs | 4 +- .../Tool/ProjectDiffTests.cs | 6 +- test/ProjectDiff.Tests/Utils/SetupResult.cs | 4 +- test/ProjectDiff.Tests/Utils/TestConsole.cs | 4 +- .../ProjectDiff.Tests/Utils/TestRepository.cs | 6 +- test/ProjectDiff.Tests/VerifyTests.cs | 6 +- 47 files changed, 134 insertions(+), 155 deletions(-) diff --git a/.editorconfig b/.editorconfig index 92beff4..4286c12 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,4 +1,6 @@ -# Verify settings +root = true + +# Verify settings [*.{received,verified}.{json,txt,xml}] charset = utf-8 end_of_line = lf @@ -6,4 +8,16 @@ indent_size = unset indent_style = unset insert_final_newline = false tab_width = unset -trim_trailing_whitespace = false \ No newline at end of file +trim_trailing_whitespace = false + + +[*.cs] +end_of_line = crlf +indent_size = 4 +indent_style = space +insert_final_newline = true +trim_trailing_whitespace = true +charset = utf-8 + +[*.sh] +end_of_line = lf diff --git a/src/ProjectDiff.Core/BuildGraph.cs b/src/ProjectDiff.Core/BuildGraph.cs index 092ae0d..0632344 100644 --- a/src/ProjectDiff.Core/BuildGraph.cs +++ b/src/ProjectDiff.Core/BuildGraph.cs @@ -1,7 +1,7 @@ -namespace ProjectDiff.Core; +namespace ProjectDiff.Core; public sealed class BuildGraph { public required IReadOnlyCollection Projects { get; init; } - -} \ No newline at end of file + +} diff --git a/src/ProjectDiff.Core/BuildGraphDiff.cs b/src/ProjectDiff.Core/BuildGraphDiff.cs index d5ed033..37d8584 100644 --- a/src/ProjectDiff.Core/BuildGraphDiff.cs +++ b/src/ProjectDiff.Core/BuildGraphDiff.cs @@ -1,4 +1,4 @@ -using System.Collections.Frozen; +using System.Collections.Frozen; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; @@ -60,7 +60,7 @@ public IEnumerable Execute(BuildGraph previous, FrozenSet m } else if (HasProjectReferencesChanged(previousProject, currentProject, modifiedFiles)) { - _logger.LogDebug("Project references have changed, marking as reference changed" ); + _logger.LogDebug("Project references have changed, marking as reference changed"); yield return new DiffProject { Path = currentProject.FullPath, @@ -197,4 +197,4 @@ FrozenSet modifiedFiles return false; } } -} \ No newline at end of file +} diff --git a/src/ProjectDiff.Core/BuildGraphFactory.cs b/src/ProjectDiff.Core/BuildGraphFactory.cs index 6c724d7..6954cc8 100644 --- a/src/ProjectDiff.Core/BuildGraphFactory.cs +++ b/src/ProjectDiff.Core/BuildGraphFactory.cs @@ -1,4 +1,4 @@ -using System.Diagnostics; +using System.Diagnostics; using LibGit2Sharp; using Microsoft.Build.Execution; using Microsoft.Build.Graph; @@ -175,4 +175,4 @@ public BuildGraphProject ToBuildGraphProject() } } } -} \ No newline at end of file +} diff --git a/src/ProjectDiff.Core/BuildGraphProject.cs b/src/ProjectDiff.Core/BuildGraphProject.cs index 297ed7d..72f4d81 100644 --- a/src/ProjectDiff.Core/BuildGraphProject.cs +++ b/src/ProjectDiff.Core/BuildGraphProject.cs @@ -1,4 +1,4 @@ -namespace ProjectDiff.Core; +namespace ProjectDiff.Core; public sealed class BuildGraphProject { @@ -16,4 +16,4 @@ IReadOnlyCollection references public string FullPath { get; } public IReadOnlyCollection InputFiles { get; } public IReadOnlyCollection References { get; } -} \ No newline at end of file +} diff --git a/src/ProjectDiff.Core/DiffProject.cs b/src/ProjectDiff.Core/DiffProject.cs index f545991..6f837f6 100644 --- a/src/ProjectDiff.Core/DiffProject.cs +++ b/src/ProjectDiff.Core/DiffProject.cs @@ -1,4 +1,4 @@ -namespace ProjectDiff.Core; +namespace ProjectDiff.Core; public sealed record DiffProject { @@ -7,4 +7,4 @@ public sealed record DiffProject public required DiffStatus Status { get; init; } public required IReadOnlyCollection ReferencedProjects { get; init; } = []; -} \ No newline at end of file +} diff --git a/src/ProjectDiff.Core/DiffStatus.cs b/src/ProjectDiff.Core/DiffStatus.cs index 3fba9ce..6b4a655 100644 --- a/src/ProjectDiff.Core/DiffStatus.cs +++ b/src/ProjectDiff.Core/DiffStatus.cs @@ -1,4 +1,4 @@ -namespace ProjectDiff.Core; +namespace ProjectDiff.Core; public enum DiffStatus { @@ -6,4 +6,4 @@ public enum DiffStatus Removed, Modified, ReferenceChanged, -} \ No newline at end of file +} diff --git a/src/ProjectDiff.Core/Entrypoints/DirectoryScanEntrypointProvider.cs b/src/ProjectDiff.Core/Entrypoints/DirectoryScanEntrypointProvider.cs index dd2128b..7d49309 100644 --- a/src/ProjectDiff.Core/Entrypoints/DirectoryScanEntrypointProvider.cs +++ b/src/ProjectDiff.Core/Entrypoints/DirectoryScanEntrypointProvider.cs @@ -1,4 +1,4 @@ -using Microsoft.Build.FileSystem; +using Microsoft.Build.FileSystem; using Microsoft.Build.Graph; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; @@ -28,4 +28,4 @@ CancellationToken cancellationToken return Task.FromResult(entrypoints); } -} \ No newline at end of file +} diff --git a/src/ProjectDiff.Core/Entrypoints/IEntrypointProvider.cs b/src/ProjectDiff.Core/Entrypoints/IEntrypointProvider.cs index 81be964..f9226cf 100644 --- a/src/ProjectDiff.Core/Entrypoints/IEntrypointProvider.cs +++ b/src/ProjectDiff.Core/Entrypoints/IEntrypointProvider.cs @@ -1,4 +1,4 @@ -using Microsoft.Build.FileSystem; +using Microsoft.Build.FileSystem; using Microsoft.Build.Graph; namespace ProjectDiff.Core.Entrypoints; @@ -10,4 +10,4 @@ Task> GetEntrypoints( MSBuildFileSystemBase fs, CancellationToken cancellationToken ); -} \ No newline at end of file +} diff --git a/src/ProjectDiff.Core/Entrypoints/SolutionEntrypointProvider.cs b/src/ProjectDiff.Core/Entrypoints/SolutionEntrypointProvider.cs index ab48992..47baf46 100644 --- a/src/ProjectDiff.Core/Entrypoints/SolutionEntrypointProvider.cs +++ b/src/ProjectDiff.Core/Entrypoints/SolutionEntrypointProvider.cs @@ -1,4 +1,4 @@ -using Microsoft.Build.FileSystem; +using Microsoft.Build.FileSystem; using Microsoft.Build.Graph; using Microsoft.Extensions.Logging; using Microsoft.VisualStudio.SolutionPersistence.Serializer; @@ -36,50 +36,15 @@ CancellationToken cancellationToken ); - return await GetProjectEntrypoints(_solution, stream, cancellationToken); - } - - - private async Task> GetProjectEntrypoints( - FileInfo solutionFile, - Stream stream, - CancellationToken cancellationToken - ) - { - switch (solutionFile.Extension) + var solutionModel = _solution.Extension switch { - case ".sln": - { - _logger.LogDebug("Reading {SolutionFile} as a .sln file", solutionFile.FullName); - var solutionModel = await SolutionSerializers.SlnFileV12.OpenAsync(stream, cancellationToken); - - _logger.LogDebug( - "Found {ProjectCount} projects in solution {SolutionFile}", - solutionModel.SolutionProjects.Count, - solutionFile.FullName - ); - return solutionModel.SolutionProjects - .Select(it => - new ProjectGraphEntryPoint(Path.GetFullPath(it.FilePath, solutionFile.DirectoryName!)) - ); - } - case ".slnx": - { - _logger.LogDebug("Reading {SolutionFile} as a .slnx file", solutionFile.FullName); - var solutionModel = await SolutionSerializers.SlnXml.OpenAsync(stream, cancellationToken); - - _logger.LogDebug( - "Found {ProjectCount} projects in solution {SolutionFile}", - solutionModel.SolutionProjects.Count, - solutionFile.FullName - ); - return solutionModel.SolutionProjects - .Select(it => - new ProjectGraphEntryPoint(Path.GetFullPath(it.FilePath, solutionFile.DirectoryName!)) - ); - } - default: - throw new NotSupportedException($"Solution file extension {solutionFile.Extension} not supported"); - } + ".sln" => await SolutionSerializers.SlnFileV12.OpenAsync(stream, cancellationToken), + ".slnx" => await SolutionSerializers.SlnXml.OpenAsync(stream, cancellationToken), + _ => throw new NotSupportedException($"Solution file extension {_solution.Extension} is not supported") + }; + return solutionModel.SolutionProjects + .Select(it => + new ProjectGraphEntryPoint(Path.GetFullPath(it.FilePath, _solution.DirectoryName!)) + ); } -} \ No newline at end of file +} diff --git a/src/ProjectDiff.Core/GitTreeFileSystem.cs b/src/ProjectDiff.Core/GitTreeFileSystem.cs index 61e0847..074b086 100644 --- a/src/ProjectDiff.Core/GitTreeFileSystem.cs +++ b/src/ProjectDiff.Core/GitTreeFileSystem.cs @@ -1,4 +1,4 @@ -using System.IO.Enumeration; +using System.IO.Enumeration; using System.Xml; using LibGit2Sharp; using Microsoft.Build.Construction; @@ -333,4 +333,4 @@ bool ShouldInclude(TreeEntry entry) return (entry.Target.Peel(), Path.GetFullPath(Path.Combine(_repository.Info.WorkingDirectory, relativePath))); } -} \ No newline at end of file +} diff --git a/src/ProjectDiff.Core/ProjectDiffExecutionStatus.cs b/src/ProjectDiff.Core/ProjectDiffExecutionStatus.cs index 05202c3..8ecd436 100644 --- a/src/ProjectDiff.Core/ProjectDiffExecutionStatus.cs +++ b/src/ProjectDiff.Core/ProjectDiffExecutionStatus.cs @@ -1,4 +1,4 @@ -namespace ProjectDiff.Core; +namespace ProjectDiff.Core; public enum ProjectDiffExecutionStatus { @@ -8,4 +8,4 @@ public enum ProjectDiffExecutionStatus BaseCommitNotFound, HeadCommitNotFound, MergeBaseNotFound, -} \ No newline at end of file +} diff --git a/src/ProjectDiff.Core/ProjectDiffExecutor.cs b/src/ProjectDiff.Core/ProjectDiffExecutor.cs index d03932d..03ce569 100644 --- a/src/ProjectDiff.Core/ProjectDiffExecutor.cs +++ b/src/ProjectDiff.Core/ProjectDiffExecutor.cs @@ -1,4 +1,4 @@ -using LibGit2Sharp; +using LibGit2Sharp; using Microsoft.Build.Graph; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; @@ -221,4 +221,4 @@ private static IEnumerable GetGitModifiedFiles( yield return Path.GetFullPath(change.Path, repository.Info.WorkingDirectory); } } -} \ No newline at end of file +} diff --git a/src/ProjectDiff.Core/ProjectDiffExecutorOptions.cs b/src/ProjectDiff.Core/ProjectDiffExecutorOptions.cs index 5db6879..2d69d9f 100644 --- a/src/ProjectDiff.Core/ProjectDiffExecutorOptions.cs +++ b/src/ProjectDiff.Core/ProjectDiffExecutorOptions.cs @@ -1,7 +1,7 @@ -namespace ProjectDiff.Core; +namespace ProjectDiff.Core; public sealed class ProjectDiffExecutorOptions { public bool FindMergeBase { get; init; } public FileInfo[] IgnoreChangedFiles { get; init; } = []; -} \ No newline at end of file +} diff --git a/src/ProjectDiff.Core/ProjectDiffResult.cs b/src/ProjectDiff.Core/ProjectDiffResult.cs index 3cf5012..55c225d 100644 --- a/src/ProjectDiff.Core/ProjectDiffResult.cs +++ b/src/ProjectDiff.Core/ProjectDiffResult.cs @@ -1,8 +1,8 @@ -namespace ProjectDiff.Core; +namespace ProjectDiff.Core; public sealed record ProjectDiffResult { public required ProjectDiffExecutionStatus Status { get; init; } public IEnumerable Projects { get; init; } = []; public IReadOnlyCollection ChangedFiles { get; init; } = []; -} \ No newline at end of file +} diff --git a/src/ProjectDiff.Core/ProjectGraphFactory.cs b/src/ProjectDiff.Core/ProjectGraphFactory.cs index cd89ed4..90747ef 100644 --- a/src/ProjectDiff.Core/ProjectGraphFactory.cs +++ b/src/ProjectDiff.Core/ProjectGraphFactory.cs @@ -1,4 +1,4 @@ -using LibGit2Sharp; +using LibGit2Sharp; using Microsoft.Build.Definition; using Microsoft.Build.Evaluation; using Microsoft.Build.Evaluation.Context; @@ -104,4 +104,4 @@ public async Task BuildForWorkingDirectory( private sealed class DefaultFileSystem : MSBuildFileSystemBase; -} \ No newline at end of file +} diff --git a/src/dotnet-proj-diff/IConsole.cs b/src/dotnet-proj-diff/IConsole.cs index 2ca407a..3b8f2e8 100644 --- a/src/dotnet-proj-diff/IConsole.cs +++ b/src/dotnet-proj-diff/IConsole.cs @@ -1,4 +1,4 @@ -namespace ProjectDiff.Tool; +namespace ProjectDiff.Tool; public interface IConsole { @@ -7,4 +7,4 @@ public interface IConsole Stream OpenStandardOutput(); string WorkingDirectory { get; } -} \ No newline at end of file +} diff --git a/src/dotnet-proj-diff/Output.cs b/src/dotnet-proj-diff/Output.cs index a30b585..bcf1039 100644 --- a/src/dotnet-proj-diff/Output.cs +++ b/src/dotnet-proj-diff/Output.cs @@ -1,4 +1,4 @@ -namespace ProjectDiff.Tool; +namespace ProjectDiff.Tool; public sealed class Output(FileInfo? outputFile, IConsole console) { @@ -11,4 +11,4 @@ public Stream Open() public string NormalizePath(string path, bool absolutePaths) => absolutePaths ? path.Replace('\\', '/') : Path.GetRelativePath(RootDirectory, path).Replace('\\', '/'); -} \ No newline at end of file +} diff --git a/src/dotnet-proj-diff/OutputFormat.cs b/src/dotnet-proj-diff/OutputFormat.cs index 0abce81..960dfc6 100644 --- a/src/dotnet-proj-diff/OutputFormat.cs +++ b/src/dotnet-proj-diff/OutputFormat.cs @@ -1,4 +1,4 @@ -namespace ProjectDiff.Tool; +namespace ProjectDiff.Tool; public enum OutputFormat { @@ -6,4 +6,4 @@ public enum OutputFormat Json = 1, Slnf = 2, Traversal = 3, -} \ No newline at end of file +} diff --git a/src/dotnet-proj-diff/OutputFormatters/IOutputFormatter.cs b/src/dotnet-proj-diff/OutputFormatters/IOutputFormatter.cs index 525c91f..a76529e 100644 --- a/src/dotnet-proj-diff/OutputFormatters/IOutputFormatter.cs +++ b/src/dotnet-proj-diff/OutputFormatters/IOutputFormatter.cs @@ -1,4 +1,4 @@ -using ProjectDiff.Core; +using ProjectDiff.Core; namespace ProjectDiff.Tool.OutputFormatters; @@ -9,4 +9,4 @@ Task WriteAsync( Output output, CancellationToken cancellationToken = default ); -} \ No newline at end of file +} diff --git a/src/dotnet-proj-diff/OutputFormatters/JsonOutputFormatter.cs b/src/dotnet-proj-diff/OutputFormatters/JsonOutputFormatter.cs index 85acae2..33e8913 100644 --- a/src/dotnet-proj-diff/OutputFormatters/JsonOutputFormatter.cs +++ b/src/dotnet-proj-diff/OutputFormatters/JsonOutputFormatter.cs @@ -1,4 +1,4 @@ -using System.Text.Json; +using System.Text.Json; using ProjectDiff.Core; namespace ProjectDiff.Tool.OutputFormatters; @@ -21,21 +21,21 @@ public async Task WriteAsync( ) { projects = projects.Select(project => project with - { - Path = output.NormalizePath( + { + Path = output.NormalizePath( project.Path, _absolutePaths ), - ReferencedProjects = project.ReferencedProjects + ReferencedProjects = project.ReferencedProjects .Select(refProject => output.NormalizePath( refProject, _absolutePaths ) ).ToList() - } + } ); await using var stream = output.Open(); await JsonSerializer.SerializeAsync(stream, projects, _options, cancellationToken); } -} \ No newline at end of file +} diff --git a/src/dotnet-proj-diff/OutputFormatters/PlainOutputFormatter.cs b/src/dotnet-proj-diff/OutputFormatters/PlainOutputFormatter.cs index f31368a..bfaf069 100644 --- a/src/dotnet-proj-diff/OutputFormatters/PlainOutputFormatter.cs +++ b/src/dotnet-proj-diff/OutputFormatters/PlainOutputFormatter.cs @@ -1,4 +1,4 @@ -using ProjectDiff.Core; +using ProjectDiff.Core; namespace ProjectDiff.Tool.OutputFormatters; @@ -28,4 +28,4 @@ public async Task WriteAsync( await writer.WriteLineAsync(path); } } -} \ No newline at end of file +} diff --git a/src/dotnet-proj-diff/OutputFormatters/SlnfOutputFormatter.cs b/src/dotnet-proj-diff/OutputFormatters/SlnfOutputFormatter.cs index 0992f9d..370fdc1 100644 --- a/src/dotnet-proj-diff/OutputFormatters/SlnfOutputFormatter.cs +++ b/src/dotnet-proj-diff/OutputFormatters/SlnfOutputFormatter.cs @@ -1,4 +1,4 @@ -using System.Text.Json; +using System.Text.Json; using System.Text.Json.Nodes; using ProjectDiff.Core; @@ -47,4 +47,4 @@ public async Task WriteAsync( await using var stream = output.Open(); await JsonSerializer.SerializeAsync(stream, root, _options, cancellationToken); } -} \ No newline at end of file +} diff --git a/src/dotnet-proj-diff/OutputFormatters/TraversalOutputFormatter.cs b/src/dotnet-proj-diff/OutputFormatters/TraversalOutputFormatter.cs index 696322a..e18c2a9 100644 --- a/src/dotnet-proj-diff/OutputFormatters/TraversalOutputFormatter.cs +++ b/src/dotnet-proj-diff/OutputFormatters/TraversalOutputFormatter.cs @@ -1,4 +1,4 @@ -using Microsoft.Build.Construction; +using Microsoft.Build.Construction; using Microsoft.Build.Evaluation; using ProjectDiff.Core; @@ -39,4 +39,4 @@ public async Task WriteAsync( await using var writer = new StreamWriter(stream); element.Save(writer); } -} \ No newline at end of file +} diff --git a/src/dotnet-proj-diff/Program.cs b/src/dotnet-proj-diff/Program.cs index 9d1eb17..9513a67 100644 --- a/src/dotnet-proj-diff/Program.cs +++ b/src/dotnet-proj-diff/Program.cs @@ -1,8 +1,8 @@ -using Microsoft.Build.Locator; +using Microsoft.Build.Locator; using ProjectDiff.Tool; MSBuildLocator.RegisterDefaults(); var tool = ProjectDiffTool.BuildCli(new SystemConsole()); -return await tool.InvokeAsync(args); \ No newline at end of file +return await tool.InvokeAsync(args); diff --git a/src/dotnet-proj-diff/ProjectDiffCommand.cs b/src/dotnet-proj-diff/ProjectDiffCommand.cs index 957e284..f379349 100644 --- a/src/dotnet-proj-diff/ProjectDiffCommand.cs +++ b/src/dotnet-proj-diff/ProjectDiffCommand.cs @@ -1,4 +1,4 @@ -using System.CommandLine; +using System.CommandLine; using System.Text.Json; using System.Text.Json.Serialization; using Microsoft.Extensions.Logging; @@ -255,7 +255,7 @@ CancellationToken cancellationToken logger.LogDebug( "Diff projects: {Projects}", projects.Select(it => new - { it.Path, it.Status, ReferencedProjects = string.Join(',', it.ReferencedProjects) } + { it.Path, it.Status, ReferencedProjects = string.Join(',', it.ReferencedProjects) } ) ); } @@ -305,4 +305,4 @@ bool ShouldInclude(DiffProject project) => ".json" => OutputFormat.Json, _ => OutputFormat.Plain }; -} \ No newline at end of file +} diff --git a/src/dotnet-proj-diff/ProjectDiffSettings.cs b/src/dotnet-proj-diff/ProjectDiffSettings.cs index 5e35687..5f98dc7 100644 --- a/src/dotnet-proj-diff/ProjectDiffSettings.cs +++ b/src/dotnet-proj-diff/ProjectDiffSettings.cs @@ -1,4 +1,4 @@ -using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging; namespace ProjectDiff.Tool; @@ -18,4 +18,4 @@ public sealed class ProjectDiffSettings public required FileInfo[] IgnoreChangedFile { get; init; } = []; public string? MicrosoftBuildTraversalVersion { get; init; } public LogLevel LogLevel { get; init; } = LogLevel.Information; -} \ No newline at end of file +} diff --git a/src/dotnet-proj-diff/ProjectDiffTool.cs b/src/dotnet-proj-diff/ProjectDiffTool.cs index 9b5a40f..03ba845 100644 --- a/src/dotnet-proj-diff/ProjectDiffTool.cs +++ b/src/dotnet-proj-diff/ProjectDiffTool.cs @@ -1,4 +1,4 @@ -using System.CommandLine; +using System.CommandLine; namespace ProjectDiff.Tool; @@ -12,4 +12,4 @@ public static CommandLineConfiguration BuildCli(IConsole console) Output = console.Out, }; } -} \ No newline at end of file +} diff --git a/src/dotnet-proj-diff/SystemConsole.cs b/src/dotnet-proj-diff/SystemConsole.cs index a2df364..34c9792 100644 --- a/src/dotnet-proj-diff/SystemConsole.cs +++ b/src/dotnet-proj-diff/SystemConsole.cs @@ -1,4 +1,4 @@ -namespace ProjectDiff.Tool; +namespace ProjectDiff.Tool; public sealed class SystemConsole : IConsole { @@ -7,4 +7,4 @@ public sealed class SystemConsole : IConsole public Stream OpenStandardOutput() => Console.OpenStandardOutput(); public string WorkingDirectory { get; } = Directory.GetCurrentDirectory(); -} \ No newline at end of file +} diff --git a/test/ProjectDiff.Tests/Core/BranchTests.cs b/test/ProjectDiff.Tests/Core/BranchTests.cs index 9f46a75..4e7e29e 100644 --- a/test/ProjectDiff.Tests/Core/BranchTests.cs +++ b/test/ProjectDiff.Tests/Core/BranchTests.cs @@ -1,4 +1,4 @@ -using Microsoft.Extensions.Logging.Abstractions; +using Microsoft.Extensions.Logging.Abstractions; using ProjectDiff.Core; using ProjectDiff.Core.Entrypoints; using ProjectDiff.Tests.Utils; @@ -182,4 +182,4 @@ public async Task ModifyProjectInBaseBranch_WithMergeBaseOption() Assert.Equal(ProjectDiffExecutionStatus.Success, result.Status); Assert.Empty(result.Projects); } -} \ No newline at end of file +} diff --git a/test/ProjectDiff.Tests/Core/BuildGraphDiffTests.cs b/test/ProjectDiff.Tests/Core/BuildGraphDiffTests.cs index a2ff20f..8fcb2b7 100644 --- a/test/ProjectDiff.Tests/Core/BuildGraphDiffTests.cs +++ b/test/ProjectDiff.Tests/Core/BuildGraphDiffTests.cs @@ -1,4 +1,4 @@ -using ProjectDiff.Core; +using ProjectDiff.Core; namespace ProjectDiff.Tests.Core; @@ -203,7 +203,7 @@ public void ReturnsProjectWhenInputFileIsAdded() Assert.Equal("/path/to/project1.csproj", project.Path); Assert.Equal(DiffStatus.Modified, project.Status); } - + [Fact] public void ReturnsProjectWhenInputFileIsRemoved() { @@ -220,7 +220,7 @@ public void ReturnsProjectWhenInputFileIsRemoved() Assert.Equal("/path/to/project1.csproj", project.Path); Assert.Equal(DiffStatus.Modified, project.Status); } - + [Fact] public void ReturnsProjectWhenInputFileIsChangedButNotModified() { @@ -237,7 +237,7 @@ public void ReturnsProjectWhenInputFileIsChangedButNotModified() Assert.Equal("/path/to/project1.csproj", project.Path); Assert.Equal(DiffStatus.Modified, project.Status); } - + [Fact] public void ReturnsProjectWhenReferenceIsChangedButNotModified() { @@ -254,4 +254,4 @@ public void ReturnsProjectWhenReferenceIsChangedButNotModified() Assert.Equal("/path/to/project1.csproj", project.Path); Assert.Equal(DiffStatus.ReferenceChanged, project.Status); } -} \ No newline at end of file +} diff --git a/test/ProjectDiff.Tests/Core/DirectoryBuildPropsTests.cs b/test/ProjectDiff.Tests/Core/DirectoryBuildPropsTests.cs index d37e9e2..905ff18 100644 --- a/test/ProjectDiff.Tests/Core/DirectoryBuildPropsTests.cs +++ b/test/ProjectDiff.Tests/Core/DirectoryBuildPropsTests.cs @@ -1,4 +1,4 @@ -using Microsoft.Extensions.Logging.Abstractions; +using Microsoft.Extensions.Logging.Abstractions; using ProjectDiff.Core; using ProjectDiff.Core.Entrypoints; using ProjectDiff.Tests.Utils; @@ -217,4 +217,4 @@ private static Task GetProjectDiff(TestRepository repo) cancellationToken: TestContext.Current.CancellationToken ); } -} \ No newline at end of file +} diff --git a/test/ProjectDiff.Tests/Core/ErrorTests.cs b/test/ProjectDiff.Tests/Core/ErrorTests.cs index ca5e33a..1a66b8c 100644 --- a/test/ProjectDiff.Tests/Core/ErrorTests.cs +++ b/test/ProjectDiff.Tests/Core/ErrorTests.cs @@ -1,4 +1,4 @@ -using Microsoft.Build.FileSystem; +using Microsoft.Build.FileSystem; using Microsoft.Build.Graph; using ProjectDiff.Core; using ProjectDiff.Core.Entrypoints; @@ -77,4 +77,4 @@ CancellationToken cancellationToken return Task.FromResult(Enumerable.Empty()); } } -} \ No newline at end of file +} diff --git a/test/ProjectDiff.Tests/Core/GitTreeFileSystemTests.cs b/test/ProjectDiff.Tests/Core/GitTreeFileSystemTests.cs index b29212c..f039aad 100644 --- a/test/ProjectDiff.Tests/Core/GitTreeFileSystemTests.cs +++ b/test/ProjectDiff.Tests/Core/GitTreeFileSystemTests.cs @@ -1,4 +1,4 @@ -using System.Text; +using System.Text; using Microsoft.Build.Evaluation; using Microsoft.Extensions.Logging.Abstractions; using ProjectDiff.Core; @@ -504,4 +504,4 @@ public async Task EnumerateFiles_InSubdirectoryWithSearchOptionAllDirectoriesRet Assert.Equivalent(expectedFiles, files); } -} \ No newline at end of file +} diff --git a/test/ProjectDiff.Tests/Core/IgnoreChangesTests.cs b/test/ProjectDiff.Tests/Core/IgnoreChangesTests.cs index 6ae5a17..5c1ec53 100644 --- a/test/ProjectDiff.Tests/Core/IgnoreChangesTests.cs +++ b/test/ProjectDiff.Tests/Core/IgnoreChangesTests.cs @@ -1,4 +1,4 @@ -using Microsoft.Extensions.Logging.Abstractions; +using Microsoft.Extensions.Logging.Abstractions; using ProjectDiff.Core; using ProjectDiff.Core.Entrypoints; using ProjectDiff.Tests.Utils; @@ -103,4 +103,4 @@ public async Task IgnoresDeletedFiles() Assert.Empty(diff.Projects); } -} \ No newline at end of file +} diff --git a/test/ProjectDiff.Tests/Core/MoveFileTests.cs b/test/ProjectDiff.Tests/Core/MoveFileTests.cs index 9cdac33..899403c 100644 --- a/test/ProjectDiff.Tests/Core/MoveFileTests.cs +++ b/test/ProjectDiff.Tests/Core/MoveFileTests.cs @@ -20,7 +20,7 @@ public async Task MoveFileToReferencedProject() "ProjectB/ProjectB.csproj", p => p.AddItem("ProjectReference", "../ProjectA/ProjectA.csproj") ); - + await r.WriteAllTextAsync("ProjectB/FileA.cs", "File A content"); } ); @@ -30,7 +30,7 @@ public async Task MoveFileToReferencedProject() "ProjectA/FileA.cs" ); var projects = await GetDiffProjects(repo); - + Assert.Collection( projects, p => @@ -45,7 +45,7 @@ public async Task MoveFileToReferencedProject() } ); } - + [Fact] public async Task MoveFileFromReferencedProjects() { @@ -68,7 +68,7 @@ public async Task MoveFileFromReferencedProjects() "ProjectB/FileA.cs" ); var projects = await GetDiffProjects(repo); - + Assert.Collection( projects, p => @@ -140,4 +140,4 @@ private static async Task> GetDiffProjects(TestReposito return result.Projects; } -} \ No newline at end of file +} diff --git a/test/ProjectDiff.Tests/Core/MultiFrameworkTests.cs b/test/ProjectDiff.Tests/Core/MultiFrameworkTests.cs index 797e3ec..16b3e99 100644 --- a/test/ProjectDiff.Tests/Core/MultiFrameworkTests.cs +++ b/test/ProjectDiff.Tests/Core/MultiFrameworkTests.cs @@ -1,4 +1,4 @@ -using Microsoft.Extensions.Logging.Abstractions; +using Microsoft.Extensions.Logging.Abstractions; using ProjectDiff.Core; using ProjectDiff.Core.Entrypoints; using ProjectDiff.Tests.Utils; @@ -40,4 +40,4 @@ public static async Task FileModifiedInMultiFrameworkProjectOnlyReturnsASinglePr Assert.Equal(DiffStatus.Modified, proj.Status); Assert.Equal(project, proj.Path); } -} \ No newline at end of file +} diff --git a/test/ProjectDiff.Tests/ModuleInit.cs b/test/ProjectDiff.Tests/ModuleInit.cs index e54c8c8..da72a37 100644 --- a/test/ProjectDiff.Tests/ModuleInit.cs +++ b/test/ProjectDiff.Tests/ModuleInit.cs @@ -1,4 +1,4 @@ -using System.Runtime.CompilerServices; +using System.Runtime.CompilerServices; using Microsoft.Build.Locator; namespace ProjectDiff.Tests; @@ -10,4 +10,4 @@ public static void Run() { MSBuildLocator.RegisterDefaults(); } -} \ No newline at end of file +} diff --git a/test/ProjectDiff.Tests/Tool/OutputFormatters/JsonOutputFormatterTests.cs b/test/ProjectDiff.Tests/Tool/OutputFormatters/JsonOutputFormatterTests.cs index 82fcb51..33a4ec1 100644 --- a/test/ProjectDiff.Tests/Tool/OutputFormatters/JsonOutputFormatterTests.cs +++ b/test/ProjectDiff.Tests/Tool/OutputFormatters/JsonOutputFormatterTests.cs @@ -1,4 +1,4 @@ -using ProjectDiff.Core; +using ProjectDiff.Core; using ProjectDiff.Tests.Utils; using ProjectDiff.Tool; using ProjectDiff.Tool.OutputFormatters; @@ -41,4 +41,4 @@ public async Task WriteAsync_OutputsJson(bool absolutePaths) await VerifyJson(console.GetStandardOutput()) .UseParameters(absolutePaths); } -} \ No newline at end of file +} diff --git a/test/ProjectDiff.Tests/Tool/OutputFormatters/PlainOutputFormatterTests.cs b/test/ProjectDiff.Tests/Tool/OutputFormatters/PlainOutputFormatterTests.cs index fdb6044..3c70326 100644 --- a/test/ProjectDiff.Tests/Tool/OutputFormatters/PlainOutputFormatterTests.cs +++ b/test/ProjectDiff.Tests/Tool/OutputFormatters/PlainOutputFormatterTests.cs @@ -1,4 +1,4 @@ -using ProjectDiff.Core; +using ProjectDiff.Core; using ProjectDiff.Tests.Utils; using ProjectDiff.Tool; using ProjectDiff.Tool.OutputFormatters; @@ -40,4 +40,4 @@ public async Task WriteAsync_OutputsPlainText(bool absolutePaths) await Verify(console.GetStandardOutput()) .UseParameters(absolutePaths); } -} \ No newline at end of file +} diff --git a/test/ProjectDiff.Tests/Tool/OutputFormatters/SlnfOutputFormatterTests.cs b/test/ProjectDiff.Tests/Tool/OutputFormatters/SlnfOutputFormatterTests.cs index 37c6a84..4389a97 100644 --- a/test/ProjectDiff.Tests/Tool/OutputFormatters/SlnfOutputFormatterTests.cs +++ b/test/ProjectDiff.Tests/Tool/OutputFormatters/SlnfOutputFormatterTests.cs @@ -1,4 +1,4 @@ -using ProjectDiff.Core; +using ProjectDiff.Core; using ProjectDiff.Tests.Utils; using ProjectDiff.Tool; using ProjectDiff.Tool.OutputFormatters; @@ -39,7 +39,7 @@ public async Task WriteAsync_WritesSlnfFiles() sln, ProjectDiffCommand.JsonSerializerOptions ); - + await formatter.WriteAsync( projects, output, @@ -48,4 +48,4 @@ await formatter.WriteAsync( await VerifyJson(console.GetStandardOutput()); } -} \ No newline at end of file +} diff --git a/test/ProjectDiff.Tests/Tool/OutputFormatters/TraversalOutputFormatterTests.cs b/test/ProjectDiff.Tests/Tool/OutputFormatters/TraversalOutputFormatterTests.cs index 5c1f69a..df0577c 100644 --- a/test/ProjectDiff.Tests/Tool/OutputFormatters/TraversalOutputFormatterTests.cs +++ b/test/ProjectDiff.Tests/Tool/OutputFormatters/TraversalOutputFormatterTests.cs @@ -1,4 +1,4 @@ -using ProjectDiff.Core; +using ProjectDiff.Core; using ProjectDiff.Tests.Utils; using ProjectDiff.Tool; using ProjectDiff.Tool.OutputFormatters; @@ -48,4 +48,4 @@ public async Task WriteAsync_ShouldWriteTraversalOutput(string? traversalVersion await VerifyXml(console.GetStandardOutput()) .UseParameters(traversalVersion, absolutePaths); } -} \ No newline at end of file +} diff --git a/test/ProjectDiff.Tests/Tool/ProjectDiffTests.cs b/test/ProjectDiff.Tests/Tool/ProjectDiffTests.cs index 9775c3e..d35aaa8 100644 --- a/test/ProjectDiff.Tests/Tool/ProjectDiffTests.cs +++ b/test/ProjectDiff.Tests/Tool/ProjectDiffTests.cs @@ -1,4 +1,4 @@ -using ProjectDiff.Tests.Utils; +using ProjectDiff.Tests.Utils; using ProjectDiff.Tool; namespace ProjectDiff.Tests.Tool; @@ -306,7 +306,7 @@ params string[] args var console = new TestConsole(repository.WorkingDirectory); var cli = ProjectDiffTool.BuildCli(console); - var exitCode = await cli.InvokeAsync([..args, ..defaultArgs]); + var exitCode = await cli.InvokeAsync([.. args, .. defaultArgs]); if (exitCode != 0) { var stderr = console.GetStandardError(); @@ -315,4 +315,4 @@ params string[] args return console.GetStandardOutput(); } -} \ No newline at end of file +} diff --git a/test/ProjectDiff.Tests/Utils/SetupResult.cs b/test/ProjectDiff.Tests/Utils/SetupResult.cs index 87d6f92..1f4e112 100644 --- a/test/ProjectDiff.Tests/Utils/SetupResult.cs +++ b/test/ProjectDiff.Tests/Utils/SetupResult.cs @@ -1,4 +1,4 @@ -namespace ProjectDiff.Tests.Utils; +namespace ProjectDiff.Tests.Utils; public sealed class SetupResult : IDisposable { @@ -21,4 +21,4 @@ public void Dispose() { Repository.Dispose(); } -} \ No newline at end of file +} diff --git a/test/ProjectDiff.Tests/Utils/TestConsole.cs b/test/ProjectDiff.Tests/Utils/TestConsole.cs index 5d33d07..8acf04f 100644 --- a/test/ProjectDiff.Tests/Utils/TestConsole.cs +++ b/test/ProjectDiff.Tests/Utils/TestConsole.cs @@ -1,4 +1,4 @@ -using System.IO.Pipelines; +using System.IO.Pipelines; using ProjectDiff.Tool; namespace ProjectDiff.Tests.Utils; @@ -44,4 +44,4 @@ public Stream OpenStandardOutput() return writer.AsStream(leaveOpen: true); } -} \ No newline at end of file +} diff --git a/test/ProjectDiff.Tests/Utils/TestRepository.cs b/test/ProjectDiff.Tests/Utils/TestRepository.cs index b739ffc..cd411a5 100644 --- a/test/ProjectDiff.Tests/Utils/TestRepository.cs +++ b/test/ProjectDiff.Tests/Utils/TestRepository.cs @@ -1,4 +1,4 @@ -using LibGit2Sharp; +using LibGit2Sharp; using Microsoft.Build.Construction; using Microsoft.VisualStudio.SolutionPersistence.Model; using Microsoft.VisualStudio.SolutionPersistence.Serializer; @@ -65,7 +65,7 @@ public Task WriteAllTextAsync(string file, string content) public string GetPath(params string[] parts) { - return Path.Join([WorkingDirectory, ..parts]); + return Path.Join([WorkingDirectory, .. parts]); } public string GetPath(string relativePath) @@ -198,4 +198,4 @@ public void UpdateProject(string path, Action configure) configure(root); root.Save(p); } -} \ No newline at end of file +} diff --git a/test/ProjectDiff.Tests/VerifyTests.cs b/test/ProjectDiff.Tests/VerifyTests.cs index feed9a3..373be9a 100644 --- a/test/ProjectDiff.Tests/VerifyTests.cs +++ b/test/ProjectDiff.Tests/VerifyTests.cs @@ -1,4 +1,4 @@ -namespace ProjectDiff.Tests; +namespace ProjectDiff.Tests; public sealed class VerifyTests { @@ -7,5 +7,5 @@ public async Task VerifyIsSetupCorrectly() { await VerifyChecks.Run(); } - -} \ No newline at end of file + +}