From cdf28f53d4574b7cab224e84808df63f3401a3f9 Mon Sep 17 00:00:00 2001 From: Niklas Wendel Date: Fri, 13 Jun 2025 06:02:49 +0200 Subject: [PATCH 1/2] Support centralized package management --- .../Asdf/Asdf.csproj | 15 +++++++++ .../Asdf/Class1.cs | 7 +++++ .../CentralizedPackageManagement.sln | 31 +++++++++++++++++++ .../Directory.Packages.props | 12 +++++++ .../Qwerty/Class1.cs | 7 +++++ .../Qwerty/Qwerty.csproj | 11 +++++++ .../Expectations/Asdf.Default.verified.txt | 13 ++++++++ src/Snitch.Tests/ProgramTests.cs | 22 +++++++++++-- src/Snitch/Analysis/Models/Package.cs | 21 ++++++++----- src/Snitch/Analysis/ProjectBuilder.cs | 9 ++---- src/Snitch/Snitch.csproj | 4 +-- 11 files changed, 133 insertions(+), 19 deletions(-) create mode 100644 src/Snitch.Tests.Fixtures/CentralizedPackageManagement/Asdf/Asdf.csproj create mode 100644 src/Snitch.Tests.Fixtures/CentralizedPackageManagement/Asdf/Class1.cs create mode 100644 src/Snitch.Tests.Fixtures/CentralizedPackageManagement/CentralizedPackageManagement.sln create mode 100644 src/Snitch.Tests.Fixtures/CentralizedPackageManagement/Directory.Packages.props create mode 100644 src/Snitch.Tests.Fixtures/CentralizedPackageManagement/Qwerty/Class1.cs create mode 100644 src/Snitch.Tests.Fixtures/CentralizedPackageManagement/Qwerty/Qwerty.csproj create mode 100644 src/Snitch.Tests/Expectations/Asdf.Default.verified.txt diff --git a/src/Snitch.Tests.Fixtures/CentralizedPackageManagement/Asdf/Asdf.csproj b/src/Snitch.Tests.Fixtures/CentralizedPackageManagement/Asdf/Asdf.csproj new file mode 100644 index 0000000..8046f18 --- /dev/null +++ b/src/Snitch.Tests.Fixtures/CentralizedPackageManagement/Asdf/Asdf.csproj @@ -0,0 +1,15 @@ + + + + net8.0 + + + + + + + + + + + diff --git a/src/Snitch.Tests.Fixtures/CentralizedPackageManagement/Asdf/Class1.cs b/src/Snitch.Tests.Fixtures/CentralizedPackageManagement/Asdf/Class1.cs new file mode 100644 index 0000000..613a9e1 --- /dev/null +++ b/src/Snitch.Tests.Fixtures/CentralizedPackageManagement/Asdf/Class1.cs @@ -0,0 +1,7 @@ +namespace Asdf +{ + public class Class1 + { + + } +} diff --git a/src/Snitch.Tests.Fixtures/CentralizedPackageManagement/CentralizedPackageManagement.sln b/src/Snitch.Tests.Fixtures/CentralizedPackageManagement/CentralizedPackageManagement.sln new file mode 100644 index 0000000..f53130e --- /dev/null +++ b/src/Snitch.Tests.Fixtures/CentralizedPackageManagement/CentralizedPackageManagement.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.13.36105.23 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Asdf", "Asdf\Asdf.csproj", "{0026E591-BDA2-59CD-C237-1513DA9668F8}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Qwerty", "Qwerty\Qwerty.csproj", "{D9EE6D9A-329C-4B70-831C-EBDB4498C490}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {0026E591-BDA2-59CD-C237-1513DA9668F8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0026E591-BDA2-59CD-C237-1513DA9668F8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0026E591-BDA2-59CD-C237-1513DA9668F8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0026E591-BDA2-59CD-C237-1513DA9668F8}.Release|Any CPU.Build.0 = Release|Any CPU + {D9EE6D9A-329C-4B70-831C-EBDB4498C490}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D9EE6D9A-329C-4B70-831C-EBDB4498C490}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D9EE6D9A-329C-4B70-831C-EBDB4498C490}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D9EE6D9A-329C-4B70-831C-EBDB4498C490}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {95C9EDD6-8E73-4BC8-9DD0-D25CE6E91111} + EndGlobalSection +EndGlobal diff --git a/src/Snitch.Tests.Fixtures/CentralizedPackageManagement/Directory.Packages.props b/src/Snitch.Tests.Fixtures/CentralizedPackageManagement/Directory.Packages.props new file mode 100644 index 0000000..22df90f --- /dev/null +++ b/src/Snitch.Tests.Fixtures/CentralizedPackageManagement/Directory.Packages.props @@ -0,0 +1,12 @@ + + + + + true + + + + + + + \ No newline at end of file diff --git a/src/Snitch.Tests.Fixtures/CentralizedPackageManagement/Qwerty/Class1.cs b/src/Snitch.Tests.Fixtures/CentralizedPackageManagement/Qwerty/Class1.cs new file mode 100644 index 0000000..93564a8 --- /dev/null +++ b/src/Snitch.Tests.Fixtures/CentralizedPackageManagement/Qwerty/Class1.cs @@ -0,0 +1,7 @@ +namespace Qwerty +{ + public class Class1 + { + + } +} diff --git a/src/Snitch.Tests.Fixtures/CentralizedPackageManagement/Qwerty/Qwerty.csproj b/src/Snitch.Tests.Fixtures/CentralizedPackageManagement/Qwerty/Qwerty.csproj new file mode 100644 index 0000000..7fa6775 --- /dev/null +++ b/src/Snitch.Tests.Fixtures/CentralizedPackageManagement/Qwerty/Qwerty.csproj @@ -0,0 +1,11 @@ + + + + net8.0 + + + + + + + diff --git a/src/Snitch.Tests/Expectations/Asdf.Default.verified.txt b/src/Snitch.Tests/Expectations/Asdf.Default.verified.txt new file mode 100644 index 0000000..30ef531 --- /dev/null +++ b/src/Snitch.Tests/Expectations/Asdf.Default.verified.txt @@ -0,0 +1,13 @@ +Analyzing... +Analyzing CentralizedPackageManagement.sln +Analyzing Asdf... + * Analyzing Qwerty (net8.0)... + +╭──────────────────────────────────────────╮ +│ Packages that can be removed from Asdf: │ +│ ┌──────────────┬───────────────────────┐ │ +│ │ Package │ Referenced by │ │ +│ ├──────────────┼───────────────────────┤ │ +│ │ Autofac │ Qwerty │ │ +│ └──────────────┴───────────────────────┘ │ +╰──────────────────────────────────────────╯ \ No newline at end of file diff --git a/src/Snitch.Tests/ProgramTests.cs b/src/Snitch.Tests/ProgramTests.cs index f264bcd..52e3e90 100644 --- a/src/Snitch.Tests/ProgramTests.cs +++ b/src/Snitch.Tests/ProgramTests.cs @@ -1,13 +1,13 @@ -using Shouldly; -using Snitch; using System; using System.IO; using System.Threading.Tasks; +using Shouldly; +using Snitch; using Spectre.Console.Cli; using Spectre.Console.Testing; using VerifyTests; -using Xunit; using VerifyXunit; +using Xunit; namespace Sntich.Tests { @@ -190,6 +190,22 @@ public async Task Should_Return_Zero_Exit_Code_For_Thuuud_When_Running_With_NoPr await Verifier.Verify(output); } + [Fact] + [Expectation("Asdf", "Default")] + public async Task Should_Return_Expected_Result_For_Centralized_Package_Management() + { + // Given + var fixture = new Fixture(); + var project = Fixture.GetPath("CentralizedPackageManagement/CentralizedPackageManagement.sln"); + + // When + var (exitCode, output) = await Fixture.Run(project); + + // Then + exitCode.ShouldBe(0); + await Verifier.Verify(output); + } + public sealed class Fixture { public static string GetPath(string path) diff --git a/src/Snitch/Analysis/Models/Package.cs b/src/Snitch/Analysis/Models/Package.cs index eb6374d..b4da3ed 100644 --- a/src/Snitch/Analysis/Models/Package.cs +++ b/src/Snitch/Analysis/Models/Package.cs @@ -45,7 +45,12 @@ public bool IsGreaterThan(Package package, out bool indeterminate) public bool IsSameVersion(Package package) { - if (Version != null && package.Version != null) + if (Version == null && package.Version == null && Range == null && package.Range == null) + { + // Both are null, considered equal + return true; + } + else if (Version != null && package.Version != null) { // Version == Version return new VersionComparer().Equals(Version, package.Version); @@ -69,7 +74,7 @@ public string GetVersionString() return Range?.OriginalString ?? "?"; } - public Package(string name, string version, string? privateAssets) + public Package(string name, string? version, string? privateAssets) { Name = name ?? throw new ArgumentNullException(nameof(name)); PrivateAssets = privateAssets; @@ -79,16 +84,16 @@ public Package(string name, string version, string? privateAssets) Version = semanticVersion; Range = null; } - else + else if (VersionRange.TryParse(version, out var range)) { - if (!VersionRange.TryParse(version, out var range)) - { - throw new ArgumentException($"Version '{version}' for package '{name}' is not valid.", nameof(version)); - } - Version = null; Range = range; } + else + { + Version = null; + Range = null; + } } } } \ No newline at end of file diff --git a/src/Snitch/Analysis/ProjectBuilder.cs b/src/Snitch/Analysis/ProjectBuilder.cs index dbd30c3..587c7a1 100644 --- a/src/Snitch/Analysis/ProjectBuilder.cs +++ b/src/Snitch/Analysis/ProjectBuilder.cs @@ -101,12 +101,9 @@ private Project Build( // Get the package references. foreach (var packageReference in result.PackageReferences) { - if (packageReference.Value.TryGetValue("Version", out var version)) - { - var privateAssets = packageReference.Value.GetValueOrDefault("PrivateAssets"); - - project.Packages.Add(new Package(packageReference.Key, version, privateAssets)); - } + var version = packageReference.Value.GetValueOrDefault("Version"); + var privateAssets = packageReference.Value.GetValueOrDefault("PrivateAssets"); + project.Packages.Add(new Package(packageReference.Key, version, privateAssets)); } // Analyze all project references. diff --git a/src/Snitch/Snitch.csproj b/src/Snitch/Snitch.csproj index b05f8ba..3800cdf 100644 --- a/src/Snitch/Snitch.csproj +++ b/src/Snitch/Snitch.csproj @@ -23,8 +23,8 @@ - - + + From 5b83c1266e87e52f29d1bea5e3f48cd061cbd482 Mon Sep 17 00:00:00 2001 From: Niklas Wendel Date: Fri, 13 Jun 2025 06:07:30 +0200 Subject: [PATCH 2/2] revert dependency updates --- src/Snitch/Snitch.csproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Snitch/Snitch.csproj b/src/Snitch/Snitch.csproj index 3800cdf..b05f8ba 100644 --- a/src/Snitch/Snitch.csproj +++ b/src/Snitch/Snitch.csproj @@ -23,8 +23,8 @@ - - + +