From b3438c5d2d2adb697c0fcf07875454c9d8aed17c Mon Sep 17 00:00:00 2001 From: darthsharp <48331467+darthsharp@users.noreply.github.com> Date: Sun, 15 Feb 2026 12:01:15 +0100 Subject: [PATCH 01/14] Refactored CLI commands to organize Homebrew and UserDefaults subcommands into separate namespaces and command groups; upgraded project dependencies to version 6.6.0. --- samples/SampleConsoleApp/SampleConsoleApp.csproj | 6 +++--- .../CreativeCoders.MacOS.Core.csproj | 4 ++-- .../CreativeCoders.MacOS.HomeBrew.csproj | 4 ++-- .../CreativeCoders.MacOS.UserDefaults.csproj | 6 +++--- .../Commands/HomeBrew/HomebrewCommandGroup.cs | 11 +++++++++++ .../Commands/HomeBrew/{ => Info}/BrewInfoCommand.cs | 4 ++-- .../{ => List}/BrewListInstalledSoftwareCommand.cs | 4 ++-- .../{ => List}/BrewListInstalledSoftwareOptions.cs | 2 +- .../HomeBrew/{ => Upgrade}/BrewUpgradeCommand.cs | 4 ++-- .../HomeBrew/{ => Upgrade}/BrewUpgradeOptions.cs | 2 +- .../{ => ExportDomain}/ExportDomainCommand.cs | 4 ++-- .../{ => ExportDomain}/ExportDomainOptions.cs | 2 +- .../{ => ImportDomain}/ImportDomainCommand.cs | 4 ++-- .../{ => ImportDomain}/ImportDomainOptions.cs | 2 +- .../{ => ListDomains}/ListDomainsCommand.cs | 4 ++-- .../Commands/UserDefaults/UserDefaultsCommandGroup.cs | 11 +++++++++++ .../CreativeCoders.MacSynkker.Cli.csproj | 6 +++--- .../CreativeCoders.MacOS.UserDefaults.Tests.csproj | 6 +++--- 18 files changed, 54 insertions(+), 32 deletions(-) create mode 100644 source/CreativeCoders.MacSynkker.Cli/Commands/HomeBrew/HomebrewCommandGroup.cs rename source/CreativeCoders.MacSynkker.Cli/Commands/HomeBrew/{ => Info}/BrewInfoCommand.cs (89%) rename source/CreativeCoders.MacSynkker.Cli/Commands/HomeBrew/{ => List}/BrewListInstalledSoftwareCommand.cs (97%) rename source/CreativeCoders.MacSynkker.Cli/Commands/HomeBrew/{ => List}/BrewListInstalledSoftwareOptions.cs (89%) rename source/CreativeCoders.MacSynkker.Cli/Commands/HomeBrew/{ => Upgrade}/BrewUpgradeCommand.cs (96%) rename source/CreativeCoders.MacSynkker.Cli/Commands/HomeBrew/{ => Upgrade}/BrewUpgradeOptions.cs (89%) rename source/CreativeCoders.MacSynkker.Cli/Commands/UserDefaults/{ => ExportDomain}/ExportDomainCommand.cs (95%) rename source/CreativeCoders.MacSynkker.Cli/Commands/UserDefaults/{ => ExportDomain}/ExportDomainOptions.cs (95%) rename source/CreativeCoders.MacSynkker.Cli/Commands/UserDefaults/{ => ImportDomain}/ImportDomainCommand.cs (93%) rename source/CreativeCoders.MacSynkker.Cli/Commands/UserDefaults/{ => ImportDomain}/ImportDomainOptions.cs (86%) rename source/CreativeCoders.MacSynkker.Cli/Commands/UserDefaults/{ => ListDomains}/ListDomainsCommand.cs (83%) create mode 100644 source/CreativeCoders.MacSynkker.Cli/Commands/UserDefaults/UserDefaultsCommandGroup.cs diff --git a/samples/SampleConsoleApp/SampleConsoleApp.csproj b/samples/SampleConsoleApp/SampleConsoleApp.csproj index 19b7bd3..8d8ebbf 100644 --- a/samples/SampleConsoleApp/SampleConsoleApp.csproj +++ b/samples/SampleConsoleApp/SampleConsoleApp.csproj @@ -8,12 +8,12 @@ - - + + - + diff --git a/source/CreativeCoders.MacOS.Core/CreativeCoders.MacOS.Core.csproj b/source/CreativeCoders.MacOS.Core/CreativeCoders.MacOS.Core.csproj index 3d426e1..3a9485d 100644 --- a/source/CreativeCoders.MacOS.Core/CreativeCoders.MacOS.Core.csproj +++ b/source/CreativeCoders.MacOS.Core/CreativeCoders.MacOS.Core.csproj @@ -7,8 +7,8 @@ - - + + diff --git a/source/CreativeCoders.MacOS.HomeBrew/CreativeCoders.MacOS.HomeBrew.csproj b/source/CreativeCoders.MacOS.HomeBrew/CreativeCoders.MacOS.HomeBrew.csproj index afbd525..7caf0f1 100644 --- a/source/CreativeCoders.MacOS.HomeBrew/CreativeCoders.MacOS.HomeBrew.csproj +++ b/source/CreativeCoders.MacOS.HomeBrew/CreativeCoders.MacOS.HomeBrew.csproj @@ -11,8 +11,8 @@ - - + + diff --git a/source/CreativeCoders.MacOS.UserDefaults/CreativeCoders.MacOS.UserDefaults.csproj b/source/CreativeCoders.MacOS.UserDefaults/CreativeCoders.MacOS.UserDefaults.csproj index 1bd42c7..84a82a2 100644 --- a/source/CreativeCoders.MacOS.UserDefaults/CreativeCoders.MacOS.UserDefaults.csproj +++ b/source/CreativeCoders.MacOS.UserDefaults/CreativeCoders.MacOS.UserDefaults.csproj @@ -7,9 +7,9 @@ - - - + + + diff --git a/source/CreativeCoders.MacSynkker.Cli/Commands/HomeBrew/HomebrewCommandGroup.cs b/source/CreativeCoders.MacSynkker.Cli/Commands/HomeBrew/HomebrewCommandGroup.cs new file mode 100644 index 0000000..df4bb79 --- /dev/null +++ b/source/CreativeCoders.MacSynkker.Cli/Commands/HomeBrew/HomebrewCommandGroup.cs @@ -0,0 +1,11 @@ +using CreativeCoders.Cli.Core; +using CreativeCoders.MacSynkker.Cli.Commands.HomeBrew; + +[assembly: CliCommandGroup([HomebrewCommandGroup.Name], "Commands for managing Homebrew packages")] + +namespace CreativeCoders.MacSynkker.Cli.Commands.HomeBrew; + +public static class HomebrewCommandGroup +{ + public const string Name = "brew"; +} diff --git a/source/CreativeCoders.MacSynkker.Cli/Commands/HomeBrew/BrewInfoCommand.cs b/source/CreativeCoders.MacSynkker.Cli/Commands/HomeBrew/Info/BrewInfoCommand.cs similarity index 89% rename from source/CreativeCoders.MacSynkker.Cli/Commands/HomeBrew/BrewInfoCommand.cs rename to source/CreativeCoders.MacSynkker.Cli/Commands/HomeBrew/Info/BrewInfoCommand.cs index 23a2881..a0e6cbb 100644 --- a/source/CreativeCoders.MacSynkker.Cli/Commands/HomeBrew/BrewInfoCommand.cs +++ b/source/CreativeCoders.MacSynkker.Cli/Commands/HomeBrew/Info/BrewInfoCommand.cs @@ -4,9 +4,9 @@ using JetBrains.Annotations; using Spectre.Console; -namespace CreativeCoders.MacSynkker.Cli.Commands.HomeBrew; +namespace CreativeCoders.MacSynkker.Cli.Commands.HomeBrew.Info; -[CliCommand(["brew", "info"])] +[CliCommand([HomebrewCommandGroup.Name, "info"])] public class BrewInfoCommand(IAnsiConsole ansiConsole, IBrewInfo brewInfo) : ICliCommand { private readonly IBrewInfo _brewInfo = Ensure.NotNull(brewInfo); diff --git a/source/CreativeCoders.MacSynkker.Cli/Commands/HomeBrew/BrewListInstalledSoftwareCommand.cs b/source/CreativeCoders.MacSynkker.Cli/Commands/HomeBrew/List/BrewListInstalledSoftwareCommand.cs similarity index 97% rename from source/CreativeCoders.MacSynkker.Cli/Commands/HomeBrew/BrewListInstalledSoftwareCommand.cs rename to source/CreativeCoders.MacSynkker.Cli/Commands/HomeBrew/List/BrewListInstalledSoftwareCommand.cs index d736349..14c552f 100644 --- a/source/CreativeCoders.MacSynkker.Cli/Commands/HomeBrew/BrewListInstalledSoftwareCommand.cs +++ b/source/CreativeCoders.MacSynkker.Cli/Commands/HomeBrew/List/BrewListInstalledSoftwareCommand.cs @@ -7,10 +7,10 @@ using JetBrains.Annotations; using Spectre.Console; -namespace CreativeCoders.MacSynkker.Cli.Commands.HomeBrew; +namespace CreativeCoders.MacSynkker.Cli.Commands.HomeBrew.List; [UsedImplicitly] -[CliCommand(["brew", "list"])] +[CliCommand([HomebrewCommandGroup.Name, "list"])] public class BrewListInstalledSoftwareCommand(IAnsiConsole ansiConsole, IBrewInstalledSoftware brewInstalledSoftware) : ICliCommand { diff --git a/source/CreativeCoders.MacSynkker.Cli/Commands/HomeBrew/BrewListInstalledSoftwareOptions.cs b/source/CreativeCoders.MacSynkker.Cli/Commands/HomeBrew/List/BrewListInstalledSoftwareOptions.cs similarity index 89% rename from source/CreativeCoders.MacSynkker.Cli/Commands/HomeBrew/BrewListInstalledSoftwareOptions.cs rename to source/CreativeCoders.MacSynkker.Cli/Commands/HomeBrew/List/BrewListInstalledSoftwareOptions.cs index 699af11..43559ff 100644 --- a/source/CreativeCoders.MacSynkker.Cli/Commands/HomeBrew/BrewListInstalledSoftwareOptions.cs +++ b/source/CreativeCoders.MacSynkker.Cli/Commands/HomeBrew/List/BrewListInstalledSoftwareOptions.cs @@ -1,7 +1,7 @@ using CreativeCoders.SysConsole.Cli.Parsing; using JetBrains.Annotations; -namespace CreativeCoders.MacSynkker.Cli.Commands.HomeBrew; +namespace CreativeCoders.MacSynkker.Cli.Commands.HomeBrew.List; [UsedImplicitly] public class BrewListInstalledSoftwareOptions diff --git a/source/CreativeCoders.MacSynkker.Cli/Commands/HomeBrew/BrewUpgradeCommand.cs b/source/CreativeCoders.MacSynkker.Cli/Commands/HomeBrew/Upgrade/BrewUpgradeCommand.cs similarity index 96% rename from source/CreativeCoders.MacSynkker.Cli/Commands/HomeBrew/BrewUpgradeCommand.cs rename to source/CreativeCoders.MacSynkker.Cli/Commands/HomeBrew/Upgrade/BrewUpgradeCommand.cs index f30966c..7ddbe53 100644 --- a/source/CreativeCoders.MacSynkker.Cli/Commands/HomeBrew/BrewUpgradeCommand.cs +++ b/source/CreativeCoders.MacSynkker.Cli/Commands/HomeBrew/Upgrade/BrewUpgradeCommand.cs @@ -4,10 +4,10 @@ using JetBrains.Annotations; using Spectre.Console; -namespace CreativeCoders.MacSynkker.Cli.Commands.HomeBrew; +namespace CreativeCoders.MacSynkker.Cli.Commands.HomeBrew.Upgrade; [UsedImplicitly] -[CliCommand(["brew", "upgrade"])] +[CliCommand([HomebrewCommandGroup.Name, "upgrade"])] public class BrewUpgradeCommand( IBrewUpgrader brewUpgrader, IBrewInstalledSoftware brewInstalledSoftware, diff --git a/source/CreativeCoders.MacSynkker.Cli/Commands/HomeBrew/BrewUpgradeOptions.cs b/source/CreativeCoders.MacSynkker.Cli/Commands/HomeBrew/Upgrade/BrewUpgradeOptions.cs similarity index 89% rename from source/CreativeCoders.MacSynkker.Cli/Commands/HomeBrew/BrewUpgradeOptions.cs rename to source/CreativeCoders.MacSynkker.Cli/Commands/HomeBrew/Upgrade/BrewUpgradeOptions.cs index 130da76..333d40b 100644 --- a/source/CreativeCoders.MacSynkker.Cli/Commands/HomeBrew/BrewUpgradeOptions.cs +++ b/source/CreativeCoders.MacSynkker.Cli/Commands/HomeBrew/Upgrade/BrewUpgradeOptions.cs @@ -1,7 +1,7 @@ using CreativeCoders.SysConsole.Cli.Parsing; using JetBrains.Annotations; -namespace CreativeCoders.MacSynkker.Cli.Commands.HomeBrew; +namespace CreativeCoders.MacSynkker.Cli.Commands.HomeBrew.Upgrade; [UsedImplicitly] public class BrewUpgradeOptions diff --git a/source/CreativeCoders.MacSynkker.Cli/Commands/UserDefaults/ExportDomainCommand.cs b/source/CreativeCoders.MacSynkker.Cli/Commands/UserDefaults/ExportDomain/ExportDomainCommand.cs similarity index 95% rename from source/CreativeCoders.MacSynkker.Cli/Commands/UserDefaults/ExportDomainCommand.cs rename to source/CreativeCoders.MacSynkker.Cli/Commands/UserDefaults/ExportDomain/ExportDomainCommand.cs index 7949071..8ee4d5e 100644 --- a/source/CreativeCoders.MacSynkker.Cli/Commands/UserDefaults/ExportDomainCommand.cs +++ b/source/CreativeCoders.MacSynkker.Cli/Commands/UserDefaults/ExportDomain/ExportDomainCommand.cs @@ -8,10 +8,10 @@ using JetBrains.Annotations; using Spectre.Console; -namespace CreativeCoders.MacSynkker.Cli.Commands.UserDefaults; +namespace CreativeCoders.MacSynkker.Cli.Commands.UserDefaults.ExportDomain; [UsedImplicitly] -[CliCommand(["defaults", "domains", "export"])] +[CliCommand([UserDefaultsCommandGroup.Name, "domains", "export"])] public class ExportDomainCommand( IUserDefaultsExporter userDefaultsExporter, IUserDefaultsEnumerator userDefaultsEnumerator, diff --git a/source/CreativeCoders.MacSynkker.Cli/Commands/UserDefaults/ExportDomainOptions.cs b/source/CreativeCoders.MacSynkker.Cli/Commands/UserDefaults/ExportDomain/ExportDomainOptions.cs similarity index 95% rename from source/CreativeCoders.MacSynkker.Cli/Commands/UserDefaults/ExportDomainOptions.cs rename to source/CreativeCoders.MacSynkker.Cli/Commands/UserDefaults/ExportDomain/ExportDomainOptions.cs index 94b589e..c798dd8 100644 --- a/source/CreativeCoders.MacSynkker.Cli/Commands/UserDefaults/ExportDomainOptions.cs +++ b/source/CreativeCoders.MacSynkker.Cli/Commands/UserDefaults/ExportDomain/ExportDomainOptions.cs @@ -4,7 +4,7 @@ using CreativeCoders.SysConsole.Cli.Parsing; using JetBrains.Annotations; -namespace CreativeCoders.MacSynkker.Cli.Commands.UserDefaults; +namespace CreativeCoders.MacSynkker.Cli.Commands.UserDefaults.ExportDomain; [UsedImplicitly] public class ExportDomainOptions : IOptionsValidation diff --git a/source/CreativeCoders.MacSynkker.Cli/Commands/UserDefaults/ImportDomainCommand.cs b/source/CreativeCoders.MacSynkker.Cli/Commands/UserDefaults/ImportDomain/ImportDomainCommand.cs similarity index 93% rename from source/CreativeCoders.MacSynkker.Cli/Commands/UserDefaults/ImportDomainCommand.cs rename to source/CreativeCoders.MacSynkker.Cli/Commands/UserDefaults/ImportDomain/ImportDomainCommand.cs index eb706e7..87aa355 100644 --- a/source/CreativeCoders.MacSynkker.Cli/Commands/UserDefaults/ImportDomainCommand.cs +++ b/source/CreativeCoders.MacSynkker.Cli/Commands/UserDefaults/ImportDomain/ImportDomainCommand.cs @@ -4,9 +4,9 @@ using CreativeCoders.MacOS.UserDefaults; using Spectre.Console; -namespace CreativeCoders.MacSynkker.Cli.Commands.UserDefaults; +namespace CreativeCoders.MacSynkker.Cli.Commands.UserDefaults.ImportDomain; -[CliCommand(["defaults", "domains", "import"])] +[CliCommand([UserDefaultsCommandGroup.Name, "domains", "import"])] public class ImportDomainCommand( IFileSystem fileSystem, IAnsiConsole ansiConsole, diff --git a/source/CreativeCoders.MacSynkker.Cli/Commands/UserDefaults/ImportDomainOptions.cs b/source/CreativeCoders.MacSynkker.Cli/Commands/UserDefaults/ImportDomain/ImportDomainOptions.cs similarity index 86% rename from source/CreativeCoders.MacSynkker.Cli/Commands/UserDefaults/ImportDomainOptions.cs rename to source/CreativeCoders.MacSynkker.Cli/Commands/UserDefaults/ImportDomain/ImportDomainOptions.cs index 0768885..ed42821 100644 --- a/source/CreativeCoders.MacSynkker.Cli/Commands/UserDefaults/ImportDomainOptions.cs +++ b/source/CreativeCoders.MacSynkker.Cli/Commands/UserDefaults/ImportDomain/ImportDomainOptions.cs @@ -1,7 +1,7 @@ using CreativeCoders.SysConsole.Cli.Parsing; using JetBrains.Annotations; -namespace CreativeCoders.MacSynkker.Cli.Commands.UserDefaults; +namespace CreativeCoders.MacSynkker.Cli.Commands.UserDefaults.ImportDomain; [UsedImplicitly] public class ImportDomainOptions diff --git a/source/CreativeCoders.MacSynkker.Cli/Commands/UserDefaults/ListDomainsCommand.cs b/source/CreativeCoders.MacSynkker.Cli/Commands/UserDefaults/ListDomains/ListDomainsCommand.cs similarity index 83% rename from source/CreativeCoders.MacSynkker.Cli/Commands/UserDefaults/ListDomainsCommand.cs rename to source/CreativeCoders.MacSynkker.Cli/Commands/UserDefaults/ListDomains/ListDomainsCommand.cs index be0dd09..7769fa5 100644 --- a/source/CreativeCoders.MacSynkker.Cli/Commands/UserDefaults/ListDomainsCommand.cs +++ b/source/CreativeCoders.MacSynkker.Cli/Commands/UserDefaults/ListDomains/ListDomainsCommand.cs @@ -6,10 +6,10 @@ using JetBrains.Annotations; using Spectre.Console; -namespace CreativeCoders.MacSynkker.Cli.Commands.UserDefaults; +namespace CreativeCoders.MacSynkker.Cli.Commands.UserDefaults.ListDomains; [UsedImplicitly] -[CliCommand(["defaults", "domains", "list"], Description = "Lists all domains for user defaults")] +[CliCommand([UserDefaultsCommandGroup.Name, "domains", "list"], Description = "Lists all domains for user defaults")] public class ListDomainsCommand(IAnsiConsole ansiConsole, IUserDefaultsEnumerator userDefaultsEnumerator) : ICliCommand { private readonly IUserDefaultsEnumerator _userDefaultsEnumerator = Ensure.NotNull(userDefaultsEnumerator); diff --git a/source/CreativeCoders.MacSynkker.Cli/Commands/UserDefaults/UserDefaultsCommandGroup.cs b/source/CreativeCoders.MacSynkker.Cli/Commands/UserDefaults/UserDefaultsCommandGroup.cs new file mode 100644 index 0000000..1b690fc --- /dev/null +++ b/source/CreativeCoders.MacSynkker.Cli/Commands/UserDefaults/UserDefaultsCommandGroup.cs @@ -0,0 +1,11 @@ +using CreativeCoders.Cli.Core; +using CreativeCoders.MacSynkker.Cli.Commands.UserDefaults; + +[assembly: CliCommandGroup([UserDefaultsCommandGroup.Name], "Commands for managing MacOS user defaults")] + +namespace CreativeCoders.MacSynkker.Cli.Commands.UserDefaults; + +public static class UserDefaultsCommandGroup +{ + public const string Name = "defaults"; +} diff --git a/source/CreativeCoders.MacSynkker.Cli/CreativeCoders.MacSynkker.Cli.csproj b/source/CreativeCoders.MacSynkker.Cli/CreativeCoders.MacSynkker.Cli.csproj index e9a676a..869a969 100644 --- a/source/CreativeCoders.MacSynkker.Cli/CreativeCoders.MacSynkker.Cli.csproj +++ b/source/CreativeCoders.MacSynkker.Cli/CreativeCoders.MacSynkker.Cli.csproj @@ -5,7 +5,7 @@ net10.0 enable enable - msc + mcs @@ -13,8 +13,8 @@ - - + + diff --git a/tests/CreativeCoders.MacOS.UserDefaults.Tests/CreativeCoders.MacOS.UserDefaults.Tests.csproj b/tests/CreativeCoders.MacOS.UserDefaults.Tests/CreativeCoders.MacOS.UserDefaults.Tests.csproj index ec85901..d59a34a 100644 --- a/tests/CreativeCoders.MacOS.UserDefaults.Tests/CreativeCoders.MacOS.UserDefaults.Tests.csproj +++ b/tests/CreativeCoders.MacOS.UserDefaults.Tests/CreativeCoders.MacOS.UserDefaults.Tests.csproj @@ -7,7 +7,7 @@ - + @@ -18,11 +18,11 @@ runtime; build; native; contentfiles; analyzers; buildtransitive all - + runtime; build; native; contentfiles; analyzers; buildtransitive all - + From e1b3c937179c0a866afeae968801107400cb5007 Mon Sep 17 00:00:00 2001 From: darthsharp <48331467+darthsharp@users.noreply.github.com> Date: Sun, 15 Feb 2026 13:26:45 +0100 Subject: [PATCH 02/14] Refactored CLI commands and project structure; introduced `Directory.Build.props` for shared settings; added `UserDefaultsDomainsCommandGroup` and reorganized namespaces for improved modularity. --- macSynkker.sln | 3 +++ .../CreativeCoders.MacOS.Core.csproj | 1 - .../CreativeCoders.MacOS.HomeBrew.csproj | 1 - .../CreativeCoders.MacOS.UserDefaults.csproj | 1 - .../Commands/HomeBrew/Info/BrewInfoCommand.cs | 1 + .../ExportDomain/ExportDomainCommand.cs | 4 ++-- .../ExportDomain/ExportDomainOptions.cs | 2 +- .../ImportDomain/ImportDomainCommand.cs | 6 ++++-- .../ImportDomain/ImportDomainOptions.cs | 2 +- .../{ => Domains}/ListDomains/ListDomainsCommand.cs | 5 +++-- .../Domains/UserDefaultsDomainsCommandGroup.cs | 13 +++++++++++++ .../CreativeCoders.MacSynkker.Cli.csproj | 5 ++++- source/CreativeCoders.MacSynkker.Cli/Program.cs | 3 ++- source/Directory.Build.props | 8 ++++++++ 14 files changed, 42 insertions(+), 13 deletions(-) rename source/CreativeCoders.MacSynkker.Cli/Commands/UserDefaults/{ => Domains}/ExportDomain/ExportDomainCommand.cs (94%) rename source/CreativeCoders.MacSynkker.Cli/Commands/UserDefaults/{ => Domains}/ExportDomain/ExportDomainOptions.cs (95%) rename source/CreativeCoders.MacSynkker.Cli/Commands/UserDefaults/{ => Domains}/ImportDomain/ImportDomainCommand.cs (90%) rename source/CreativeCoders.MacSynkker.Cli/Commands/UserDefaults/{ => Domains}/ImportDomain/ImportDomainOptions.cs (85%) rename source/CreativeCoders.MacSynkker.Cli/Commands/UserDefaults/{ => Domains}/ListDomains/ListDomainsCommand.cs (80%) create mode 100644 source/CreativeCoders.MacSynkker.Cli/Commands/UserDefaults/Domains/UserDefaultsDomainsCommandGroup.cs create mode 100644 source/Directory.Build.props diff --git a/macSynkker.sln b/macSynkker.sln index 21ae6c3..aca851f 100644 --- a/macSynkker.sln +++ b/macSynkker.sln @@ -3,6 +3,9 @@ Microsoft Visual Studio Solution File, Format Version 12.00 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{D3F213BB-A6EC-4DDA-9C43-59094DF2FD09}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "source", "source", "{A9CE4FEF-F010-408C-9B5E-F00DC960A792}" + ProjectSection(SolutionItems) = preProject + source\Directory.Build.props = source\Directory.Build.props + EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "__ai", "__ai", "{3CA6C44F-1F49-4D5D-A26F-92046B51B4F5}" EndProject diff --git a/source/CreativeCoders.MacOS.Core/CreativeCoders.MacOS.Core.csproj b/source/CreativeCoders.MacOS.Core/CreativeCoders.MacOS.Core.csproj index 3a9485d..c8062ca 100644 --- a/source/CreativeCoders.MacOS.Core/CreativeCoders.MacOS.Core.csproj +++ b/source/CreativeCoders.MacOS.Core/CreativeCoders.MacOS.Core.csproj @@ -1,7 +1,6 @@  - net10.0 enable enable diff --git a/source/CreativeCoders.MacOS.HomeBrew/CreativeCoders.MacOS.HomeBrew.csproj b/source/CreativeCoders.MacOS.HomeBrew/CreativeCoders.MacOS.HomeBrew.csproj index 7caf0f1..88ece31 100644 --- a/source/CreativeCoders.MacOS.HomeBrew/CreativeCoders.MacOS.HomeBrew.csproj +++ b/source/CreativeCoders.MacOS.HomeBrew/CreativeCoders.MacOS.HomeBrew.csproj @@ -1,7 +1,6 @@  - net10.0 enable enable diff --git a/source/CreativeCoders.MacOS.UserDefaults/CreativeCoders.MacOS.UserDefaults.csproj b/source/CreativeCoders.MacOS.UserDefaults/CreativeCoders.MacOS.UserDefaults.csproj index 84a82a2..b565cbc 100644 --- a/source/CreativeCoders.MacOS.UserDefaults/CreativeCoders.MacOS.UserDefaults.csproj +++ b/source/CreativeCoders.MacOS.UserDefaults/CreativeCoders.MacOS.UserDefaults.csproj @@ -1,7 +1,6 @@  - net10.0 enable enable diff --git a/source/CreativeCoders.MacSynkker.Cli/Commands/HomeBrew/Info/BrewInfoCommand.cs b/source/CreativeCoders.MacSynkker.Cli/Commands/HomeBrew/Info/BrewInfoCommand.cs index a0e6cbb..69f9c1b 100644 --- a/source/CreativeCoders.MacSynkker.Cli/Commands/HomeBrew/Info/BrewInfoCommand.cs +++ b/source/CreativeCoders.MacSynkker.Cli/Commands/HomeBrew/Info/BrewInfoCommand.cs @@ -6,6 +6,7 @@ namespace CreativeCoders.MacSynkker.Cli.Commands.HomeBrew.Info; +[UsedImplicitly] [CliCommand([HomebrewCommandGroup.Name, "info"])] public class BrewInfoCommand(IAnsiConsole ansiConsole, IBrewInfo brewInfo) : ICliCommand { diff --git a/source/CreativeCoders.MacSynkker.Cli/Commands/UserDefaults/ExportDomain/ExportDomainCommand.cs b/source/CreativeCoders.MacSynkker.Cli/Commands/UserDefaults/Domains/ExportDomain/ExportDomainCommand.cs similarity index 94% rename from source/CreativeCoders.MacSynkker.Cli/Commands/UserDefaults/ExportDomain/ExportDomainCommand.cs rename to source/CreativeCoders.MacSynkker.Cli/Commands/UserDefaults/Domains/ExportDomain/ExportDomainCommand.cs index 8ee4d5e..a72aefd 100644 --- a/source/CreativeCoders.MacSynkker.Cli/Commands/UserDefaults/ExportDomain/ExportDomainCommand.cs +++ b/source/CreativeCoders.MacSynkker.Cli/Commands/UserDefaults/Domains/ExportDomain/ExportDomainCommand.cs @@ -8,10 +8,10 @@ using JetBrains.Annotations; using Spectre.Console; -namespace CreativeCoders.MacSynkker.Cli.Commands.UserDefaults.ExportDomain; +namespace CreativeCoders.MacSynkker.Cli.Commands.UserDefaults.Domains.ExportDomain; [UsedImplicitly] -[CliCommand([UserDefaultsCommandGroup.Name, "domains", "export"])] +[CliCommand([UserDefaultsCommandGroup.Name, UserDefaultsDomainsCommandGroup.Name, "export"])] public class ExportDomainCommand( IUserDefaultsExporter userDefaultsExporter, IUserDefaultsEnumerator userDefaultsEnumerator, diff --git a/source/CreativeCoders.MacSynkker.Cli/Commands/UserDefaults/ExportDomain/ExportDomainOptions.cs b/source/CreativeCoders.MacSynkker.Cli/Commands/UserDefaults/Domains/ExportDomain/ExportDomainOptions.cs similarity index 95% rename from source/CreativeCoders.MacSynkker.Cli/Commands/UserDefaults/ExportDomain/ExportDomainOptions.cs rename to source/CreativeCoders.MacSynkker.Cli/Commands/UserDefaults/Domains/ExportDomain/ExportDomainOptions.cs index c798dd8..f0221b9 100644 --- a/source/CreativeCoders.MacSynkker.Cli/Commands/UserDefaults/ExportDomain/ExportDomainOptions.cs +++ b/source/CreativeCoders.MacSynkker.Cli/Commands/UserDefaults/Domains/ExportDomain/ExportDomainOptions.cs @@ -4,7 +4,7 @@ using CreativeCoders.SysConsole.Cli.Parsing; using JetBrains.Annotations; -namespace CreativeCoders.MacSynkker.Cli.Commands.UserDefaults.ExportDomain; +namespace CreativeCoders.MacSynkker.Cli.Commands.UserDefaults.Domains.ExportDomain; [UsedImplicitly] public class ExportDomainOptions : IOptionsValidation diff --git a/source/CreativeCoders.MacSynkker.Cli/Commands/UserDefaults/ImportDomain/ImportDomainCommand.cs b/source/CreativeCoders.MacSynkker.Cli/Commands/UserDefaults/Domains/ImportDomain/ImportDomainCommand.cs similarity index 90% rename from source/CreativeCoders.MacSynkker.Cli/Commands/UserDefaults/ImportDomain/ImportDomainCommand.cs rename to source/CreativeCoders.MacSynkker.Cli/Commands/UserDefaults/Domains/ImportDomain/ImportDomainCommand.cs index 87aa355..04bb4fc 100644 --- a/source/CreativeCoders.MacSynkker.Cli/Commands/UserDefaults/ImportDomain/ImportDomainCommand.cs +++ b/source/CreativeCoders.MacSynkker.Cli/Commands/UserDefaults/Domains/ImportDomain/ImportDomainCommand.cs @@ -2,11 +2,13 @@ using CreativeCoders.Cli.Core; using CreativeCoders.Core; using CreativeCoders.MacOS.UserDefaults; +using JetBrains.Annotations; using Spectre.Console; -namespace CreativeCoders.MacSynkker.Cli.Commands.UserDefaults.ImportDomain; +namespace CreativeCoders.MacSynkker.Cli.Commands.UserDefaults.Domains.ImportDomain; -[CliCommand([UserDefaultsCommandGroup.Name, "domains", "import"])] +[UsedImplicitly] +[CliCommand([UserDefaultsCommandGroup.Name, UserDefaultsDomainsCommandGroup.Name, "import"])] public class ImportDomainCommand( IFileSystem fileSystem, IAnsiConsole ansiConsole, diff --git a/source/CreativeCoders.MacSynkker.Cli/Commands/UserDefaults/ImportDomain/ImportDomainOptions.cs b/source/CreativeCoders.MacSynkker.Cli/Commands/UserDefaults/Domains/ImportDomain/ImportDomainOptions.cs similarity index 85% rename from source/CreativeCoders.MacSynkker.Cli/Commands/UserDefaults/ImportDomain/ImportDomainOptions.cs rename to source/CreativeCoders.MacSynkker.Cli/Commands/UserDefaults/Domains/ImportDomain/ImportDomainOptions.cs index ed42821..98cbfdb 100644 --- a/source/CreativeCoders.MacSynkker.Cli/Commands/UserDefaults/ImportDomain/ImportDomainOptions.cs +++ b/source/CreativeCoders.MacSynkker.Cli/Commands/UserDefaults/Domains/ImportDomain/ImportDomainOptions.cs @@ -1,7 +1,7 @@ using CreativeCoders.SysConsole.Cli.Parsing; using JetBrains.Annotations; -namespace CreativeCoders.MacSynkker.Cli.Commands.UserDefaults.ImportDomain; +namespace CreativeCoders.MacSynkker.Cli.Commands.UserDefaults.Domains.ImportDomain; [UsedImplicitly] public class ImportDomainOptions diff --git a/source/CreativeCoders.MacSynkker.Cli/Commands/UserDefaults/ListDomains/ListDomainsCommand.cs b/source/CreativeCoders.MacSynkker.Cli/Commands/UserDefaults/Domains/ListDomains/ListDomainsCommand.cs similarity index 80% rename from source/CreativeCoders.MacSynkker.Cli/Commands/UserDefaults/ListDomains/ListDomainsCommand.cs rename to source/CreativeCoders.MacSynkker.Cli/Commands/UserDefaults/Domains/ListDomains/ListDomainsCommand.cs index 7769fa5..b015157 100644 --- a/source/CreativeCoders.MacSynkker.Cli/Commands/UserDefaults/ListDomains/ListDomainsCommand.cs +++ b/source/CreativeCoders.MacSynkker.Cli/Commands/UserDefaults/Domains/ListDomains/ListDomainsCommand.cs @@ -6,10 +6,11 @@ using JetBrains.Annotations; using Spectre.Console; -namespace CreativeCoders.MacSynkker.Cli.Commands.UserDefaults.ListDomains; +namespace CreativeCoders.MacSynkker.Cli.Commands.UserDefaults.Domains.ListDomains; [UsedImplicitly] -[CliCommand([UserDefaultsCommandGroup.Name, "domains", "list"], Description = "Lists all domains for user defaults")] +[CliCommand([UserDefaultsCommandGroup.Name, UserDefaultsDomainsCommandGroup.Name, "list"], + Description = "Lists all domains for user defaults")] public class ListDomainsCommand(IAnsiConsole ansiConsole, IUserDefaultsEnumerator userDefaultsEnumerator) : ICliCommand { private readonly IUserDefaultsEnumerator _userDefaultsEnumerator = Ensure.NotNull(userDefaultsEnumerator); diff --git a/source/CreativeCoders.MacSynkker.Cli/Commands/UserDefaults/Domains/UserDefaultsDomainsCommandGroup.cs b/source/CreativeCoders.MacSynkker.Cli/Commands/UserDefaults/Domains/UserDefaultsDomainsCommandGroup.cs new file mode 100644 index 0000000..7b53494 --- /dev/null +++ b/source/CreativeCoders.MacSynkker.Cli/Commands/UserDefaults/Domains/UserDefaultsDomainsCommandGroup.cs @@ -0,0 +1,13 @@ +using CreativeCoders.Cli.Core; +using CreativeCoders.MacSynkker.Cli.Commands.UserDefaults; +using CreativeCoders.MacSynkker.Cli.Commands.UserDefaults.Domains; + +[assembly: CliCommandGroup([UserDefaultsCommandGroup.Name, UserDefaultsDomainsCommandGroup.Name], + "Commands for managing MacOS user defaults domains")] + +namespace CreativeCoders.MacSynkker.Cli.Commands.UserDefaults.Domains; + +public static class UserDefaultsDomainsCommandGroup +{ + public const string Name = "domains"; +} diff --git a/source/CreativeCoders.MacSynkker.Cli/CreativeCoders.MacSynkker.Cli.csproj b/source/CreativeCoders.MacSynkker.Cli/CreativeCoders.MacSynkker.Cli.csproj index 869a969..f714cb2 100644 --- a/source/CreativeCoders.MacSynkker.Cli/CreativeCoders.MacSynkker.Cli.csproj +++ b/source/CreativeCoders.MacSynkker.Cli/CreativeCoders.MacSynkker.Cli.csproj @@ -2,10 +2,13 @@ Exe - net10.0 enable enable mcs + true + true + mcs + CreativeCoders.MacSynkker.Cli diff --git a/source/CreativeCoders.MacSynkker.Cli/Program.cs b/source/CreativeCoders.MacSynkker.Cli/Program.cs index 5ac57e8..4dcdf20 100644 --- a/source/CreativeCoders.MacSynkker.Cli/Program.cs +++ b/source/CreativeCoders.MacSynkker.Cli/Program.cs @@ -25,7 +25,8 @@ public static async Task Main(string[] args) x.AddMacOSUserDefaults(true); x.AddHomeBrew(); }) - .EnableHelp(HelpCommandKind.CommandOrArgument) + .PrintFooterText([""]) + .EnableHelp(HelpCommandKind.CommandOrArgument, HelpCommandKind.EmptyArgs) .Build() .RunAsync(args).ConfigureAwait(false); diff --git a/source/Directory.Build.props b/source/Directory.Build.props new file mode 100644 index 0000000..df8fb07 --- /dev/null +++ b/source/Directory.Build.props @@ -0,0 +1,8 @@ + + + net10.0 + CreativeCoders + False + $(NoWarn);IDE0079 + + \ No newline at end of file From 730d20f776df55ef85ddcf4cf2cac63fc0d88b43 Mon Sep 17 00:00:00 2001 From: darthsharp <48331467+darthsharp@users.noreply.github.com> Date: Sun, 15 Feb 2026 13:49:49 +0100 Subject: [PATCH 03/14] Refactored console output handling in `BrewListInstalledSoftwareCommand` and `ExportDomainCommand`; introduced `ListDomainsOptions` with filtering support in `ListDomainsCommand`. --- .../List/BrewListInstalledSoftwareCommand.cs | 12 ++++-------- .../ExportDomain/ExportDomainCommand.cs | 10 +++------- .../Domains/ListDomains/ListDomainsCommand.cs | 19 +++++++++++-------- .../Domains/ListDomains/ListDomainsOptions.cs | 11 +++++++++++ 4 files changed, 29 insertions(+), 23 deletions(-) create mode 100644 source/CreativeCoders.MacSynkker.Cli/Commands/UserDefaults/Domains/ListDomains/ListDomainsOptions.cs diff --git a/source/CreativeCoders.MacSynkker.Cli/Commands/HomeBrew/List/BrewListInstalledSoftwareCommand.cs b/source/CreativeCoders.MacSynkker.Cli/Commands/HomeBrew/List/BrewListInstalledSoftwareCommand.cs index 14c552f..891962c 100644 --- a/source/CreativeCoders.MacSynkker.Cli/Commands/HomeBrew/List/BrewListInstalledSoftwareCommand.cs +++ b/source/CreativeCoders.MacSynkker.Cli/Commands/HomeBrew/List/BrewListInstalledSoftwareCommand.cs @@ -32,6 +32,8 @@ public async Task ExecuteAsync(BrewListInstalledSoftwareOptions o if ((!options.Casks.HasValue && !options.Formulae.HasValue) || options.Casks == true) { PrintCasks(installedSoftware.GetCasks(options.ShowOnlyOutdated), options.ShowAsListView); + + _ansiConsole.WriteLine(); } if ((!options.Casks.HasValue && !options.Formulae.HasValue) || options.Formulae == true) @@ -44,8 +46,7 @@ public async Task ExecuteAsync(BrewListInstalledSoftwareOptions o private void PrintFormulae(BrewFormulaModel[] installedSoftwareFormulae, bool optionsShowAsListView) { - _ansiConsole.WriteLine("Installed HomeBrew formulae:"); - _ansiConsole.WriteLine(); + _ansiConsole.WriteLines("Installed HomeBrew formulae:", string.Empty); if (optionsShowAsListView) { @@ -64,14 +65,11 @@ private void PrintFormulae(BrewFormulaModel[] installedSoftwareFormulae, bool op $"- {installedSoftwareFormula.Name} ({installedSoftwareFormula.Versions?.Stable})"); } } - - _ansiConsole.WriteLine(); } private void PrintCasks(BrewCaskModel[] installedSoftwareCasks, bool optionsShowAsListView) { - _ansiConsole.WriteLine("Installed HomeBrew casks:"); - _ansiConsole.WriteLine(); + _ansiConsole.WriteLine("Installed HomeBrew casks:", string.Empty); if (optionsShowAsListView) { @@ -92,8 +90,6 @@ private void PrintCasks(BrewCaskModel[] installedSoftwareCasks, bool optionsShow $"- {installedSoftwareCask.Name?.FirstOrDefault() ?? "unknown"} ({ExtractCaskVersion(installedSoftwareCask.Installed)}) [{installedSoftwareCask.Installed}]"); } } - - _ansiConsole.WriteLine(); } private static string ExtractCaskVersion(string? versionString) diff --git a/source/CreativeCoders.MacSynkker.Cli/Commands/UserDefaults/Domains/ExportDomain/ExportDomainCommand.cs b/source/CreativeCoders.MacSynkker.Cli/Commands/UserDefaults/Domains/ExportDomain/ExportDomainCommand.cs index a72aefd..7d6fae0 100644 --- a/source/CreativeCoders.MacSynkker.Cli/Commands/UserDefaults/Domains/ExportDomain/ExportDomainCommand.cs +++ b/source/CreativeCoders.MacSynkker.Cli/Commands/UserDefaults/Domains/ExportDomain/ExportDomainCommand.cs @@ -41,17 +41,14 @@ public async Task ExecuteAsync(ExportDomainOptions options) await _userDefaultsExporter.ExportDomainAsync(options.DomainName, options.OutputPath, options.PlistFormat) .ConfigureAwait(false); - _ansiConsole.MarkupLine("[green]Done[/]"); - _ansiConsole.WriteLine(); + _ansiConsole.MarkupLines("[green]Done[/]", string.Empty); return CommandResult.Success; } private async Task ExportAllDomainsAsync(ExportDomainOptions options) { - _ansiConsole.PrintBlock() - .WriteLine($"Export all domains to '{options.OutputPath}'") - .WriteLine(); + _ansiConsole.WriteLines($"Export all domains to '{options.OutputPath}'", string.Empty); _fileSystem.Directory.EnsureDirectoryExists(options.OutputPath); @@ -77,8 +74,7 @@ await _userDefaultsExporter.ExportDomainAsync(domainName, outputFileName, option _ansiConsole.MarkupLine("[green]Done[/]"); } - _ansiConsole.WriteLine(); - _ansiConsole.WriteLine($"Exported {domainNames.Length} domains to '{options.OutputPath}'"); + _ansiConsole.WriteLines(string.Empty, $"Exported {domainNames.Length} domains to '{options.OutputPath}'"); return new CommandResult(); } diff --git a/source/CreativeCoders.MacSynkker.Cli/Commands/UserDefaults/Domains/ListDomains/ListDomainsCommand.cs b/source/CreativeCoders.MacSynkker.Cli/Commands/UserDefaults/Domains/ListDomains/ListDomainsCommand.cs index b015157..3e72f9f 100644 --- a/source/CreativeCoders.MacSynkker.Cli/Commands/UserDefaults/Domains/ListDomains/ListDomainsCommand.cs +++ b/source/CreativeCoders.MacSynkker.Cli/Commands/UserDefaults/Domains/ListDomains/ListDomainsCommand.cs @@ -1,6 +1,6 @@ using CreativeCoders.Cli.Core; using CreativeCoders.Core; -using CreativeCoders.Core.Collections; +using CreativeCoders.Core.Text; using CreativeCoders.MacOS.UserDefaults; using CreativeCoders.SysConsole.Core; using JetBrains.Annotations; @@ -11,22 +11,25 @@ namespace CreativeCoders.MacSynkker.Cli.Commands.UserDefaults.Domains.ListDomain [UsedImplicitly] [CliCommand([UserDefaultsCommandGroup.Name, UserDefaultsDomainsCommandGroup.Name, "list"], Description = "Lists all domains for user defaults")] -public class ListDomainsCommand(IAnsiConsole ansiConsole, IUserDefaultsEnumerator userDefaultsEnumerator) : ICliCommand +public class ListDomainsCommand(IAnsiConsole ansiConsole, IUserDefaultsEnumerator userDefaultsEnumerator) + : ICliCommand { private readonly IUserDefaultsEnumerator _userDefaultsEnumerator = Ensure.NotNull(userDefaultsEnumerator); private readonly IAnsiConsole _ansiConsole = Ensure.NotNull(ansiConsole); - public async Task ExecuteAsync() + public async Task ExecuteAsync(ListDomainsOptions options) { - _ansiConsole.PrintBlock() - .WriteLine("Show all user defaults domains") - .WriteLine(); + _ansiConsole.WriteLines("Show all user defaults domains", string.Empty); var domains = await _userDefaultsEnumerator.GetDomainNamesAsync().ConfigureAwait(false); - domains.OrderBy(x => x).ForEach(x => - _ansiConsole.WriteLine(x)); + if (!string.IsNullOrWhiteSpace(options.FilterPattern)) + { + domains = domains.Where(x => PatternMatcher.MatchesPattern(x, options.FilterPattern)).ToArray(); + } + + _ansiConsole.WriteLines(domains.OrderBy(x => x).Select(x => $"- {x}").ToArray()); return new CommandResult(); } diff --git a/source/CreativeCoders.MacSynkker.Cli/Commands/UserDefaults/Domains/ListDomains/ListDomainsOptions.cs b/source/CreativeCoders.MacSynkker.Cli/Commands/UserDefaults/Domains/ListDomains/ListDomainsOptions.cs new file mode 100644 index 0000000..a42fcf6 --- /dev/null +++ b/source/CreativeCoders.MacSynkker.Cli/Commands/UserDefaults/Domains/ListDomains/ListDomainsOptions.cs @@ -0,0 +1,11 @@ +using CreativeCoders.SysConsole.Cli.Parsing; +using JetBrains.Annotations; + +namespace CreativeCoders.MacSynkker.Cli.Commands.UserDefaults.Domains.ListDomains; + +[UsedImplicitly] +public class ListDomainsOptions +{ + [OptionParameter('f', "filter", HelpText = "Filter domains by name pattern.")] + public string FilterPattern { get; set; } = string.Empty; +} From ec44c8d07b3c22529020576fde15241039d27e1c Mon Sep 17 00:00:00 2001 From: darthsharp <48331467+darthsharp@users.noreply.github.com> Date: Sun, 15 Feb 2026 13:54:03 +0100 Subject: [PATCH 04/14] Added descriptions to CLI commands for Homebrew and UserDefaults functionality; implemented validation in `BrewUpgradeOptions`. --- .../Commands/HomeBrew/Info/BrewInfoCommand.cs | 2 +- .../HomeBrew/List/BrewListInstalledSoftwareCommand.cs | 2 +- .../Commands/HomeBrew/Upgrade/BrewUpgradeCommand.cs | 2 +- .../Commands/HomeBrew/Upgrade/BrewUpgradeOptions.cs | 8 +++++++- .../Domains/ExportDomain/ExportDomainCommand.cs | 3 ++- .../Domains/ImportDomain/ImportDomainCommand.cs | 3 ++- 6 files changed, 14 insertions(+), 6 deletions(-) diff --git a/source/CreativeCoders.MacSynkker.Cli/Commands/HomeBrew/Info/BrewInfoCommand.cs b/source/CreativeCoders.MacSynkker.Cli/Commands/HomeBrew/Info/BrewInfoCommand.cs index 69f9c1b..fa96fb2 100644 --- a/source/CreativeCoders.MacSynkker.Cli/Commands/HomeBrew/Info/BrewInfoCommand.cs +++ b/source/CreativeCoders.MacSynkker.Cli/Commands/HomeBrew/Info/BrewInfoCommand.cs @@ -7,7 +7,7 @@ namespace CreativeCoders.MacSynkker.Cli.Commands.HomeBrew.Info; [UsedImplicitly] -[CliCommand([HomebrewCommandGroup.Name, "info"])] +[CliCommand([HomebrewCommandGroup.Name, "info"], Description = "Shows Homebrew info")] public class BrewInfoCommand(IAnsiConsole ansiConsole, IBrewInfo brewInfo) : ICliCommand { private readonly IBrewInfo _brewInfo = Ensure.NotNull(brewInfo); diff --git a/source/CreativeCoders.MacSynkker.Cli/Commands/HomeBrew/List/BrewListInstalledSoftwareCommand.cs b/source/CreativeCoders.MacSynkker.Cli/Commands/HomeBrew/List/BrewListInstalledSoftwareCommand.cs index 891962c..d42b1d1 100644 --- a/source/CreativeCoders.MacSynkker.Cli/Commands/HomeBrew/List/BrewListInstalledSoftwareCommand.cs +++ b/source/CreativeCoders.MacSynkker.Cli/Commands/HomeBrew/List/BrewListInstalledSoftwareCommand.cs @@ -10,7 +10,7 @@ namespace CreativeCoders.MacSynkker.Cli.Commands.HomeBrew.List; [UsedImplicitly] -[CliCommand([HomebrewCommandGroup.Name, "list"])] +[CliCommand([HomebrewCommandGroup.Name, "list"], Description = "Shows Homebrew installed software")] public class BrewListInstalledSoftwareCommand(IAnsiConsole ansiConsole, IBrewInstalledSoftware brewInstalledSoftware) : ICliCommand { diff --git a/source/CreativeCoders.MacSynkker.Cli/Commands/HomeBrew/Upgrade/BrewUpgradeCommand.cs b/source/CreativeCoders.MacSynkker.Cli/Commands/HomeBrew/Upgrade/BrewUpgradeCommand.cs index 7ddbe53..c1614ae 100644 --- a/source/CreativeCoders.MacSynkker.Cli/Commands/HomeBrew/Upgrade/BrewUpgradeCommand.cs +++ b/source/CreativeCoders.MacSynkker.Cli/Commands/HomeBrew/Upgrade/BrewUpgradeCommand.cs @@ -7,7 +7,7 @@ namespace CreativeCoders.MacSynkker.Cli.Commands.HomeBrew.Upgrade; [UsedImplicitly] -[CliCommand([HomebrewCommandGroup.Name, "upgrade"])] +[CliCommand([HomebrewCommandGroup.Name, "upgrade"], Description = "Upgrade Homebrew installed software")] public class BrewUpgradeCommand( IBrewUpgrader brewUpgrader, IBrewInstalledSoftware brewInstalledSoftware, diff --git a/source/CreativeCoders.MacSynkker.Cli/Commands/HomeBrew/Upgrade/BrewUpgradeOptions.cs b/source/CreativeCoders.MacSynkker.Cli/Commands/HomeBrew/Upgrade/BrewUpgradeOptions.cs index 333d40b..2cb875b 100644 --- a/source/CreativeCoders.MacSynkker.Cli/Commands/HomeBrew/Upgrade/BrewUpgradeOptions.cs +++ b/source/CreativeCoders.MacSynkker.Cli/Commands/HomeBrew/Upgrade/BrewUpgradeOptions.cs @@ -1,10 +1,11 @@ +using CreativeCoders.Cli.Core; using CreativeCoders.SysConsole.Cli.Parsing; using JetBrains.Annotations; namespace CreativeCoders.MacSynkker.Cli.Commands.HomeBrew.Upgrade; [UsedImplicitly] -public class BrewUpgradeOptions +public class BrewUpgradeOptions : IOptionsValidation { [OptionValue(0)] public string AppName { get; set; } = string.Empty; @@ -16,4 +17,9 @@ public class BrewUpgradeOptions [OptionParameter('h', "haltonerror", HelpText = "Halt on error upgrading an app")] public bool HaltOnError { get; set; } + + public Task ValidateAsync() + { + throw new NotImplementedException(); + } } diff --git a/source/CreativeCoders.MacSynkker.Cli/Commands/UserDefaults/Domains/ExportDomain/ExportDomainCommand.cs b/source/CreativeCoders.MacSynkker.Cli/Commands/UserDefaults/Domains/ExportDomain/ExportDomainCommand.cs index 7d6fae0..a2e0a7c 100644 --- a/source/CreativeCoders.MacSynkker.Cli/Commands/UserDefaults/Domains/ExportDomain/ExportDomainCommand.cs +++ b/source/CreativeCoders.MacSynkker.Cli/Commands/UserDefaults/Domains/ExportDomain/ExportDomainCommand.cs @@ -11,7 +11,8 @@ namespace CreativeCoders.MacSynkker.Cli.Commands.UserDefaults.Domains.ExportDomain; [UsedImplicitly] -[CliCommand([UserDefaultsCommandGroup.Name, UserDefaultsDomainsCommandGroup.Name, "export"])] +[CliCommand([UserDefaultsCommandGroup.Name, UserDefaultsDomainsCommandGroup.Name, "export"], + Description = "Exports a MacOS user defaults domain to a plist file")] public class ExportDomainCommand( IUserDefaultsExporter userDefaultsExporter, IUserDefaultsEnumerator userDefaultsEnumerator, diff --git a/source/CreativeCoders.MacSynkker.Cli/Commands/UserDefaults/Domains/ImportDomain/ImportDomainCommand.cs b/source/CreativeCoders.MacSynkker.Cli/Commands/UserDefaults/Domains/ImportDomain/ImportDomainCommand.cs index 04bb4fc..0b26c8b 100644 --- a/source/CreativeCoders.MacSynkker.Cli/Commands/UserDefaults/Domains/ImportDomain/ImportDomainCommand.cs +++ b/source/CreativeCoders.MacSynkker.Cli/Commands/UserDefaults/Domains/ImportDomain/ImportDomainCommand.cs @@ -8,7 +8,8 @@ namespace CreativeCoders.MacSynkker.Cli.Commands.UserDefaults.Domains.ImportDomain; [UsedImplicitly] -[CliCommand([UserDefaultsCommandGroup.Name, UserDefaultsDomainsCommandGroup.Name, "import"])] +[CliCommand([UserDefaultsCommandGroup.Name, UserDefaultsDomainsCommandGroup.Name, "import"], + Description = "Imports a MacOS user defaults domain from a plist file")] public class ImportDomainCommand( IFileSystem fileSystem, IAnsiConsole ansiConsole, From dc1a270c964ea93340b2a0b07aa1442da381cc80 Mon Sep 17 00:00:00 2001 From: darthsharp <48331467+darthsharp@users.noreply.github.com> Date: Sun, 15 Feb 2026 13:56:30 +0100 Subject: [PATCH 05/14] Enhanced validation in `BrewUpgradeOptions` to enforce mutual exclusivity between `AppName` and `UpgradeOutdated` options; improved help text descriptions. --- .../HomeBrew/Upgrade/BrewUpgradeOptions.cs | 20 ++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/source/CreativeCoders.MacSynkker.Cli/Commands/HomeBrew/Upgrade/BrewUpgradeOptions.cs b/source/CreativeCoders.MacSynkker.Cli/Commands/HomeBrew/Upgrade/BrewUpgradeOptions.cs index 2cb875b..06d61f4 100644 --- a/source/CreativeCoders.MacSynkker.Cli/Commands/HomeBrew/Upgrade/BrewUpgradeOptions.cs +++ b/source/CreativeCoders.MacSynkker.Cli/Commands/HomeBrew/Upgrade/BrewUpgradeOptions.cs @@ -7,9 +7,11 @@ namespace CreativeCoders.MacSynkker.Cli.Commands.HomeBrew.Upgrade; [UsedImplicitly] public class BrewUpgradeOptions : IOptionsValidation { - [OptionValue(0)] public string AppName { get; set; } = string.Empty; + [OptionValue(0, HelpText = "App name to upgrade. If specified, upgrade outdated option is not allowed.")] + public string AppName { get; set; } = string.Empty; - [OptionParameter('o', "outdated", HelpText = "Upgrade all outdated software")] + [OptionParameter('o', "outdated", + HelpText = "Upgrade all outdated software. If specified, app name option is not allowed.")] public bool UpgradeOutdated { get; set; } [OptionParameter('f', "force", HelpText = "Force upgrade of software")] @@ -20,6 +22,18 @@ public class BrewUpgradeOptions : IOptionsValidation public Task ValidateAsync() { - throw new NotImplementedException(); + if (string.IsNullOrWhiteSpace(AppName) && !UpgradeOutdated) + { + return Task.FromResult( + OptionsValidationResult.Invalid(["Either app name or upgrade outdated option must be specified"])); + } + + if (!string.IsNullOrWhiteSpace(AppName) && UpgradeOutdated) + { + return Task.FromResult( + OptionsValidationResult.Invalid(["App name and upgrade outdated option are mutually exclusive"])); + } + + return Task.FromResult(OptionsValidationResult.Valid()); } } From 719bd6ac8509c954e138cff03c06b313f6e63288 Mon Sep 17 00:00:00 2001 From: darthsharp <48331467+darthsharp@users.noreply.github.com> Date: Sun, 15 Feb 2026 14:19:59 +0100 Subject: [PATCH 06/14] Refactored outdated formula detection in `BrewInstalledModelExtensions` and improved version comparison logic; updated `BrewListInstalledSoftwareCommand` output method to use `WriteLines`; added `.UseValidation()` to CLI setup. --- .../BrewInstalledModelExtensions.cs | 12 +++++++++++- .../List/BrewListInstalledSoftwareCommand.cs | 2 +- source/CreativeCoders.MacSynkker.Cli/Program.cs | 1 + 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/source/CreativeCoders.MacOS.HomeBrew/BrewInstalledModelExtensions.cs b/source/CreativeCoders.MacOS.HomeBrew/BrewInstalledModelExtensions.cs index 2fae4a9..bfc2144 100644 --- a/source/CreativeCoders.MacOS.HomeBrew/BrewInstalledModelExtensions.cs +++ b/source/CreativeCoders.MacOS.HomeBrew/BrewInstalledModelExtensions.cs @@ -23,10 +23,20 @@ public static BrewCaskModel[] GetCasks(this BrewInstalledModel installedModel, b public static BrewFormulaModel[] GetOutdatedFormulae(this BrewInstalledModel installedModel) { return installedModel.Formulae - .Where(x => x.Installed?.Any(y => y.Version != x.Versions?.Stable) == true) + .Where(IsFormulaOutdated) .ToArray(); } + private static bool IsFormulaOutdated(BrewFormulaModel formula) + { + return formula.Installed?.Any(y => !FormulaeVersionsAreEqual(y.Version, formula.Versions?.Stable)) == true; + } + + private static bool FormulaeVersionsAreEqual(string? installedVersion, string? availableVersion) + { + return installedVersion == availableVersion || installedVersion?.StartsWith($"{availableVersion}_") == true; + } + public static BrewFormulaModel[] GetFormulae(this BrewInstalledModel installedModel, bool onlyOutdated) { return onlyOutdated diff --git a/source/CreativeCoders.MacSynkker.Cli/Commands/HomeBrew/List/BrewListInstalledSoftwareCommand.cs b/source/CreativeCoders.MacSynkker.Cli/Commands/HomeBrew/List/BrewListInstalledSoftwareCommand.cs index d42b1d1..9620654 100644 --- a/source/CreativeCoders.MacSynkker.Cli/Commands/HomeBrew/List/BrewListInstalledSoftwareCommand.cs +++ b/source/CreativeCoders.MacSynkker.Cli/Commands/HomeBrew/List/BrewListInstalledSoftwareCommand.cs @@ -69,7 +69,7 @@ private void PrintFormulae(BrewFormulaModel[] installedSoftwareFormulae, bool op private void PrintCasks(BrewCaskModel[] installedSoftwareCasks, bool optionsShowAsListView) { - _ansiConsole.WriteLine("Installed HomeBrew casks:", string.Empty); + _ansiConsole.WriteLines("Installed HomeBrew casks:", string.Empty); if (optionsShowAsListView) { diff --git a/source/CreativeCoders.MacSynkker.Cli/Program.cs b/source/CreativeCoders.MacSynkker.Cli/Program.cs index 4dcdf20..5ef990d 100644 --- a/source/CreativeCoders.MacSynkker.Cli/Program.cs +++ b/source/CreativeCoders.MacSynkker.Cli/Program.cs @@ -25,6 +25,7 @@ public static async Task Main(string[] args) x.AddMacOSUserDefaults(true); x.AddHomeBrew(); }) + .UseValidation() .PrintFooterText([""]) .EnableHelp(HelpCommandKind.CommandOrArgument, HelpCommandKind.EmptyArgs) .Build() From e23466dd00094779b503b561b3785ba2c60aca9e Mon Sep 17 00:00:00 2001 From: darthsharp <48331467+darthsharp@users.noreply.github.com> Date: Sun, 15 Feb 2026 15:34:00 +0100 Subject: [PATCH 07/14] Added build system integration using CreativeCoders.CakeBuild, implemented CI/CD workflows for GitHub Actions, and restructured project to include detailed C# development guidelines and a unified build context. --- .../{ => instructions}/csharp.instructions.md | 0 .github/workflows/integration.yml | 28 +++++ .github/workflows/main.yml | 28 +++++ .github/workflows/pull-request.yml | 28 +++++ .github/workflows/release.yml | 34 ++++++ build/Build.csproj | 14 +++ build/BuildContext.cs | 103 ++++++++++++++++++ build/Program.cs | 19 ++++ macSynkker.sln | 25 ++++- 9 files changed, 276 insertions(+), 3 deletions(-) rename .github/{ => instructions}/csharp.instructions.md (100%) create mode 100644 .github/workflows/integration.yml create mode 100644 .github/workflows/main.yml create mode 100644 .github/workflows/pull-request.yml create mode 100644 .github/workflows/release.yml create mode 100644 build/Build.csproj create mode 100644 build/BuildContext.cs create mode 100644 build/Program.cs diff --git a/.github/csharp.instructions.md b/.github/instructions/csharp.instructions.md similarity index 100% rename from .github/csharp.instructions.md rename to .github/instructions/csharp.instructions.md diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml new file mode 100644 index 0000000..5c3b9b3 --- /dev/null +++ b/.github/workflows/integration.yml @@ -0,0 +1,28 @@ +name: integration + +on: + push: + branches: + - 'feature/**' + +jobs: + macos-latest: + name: macos-latest + runs-on: macos-latest + steps: + - uses: actions/checkout@v5 + with: + fetch-depth: 0 + - name: 'Cache: ~/.nuget/packages' + uses: actions/cache@v4 + with: + path: | + ~/.nuget/packages + key: ${{ runner.os }}-${{ hashFiles('**/global.json', '**/*.csproj', '**/Directory.Packages.props') }} + - name: 'Build with target: NuGetPush, Publish, CreateDistPackages' + run: ./build.cmd -t nugetpush -t publish -t createdistpackages + - name: 'Publish: coverage_report' + uses: actions/upload-artifact@v4 + with: + name: coverage-report-macos + path: .tests/coverage-report diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 0000000..5d7bd92 --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,28 @@ +name: main + +on: + push: + branches: + - main + +jobs: + macos-latest: + name: macos-latest + runs-on: macos-latest + steps: + - uses: actions/checkout@v5 + with: + fetch-depth: 0 + - name: 'Cache: ~/.nuget/packages' + uses: actions/cache@v4 + with: + path: | + ~/.nuget/packages + key: ${{ runner.os }}-${{ hashFiles('**/global.json', '**/*.csproj', '**/Directory.Packages.props') }} + - name: 'Build with target: NuGetPush, Publish, CreateDistPackages, CreateGitHubRelease' + run: ./build.cmd -t nugetpush -t publish -t createdistpackages -t creategithubrelease + - name: 'Publish: coverage_report' + uses: actions/upload-artifact@v4 + with: + name: coverage-report + path: .tests/coverage-report diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml new file mode 100644 index 0000000..96dcf1a --- /dev/null +++ b/.github/workflows/pull-request.yml @@ -0,0 +1,28 @@ +name: pull-request + +on: + pull_request: + branches: + - main + +jobs: + macos-latest: + name: macos-latest + runs-on: macos-latest + steps: + - uses: actions/checkout@v5 + with: + fetch-depth: 0 + - name: 'Cache: ~/.nuget/packages' + uses: actions/cache@v4 + with: + path: | + ~/.nuget/packages + key: ${{ runner.os }}-${{ hashFiles('**/global.json', '**/*.csproj', '**/Directory.Packages.props') }} + - name: 'Build with target: Pack' + run: ./build.cmd -t pack + - name: 'Publish: coverage_report' + uses: actions/upload-artifact@v4 + with: + name: coverage-report + path: .tests/coverage-report diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..281bd3a --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,34 @@ +name: release + +concurrency: + group: release-${{ github.ref }} + cancel-in-progress: false + +on: + push: + tags: + - 'v**' + +jobs: + macos-latest: + name: macos-latest + runs-on: macos-latest + steps: + - uses: actions/checkout@v5 + with: + fetch-depth: 0 + - name: 'Cache: ~/.nuget/packages' + uses: actions/cache@v4 + with: + path: | + ~/.nuget/packages + key: ${{ runner.os }}-${{ hashFiles('**/global.json', '**/*.csproj', '**/Directory.Packages.props') }} + - name: 'Build with target: NuGetPush, Publish, CreateDistPackages, CreateGitHubRelease' + run: ./build.cmd -t nugetpush -t publish -t createdistpackages -t creategithubrelease + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - name: 'Publish: coverage_report' + uses: actions/upload-artifact@v4 + with: + name: coverage-report + path: .tests/coverage-report diff --git a/build/Build.csproj b/build/Build.csproj new file mode 100644 index 0000000..caf68a7 --- /dev/null +++ b/build/Build.csproj @@ -0,0 +1,14 @@ + + + + Exe + net10.0 + enable + enable + + + + + + + diff --git a/build/BuildContext.cs b/build/BuildContext.cs new file mode 100644 index 0000000..05351cf --- /dev/null +++ b/build/BuildContext.cs @@ -0,0 +1,103 @@ +using Cake.Common.Build; +using Cake.Core; +using Cake.Core.IO; +using CreativeCoders.CakeBuild; +using CreativeCoders.CakeBuild.Tasks.Defaults; +using CreativeCoders.CakeBuild.Tasks.Templates.Settings; +using CreativeCoders.Core; +using CreativeCoders.Core.Collections; +using CreativeCoders.Core.IO; +using JetBrains.Annotations; + +namespace Build; + +[UsedImplicitly] +public class BuildContext(ICakeContext context) + : CakeBuildContext(context), IDefaultTaskSettings, ICreateDistPackagesTaskSettings, ICreateGitHubReleaseTaskSettings +{ + public IList DirectoriesToClean => this.CastAs() + .GetDefaultDirectoriesToClean().AddRange(RootDir.Combine(".tests")); + + + public string Copyright => $"{DateTime.Now.Year} CreativeCoders"; + + public string PackageProjectUrl => "https://github.com/CreativeCodersTeam/macsynkker"; + + public string PackageLicenseExpression => PackageLicenseExpressions.ApacheLicense20; + + public string NuGetFeedUrl => this.GitHubActions().Environment.Workflow.Workflow == "release" + ? "nuget.org" + : "https://nuget.pkg.github.com/CreativeCodersTeam/index.json"; + + public bool SkipPush => this.BuildSystem().IsPullRequest || + this.BuildSystem().IsLocalBuild || + this.GitHubActions().Environment.Runner.OS != "Linux"; + + public DirectoryPath PublishOutputDir => ArtifactsDir.Combine("published"); + + private const string CliPath = "source/CreativeCoders.MacSynkker.Cli"; + + private const string CliProjectFile = "CreativeCoders.MacSynkker.Cli.csproj"; + + public IEnumerable PublishingItems => + [ + new PublishingItem( + RootDir + .Combine(CliPath) + .CombineWithFilePath(CliProjectFile), + PublishOutputDir.Combine("cli")), + new PublishingItem( + RootDir + .Combine(CliPath) + .CombineWithFilePath(CliProjectFile), + PublishOutputDir.Combine("cli-win64")) + { + Runtime = "win-x64", + SelfContained = true + }, + new PublishingItem( + RootDir + .Combine(CliPath) + .CombineWithFilePath(CliProjectFile), + PublishOutputDir.Combine("cli-win64-no-selfcontained")) + { + Runtime = "win-x64", + SelfContained = false + }, + new PublishingItem( + RootDir + .Combine(CliPath) + .CombineWithFilePath(CliProjectFile), + PublishOutputDir.Combine("cli-win-arm64")) + { + Runtime = "win-arm64", + SelfContained = true + } + ]; + + private const string DistPackageName = "GitTool.Cli"; + + public IEnumerable DistPackages => + [ + new DistPackage(DistPackageName, PublishOutputDir.Combine("cli")) + ]; + + public string ReleaseName => $"v{Version.FullSemVer}"; + + public string ReleaseVersion => $"v{Version.FullSemVer}"; + + public string ReleaseBody => "GitTools Release"; + + public bool IsPreRelease => !string.IsNullOrWhiteSpace(Version.PreReleaseTag); + + private DirectoryPath SetupOutputDir => ArtifactsDir.Combine("setups"); + + public IEnumerable ReleaseAssets => + [ + new GitHubReleaseFileAsset( + FileSys.Directory.EnumerateFiles(SetupOutputDir.FullPath, "*.exe").First(), null), + new GitHubReleaseFileAsset( + GetRequiredSettings().DistOutputPath + .CombineWithFilePath(DistPackageName + ".tar.gz").FullPath, null) + ]; +} diff --git a/build/Program.cs b/build/Program.cs new file mode 100644 index 0000000..34637f1 --- /dev/null +++ b/build/Program.cs @@ -0,0 +1,19 @@ +using CreativeCoders.CakeBuild; + +namespace Build; + +internal static class Program +{ + internal static int Main(string[] args) + { + return CakeHostBuilder.Create() + .UseBuildContext() + .AddDefaultTasks() + .AddBuildServerIntegration() + .InstallTools( + new DotNetToolInstallation("GitVersion.Tool", "6.5.1"), + new DotNetToolInstallation("dotnet-reportgenerator-globaltool", "5.5.1")) + .Build() + .Run(args); + } +} diff --git a/macSynkker.sln b/macSynkker.sln index aca851f..e4a8260 100644 --- a/macSynkker.sln +++ b/macSynkker.sln @@ -26,9 +26,6 @@ EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CreativeCoders.MacSynkker.Cli", "source\CreativeCoders.MacSynkker.Cli\CreativeCoders.MacSynkker.Cli.csproj", "{4B29C32B-9BAF-471E-B83A-D7F5735F27B8}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "copilot", "copilot", "{083C21F2-8C37-4E30-9CA8-82AAD4F77DD9}" - ProjectSection(SolutionItems) = preProject - .github\csharp.instructions.md = .github\csharp.instructions.md - EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "junie", "junie", "{16659358-8B04-4FAD-80A0-467982B00A9D}" ProjectSection(SolutionItems) = preProject @@ -47,6 +44,23 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SampleConsoleApp", "samples EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CreativeCoders.MacOS.UserDefaults.Tests", "tests\CreativeCoders.MacOS.UserDefaults.Tests\CreativeCoders.MacOS.UserDefaults.Tests.csproj", "{BF53FB30-8068-426D-BC06-B692E45CE94D}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{9A2D709F-395D-4373-9B73-FDAE4E606B64}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Build", "build\Build.csproj", "{5D00B0B9-E9B4-423C-AFCF-0F7CB21B2A78}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ci", "ci", "{076341D1-E2B7-47A8-AB79-78BFD7DBA646}" + ProjectSection(SolutionItems) = preProject + .github\workflows\main.yml = .github\workflows\main.yml + .github\workflows\pull-request.yml = .github\workflows\pull-request.yml + .github\workflows\integration.yml = .github\workflows\integration.yml + .github\workflows\release.yml = .github\workflows\release.yml + EndProjectSection +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "instructions", "instructions", "{3CAC9757-F7D3-4A37-9820-B8755EF7FF3F}" + ProjectSection(SolutionItems) = preProject + .github\instructions\csharp.instructions.md = .github\instructions\csharp.instructions.md + EndProjectSection +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -63,6 +77,9 @@ Global {6C7AB20D-847C-48A0-92EF-C45C621E11F0} = {A9CE4FEF-F010-408C-9B5E-F00DC960A792} {75784FD0-11AA-4DB2-95AE-92DA3C3B793D} = {215614E0-F85F-460E-BCAA-13368AE1E3BD} {BF53FB30-8068-426D-BC06-B692E45CE94D} = {D3F213BB-A6EC-4DDA-9C43-59094DF2FD09} + {5D00B0B9-E9B4-423C-AFCF-0F7CB21B2A78} = {9A2D709F-395D-4373-9B73-FDAE4E606B64} + {076341D1-E2B7-47A8-AB79-78BFD7DBA646} = {BF2B8E40-4D03-41A1-8ABD-7AD1A33D5B53} + {3CAC9757-F7D3-4A37-9820-B8755EF7FF3F} = {083C21F2-8C37-4E30-9CA8-82AAD4F77DD9} EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {4B29C32B-9BAF-471E-B83A-D7F5735F27B8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU @@ -89,5 +106,7 @@ Global {BF53FB30-8068-426D-BC06-B692E45CE94D}.Debug|Any CPU.Build.0 = Debug|Any CPU {BF53FB30-8068-426D-BC06-B692E45CE94D}.Release|Any CPU.ActiveCfg = Release|Any CPU {BF53FB30-8068-426D-BC06-B692E45CE94D}.Release|Any CPU.Build.0 = Release|Any CPU + {5D00B0B9-E9B4-423C-AFCF-0F7CB21B2A78}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5D00B0B9-E9B4-423C-AFCF-0F7CB21B2A78}.Release|Any CPU.ActiveCfg = Release|Any CPU EndGlobalSection EndGlobal From cae628daecd62cb23a0194253f5a168416419fe7 Mon Sep 17 00:00:00 2001 From: darthsharp <48331467+darthsharp@users.noreply.github.com> Date: Sun, 15 Feb 2026 15:38:22 +0100 Subject: [PATCH 08/14] Added cross-platform build scripts (`build.cmd`, `build.sh`, `build.ps1`) and `GitVersion.yml` configuration; integrated them into the solution for streamlined builds and versioning. Updated `BuildContext` to simplify publishing targets. --- GitVersion.yml | 55 +++++++++++++++++++++++++++++++++++++++++++ build.cmd | 7 ++++++ build.ps1 | 45 +++++++++++++++++++++++++++++++++++ build.sh | 33 ++++++++++++++++++++++++++ build/BuildContext.cs | 40 ++++--------------------------- macSynkker.sln | 9 +++++++ 6 files changed, 153 insertions(+), 36 deletions(-) create mode 100644 GitVersion.yml create mode 100755 build.cmd create mode 100644 build.ps1 create mode 100755 build.sh diff --git a/GitVersion.yml b/GitVersion.yml new file mode 100644 index 0000000..acef5c9 --- /dev/null +++ b/GitVersion.yml @@ -0,0 +1,55 @@ +assembly-versioning-scheme: MajorMinorPatch +assembly-file-versioning-scheme: MajorMinorPatchTag +tag-prefix: '^v?' +semantic-version-format: Loose +major-version-bump-message: '\+semver:\s?(breaking|major)' +minor-version-bump-message: '\+semver:\s?(feature|minor)' +patch-version-bump-message: '\+semver:\s?(fix|patch)' +no-bump-message: '\+semver:\s?(none|skip)' +mode: ContinuousDeployment +branches: + feature: + mode: ContinuousDelivery + label: feature.{BranchName} + increment: Minor + track-merge-target: false + regex: ^features?[\/-](?.+) + prevent-increment: + when-current-commit-tagged: false + source-branches: + - main + tracks-release-branches: false + is-release-branch: false + is-main-branch: false + pre-release-weight: 30000 + main: + mode: ContinuousDelivery + label: 'ci' + increment: Patch + track-merge-target: false + regex: ^master$|^main$ + prevent-increment: + when-current-commit-tagged: true + source-branches: + - develop + - release + tracks-release-branches: false + is-release-branch: false + pre-release-weight: 55000 + pull-request: + mode: ContinuousDelivery + label: PR-{PullRequestName} + increment: Inherit + track-merge-target: false + regex: ^(pull|pull\-requests|pr)[/-](?.+) + prevent-increment: + when-current-commit-tagged: false + source-branches: + - main + - feature + tracks-release-branches: false + is-release-branch: false + pre-release-weight: 30000 +ignore: + sha: [ ] +merge-message-formats: { } diff --git a/build.cmd b/build.cmd new file mode 100755 index 0000000..b08cc59 --- /dev/null +++ b/build.cmd @@ -0,0 +1,7 @@ +:; set -eo pipefail +:; SCRIPT_DIR=$(cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd) +:; ${SCRIPT_DIR}/build.sh "$@" +:; exit $? + +@ECHO OFF +powershell -ExecutionPolicy ByPass -NoProfile -File "%~dp0build.ps1" %* diff --git a/build.ps1 b/build.ps1 new file mode 100644 index 0000000..1b91f63 --- /dev/null +++ b/build.ps1 @@ -0,0 +1,45 @@ +[CmdletBinding()] +Param( + [Parameter(Position=0,Mandatory=$false,ValueFromRemainingArguments=$true)] + [string[]]$BuildArguments +) + +Write-Output "PowerShell $($PSVersionTable.PSEdition) version $($PSVersionTable.PSVersion)" + +Set-StrictMode -Version 2.0; $ErrorActionPreference = "Stop"; $ConfirmPreference = "None"; trap { Write-Error $_ -ErrorAction Continue; exit 1 } +$PSScriptRoot = Split-Path $MyInvocation.MyCommand.Path -Parent + +########################################################################### +# CONFIGURATION +########################################################################### + +$BuildProjectFile = "$PSScriptRoot\build\Build.csproj" +$DotNetGlobalFile = "$PSScriptRoot\\global.json" + +$env:DOTNET_CLI_TELEMETRY_OPTOUT = 1 +$env:DOTNET_NOLOGO = 1 + +########################################################################### +# EXECUTION +########################################################################### + +function ExecSafe([scriptblock] $cmd) { + & $cmd + if ($LASTEXITCODE) { exit $LASTEXITCODE } +} + +# If dotnet CLI is installed globally and it matches requested version, use for execution +if ($null -ne (Get-Command "dotnet" -ErrorAction SilentlyContinue) -and ` + $(dotnet --version) -and $LASTEXITCODE -eq 0) { + $env:DOTNET_EXE = (Get-Command "dotnet").Path +} +else { + Write-Host "No matching dotnet version found" + + exit 1 +} + +Write-Output "Microsoft (R) .NET SDK version $(& $env:DOTNET_EXE --version)" + +ExecSafe { & $env:DOTNET_EXE build $BuildProjectFile /nodeReuse:false /p:UseSharedCompilation=false -nologo -clp:NoSummary --verbosity quiet } +ExecSafe { & $env:DOTNET_EXE run --project $BuildProjectFile --no-build -- $BuildArguments } diff --git a/build.sh b/build.sh new file mode 100755 index 0000000..35eaaba --- /dev/null +++ b/build.sh @@ -0,0 +1,33 @@ +#!/usr/bin/env bash + +bash --version 2>&1 | head -n 1 + +set -e +SCRIPT_DIR=$(cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd) + +########################################################################### +# CONFIGURATION +########################################################################### + +BUILD_PROJECT_FILE="$SCRIPT_DIR/build/Build.csproj" +DOTNET_GLOBAL_FILE="$SCRIPT_DIR//global.json" + +export DOTNET_CLI_TELEMETRY_OPTOUT=1 +export DOTNET_NOLOGO=1 + +########################################################################### +# EXECUTION +########################################################################### + +# If dotnet CLI is installed globally and it matches requested version, use for execution +if [ -x "$(command -v dotnet)" ] && dotnet --version &>/dev/null; then + export DOTNET_EXE="$(command -v dotnet)" +else + echo "No matching dotnet version found" + exit 1 +fi + +echo "Microsoft (R) .NET SDK version $("$DOTNET_EXE" --version)" + +"$DOTNET_EXE" build "$BUILD_PROJECT_FILE" /nodeReuse:false /p:UseSharedCompilation=false -nologo -clp:NoSummary --verbosity quiet +"$DOTNET_EXE" run --project "$BUILD_PROJECT_FILE" --no-build -- "$@" diff --git a/build/BuildContext.cs b/build/BuildContext.cs index 05351cf..af1ac2c 100644 --- a/build/BuildContext.cs +++ b/build/BuildContext.cs @@ -30,8 +30,7 @@ public class BuildContext(ICakeContext context) : "https://nuget.pkg.github.com/CreativeCodersTeam/index.json"; public bool SkipPush => this.BuildSystem().IsPullRequest || - this.BuildSystem().IsLocalBuild || - this.GitHubActions().Environment.Runner.OS != "Linux"; + this.BuildSystem().IsLocalBuild; public DirectoryPath PublishOutputDir => ArtifactsDir.Combine("published"); @@ -45,37 +44,10 @@ public class BuildContext(ICakeContext context) RootDir .Combine(CliPath) .CombineWithFilePath(CliProjectFile), - PublishOutputDir.Combine("cli")), - new PublishingItem( - RootDir - .Combine(CliPath) - .CombineWithFilePath(CliProjectFile), - PublishOutputDir.Combine("cli-win64")) - { - Runtime = "win-x64", - SelfContained = true - }, - new PublishingItem( - RootDir - .Combine(CliPath) - .CombineWithFilePath(CliProjectFile), - PublishOutputDir.Combine("cli-win64-no-selfcontained")) - { - Runtime = "win-x64", - SelfContained = false - }, - new PublishingItem( - RootDir - .Combine(CliPath) - .CombineWithFilePath(CliProjectFile), - PublishOutputDir.Combine("cli-win-arm64")) - { - Runtime = "win-arm64", - SelfContained = true - } + PublishOutputDir.Combine("cli")) ]; - private const string DistPackageName = "GitTool.Cli"; + private const string DistPackageName = "MacSynkker.Cli"; public IEnumerable DistPackages => [ @@ -86,16 +58,12 @@ public class BuildContext(ICakeContext context) public string ReleaseVersion => $"v{Version.FullSemVer}"; - public string ReleaseBody => "GitTools Release"; + public string ReleaseBody => "MacSynkker Release"; public bool IsPreRelease => !string.IsNullOrWhiteSpace(Version.PreReleaseTag); - private DirectoryPath SetupOutputDir => ArtifactsDir.Combine("setups"); - public IEnumerable ReleaseAssets => [ - new GitHubReleaseFileAsset( - FileSys.Directory.EnumerateFiles(SetupOutputDir.FullPath, "*.exe").First(), null), new GitHubReleaseFileAsset( GetRequiredSettings().DistOutputPath .CombineWithFilePath(DistPackageName + ".tar.gz").FullPath, null) diff --git a/macSynkker.sln b/macSynkker.sln index e4a8260..9f1c428 100644 --- a/macSynkker.sln +++ b/macSynkker.sln @@ -17,6 +17,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "__global", "__global", "{BF global.json = global.json LICENSE = LICENSE README.md = README.md + GitVersion.yml = GitVersion.yml EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "apps", "apps", "{C033DF64-285B-4C44-AFFC-400878C92C73}" @@ -61,6 +62,13 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "instructions", "instruction .github\instructions\csharp.instructions.md = .github\instructions\csharp.instructions.md EndProjectSection EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{1A70000D-DAC9-4D34-9306-7914CC837B05}" + ProjectSection(SolutionItems) = preProject + build.sh = build.sh + build.ps1 = build.ps1 + build.cmd = build.cmd + EndProjectSection +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -80,6 +88,7 @@ Global {5D00B0B9-E9B4-423C-AFCF-0F7CB21B2A78} = {9A2D709F-395D-4373-9B73-FDAE4E606B64} {076341D1-E2B7-47A8-AB79-78BFD7DBA646} = {BF2B8E40-4D03-41A1-8ABD-7AD1A33D5B53} {3CAC9757-F7D3-4A37-9820-B8755EF7FF3F} = {083C21F2-8C37-4E30-9CA8-82AAD4F77DD9} + {1A70000D-DAC9-4D34-9306-7914CC837B05} = {BF2B8E40-4D03-41A1-8ABD-7AD1A33D5B53} EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {4B29C32B-9BAF-471E-B83A-D7F5735F27B8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU From ca329303df9b6e2c909202e6cd6331d27fd1ca2a Mon Sep 17 00:00:00 2001 From: darthsharp <48331467+darthsharp@users.noreply.github.com> Date: Sun, 15 Feb 2026 15:41:16 +0100 Subject: [PATCH 09/14] Updated GitHub Actions workflow environment variables for NuGet publishing. - Replaced `GITHUB_TOKEN` with `NUGET_ORG_TOKEN` in `release.yml`. - Added `NUGET_TOKEN` to `main.yml` and `integration.yml`. --- .github/workflows/integration.yml | 2 ++ .github/workflows/main.yml | 2 ++ .github/workflows/release.yml | 2 +- 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml index 5c3b9b3..e61a366 100644 --- a/.github/workflows/integration.yml +++ b/.github/workflows/integration.yml @@ -20,6 +20,8 @@ jobs: ~/.nuget/packages key: ${{ runner.os }}-${{ hashFiles('**/global.json', '**/*.csproj', '**/Directory.Packages.props') }} - name: 'Build with target: NuGetPush, Publish, CreateDistPackages' + env: + NUGET_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: ./build.cmd -t nugetpush -t publish -t createdistpackages - name: 'Publish: coverage_report' uses: actions/upload-artifact@v4 diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 5d7bd92..256f29d 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -20,6 +20,8 @@ jobs: ~/.nuget/packages key: ${{ runner.os }}-${{ hashFiles('**/global.json', '**/*.csproj', '**/Directory.Packages.props') }} - name: 'Build with target: NuGetPush, Publish, CreateDistPackages, CreateGitHubRelease' + env: + NUGET_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: ./build.cmd -t nugetpush -t publish -t createdistpackages -t creategithubrelease - name: 'Publish: coverage_report' uses: actions/upload-artifact@v4 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 281bd3a..6d1ca0e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -26,7 +26,7 @@ jobs: - name: 'Build with target: NuGetPush, Publish, CreateDistPackages, CreateGitHubRelease' run: ./build.cmd -t nugetpush -t publish -t createdistpackages -t creategithubrelease env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + NUGET_TOKEN: ${{ secrets.NUGET_ORG_TOKEN }} - name: 'Publish: coverage_report' uses: actions/upload-artifact@v4 with: From d104c91b6e0413345e470c78657a2eb7fa5ddc5b Mon Sep 17 00:00:00 2001 From: darthsharp <48331467+darthsharp@users.noreply.github.com> Date: Sun, 15 Feb 2026 15:46:04 +0100 Subject: [PATCH 10/14] Added `Directory.Build.props` to `samples` and `tests` for shared project settings; updated solution file for new build configuration. Removed redundant `TargetFramework` entries from individual project files. --- macSynkker.sln | 6 ++++++ samples/Directory.Build.props | 8 ++++++++ samples/SampleConsoleApp/SampleConsoleApp.csproj | 1 - .../CreativeCoders.MacOS.UserDefaults.Tests.csproj | 1 - tests/Directory.Build.props | 8 ++++++++ 5 files changed, 22 insertions(+), 2 deletions(-) create mode 100644 samples/Directory.Build.props create mode 100644 tests/Directory.Build.props diff --git a/macSynkker.sln b/macSynkker.sln index 9f1c428..795fadb 100644 --- a/macSynkker.sln +++ b/macSynkker.sln @@ -1,6 +1,9 @@  Microsoft Visual Studio Solution File, Format Version 12.00 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{D3F213BB-A6EC-4DDA-9C43-59094DF2FD09}" + ProjectSection(SolutionItems) = preProject + tests\Directory.Build.props = tests\Directory.Build.props + EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "source", "source", "{A9CE4FEF-F010-408C-9B5E-F00DC960A792}" ProjectSection(SolutionItems) = preProject @@ -40,6 +43,9 @@ EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CreativeCoders.MacOS.Core", "source\CreativeCoders.MacOS.Core\CreativeCoders.MacOS.Core.csproj", "{6C7AB20D-847C-48A0-92EF-C45C621E11F0}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{215614E0-F85F-460E-BCAA-13368AE1E3BD}" + ProjectSection(SolutionItems) = preProject + samples\Directory.Build.props = samples\Directory.Build.props + EndProjectSection EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SampleConsoleApp", "samples\SampleConsoleApp\SampleConsoleApp.csproj", "{75784FD0-11AA-4DB2-95AE-92DA3C3B793D}" EndProject diff --git a/samples/Directory.Build.props b/samples/Directory.Build.props new file mode 100644 index 0000000..df8fb07 --- /dev/null +++ b/samples/Directory.Build.props @@ -0,0 +1,8 @@ + + + net10.0 + CreativeCoders + False + $(NoWarn);IDE0079 + + \ No newline at end of file diff --git a/samples/SampleConsoleApp/SampleConsoleApp.csproj b/samples/SampleConsoleApp/SampleConsoleApp.csproj index 8d8ebbf..ca4755a 100644 --- a/samples/SampleConsoleApp/SampleConsoleApp.csproj +++ b/samples/SampleConsoleApp/SampleConsoleApp.csproj @@ -2,7 +2,6 @@ Exe - net10.0 enable enable diff --git a/tests/CreativeCoders.MacOS.UserDefaults.Tests/CreativeCoders.MacOS.UserDefaults.Tests.csproj b/tests/CreativeCoders.MacOS.UserDefaults.Tests/CreativeCoders.MacOS.UserDefaults.Tests.csproj index d59a34a..e02dfbc 100644 --- a/tests/CreativeCoders.MacOS.UserDefaults.Tests/CreativeCoders.MacOS.UserDefaults.Tests.csproj +++ b/tests/CreativeCoders.MacOS.UserDefaults.Tests/CreativeCoders.MacOS.UserDefaults.Tests.csproj @@ -1,7 +1,6 @@  - net10.0 enable enable diff --git a/tests/Directory.Build.props b/tests/Directory.Build.props new file mode 100644 index 0000000..df8fb07 --- /dev/null +++ b/tests/Directory.Build.props @@ -0,0 +1,8 @@ + + + net10.0 + CreativeCoders + False + $(NoWarn);IDE0079 + + \ No newline at end of file From db536a08b42ff682055ad5781b28b80c553f14f7 Mon Sep 17 00:00:00 2001 From: darthsharp <48331467+darthsharp@users.noreply.github.com> Date: Sun, 15 Feb 2026 15:48:51 +0100 Subject: [PATCH 11/14] Added `Publish: cli dist package` step to GitHub Actions workflows for artifact upload. --- .github/workflows/integration.yml | 5 +++++ .github/workflows/main.yml | 5 +++++ .github/workflows/release.yml | 5 +++++ 3 files changed, 15 insertions(+) diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml index e61a366..52d090d 100644 --- a/.github/workflows/integration.yml +++ b/.github/workflows/integration.yml @@ -28,3 +28,8 @@ jobs: with: name: coverage-report-macos path: .tests/coverage-report + - name: 'Publish: cli dist package' + uses: actions/upload-artifact@v4 + with: + name: MacSynkker.Cli + path: .artifacts/dist/MacSynkker.Cli.tar.gz diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 256f29d..5b207ce 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -28,3 +28,8 @@ jobs: with: name: coverage-report path: .tests/coverage-report + - name: 'Publish: cli dist package' + uses: actions/upload-artifact@v4 + with: + name: MacSynkker.Cli + path: .artifacts/dist/MacSynkker.Cli.tar.gz diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 6d1ca0e..4d8c090 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -32,3 +32,8 @@ jobs: with: name: coverage-report path: .tests/coverage-report + - name: 'Publish: cli dist package' + uses: actions/upload-artifact@v4 + with: + name: MacSynkker.Cli + path: .artifacts/dist/MacSynkker.Cli.tar.gz From d3654607cf6314db3be7708d998dc53b640c9671 Mon Sep 17 00:00:00 2001 From: darthsharp <48331467+darthsharp@users.noreply.github.com> Date: Sun, 15 Feb 2026 19:07:19 +0100 Subject: [PATCH 12/14] Updated dependencies across projects and refactored `BrewUpgradeCommand` to improve dotnet-specific software handling. --- .../SampleConsoleApp/SampleConsoleApp.csproj | 6 +++--- .../CreativeCoders.MacOS.Core.csproj | 4 ++-- .../CreativeCoders.MacOS.HomeBrew.csproj | 4 ++-- .../CreativeCoders.MacOS.UserDefaults.csproj | 6 +++--- .../Commands/HomeBrew/BrewUpgradeCommand.cs | 19 +++++++++++++++++-- .../CreativeCoders.MacSynkker.Cli.csproj | 4 ++-- ...tiveCoders.MacOS.UserDefaults.Tests.csproj | 6 +++--- 7 files changed, 32 insertions(+), 17 deletions(-) diff --git a/samples/SampleConsoleApp/SampleConsoleApp.csproj b/samples/SampleConsoleApp/SampleConsoleApp.csproj index 19b7bd3..8d8ebbf 100644 --- a/samples/SampleConsoleApp/SampleConsoleApp.csproj +++ b/samples/SampleConsoleApp/SampleConsoleApp.csproj @@ -8,12 +8,12 @@ - - + + - + diff --git a/source/CreativeCoders.MacOS.Core/CreativeCoders.MacOS.Core.csproj b/source/CreativeCoders.MacOS.Core/CreativeCoders.MacOS.Core.csproj index 3d426e1..3a9485d 100644 --- a/source/CreativeCoders.MacOS.Core/CreativeCoders.MacOS.Core.csproj +++ b/source/CreativeCoders.MacOS.Core/CreativeCoders.MacOS.Core.csproj @@ -7,8 +7,8 @@ - - + + diff --git a/source/CreativeCoders.MacOS.HomeBrew/CreativeCoders.MacOS.HomeBrew.csproj b/source/CreativeCoders.MacOS.HomeBrew/CreativeCoders.MacOS.HomeBrew.csproj index afbd525..7caf0f1 100644 --- a/source/CreativeCoders.MacOS.HomeBrew/CreativeCoders.MacOS.HomeBrew.csproj +++ b/source/CreativeCoders.MacOS.HomeBrew/CreativeCoders.MacOS.HomeBrew.csproj @@ -11,8 +11,8 @@ - - + + diff --git a/source/CreativeCoders.MacOS.UserDefaults/CreativeCoders.MacOS.UserDefaults.csproj b/source/CreativeCoders.MacOS.UserDefaults/CreativeCoders.MacOS.UserDefaults.csproj index 1bd42c7..84a82a2 100644 --- a/source/CreativeCoders.MacOS.UserDefaults/CreativeCoders.MacOS.UserDefaults.csproj +++ b/source/CreativeCoders.MacOS.UserDefaults/CreativeCoders.MacOS.UserDefaults.csproj @@ -7,9 +7,9 @@ - - - + + + diff --git a/source/CreativeCoders.MacSynkker.Cli/Commands/HomeBrew/BrewUpgradeCommand.cs b/source/CreativeCoders.MacSynkker.Cli/Commands/HomeBrew/BrewUpgradeCommand.cs index f30966c..9005a5f 100644 --- a/source/CreativeCoders.MacSynkker.Cli/Commands/HomeBrew/BrewUpgradeCommand.cs +++ b/source/CreativeCoders.MacSynkker.Cli/Commands/HomeBrew/BrewUpgradeCommand.cs @@ -1,6 +1,7 @@ using CreativeCoders.Cli.Core; using CreativeCoders.Core; using CreativeCoders.MacOS.HomeBrew; +using CreativeCoders.SysConsole.Core; using JetBrains.Annotations; using Spectre.Console; @@ -26,7 +27,7 @@ public async Task ExecuteAsync(BrewUpgradeOptions options) if (!string.IsNullOrWhiteSpace(options.AppName)) { - await _brewUpgrader.UpgradeSoftwareAsync(options.AppName).ConfigureAwait(false); + await UpgradeSoftwareCoreAsync(options.AppName).ConfigureAwait(false); } else if (options.UpgradeOutdated) { @@ -36,6 +37,20 @@ public async Task ExecuteAsync(BrewUpgradeOptions options) return CommandResult.Success; } + private Task UpgradeSoftwareCoreAsync(string appName) + { + if (!appName.StartsWith("dotnet-", StringComparison.OrdinalIgnoreCase)) + { + return _brewUpgrader.UpgradeSoftwareAsync(appName); + } + + _ansiConsole.MarkupLine( + "Skipping upgrade of a dotnet part cause its possible, that its needed by this app" + .ToWarningMarkup()); + + return Task.CompletedTask; + } + private async Task UpgradeAllOutdatedAsync(BrewUpgradeOptions options) { var installedSoftware = await _brewInstalledSoftware.GetInstalledSoftwareAsync().ConfigureAwait(false); @@ -77,7 +92,7 @@ private async Task UpgradeSoftwareAsync(string appName, bool cask) try { - await _brewUpgrader.UpgradeSoftwareAsync(appName).ConfigureAwait(false); + await UpgradeSoftwareCoreAsync(appName).ConfigureAwait(false); _ansiConsole.MarkupLine("[green]Done[/]"); diff --git a/source/CreativeCoders.MacSynkker.Cli/CreativeCoders.MacSynkker.Cli.csproj b/source/CreativeCoders.MacSynkker.Cli/CreativeCoders.MacSynkker.Cli.csproj index e9a676a..5943658 100644 --- a/source/CreativeCoders.MacSynkker.Cli/CreativeCoders.MacSynkker.Cli.csproj +++ b/source/CreativeCoders.MacSynkker.Cli/CreativeCoders.MacSynkker.Cli.csproj @@ -13,8 +13,8 @@ - - + + diff --git a/tests/CreativeCoders.MacOS.UserDefaults.Tests/CreativeCoders.MacOS.UserDefaults.Tests.csproj b/tests/CreativeCoders.MacOS.UserDefaults.Tests/CreativeCoders.MacOS.UserDefaults.Tests.csproj index ec85901..d59a34a 100644 --- a/tests/CreativeCoders.MacOS.UserDefaults.Tests/CreativeCoders.MacOS.UserDefaults.Tests.csproj +++ b/tests/CreativeCoders.MacOS.UserDefaults.Tests/CreativeCoders.MacOS.UserDefaults.Tests.csproj @@ -7,7 +7,7 @@ - + @@ -18,11 +18,11 @@ runtime; build; native; contentfiles; analyzers; buildtransitive all - + runtime; build; native; contentfiles; analyzers; buildtransitive all - + From 3c70d4695082d6a4bf21c7a336f9b8f4561dd0c3 Mon Sep 17 00:00:00 2001 From: darthsharp <48331467+darthsharp@users.noreply.github.com> Date: Sun, 15 Feb 2026 19:10:37 +0100 Subject: [PATCH 13/14] Improved `FormulaeVersionsAreEqual` to handle `null` values in version comparison logic. --- .../BrewInstalledModelExtensions.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/source/CreativeCoders.MacOS.HomeBrew/BrewInstalledModelExtensions.cs b/source/CreativeCoders.MacOS.HomeBrew/BrewInstalledModelExtensions.cs index bfc2144..656d547 100644 --- a/source/CreativeCoders.MacOS.HomeBrew/BrewInstalledModelExtensions.cs +++ b/source/CreativeCoders.MacOS.HomeBrew/BrewInstalledModelExtensions.cs @@ -34,6 +34,11 @@ private static bool IsFormulaOutdated(BrewFormulaModel formula) private static bool FormulaeVersionsAreEqual(string? installedVersion, string? availableVersion) { + if (installedVersion == null || availableVersion == null) + { + return installedVersion == availableVersion; + } + return installedVersion == availableVersion || installedVersion?.StartsWith($"{availableVersion}_") == true; } From 5a85f61c192bbdcc07a2a66304c378c9c92f1dd5 Mon Sep 17 00:00:00 2001 From: darthsharp <48331467+darthsharp@users.noreply.github.com> Date: Sun, 15 Feb 2026 19:12:13 +0100 Subject: [PATCH 14/14] Simplified null-check logic in `FormulaeVersionsAreEqual`. --- .../BrewInstalledModelExtensions.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/CreativeCoders.MacOS.HomeBrew/BrewInstalledModelExtensions.cs b/source/CreativeCoders.MacOS.HomeBrew/BrewInstalledModelExtensions.cs index 656d547..571518e 100644 --- a/source/CreativeCoders.MacOS.HomeBrew/BrewInstalledModelExtensions.cs +++ b/source/CreativeCoders.MacOS.HomeBrew/BrewInstalledModelExtensions.cs @@ -39,7 +39,7 @@ private static bool FormulaeVersionsAreEqual(string? installedVersion, string? a return installedVersion == availableVersion; } - return installedVersion == availableVersion || installedVersion?.StartsWith($"{availableVersion}_") == true; + return installedVersion == availableVersion || installedVersion.StartsWith($"{availableVersion}_"); } public static BrewFormulaModel[] GetFormulae(this BrewInstalledModel installedModel, bool onlyOutdated)