Sfoglia il codice sorgente

Add 'rpk other' CLI command tree

Wires the previously unused DescribeOtherUseCase and
OtherHardwareReportUseCase into a full command set mirroring the
UPS commands: summary, add, list, get, describe, set, del, rename,
label add/remove, tag add/remove.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Tim Jones 1 giorno fa
parent
commit
191f455019

+ 44 - 0
Shared.Rcl/CliBootstrap.cs

@@ -59,6 +59,9 @@ using Shared.Rcl.Commands.Switches.Rename;
 using Shared.Rcl.Commands.Systems;
 using Shared.Rcl.Commands.Systems;
 using Shared.Rcl.Commands.Systems.Labels;
 using Shared.Rcl.Commands.Systems.Labels;
 using Shared.Rcl.Commands.Systems.Rename;
 using Shared.Rcl.Commands.Systems.Rename;
+using Shared.Rcl.Commands.OtherHardware;
+using Shared.Rcl.Commands.OtherHardware.Labels;
+using Shared.Rcl.Commands.OtherHardware.Rename;
 using Shared.Rcl.Commands.Tags;
 using Shared.Rcl.Commands.Tags;
 using Shared.Rcl.Commands.Ups;
 using Shared.Rcl.Commands.Ups;
 using Shared.Rcl.Commands.Ups.Labels;
 using Shared.Rcl.Commands.Ups.Labels;
@@ -504,6 +507,47 @@ public static class CliBootstrap {
                 });
                 });
             });
             });
 
 
+            // ----------------------------
+            // Other hardware
+            // ----------------------------
+            config.AddBranch("other", other => {
+                other.SetDescription("Manage other hardware that doesn't fit an existing category.");
+
+                other.AddCommand<OtherReportCommand>("summary")
+                    .WithDescription("Show a hardware report for all other hardware.");
+
+                other.AddCommand<OtherAddCommand>("add").WithDescription("Add new other hardware.");
+
+                other.AddCommand<OtherGetCommand>("list").WithDescription("List all other hardware.");
+
+                other.AddCommand<OtherGetByNameCommand>("get").WithDescription("Retrieve other hardware by name.");
+
+                other.AddCommand<OtherDescribeCommand>("describe")
+                    .WithDescription("Show detailed information about other hardware.");
+
+                other.AddCommand<OtherSetCommand>("set").WithDescription("Update properties of other hardware.");
+
+                other.AddCommand<OtherDeleteCommand>("del").WithDescription("Delete other hardware.");
+
+                other.AddCommand<OtherRenameCommand>("rename")
+                    .WithDescription("Rename other hardware to a new name.");
+
+                other.AddBranch("label", label => {
+                    label.SetDescription("Manage labels on other hardware.");
+                    label.AddCommand<OtherLabelAddCommand>("add").WithDescription("Add a label to other hardware.");
+                    label.AddCommand<OtherLabelRemoveCommand>("remove")
+                        .WithDescription("Remove a label from other hardware.");
+                });
+
+                other.AddBranch("tag", tag => {
+                    tag.SetDescription("Manage tags on other hardware.");
+                    tag.AddCommand<TagAddCommand<RackPeek.Domain.Resources.OtherHardware.Other>>("add")
+                        .WithDescription("Add a tag to other hardware.");
+                    tag.AddCommand<TagRemoveCommand<RackPeek.Domain.Resources.OtherHardware.Other>>("remove")
+                        .WithDescription("Remove a tag from other hardware.");
+                });
+            });
+
             // ----------------------------
             // ----------------------------
             // Desktops
             // Desktops
             // ----------------------------
             // ----------------------------

+ 23 - 0
Shared.Rcl/Commands/OtherHardware/Labels/OtherLabelAddCommand.cs

@@ -0,0 +1,23 @@
+using Microsoft.Extensions.DependencyInjection;
+using RackPeek.Domain.UseCases.Labels;
+using Spectre.Console;
+using Spectre.Console.Cli;
+using OtherResource = RackPeek.Domain.Resources.OtherHardware.Other;
+
+namespace Shared.Rcl.Commands.OtherHardware.Labels;
+
+public class OtherLabelAddSettings : OtherNameSettings {
+    [CommandOption("--key <KEY>")] public string Key { get; set; } = default!;
+    [CommandOption("--value <VALUE>")] public string Value { get; set; } = default!;
+}
+
+public class OtherLabelAddCommand(IServiceProvider serviceProvider) : AsyncCommand<OtherLabelAddSettings> {
+    protected override async Task<int> ExecuteAsync(CommandContext context, OtherLabelAddSettings settings,
+        CancellationToken cancellationToken) {
+        using IServiceScope scope = serviceProvider.CreateScope();
+        IAddLabelUseCase<OtherResource> useCase = scope.ServiceProvider.GetRequiredService<IAddLabelUseCase<OtherResource>>();
+        await useCase.ExecuteAsync(settings.Name, settings.Key, settings.Value);
+        AnsiConsole.MarkupLine($"[green]Label '{settings.Key}' added to '{settings.Name}'.[/]");
+        return 0;
+    }
+}

+ 22 - 0
Shared.Rcl/Commands/OtherHardware/Labels/OtherLabelRemoveCommand.cs

@@ -0,0 +1,22 @@
+using Microsoft.Extensions.DependencyInjection;
+using RackPeek.Domain.UseCases.Labels;
+using Spectre.Console;
+using Spectre.Console.Cli;
+using OtherResource = RackPeek.Domain.Resources.OtherHardware.Other;
+
+namespace Shared.Rcl.Commands.OtherHardware.Labels;
+
+public class OtherLabelRemoveSettings : OtherNameSettings {
+    [CommandOption("--key <KEY>")] public string Key { get; set; } = default!;
+}
+
+public class OtherLabelRemoveCommand(IServiceProvider serviceProvider) : AsyncCommand<OtherLabelRemoveSettings> {
+    protected override async Task<int> ExecuteAsync(CommandContext context, OtherLabelRemoveSettings settings,
+        CancellationToken cancellationToken) {
+        using IServiceScope scope = serviceProvider.CreateScope();
+        IRemoveLabelUseCase<OtherResource> useCase = scope.ServiceProvider.GetRequiredService<IRemoveLabelUseCase<OtherResource>>();
+        await useCase.ExecuteAsync(settings.Name, settings.Key);
+        AnsiConsole.MarkupLine($"[green]Label '{settings.Key}' removed from '{settings.Name}'.[/]");
+        return 0;
+    }
+}

+ 28 - 0
Shared.Rcl/Commands/OtherHardware/OtherAddCommand.cs

@@ -0,0 +1,28 @@
+using Microsoft.Extensions.DependencyInjection;
+using RackPeek.Domain.UseCases;
+using Spectre.Console;
+using Spectre.Console.Cli;
+using OtherResource = RackPeek.Domain.Resources.OtherHardware.Other;
+
+namespace Shared.Rcl.Commands.OtherHardware;
+
+public class OtherAddSettings : CommandSettings {
+    [CommandArgument(0, "<name>")] public string Name { get; set; } = default!;
+}
+
+public class OtherAddCommand(IServiceProvider provider)
+    : AsyncCommand<OtherAddSettings> {
+    protected override async Task<int> ExecuteAsync(
+        CommandContext context,
+        OtherAddSettings settings,
+        CancellationToken cancellationToken) {
+        using IServiceScope scope = provider.CreateScope();
+        IAddResourceUseCase<OtherResource> useCase = scope.ServiceProvider
+            .GetRequiredService<IAddResourceUseCase<OtherResource>>();
+
+        await useCase.ExecuteAsync(settings.Name);
+
+        AnsiConsole.MarkupLine($"[green]Other hardware '{settings.Name}' added.[/]");
+        return 0;
+    }
+}

+ 28 - 0
Shared.Rcl/Commands/OtherHardware/OtherDeleteCommand.cs

@@ -0,0 +1,28 @@
+using Microsoft.Extensions.DependencyInjection;
+using RackPeek.Domain.UseCases;
+using Spectre.Console;
+using Spectre.Console.Cli;
+using OtherResource = RackPeek.Domain.Resources.OtherHardware.Other;
+
+namespace Shared.Rcl.Commands.OtherHardware;
+
+public class OtherNameSettings : CommandSettings {
+    [CommandArgument(0, "<name>")] public string Name { get; set; } = default!;
+}
+
+public class OtherDeleteCommand(IServiceProvider provider)
+    : AsyncCommand<OtherNameSettings> {
+    protected override async Task<int> ExecuteAsync(
+        CommandContext context,
+        OtherNameSettings settings,
+        CancellationToken cancellationToken) {
+        using IServiceScope scope = provider.CreateScope();
+        IDeleteResourceUseCase<OtherResource> useCase = scope.ServiceProvider
+            .GetRequiredService<IDeleteResourceUseCase<OtherResource>>();
+
+        await useCase.ExecuteAsync(settings.Name);
+
+        AnsiConsole.MarkupLine($"[green]Other hardware '{settings.Name}' deleted.[/]");
+        return 0;
+    }
+}

+ 34 - 0
Shared.Rcl/Commands/OtherHardware/OtherDescribeCommand.cs

@@ -0,0 +1,34 @@
+using Microsoft.Extensions.DependencyInjection;
+using RackPeek.Domain.Resources.OtherHardware;
+using Spectre.Console;
+using Spectre.Console.Cli;
+
+namespace Shared.Rcl.Commands.OtherHardware;
+
+public class OtherDescribeCommand(IServiceProvider provider)
+    : AsyncCommand<OtherNameSettings> {
+    protected override async Task<int> ExecuteAsync(
+        CommandContext context,
+        OtherNameSettings settings,
+        CancellationToken cancellationToken) {
+        using IServiceScope scope = provider.CreateScope();
+        DescribeOtherUseCase useCase = scope.ServiceProvider.GetRequiredService<DescribeOtherUseCase>();
+
+        OtherDescription other = await useCase.ExecuteAsync(settings.Name);
+
+        Grid grid = new Grid()
+            .AddColumn()
+            .AddColumn();
+
+        grid.AddRow("Name:", other.Name.EscapeMarkup());
+        grid.AddRow("Model:", (other.Model ?? "Unknown").EscapeMarkup());
+        grid.AddRow("Description:", (other.Description ?? "Unknown").EscapeMarkup());
+
+        if (other.Labels.Count > 0)
+            grid.AddRow("Labels:", string.Join(", ", other.Labels.Select(kvp => $"{kvp.Key.EscapeMarkup()}: {kvp.Value.EscapeMarkup()}")));
+
+        AnsiConsole.Write(new Panel(grid).Header("Other").Border(BoxBorder.Rounded));
+
+        return 0;
+    }
+}

+ 24 - 0
Shared.Rcl/Commands/OtherHardware/OtherGetByNameCommand.cs

@@ -0,0 +1,24 @@
+using Microsoft.Extensions.DependencyInjection;
+using RackPeek.Domain.Resources.OtherHardware;
+using Spectre.Console;
+using Spectre.Console.Cli;
+
+namespace Shared.Rcl.Commands.OtherHardware;
+
+public class OtherGetByNameCommand(IServiceProvider provider)
+    : AsyncCommand<OtherNameSettings> {
+    protected override async Task<int> ExecuteAsync(
+        CommandContext context,
+        OtherNameSettings settings,
+        CancellationToken cancellationToken) {
+        using IServiceScope scope = provider.CreateScope();
+        DescribeOtherUseCase useCase = scope.ServiceProvider.GetRequiredService<DescribeOtherUseCase>();
+
+        OtherDescription other = await useCase.ExecuteAsync(settings.Name);
+
+        AnsiConsole.MarkupLine(
+            $"[green]{other.Name}[/]  Model: {other.Model ?? "Unknown"}, Description: {other.Description ?? "Unknown"}");
+
+        return 0;
+    }
+}

+ 39 - 0
Shared.Rcl/Commands/OtherHardware/OtherGetCommand.cs

@@ -0,0 +1,39 @@
+using Microsoft.Extensions.DependencyInjection;
+using RackPeek.Domain.Resources.OtherHardware;
+using Spectre.Console;
+using Spectre.Console.Cli;
+
+namespace Shared.Rcl.Commands.OtherHardware;
+
+public class OtherGetCommand(IServiceProvider provider)
+    : AsyncCommand {
+    protected override async Task<int> ExecuteAsync(
+        CommandContext context,
+        CancellationToken cancellationToken) {
+        using IServiceScope scope = provider.CreateScope();
+        OtherHardwareReportUseCase useCase = scope.ServiceProvider.GetRequiredService<OtherHardwareReportUseCase>();
+
+        OtherHardwareReport report = await useCase.ExecuteAsync();
+
+        if (report.Others.Count == 0) {
+            AnsiConsole.MarkupLine("[yellow]No other hardware found.[/]");
+            return 0;
+        }
+
+        Table table = new Table()
+            .Border(TableBorder.Rounded)
+            .AddColumn("Name")
+            .AddColumn("Model")
+            .AddColumn("Description");
+
+        foreach (OtherHardwareRow other in report.Others)
+            table.AddRow(
+                other.Name.EscapeMarkup(),
+                other.Model.EscapeMarkup(),
+                other.Description.EscapeMarkup()
+            );
+
+        AnsiConsole.Write(table);
+        return 0;
+    }
+}

+ 38 - 0
Shared.Rcl/Commands/OtherHardware/OtherReportCommand.cs

@@ -0,0 +1,38 @@
+using Microsoft.Extensions.DependencyInjection;
+using RackPeek.Domain.Resources.OtherHardware;
+using Spectre.Console;
+using Spectre.Console.Cli;
+
+namespace Shared.Rcl.Commands.OtherHardware;
+
+public class OtherReportCommand(
+    IServiceProvider serviceProvider
+) : AsyncCommand {
+    protected override async Task<int> ExecuteAsync(CommandContext context, CancellationToken cancellationToken) {
+        using IServiceScope scope = serviceProvider.CreateScope();
+        OtherHardwareReportUseCase useCase = scope.ServiceProvider.GetRequiredService<OtherHardwareReportUseCase>();
+
+        OtherHardwareReport report = await useCase.ExecuteAsync();
+
+        if (report.Others.Count == 0) {
+            AnsiConsole.MarkupLine("[yellow]No other hardware found.[/]");
+            return 0;
+        }
+
+        Table table = new Table()
+            .Border(TableBorder.Rounded)
+            .AddColumn("Name")
+            .AddColumn("Model")
+            .AddColumn("Description");
+
+        foreach (OtherHardwareRow other in report.Others)
+            table.AddRow(
+                other.Name,
+                other.Model,
+                other.Description
+            );
+
+        AnsiConsole.Write(table);
+        return 0;
+    }
+}

+ 27 - 0
Shared.Rcl/Commands/OtherHardware/OtherSetCommand.cs

@@ -0,0 +1,27 @@
+using Microsoft.Extensions.DependencyInjection;
+using RackPeek.Domain.Resources.OtherHardware;
+using Spectre.Console;
+using Spectre.Console.Cli;
+
+namespace Shared.Rcl.Commands.OtherHardware;
+
+public class OtherSetSettings : OtherNameSettings {
+    [CommandOption("--model")] public string? Model { get; set; }
+    [CommandOption("--description")] public string? Description { get; set; }
+}
+
+public class OtherSetCommand(IServiceProvider provider)
+    : AsyncCommand<OtherSetSettings> {
+    protected override async Task<int> ExecuteAsync(
+        CommandContext context,
+        OtherSetSettings settings,
+        CancellationToken cancellationToken) {
+        using IServiceScope scope = provider.CreateScope();
+        UpdateOtherUseCase useCase = scope.ServiceProvider.GetRequiredService<UpdateOtherUseCase>();
+
+        await useCase.ExecuteAsync(settings.Name, settings.Model, settings.Description);
+
+        AnsiConsole.MarkupLine($"[green]Other hardware '{settings.Name}' updated.[/]");
+        return 0;
+    }
+}

+ 29 - 0
Shared.Rcl/Commands/OtherHardware/Rename/OtherRenameCommand.cs

@@ -0,0 +1,29 @@
+using Microsoft.Extensions.DependencyInjection;
+using RackPeek.Domain.UseCases;
+using Spectre.Console;
+using Spectre.Console.Cli;
+using OtherResource = RackPeek.Domain.Resources.OtherHardware.Other;
+
+namespace Shared.Rcl.Commands.OtherHardware.Rename;
+
+public class OtherRenameSettings : OtherNameSettings {
+    [CommandArgument(1, "<new-name>")]
+    public string NewName { get; set; } = default!;
+}
+
+public class OtherRenameCommand(
+    IServiceProvider serviceProvider
+) : AsyncCommand<OtherRenameSettings> {
+    protected override async Task<int> ExecuteAsync(
+        CommandContext context,
+        OtherRenameSettings settings,
+        CancellationToken cancellationToken) {
+        using IServiceScope scope = serviceProvider.CreateScope();
+        IRenameResourceUseCase<OtherResource> renameUseCase = scope.ServiceProvider.GetRequiredService<IRenameResourceUseCase<OtherResource>>();
+
+        await renameUseCase.ExecuteAsync(settings.Name, settings.NewName);
+
+        AnsiConsole.MarkupLine($"[green]Other hardware '{settings.Name}' renamed to '{settings.NewName}'.[/]");
+        return 0;
+    }
+}