diff --git a/src/EthernaGatewayCli/Commands/Etherna/DownloadCommand.cs b/src/EthernaGatewayCli/Commands/Etherna/DownloadCommand.cs
index a4a5f04..3d79b26 100644
--- a/src/EthernaGatewayCli/Commands/Etherna/DownloadCommand.cs
+++ b/src/EthernaGatewayCli/Commands/Etherna/DownloadCommand.cs
@@ -12,10 +12,12 @@
// You should have received a copy of the GNU Affero General Public License along with Etherna Gateway CLI.
// If not, see .
-using Etherna.GatewayCli.Models.Commands;
+using Etherna.CliHelper.Models.Commands;
+using Etherna.CliHelper.Services;
using Etherna.GatewayCli.Services;
using Etherna.Sdk.Users.Clients;
using System;
+using System.Reflection;
using System.Threading.Tasks;
namespace Etherna.GatewayCli.Commands.Etherna
@@ -28,11 +30,12 @@ public class DownloadCommand : CommandBase
// Constructor.
public DownloadCommand(
+ Assembly assembly,
IAuthenticationService authService,
IEthernaUserGatewayClient gatewayClient,
IIoService ioService,
IServiceProvider serviceProvider)
- : base(ioService, serviceProvider)
+ : base(assembly, ioService, serviceProvider)
{
this.authService = authService;
this.gatewayClient = gatewayClient;
diff --git a/src/EthernaGatewayCli/Commands/Etherna/DownloadCommandOptions.cs b/src/EthernaGatewayCli/Commands/Etherna/DownloadCommandOptions.cs
index 8034cff..bbd85b6 100644
--- a/src/EthernaGatewayCli/Commands/Etherna/DownloadCommandOptions.cs
+++ b/src/EthernaGatewayCli/Commands/Etherna/DownloadCommandOptions.cs
@@ -12,7 +12,7 @@
// You should have received a copy of the GNU Affero General Public License along with Etherna Gateway CLI.
// If not, see .
-using Etherna.GatewayCli.Models.Commands;
+using Etherna.CliHelper.Models.Commands;
using System;
using System.Collections.Generic;
diff --git a/src/EthernaGatewayCli/Commands/Etherna/Postage/CreateCommand.cs b/src/EthernaGatewayCli/Commands/Etherna/Postage/CreateCommand.cs
index f235461..1d58aad 100644
--- a/src/EthernaGatewayCli/Commands/Etherna/Postage/CreateCommand.cs
+++ b/src/EthernaGatewayCli/Commands/Etherna/Postage/CreateCommand.cs
@@ -13,9 +13,11 @@
// If not, see .
using Etherna.BeeNet.Models;
-using Etherna.GatewayCli.Models.Commands;
+using Etherna.CliHelper.Models.Commands;
+using Etherna.CliHelper.Services;
using Etherna.GatewayCli.Services;
using System;
+using System.Reflection;
using System.Threading.Tasks;
namespace Etherna.GatewayCli.Commands.Etherna.Postage
@@ -28,11 +30,12 @@ public class CreateCommand : CommandBase
// Constructor.
public CreateCommand(
+ Assembly assembly,
IAuthenticationService authService,
IGatewayService gatewayService,
IIoService ioService,
IServiceProvider serviceProvider)
- : base(ioService, serviceProvider)
+ : base(assembly, ioService, serviceProvider)
{
this.authService = authService;
this.gatewayService = gatewayService;
diff --git a/src/EthernaGatewayCli/Commands/Etherna/Postage/CreateCommandOptions.cs b/src/EthernaGatewayCli/Commands/Etherna/Postage/CreateCommandOptions.cs
index 5bf08c5..b6f58ad 100644
--- a/src/EthernaGatewayCli/Commands/Etherna/Postage/CreateCommandOptions.cs
+++ b/src/EthernaGatewayCli/Commands/Etherna/Postage/CreateCommandOptions.cs
@@ -13,8 +13,8 @@
// If not, see .
using Etherna.BeeNet.Models;
-using Etherna.GatewayCli.Models.Commands;
-using Etherna.GatewayCli.Models.Commands.OptionRequirements;
+using Etherna.CliHelper.Models.Commands;
+using Etherna.CliHelper.Models.Commands.OptionRequirements;
using System;
using System.Collections.Generic;
diff --git a/src/EthernaGatewayCli/Commands/Etherna/Postage/InfoCommand.cs b/src/EthernaGatewayCli/Commands/Etherna/Postage/InfoCommand.cs
index 40f5bda..543377f 100644
--- a/src/EthernaGatewayCli/Commands/Etherna/Postage/InfoCommand.cs
+++ b/src/EthernaGatewayCli/Commands/Etherna/Postage/InfoCommand.cs
@@ -14,10 +14,12 @@
using Etherna.BeeNet.JsonConverters;
using Etherna.BeeNet.Models;
-using Etherna.GatewayCli.Models.Commands;
+using Etherna.CliHelper.Models.Commands;
+using Etherna.CliHelper.Services;
using Etherna.GatewayCli.Services;
using Etherna.Sdk.Common.GenClients.Gateway;
using System;
+using System.Reflection;
using System.Text.Json;
using System.Threading.Tasks;
@@ -43,11 +45,12 @@ public class InfoCommand : CommandBase
// Constructor.
public InfoCommand(
+ Assembly assembly,
IAuthenticationService authService,
IGatewayService gatewayService,
IIoService ioService,
IServiceProvider serviceProvider)
- : base(ioService, serviceProvider)
+ : base(assembly, ioService, serviceProvider)
{
this.authService = authService;
this.gatewayService = gatewayService;
diff --git a/src/EthernaGatewayCli/Commands/Etherna/PostageCommand.cs b/src/EthernaGatewayCli/Commands/Etherna/PostageCommand.cs
index 6a050ec..b6173a0 100644
--- a/src/EthernaGatewayCli/Commands/Etherna/PostageCommand.cs
+++ b/src/EthernaGatewayCli/Commands/Etherna/PostageCommand.cs
@@ -12,9 +12,10 @@
// You should have received a copy of the GNU Affero General Public License along with Etherna Gateway CLI.
// If not, see .
-using Etherna.GatewayCli.Models.Commands;
-using Etherna.GatewayCli.Services;
+using Etherna.CliHelper.Models.Commands;
+using Etherna.CliHelper.Services;
using System;
+using System.Reflection;
namespace Etherna.GatewayCli.Commands.Etherna
{
@@ -22,9 +23,10 @@ public class PostageCommand : CommandBase
{
// Constructor.
public PostageCommand(
+ Assembly assembly,
IIoService ioService,
IServiceProvider serviceProvider)
- : base(ioService, serviceProvider)
+ : base(assembly, ioService, serviceProvider)
{ }
// Properties.
diff --git a/src/EthernaGatewayCli/Commands/Etherna/Resource/DefundCommand.cs b/src/EthernaGatewayCli/Commands/Etherna/Resource/DefundCommand.cs
index 53ffe12..a2d4f72 100644
--- a/src/EthernaGatewayCli/Commands/Etherna/Resource/DefundCommand.cs
+++ b/src/EthernaGatewayCli/Commands/Etherna/Resource/DefundCommand.cs
@@ -12,9 +12,10 @@
// You should have received a copy of the GNU Affero General Public License along with Etherna Gateway CLI.
// If not, see .
-using Etherna.GatewayCli.Models.Commands;
-using Etherna.GatewayCli.Services;
+using Etherna.CliHelper.Models.Commands;
+using Etherna.CliHelper.Services;
using System;
+using System.Reflection;
using System.Threading.Tasks;
namespace Etherna.GatewayCli.Commands.Etherna.Resource
@@ -22,9 +23,10 @@ namespace Etherna.GatewayCli.Commands.Etherna.Resource
public class DefundCommand : CommandBase
{
public DefundCommand(
+ Assembly assembly,
IIoService ioService,
IServiceProvider serviceProvider)
- : base(ioService, serviceProvider)
+ : base(assembly, ioService, serviceProvider)
{
}
diff --git a/src/EthernaGatewayCli/Commands/Etherna/Resource/DefundCommandOptions.cs b/src/EthernaGatewayCli/Commands/Etherna/Resource/DefundCommandOptions.cs
index abce987..a66d217 100644
--- a/src/EthernaGatewayCli/Commands/Etherna/Resource/DefundCommandOptions.cs
+++ b/src/EthernaGatewayCli/Commands/Etherna/Resource/DefundCommandOptions.cs
@@ -12,8 +12,8 @@
// You should have received a copy of the GNU Affero General Public License along with Etherna Gateway CLI.
// If not, see .
-using Etherna.GatewayCli.Models.Commands;
-using Etherna.GatewayCli.Models.Commands.OptionRequirements;
+using Etherna.CliHelper.Models.Commands;
+using Etherna.CliHelper.Models.Commands.OptionRequirements;
using System.Collections.Generic;
namespace Etherna.GatewayCli.Commands.Etherna.Resource
diff --git a/src/EthernaGatewayCli/Commands/Etherna/Resource/FundCommand.cs b/src/EthernaGatewayCli/Commands/Etherna/Resource/FundCommand.cs
index ce33ecb..2896277 100644
--- a/src/EthernaGatewayCli/Commands/Etherna/Resource/FundCommand.cs
+++ b/src/EthernaGatewayCli/Commands/Etherna/Resource/FundCommand.cs
@@ -12,9 +12,11 @@
// You should have received a copy of the GNU Affero General Public License along with Etherna Gateway CLI.
// If not, see .
-using Etherna.GatewayCli.Models.Commands;
+using Etherna.CliHelper.Models.Commands;
+using Etherna.CliHelper.Services;
using Etherna.GatewayCli.Services;
using System;
+using System.Reflection;
using System.Threading.Tasks;
namespace Etherna.GatewayCli.Commands.Etherna.Resource
@@ -27,11 +29,12 @@ public class FundCommand : CommandBase
// Constructor.
public FundCommand(
+ Assembly assembly,
IAuthenticationService authService,
IGatewayService gatewayService,
IIoService ioService,
IServiceProvider serviceProvider)
- : base(ioService, serviceProvider)
+ : base(assembly, ioService, serviceProvider)
{
this.authService = authService;
this.gatewayService = gatewayService;
diff --git a/src/EthernaGatewayCli/Commands/Etherna/Resource/FundCommandOptions.cs b/src/EthernaGatewayCli/Commands/Etherna/Resource/FundCommandOptions.cs
index 7dc0fdf..d665f50 100644
--- a/src/EthernaGatewayCli/Commands/Etherna/Resource/FundCommandOptions.cs
+++ b/src/EthernaGatewayCli/Commands/Etherna/Resource/FundCommandOptions.cs
@@ -12,8 +12,8 @@
// You should have received a copy of the GNU Affero General Public License along with Etherna Gateway CLI.
// If not, see .
-using Etherna.GatewayCli.Models.Commands;
-using Etherna.GatewayCli.Models.Commands.OptionRequirements;
+using Etherna.CliHelper.Models.Commands;
+using Etherna.CliHelper.Models.Commands.OptionRequirements;
using System.Collections.Generic;
namespace Etherna.GatewayCli.Commands.Etherna.Resource
diff --git a/src/EthernaGatewayCli/Commands/Etherna/Resource/ListCommand.cs b/src/EthernaGatewayCli/Commands/Etherna/Resource/ListCommand.cs
index 77306c3..6525219 100644
--- a/src/EthernaGatewayCli/Commands/Etherna/Resource/ListCommand.cs
+++ b/src/EthernaGatewayCli/Commands/Etherna/Resource/ListCommand.cs
@@ -12,9 +12,10 @@
// You should have received a copy of the GNU Affero General Public License along with Etherna Gateway CLI.
// If not, see .
-using Etherna.GatewayCli.Models.Commands;
-using Etherna.GatewayCli.Services;
+using Etherna.CliHelper.Models.Commands;
+using Etherna.CliHelper.Services;
using System;
+using System.Reflection;
using System.Threading.Tasks;
namespace Etherna.GatewayCli.Commands.Etherna.Resource
@@ -22,9 +23,10 @@ namespace Etherna.GatewayCli.Commands.Etherna.Resource
public class ListCommand : CommandBase
{
public ListCommand(
+ Assembly assembly,
IIoService ioService,
IServiceProvider serviceProvider)
- : base(ioService, serviceProvider)
+ : base(assembly, ioService, serviceProvider)
{
}
diff --git a/src/EthernaGatewayCli/Commands/Etherna/ResourceCommand.cs b/src/EthernaGatewayCli/Commands/Etherna/ResourceCommand.cs
index dde3102..e942d46 100644
--- a/src/EthernaGatewayCli/Commands/Etherna/ResourceCommand.cs
+++ b/src/EthernaGatewayCli/Commands/Etherna/ResourceCommand.cs
@@ -12,9 +12,10 @@
// You should have received a copy of the GNU Affero General Public License along with Etherna Gateway CLI.
// If not, see .
-using Etherna.GatewayCli.Models.Commands;
-using Etherna.GatewayCli.Services;
+using Etherna.CliHelper.Models.Commands;
+using Etherna.CliHelper.Services;
using System;
+using System.Reflection;
namespace Etherna.GatewayCli.Commands.Etherna
{
@@ -22,9 +23,10 @@ public class ResourceCommand : CommandBase
{
// Constructor.
public ResourceCommand(
+ Assembly assembly,
IIoService ioService,
IServiceProvider serviceProvider)
- : base(ioService, serviceProvider)
+ : base(assembly, ioService, serviceProvider)
{ }
// Properties.
diff --git a/src/EthernaGatewayCli/Commands/Etherna/UploadCommand.cs b/src/EthernaGatewayCli/Commands/Etherna/UploadCommand.cs
index c766367..087a3af 100644
--- a/src/EthernaGatewayCli/Commands/Etherna/UploadCommand.cs
+++ b/src/EthernaGatewayCli/Commands/Etherna/UploadCommand.cs
@@ -13,11 +13,13 @@
// If not, see .
using Etherna.BeeNet.Models;
-using Etherna.GatewayCli.Models.Commands;
+using Etherna.CliHelper.Models.Commands;
+using Etherna.CliHelper.Services;
using Etherna.GatewayCli.Services;
using Etherna.Sdk.Common.GenClients.Gateway;
using System;
using System.IO;
+using System.Reflection;
using System.Threading.Tasks;
namespace Etherna.GatewayCli.Commands.Etherna
@@ -35,12 +37,13 @@ public class UploadCommand : CommandBase
// Constructor.
public UploadCommand(
+ Assembly assembly,
IAuthenticationService authService,
IFileService fileService,
IGatewayService gatewayService,
IIoService ioService,
IServiceProvider serviceProvider)
- : base(ioService, serviceProvider)
+ : base(assembly, ioService, serviceProvider)
{
this.authService = authService;
this.fileService = fileService;
diff --git a/src/EthernaGatewayCli/Commands/Etherna/UploadCommandOptions.cs b/src/EthernaGatewayCli/Commands/Etherna/UploadCommandOptions.cs
index ec7aea2..d1263e9 100644
--- a/src/EthernaGatewayCli/Commands/Etherna/UploadCommandOptions.cs
+++ b/src/EthernaGatewayCli/Commands/Etherna/UploadCommandOptions.cs
@@ -12,8 +12,8 @@
// You should have received a copy of the GNU Affero General Public License along with Etherna Gateway CLI.
// If not, see .
-using Etherna.GatewayCli.Models.Commands;
-using Etherna.GatewayCli.Models.Commands.OptionRequirements;
+using Etherna.CliHelper.Models.Commands;
+using Etherna.CliHelper.Models.Commands.OptionRequirements;
using System;
using System.Collections.Generic;
diff --git a/src/EthernaGatewayCli/Commands/EthernaCommand.cs b/src/EthernaGatewayCli/Commands/EthernaCommand.cs
index 340623e..190bc47 100644
--- a/src/EthernaGatewayCli/Commands/EthernaCommand.cs
+++ b/src/EthernaGatewayCli/Commands/EthernaCommand.cs
@@ -12,10 +12,11 @@
// You should have received a copy of the GNU Affero General Public License along with Etherna Gateway CLI.
// If not, see .
-using Etherna.GatewayCli.Models.Commands;
-using Etherna.GatewayCli.Services;
+using Etherna.CliHelper.Models.Commands;
+using Etherna.CliHelper.Services;
using Etherna.GatewayCli.Utilities;
using System;
+using System.Reflection;
using System.Threading.Tasks;
namespace Etherna.GatewayCli.Commands
@@ -24,9 +25,10 @@ public class EthernaCommand : CommandBase
{
// Constructor.
public EthernaCommand(
+ Assembly assembly,
IIoService ioService,
IServiceProvider serviceProvider)
- : base(ioService, serviceProvider)
+ : base(assembly, ioService, serviceProvider)
{ }
// Properties.
diff --git a/src/EthernaGatewayCli/Commands/EthernaCommandOptions.cs b/src/EthernaGatewayCli/Commands/EthernaCommandOptions.cs
index 5c36f0a..b23d3b4 100644
--- a/src/EthernaGatewayCli/Commands/EthernaCommandOptions.cs
+++ b/src/EthernaGatewayCli/Commands/EthernaCommandOptions.cs
@@ -12,8 +12,7 @@
// You should have received a copy of the GNU Affero General Public License along with Etherna Gateway CLI.
// If not, see .
-using Etherna.GatewayCli.Models.Commands;
-using System;
+using Etherna.CliHelper.Models.Commands;
using System.Collections.Generic;
namespace Etherna.GatewayCli.Commands
diff --git a/src/EthernaGatewayCli/EthernaGatewayCli.csproj b/src/EthernaGatewayCli/EthernaGatewayCli.csproj
index d892853..cfa9aa0 100644
--- a/src/EthernaGatewayCli/EthernaGatewayCli.csproj
+++ b/src/EthernaGatewayCli/EthernaGatewayCli.csproj
@@ -31,6 +31,7 @@
+
all
diff --git a/src/EthernaGatewayCli/Models/Commands/CommandBase.cs b/src/EthernaGatewayCli/Models/Commands/CommandBase.cs
deleted file mode 100644
index da60b8f..0000000
--- a/src/EthernaGatewayCli/Models/Commands/CommandBase.cs
+++ /dev/null
@@ -1,319 +0,0 @@
-// Copyright 2024-present Etherna SA
-// This file is part of Etherna Gateway CLI.
-//
-// Etherna Gateway CLI is free software: you can redistribute it and/or modify it under the terms of the
-// GNU Affero General Public License as published by the Free Software Foundation,
-// either version 3 of the License, or (at your option) any later version.
-//
-// Etherna Gateway CLI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
-// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-// See the GNU Affero General Public License for more details.
-//
-// You should have received a copy of the GNU Affero General Public License along with Etherna Gateway CLI.
-// If not, see .
-
-using Etherna.GatewayCli.Services;
-using Microsoft.Extensions.DependencyInjection;
-using System;
-using System.Collections.Generic;
-using System.Collections.Immutable;
-using System.Diagnostics.CodeAnalysis;
-using System.Linq;
-using System.Reflection;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Etherna.GatewayCli.Models.Commands
-{
- public abstract class CommandBase
- {
- // Fields.
- private readonly IServiceProvider serviceProvider;
- private ImmutableArray? _availableSubCommandTypes;
- private ImmutableArray? _commandPathTypes;
-
- // Constructor.
- protected CommandBase(
- IIoService ioService,
- IServiceProvider serviceProvider)
- {
- IoService = ioService;
- this.serviceProvider = serviceProvider;
- }
-
- // Properties.
- public ImmutableArray AvailableSubCommandTypes
- {
- get
- {
- if (_availableSubCommandTypes is null)
- {
- var subCommandsNamespace = GetType().Namespace + "." + GetType().Name.Replace("Command", "");
- _availableSubCommandTypes = typeof(Program).GetTypeInfo().Assembly.GetTypes()
- .Where(t => t is {IsClass:true, IsAbstract: false} &&
- t.Namespace == subCommandsNamespace &&
- typeof(CommandBase).IsAssignableFrom(t))
- .OrderBy(t => t.Name)
- .ToImmutableArray();
- }
- return _availableSubCommandTypes.Value;
- }
- }
- public string CommandPathNames => string.Join(' ',
- CommandPathTypes.Select(cType => ((CommandBase)serviceProvider.GetRequiredService(cType)).Name));
- public ImmutableArray CommandPathTypes
- {
- get
- {
- if (_commandPathTypes is null)
- {
- var currentCommandNamespace = GetType().Namespace;
- if (currentCommandNamespace is null)
- throw new InvalidOperationException();
-
- _commandPathTypes = GetParentCommandTypesFromNamespace(currentCommandNamespace)
- .Append(GetType()).ToImmutableArray();
- }
- return _commandPathTypes.Value;
- }
- }
- public virtual string CommandArgsHelpString => HasSubCommands ? "COMMAND" : "";
- public string CommandPathUsageHelpString
- {
- get
- {
- var strBuilder = new StringBuilder();
- foreach (var commandType in CommandPathTypes)
- {
- var command = (CommandBase)serviceProvider.GetRequiredService(commandType);
- strBuilder.Append(command.Name);
- if (command.HasOptions)
- {
- strBuilder.Append(command.HasRequiredOptions ?
- $" {command.Name.ToUpperInvariant()}_OPTIONS" :
- $" [{command.Name.ToUpperInvariant()}_OPTIONS]");
- }
-
- strBuilder.Append(' ');
- }
- strBuilder.Append(CommandArgsHelpString);
- return strBuilder.ToString();
- }
- }
- public abstract string Description { get; }
- public virtual bool HasOptions => false;
- public virtual bool HasRequiredOptions => false;
- public bool HasSubCommands => AvailableSubCommandTypes.Any();
- public virtual bool IsRootCommand => false;
- public string Name => GetCommandNameFromType(GetType());
- public virtual bool PrintHelpWithNoArgs => true;
-
- // Protected properties.
- protected IIoService IoService { get; }
-
- // Public methods.
- public async Task RunAsync(string[] args)
- {
- // Parse arguments.
- var printHelp = EvaluatePrintHelp(args);
- var optionArgsCount = printHelp ? 0 : ParseOptionArgs(args);
-
- // Print help or run command.
- if (printHelp)
- PrintHelp();
- else
- await ExecuteAsync(args[optionArgsCount..]);
- }
-
- // Protected methods.
- protected virtual void AppendOptionsHelp(StringBuilder strBuilder) { }
-
- ///
- /// Parse command options
- ///
- /// Input args
- /// Found option args counter
- protected virtual int ParseOptionArgs(string[] args) => 0;
-
- protected virtual async Task ExecuteAsync(string[] commandArgs)
- {
- ArgumentNullException.ThrowIfNull(commandArgs, nameof(commandArgs));
- await ExecuteSubCommandAsync(commandArgs);
- }
-
- protected async Task ExecuteSubCommandAsync(string[] commandArgs)
- {
- ArgumentNullException.ThrowIfNull(commandArgs, nameof(commandArgs));
-
- if (commandArgs.Length == 0)
- throw new ArgumentException("A command name is required");
-
- var subCommandName = commandArgs[0];
- var subCommandArgs = commandArgs[1..];
-
- var selectedCommandType = AvailableSubCommandTypes.FirstOrDefault(
- t => GetCommandNameFromType(t) == subCommandName);
-
- if (selectedCommandType is null)
- throw new ArgumentException($"{CommandPathNames}: '{subCommandName}' is not a valid command.");
-
- var selectedCommand = (CommandBase)serviceProvider.GetRequiredService(selectedCommandType);
- await selectedCommand.RunAsync(subCommandArgs);
- }
-
- // Protected helpers.
- protected static string GetCommandNameFromType(Type commandType)
- {
- ArgumentNullException.ThrowIfNull(commandType, nameof(commandType));
-
- if (!typeof(CommandBase).IsAssignableFrom(commandType))
- throw new ArgumentException($"{commandType.Name} is not a command type");
-
- return commandType.Name.Replace("Command", "").ToLowerInvariant();
- }
-
- // Private helpers.
- private bool EvaluatePrintHelp(string[] args)
- {
- ArgumentNullException.ThrowIfNull(args, nameof(args));
-
- switch (args.Length)
- {
- case 0 when PrintHelpWithNoArgs:
- return true;
- case 1:
- switch (args[0])
- {
- case "-h":
- case "--help":
- return true;
- }
- break;
- }
- return false;
- }
-
- private static IEnumerable GetParentCommandTypesFromNamespace(string currentNamespace)
- {
- var lastSeparatorIndex = currentNamespace.LastIndexOf('.');
- var parentNamespace = currentNamespace[..lastSeparatorIndex];
- var parentCommandName = currentNamespace[(lastSeparatorIndex + 1)..] + "Command";
- var parentCommandType = typeof(CommandBase).GetTypeInfo().Assembly.GetTypes()
- .FirstOrDefault(t => t is { IsClass: true, IsAbstract: false } &&
- t.FullName == parentNamespace + '.' + parentCommandName &&
- typeof(CommandBase).IsAssignableFrom(t));
-
- if (parentCommandType is null)
- return Array.Empty();
- return GetParentCommandTypesFromNamespace(parentNamespace).Append(parentCommandType);
- }
-
- [SuppressMessage("Performance", "CA1851:Possible multiple enumerations of \'IEnumerable\' collection")]
- private void PrintHelp()
- {
- var strBuilder = new StringBuilder();
-
- // Add name and description.
- strBuilder.AppendLine(CommandPathNames);
- strBuilder.AppendLine(Description);
- strBuilder.AppendLine();
-
- // Add usage.
- strBuilder.AppendLine($"Usage: {CommandPathUsageHelpString}");
- strBuilder.AppendLine();
-
- // Add sub commands.
- var availableSubCommandTypes = AvailableSubCommandTypes;
- if (availableSubCommandTypes.Any())
- {
- var allSubCommands = availableSubCommandTypes.Select(t => (CommandBase)serviceProvider.GetRequiredService(t));
-
- strBuilder.AppendLine("Commands:");
- var descriptionShift = allSubCommands.Select(c => c.Name.Length).Max() + 4;
- foreach (var command in allSubCommands)
- {
- strBuilder.Append(" ");
- strBuilder.Append(command.Name);
- for (int i = 0; i < descriptionShift - command.Name.Length; i++)
- strBuilder.Append(' ');
- strBuilder.AppendLine(command.Description);
- }
- strBuilder.AppendLine();
- }
-
- // Add options.
- AppendOptionsHelp(strBuilder);
-
- // Add print help.
- strBuilder.AppendLine($"Run '{CommandPathNames} -h' or '{CommandPathNames} --help' to print help.");
- if (IsRootCommand)
- strBuilder.AppendLine($"Run '{CommandPathNames} COMMAND -h' or '{CommandPathNames} COMMAND --help' for more information on a command.");
- strBuilder.AppendLine();
-
- // Print it.
- var helpOutput = strBuilder.ToString();
- IoService.Write(helpOutput);
- }
- }
-
- public abstract class CommandBase : CommandBase
- where TOptions: CommandOptionsBase, new()
- {
- // Constructor.
- protected CommandBase(
- IIoService ioService,
- IServiceProvider serviceProvider)
- : base(ioService, serviceProvider)
- { }
-
- // Properties.
- public override bool HasOptions => true;
- public override bool HasRequiredOptions => Options.AreRequired;
- public TOptions Options { get; } = new TOptions();
-
- // Methods.
- protected override int ParseOptionArgs(string[] args) => Options.ParseArgs(args, IoService);
-
- protected override void AppendOptionsHelp(StringBuilder strBuilder)
- {
- ArgumentNullException.ThrowIfNull(strBuilder, nameof(strBuilder));
-
- if (!Options.Definitions.Any()) return;
-
- // Option descriptions.
- strBuilder.AppendLine("Options:");
- var descriptionShift = Options.Definitions.Select(opt =>
- {
- var len = opt.LongName.Length;
- foreach (var reqArgType in opt.RequiredArgTypes)
- len += reqArgType.Name.Length + 1;
- return len;
- }).Max() + 4;
- foreach (var option in Options.Definitions)
- {
- strBuilder.Append(" ");
- strBuilder.Append(option.ShortName is null ? " " : $"{option.ShortName}, ");
- strBuilder.Append(option.LongName);
- var strLen = option.LongName.Length;
- foreach (var reqArgType in option.RequiredArgTypes)
- {
- strBuilder.Append($" {reqArgType.Name.ToLower()}");
- strLen += reqArgType.Name.Length + 1;
- }
- for (int i = 0; i < descriptionShift - strLen; i++)
- strBuilder.Append(' ');
- strBuilder.AppendLine(option.Description);
- }
- strBuilder.AppendLine();
-
- // Requirements.
- if (Options.Requirements.Any())
- {
- strBuilder.AppendLine("Option requirements:");
- foreach (var requirement in Options.Requirements)
- strBuilder.AppendLine(" " + requirement.PrintHelpLine(Options));
- strBuilder.AppendLine();
- }
- }
- }
-}
\ No newline at end of file
diff --git a/src/EthernaGatewayCli/Models/Commands/CommandOption.cs b/src/EthernaGatewayCli/Models/Commands/CommandOption.cs
deleted file mode 100644
index 17274ec..0000000
--- a/src/EthernaGatewayCli/Models/Commands/CommandOption.cs
+++ /dev/null
@@ -1,55 +0,0 @@
-// Copyright 2024-present Etherna SA
-// This file is part of Etherna Gateway CLI.
-//
-// Etherna Gateway CLI is free software: you can redistribute it and/or modify it under the terms of the
-// GNU Affero General Public License as published by the Free Software Foundation,
-// either version 3 of the License, or (at your option) any later version.
-//
-// Etherna Gateway CLI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
-// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-// See the GNU Affero General Public License for more details.
-//
-// You should have received a copy of the GNU Affero General Public License along with Etherna Gateway CLI.
-// If not, see .
-
-using System;
-using System.Collections.Generic;
-using System.Text.RegularExpressions;
-
-namespace Etherna.GatewayCli.Models.Commands
-{
- public class CommandOption
- {
- // Regex to validate option names.
- private static readonly Regex shortNameRegex = new("^-[A-Za-z0-9]$");
- private static readonly Regex longNameRegex = new("^--[A-Za-z0-9-]+$");
-
- // Constructor.
- public CommandOption(
- string? shortName,
- string longName,
- string description,
- Action onFound,
- IEnumerable? requiredArgTypes = null)
- {
- if (shortName != null && !shortNameRegex.IsMatch(shortName))
- throw new ArgumentException("Invalid short option name");
-
- if (!longNameRegex.IsMatch(longName))
- throw new ArgumentException("Invalid long option name");
-
- ShortName = shortName;
- LongName = longName;
- RequiredArgTypes = requiredArgTypes ?? Array.Empty();
- Description = description;
- OnFound = onFound;
- }
-
- // Properties.
- public string Description { get; }
- public Action OnFound { get; }
- public string LongName { get; }
- public IEnumerable RequiredArgTypes { get; }
- public string? ShortName { get; }
- }
-}
\ No newline at end of file
diff --git a/src/EthernaGatewayCli/Models/Commands/CommandOptionsBase.cs b/src/EthernaGatewayCli/Models/Commands/CommandOptionsBase.cs
deleted file mode 100644
index 2a2ef34..0000000
--- a/src/EthernaGatewayCli/Models/Commands/CommandOptionsBase.cs
+++ /dev/null
@@ -1,93 +0,0 @@
-// Copyright 2024-present Etherna SA
-// This file is part of Etherna Gateway CLI.
-//
-// Etherna Gateway CLI is free software: you can redistribute it and/or modify it under the terms of the
-// GNU Affero General Public License as published by the Free Software Foundation,
-// either version 3 of the License, or (at your option) any later version.
-//
-// Etherna Gateway CLI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
-// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-// See the GNU Affero General Public License for more details.
-//
-// You should have received a copy of the GNU Affero General Public License along with Etherna Gateway CLI.
-// If not, see .
-
-using Etherna.GatewayCli.Models.Commands.OptionRequirements;
-using Etherna.GatewayCli.Services;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
-namespace Etherna.GatewayCli.Models.Commands
-{
- public abstract class CommandOptionsBase
- {
- // Properties.
- public bool AreRequired => Requirements.OfType().Any();
- public abstract IEnumerable Definitions { get; }
- public virtual IEnumerable Requirements => Array.Empty();
-
- // Methods.
- public CommandOption FindOptionByName(string name) =>
- Definitions.First(o => o.ShortName == name || o.LongName == name);
-
- ///
- /// Parse command options
- ///
- /// Input args
- /// Found option args counter
- public virtual int ParseArgs(
- string[] args,
- IIoService ioService)
- {
- ArgumentNullException.ThrowIfNull(args, nameof(args));
- ArgumentNullException.ThrowIfNull(ioService, nameof(args));
-
- // Parse options.
- var parsedArgsCount = 0;
- var foundOptions = new List();
- while (parsedArgsCount < args.Length && args[parsedArgsCount].StartsWith('-'))
- {
- var optName = args[parsedArgsCount++];
-
- // Find option by name.
- var foundOption = Definitions.FirstOrDefault(opt => opt.ShortName == optName || opt.LongName == optName);
- if (foundOption is null)
- throw new ArgumentException(optName + " is not a valid option");
-
- // Verify duplicate options.
- if (foundOptions.Any(opt => opt.Option.ShortName == optName || opt.Option.LongName == optName))
- throw new ArgumentException(optName + " option is duplicate");
-
- // Check required option args.
- if (args.Length - parsedArgsCount < foundOption.RequiredArgTypes.Count())
- throw new ArgumentException($"{optName} requires {foundOption.RequiredArgTypes.Count()} args: {string.Join(" ", foundOption.RequiredArgTypes.Select(t => t.Name.ToLower()))}");
-
- // Exec option code.
- var requiredOptArgs = args[parsedArgsCount..(parsedArgsCount + foundOption.RequiredArgTypes.Count())];
- parsedArgsCount += requiredOptArgs.Length;
- foundOption.OnFound(requiredOptArgs);
-
- // Save on found options.
- foundOptions.Add(new(foundOption, optName, requiredOptArgs));
- }
-
- // Verify option requirements.
- var optionErrors = Requirements.SelectMany(r => r.ValidateOptions(this, foundOptions)).ToArray();
- if (optionErrors.Length != 0)
- {
- var errorStrBuilder = new StringBuilder();
- errorStrBuilder.AppendLine("Invalid options:");
- foreach (var error in optionErrors)
- errorStrBuilder.AppendLine(" " + error.Message);
-
- ioService.WriteError(errorStrBuilder.ToString());
-
- throw new ArgumentException("Errors with command options");
- }
-
- return parsedArgsCount;
- }
- }
-}
\ No newline at end of file
diff --git a/src/EthernaGatewayCli/Models/Commands/OptionRequirements/ExclusiveOptionRequirement.cs b/src/EthernaGatewayCli/Models/Commands/OptionRequirements/ExclusiveOptionRequirement.cs
deleted file mode 100644
index 7bd571c..0000000
--- a/src/EthernaGatewayCli/Models/Commands/OptionRequirements/ExclusiveOptionRequirement.cs
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright 2024-present Etherna SA
-// This file is part of Etherna Gateway CLI.
-//
-// Etherna Gateway CLI is free software: you can redistribute it and/or modify it under the terms of the
-// GNU Affero General Public License as published by the Free Software Foundation,
-// either version 3 of the License, or (at your option) any later version.
-//
-// Etherna Gateway CLI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
-// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-// See the GNU Affero General Public License for more details.
-//
-// You should have received a copy of the GNU Affero General Public License along with Etherna Gateway CLI.
-// If not, see .
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-
-namespace Etherna.GatewayCli.Models.Commands.OptionRequirements
-{
- public class ExclusiveOptionRequirement(params string[] optionsNames)
- : OptionRequirementBase(optionsNames)
- {
- // Methods.
- public override string PrintHelpLine(CommandOptionsBase commandOptions) =>
- ComposeSentence(OptionsNames.Select(n => commandOptions.FindOptionByName(n).LongName));
-
- public override IEnumerable ValidateOptions(
- CommandOptionsBase commandOptions,
- IEnumerable parsedOptions)
- {
- if (OptionsNames.Count(optName => TryFindParsedOption(parsedOptions, optName, out _)) >= 2)
- {
- var invalidParsedNames = parsedOptions.Where(parsedOpt =>
- OptionsNames.Contains(parsedOpt.Option.ShortName) ||
- OptionsNames.Contains(parsedOpt.Option.LongName))
- .Select(foundOpt => foundOpt.ParsedName);
-
- return [new OptionRequirementError(ComposeSentence(invalidParsedNames))];
- }
-
- return Array.Empty();
- }
-
- // Private helpers.
- private string ComposeSentence(IEnumerable optNames) =>
- $"{string.Join(", ", optNames)} are mutual exclusive.";
- }
-}
\ No newline at end of file
diff --git a/src/EthernaGatewayCli/Models/Commands/OptionRequirements/ForbiddenOptionRequirement.cs b/src/EthernaGatewayCli/Models/Commands/OptionRequirements/ForbiddenOptionRequirement.cs
deleted file mode 100644
index 84c6370..0000000
--- a/src/EthernaGatewayCli/Models/Commands/OptionRequirements/ForbiddenOptionRequirement.cs
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright 2024-present Etherna SA
-// This file is part of Etherna Gateway CLI.
-//
-// Etherna Gateway CLI is free software: you can redistribute it and/or modify it under the terms of the
-// GNU Affero General Public License as published by the Free Software Foundation,
-// either version 3 of the License, or (at your option) any later version.
-//
-// Etherna Gateway CLI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
-// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-// See the GNU Affero General Public License for more details.
-//
-// You should have received a copy of the GNU Affero General Public License along with Etherna Gateway CLI.
-// If not, see .
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-
-namespace Etherna.GatewayCli.Models.Commands.OptionRequirements
-{
- public class ForbiddenOptionRequirement(params string[] optionsNames)
- : OptionRequirementBase(optionsNames)
- {
- // Methods.
- public override string PrintHelpLine(CommandOptionsBase commandOptions) =>
- string.Join(", ", OptionsNames.Select(n => commandOptions.FindOptionByName(n).LongName)) +
- (OptionsNames.Count == 1 ? " is forbidden." : " are forbidden.");
-
- public override IEnumerable ValidateOptions(CommandOptionsBase commandOptions, IEnumerable parsedOptions)
- {
- if (OptionsNames.Any(optName => TryFindParsedOption(parsedOptions, optName, out _)))
- {
- var invalidParsedNames = parsedOptions.Where(parsedOpt =>
- OptionsNames.Contains(parsedOpt.Option.ShortName) ||
- OptionsNames.Contains(parsedOpt.Option.LongName))
- .Select(foundOpt => foundOpt.ParsedName);
-
- return [new OptionRequirementError(ComposeSentence(invalidParsedNames))];
- }
-
- return Array.Empty();
- }
-
- // Private helpers.
- private string ComposeSentence(IEnumerable optNames) =>
- string.Join(", ", optNames) + (optNames.Count() == 1 ? " is forbidden." : " are forbidden.");
- }
-}
\ No newline at end of file
diff --git a/src/EthernaGatewayCli/Models/Commands/OptionRequirements/IfPresentThenOptionRequirement.cs b/src/EthernaGatewayCli/Models/Commands/OptionRequirements/IfPresentThenOptionRequirement.cs
deleted file mode 100644
index b0545df..0000000
--- a/src/EthernaGatewayCli/Models/Commands/OptionRequirements/IfPresentThenOptionRequirement.cs
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright 2024-present Etherna SA
-// This file is part of Etherna Gateway CLI.
-//
-// Etherna Gateway CLI is free software: you can redistribute it and/or modify it under the terms of the
-// GNU Affero General Public License as published by the Free Software Foundation,
-// either version 3 of the License, or (at your option) any later version.
-//
-// Etherna Gateway CLI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
-// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-// See the GNU Affero General Public License for more details.
-//
-// You should have received a copy of the GNU Affero General Public License along with Etherna Gateway CLI.
-// If not, see .
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-
-namespace Etherna.GatewayCli.Models.Commands.OptionRequirements
-{
- public class IfPresentThenOptionRequirement(
- string optionsName,
- OptionRequirementBase thenRequirement)
- : OptionRequirementBase([optionsName])
- {
- // Methods.
- public override string PrintHelpLine(CommandOptionsBase commandOptions)
- {
- ArgumentNullException.ThrowIfNull(commandOptions, nameof(commandOptions));
-
- return ComposeSentence(
- commandOptions.FindOptionByName(OptionsNames.First()).LongName,
- thenRequirement.PrintHelpLine(commandOptions),
- commandOptions);
- }
-
- public override IEnumerable ValidateOptions(CommandOptionsBase commandOptions, IEnumerable parsedOptions)
- {
- var optName = OptionsNames.First();
-
- if (!TryFindParsedOption(parsedOptions, optName, out var parsedOption))
- return Array.Empty();
-
- var thenErrors = thenRequirement.ValidateOptions(commandOptions, parsedOptions);
-
- return thenErrors.Select(thenError =>
- new OptionRequirementError(ComposeSentence(optName, thenError.Message, commandOptions)));
- }
-
- // Private helpers.
- private string ComposeSentence(string optName, string thenMessageLine, CommandOptionsBase commandOptions) =>
- $"If {optName} is present then {thenMessageLine}";
- }
-}
\ No newline at end of file
diff --git a/src/EthernaGatewayCli/Models/Commands/OptionRequirements/MaxValueOptionRequirement.cs b/src/EthernaGatewayCli/Models/Commands/OptionRequirements/MaxValueOptionRequirement.cs
deleted file mode 100644
index dd55a2d..0000000
--- a/src/EthernaGatewayCli/Models/Commands/OptionRequirements/MaxValueOptionRequirement.cs
+++ /dev/null
@@ -1,55 +0,0 @@
-// Copyright 2024-present Etherna SA
-// This file is part of Etherna Gateway CLI.
-//
-// Etherna Gateway CLI is free software: you can redistribute it and/or modify it under the terms of the
-// GNU Affero General Public License as published by the Free Software Foundation,
-// either version 3 of the License, or (at your option) any later version.
-//
-// Etherna Gateway CLI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
-// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-// See the GNU Affero General Public License for more details.
-//
-// You should have received a copy of the GNU Affero General Public License along with Etherna Gateway CLI.
-// If not, see .
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-
-namespace Etherna.GatewayCli.Models.Commands.OptionRequirements
-{
- public class MaxValueOptionRequirement(
- string optionsName,
- double maxValue)
- : OptionRequirementBase([optionsName])
- {
- // Methods.
- public override string PrintHelpLine(CommandOptionsBase commandOptions)
- {
- ArgumentNullException.ThrowIfNull(commandOptions, nameof(commandOptions));
-
- return ComposeSentence(commandOptions.FindOptionByName(OptionsNames.First()).LongName);
- }
-
- public override IEnumerable ValidateOptions(
- CommandOptionsBase commandOptions,
- IEnumerable parsedOptions)
- {
- var optName = OptionsNames.First();
-
- if (!TryFindParsedOption(parsedOptions, optName, out var parsedOption))
- return Array.Empty();
-
- if (!double.TryParse(parsedOption!.ParsedArgs.First(), out var doubleArg))
- return [new OptionRequirementError(
- $"Invalid argument value: {parsedOption.ParsedName} {parsedOption.ParsedArgs.First()}")];
-
- return doubleArg <= maxValue
- ? Array.Empty()
- : [new OptionRequirementError(ComposeSentence(parsedOption.ParsedName))];
- }
-
- // Private helpers.
- private string ComposeSentence(string optName) => $"{optName} has max value {maxValue}.";
- }
-}
\ No newline at end of file
diff --git a/src/EthernaGatewayCli/Models/Commands/OptionRequirements/MinValueOptionRequirement.cs b/src/EthernaGatewayCli/Models/Commands/OptionRequirements/MinValueOptionRequirement.cs
deleted file mode 100644
index 12556c6..0000000
--- a/src/EthernaGatewayCli/Models/Commands/OptionRequirements/MinValueOptionRequirement.cs
+++ /dev/null
@@ -1,55 +0,0 @@
-// Copyright 2024-present Etherna SA
-// This file is part of Etherna Gateway CLI.
-//
-// Etherna Gateway CLI is free software: you can redistribute it and/or modify it under the terms of the
-// GNU Affero General Public License as published by the Free Software Foundation,
-// either version 3 of the License, or (at your option) any later version.
-//
-// Etherna Gateway CLI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
-// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-// See the GNU Affero General Public License for more details.
-//
-// You should have received a copy of the GNU Affero General Public License along with Etherna Gateway CLI.
-// If not, see .
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-
-namespace Etherna.GatewayCli.Models.Commands.OptionRequirements
-{
- public class MinValueOptionRequirement(
- string optionsName,
- double minValue)
- : OptionRequirementBase([optionsName])
- {
- // Methods.
- public override string PrintHelpLine(CommandOptionsBase commandOptions)
- {
- ArgumentNullException.ThrowIfNull(commandOptions, nameof(commandOptions));
-
- return ComposeSentence(commandOptions.FindOptionByName(OptionsNames.First()).LongName);
- }
-
- public override IEnumerable ValidateOptions(
- CommandOptionsBase commandOptions,
- IEnumerable parsedOptions)
- {
- var optName = OptionsNames.First();
-
- if (!TryFindParsedOption(parsedOptions, optName, out var parsedOption))
- return Array.Empty();
-
- if (!double.TryParse(parsedOption!.ParsedArgs.First(), out var doubleArg))
- return [new OptionRequirementError(
- $"Invalid argument value: {parsedOption.ParsedName} {parsedOption.ParsedArgs.First()}")];
-
- return doubleArg >= minValue
- ? Array.Empty()
- : [new OptionRequirementError(ComposeSentence(parsedOption.ParsedName))];
- }
-
- // Private helpers.
- private string ComposeSentence(string optName) => $"{optName} has min value {minValue}.";
- }
-}
\ No newline at end of file
diff --git a/src/EthernaGatewayCli/Models/Commands/OptionRequirements/OptionRequirementBase.cs b/src/EthernaGatewayCli/Models/Commands/OptionRequirements/OptionRequirementBase.cs
deleted file mode 100644
index e61ee07..0000000
--- a/src/EthernaGatewayCli/Models/Commands/OptionRequirements/OptionRequirementBase.cs
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright 2024-present Etherna SA
-// This file is part of Etherna Gateway CLI.
-//
-// Etherna Gateway CLI is free software: you can redistribute it and/or modify it under the terms of the
-// GNU Affero General Public License as published by the Free Software Foundation,
-// either version 3 of the License, or (at your option) any later version.
-//
-// Etherna Gateway CLI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
-// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-// See the GNU Affero General Public License for more details.
-//
-// You should have received a copy of the GNU Affero General Public License along with Etherna Gateway CLI.
-// If not, see .
-
-using System.Collections.Generic;
-using System.Linq;
-
-namespace Etherna.GatewayCli.Models.Commands.OptionRequirements
-{
- public abstract class OptionRequirementBase(
- IReadOnlyCollection optionsNames)
- {
- // Properties.
- public IReadOnlyCollection OptionsNames { get; protected set; } = optionsNames;
-
- // Methods.
- public abstract string PrintHelpLine(
- CommandOptionsBase commandOptions);
-
- public abstract IEnumerable ValidateOptions(
- CommandOptionsBase commandOptions,
- IEnumerable parsedOptions);
-
- // Protected helpers.
- protected static bool TryFindParsedOption(
- IEnumerable parsedOptions,
- string optionName,
- out ParsedOption? foundParsedOption)
- {
- foundParsedOption = parsedOptions.SingleOrDefault(parsOpt =>
- parsOpt.Option.ShortName == optionName ||
- parsOpt.Option.LongName == optionName);
- return foundParsedOption != null;
- }
- }
-}
\ No newline at end of file
diff --git a/src/EthernaGatewayCli/Models/Commands/OptionRequirements/OptionRequirementError.cs b/src/EthernaGatewayCli/Models/Commands/OptionRequirements/OptionRequirementError.cs
deleted file mode 100644
index ddfa641..0000000
--- a/src/EthernaGatewayCli/Models/Commands/OptionRequirements/OptionRequirementError.cs
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright 2024-present Etherna SA
-// This file is part of Etherna Gateway CLI.
-//
-// Etherna Gateway CLI is free software: you can redistribute it and/or modify it under the terms of the
-// GNU Affero General Public License as published by the Free Software Foundation,
-// either version 3 of the License, or (at your option) any later version.
-//
-// Etherna Gateway CLI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
-// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-// See the GNU Affero General Public License for more details.
-//
-// You should have received a copy of the GNU Affero General Public License along with Etherna Gateway CLI.
-// If not, see .
-
-namespace Etherna.GatewayCli.Models.Commands.OptionRequirements
-{
- public class OptionRequirementError
- {
- // Constructor.
- public OptionRequirementError(string message)
- {
- Message = message;
- }
-
- // Properties.
- public string Message { get; }
- }
-}
\ No newline at end of file
diff --git a/src/EthernaGatewayCli/Models/Commands/OptionRequirements/RangeOptionRequirement.cs b/src/EthernaGatewayCli/Models/Commands/OptionRequirements/RangeOptionRequirement.cs
deleted file mode 100644
index 9ed94b4..0000000
--- a/src/EthernaGatewayCli/Models/Commands/OptionRequirements/RangeOptionRequirement.cs
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright 2024-present Etherna SA
-// This file is part of Etherna Gateway CLI.
-//
-// Etherna Gateway CLI is free software: you can redistribute it and/or modify it under the terms of the
-// GNU Affero General Public License as published by the Free Software Foundation,
-// either version 3 of the License, or (at your option) any later version.
-//
-// Etherna Gateway CLI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
-// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-// See the GNU Affero General Public License for more details.
-//
-// You should have received a copy of the GNU Affero General Public License along with Etherna Gateway CLI.
-// If not, see .
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-
-namespace Etherna.GatewayCli.Models.Commands.OptionRequirements
-{
- public class RangeOptionRequirement : OptionRequirementBase
- {
- // Constructor.
- public RangeOptionRequirement(string optionsName,
- double minValue,
- double maxValue) : base([optionsName])
- {
- if (minValue >= maxValue)
- throw new ArgumentException("Min value must be smaller than max value");
-
- MaxValue = maxValue;
- MinValue = minValue;
- }
-
- // Properties.
- public double MaxValue { get; }
- public double MinValue { get; }
-
- // Methods.
- public override string PrintHelpLine(CommandOptionsBase commandOptions)
- {
- ArgumentNullException.ThrowIfNull(commandOptions, nameof(commandOptions));
-
- return ComposeSentence(commandOptions.FindOptionByName(OptionsNames.First()).LongName);
- }
-
- public override IEnumerable ValidateOptions(
- CommandOptionsBase commandOptions,
- IEnumerable parsedOptions)
- {
- var optName = OptionsNames.First();
-
- if (!TryFindParsedOption(parsedOptions, optName, out var parsedOption))
- return Array.Empty();
-
- if (!double.TryParse(parsedOption!.ParsedArgs.First(), out var doubleArg))
- return [new OptionRequirementError(
- $"Invalid argument value: {parsedOption.ParsedName} {parsedOption.ParsedArgs.First()}")];
-
- return doubleArg >= MinValue && doubleArg <= MaxValue
- ? Array.Empty()
- : [new OptionRequirementError(ComposeSentence(parsedOption.ParsedName))];
- }
-
- // Private helpers.
- private string ComposeSentence(string optName) => $"{optName} has value in range [{MinValue}, {MaxValue}].";
- }
-}
\ No newline at end of file
diff --git a/src/EthernaGatewayCli/Models/Commands/OptionRequirements/RequireOneOfOptionRequirement.cs b/src/EthernaGatewayCli/Models/Commands/OptionRequirements/RequireOneOfOptionRequirement.cs
deleted file mode 100644
index 0e82dfe..0000000
--- a/src/EthernaGatewayCli/Models/Commands/OptionRequirements/RequireOneOfOptionRequirement.cs
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright 2024-present Etherna SA
-// This file is part of Etherna Gateway CLI.
-//
-// Etherna Gateway CLI is free software: you can redistribute it and/or modify it under the terms of the
-// GNU Affero General Public License as published by the Free Software Foundation,
-// either version 3 of the License, or (at your option) any later version.
-//
-// Etherna Gateway CLI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
-// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-// See the GNU Affero General Public License for more details.
-//
-// You should have received a copy of the GNU Affero General Public License along with Etherna Gateway CLI.
-// If not, see .
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-
-namespace Etherna.GatewayCli.Models.Commands.OptionRequirements
-{
- public class RequireOneOfOptionRequirement(params string[] optionsNames)
- : OptionRequirementBase(optionsNames)
- {
- public override string PrintHelpLine(CommandOptionsBase commandOptions) =>
- string.Join(", ", OptionsNames.Select(n => commandOptions.FindOptionByName(n).LongName)) +
- (OptionsNames.Count == 1 ? " is required." : " at least one is required.");
-
- public override IEnumerable ValidateOptions(
- CommandOptionsBase commandOptions,
- IEnumerable parsedOptions) =>
- OptionsNames.Any(optName => TryFindParsedOption(parsedOptions, optName, out _)) ?
- Array.Empty() :
- [new OptionRequirementError(PrintHelpLine(commandOptions))];
- }
-}
\ No newline at end of file
diff --git a/src/EthernaGatewayCli/Models/Commands/ParsedOption.cs b/src/EthernaGatewayCli/Models/Commands/ParsedOption.cs
deleted file mode 100644
index 4f1afe5..0000000
--- a/src/EthernaGatewayCli/Models/Commands/ParsedOption.cs
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright 2024-present Etherna SA
-// This file is part of Etherna Gateway CLI.
-//
-// Etherna Gateway CLI is free software: you can redistribute it and/or modify it under the terms of the
-// GNU Affero General Public License as published by the Free Software Foundation,
-// either version 3 of the License, or (at your option) any later version.
-//
-// Etherna Gateway CLI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
-// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-// See the GNU Affero General Public License for more details.
-//
-// You should have received a copy of the GNU Affero General Public License along with Etherna Gateway CLI.
-// If not, see .
-
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-
-namespace Etherna.GatewayCli.Models.Commands
-{
- public class ParsedOption(
- CommandOption option,
- string parsedName,
- params string[] parsedArgs)
- {
- // Properties.
- public CommandOption Option { get; } = option;
- public ReadOnlyCollection ParsedArgs { get; } = parsedArgs.AsReadOnly();
- public string ParsedName { get; } = parsedName;
- }
-}
\ No newline at end of file
diff --git a/src/EthernaGatewayCli/Program.cs b/src/EthernaGatewayCli/Program.cs
index 4258a02..97f02d4 100644
--- a/src/EthernaGatewayCli/Program.cs
+++ b/src/EthernaGatewayCli/Program.cs
@@ -12,9 +12,9 @@
// You should have received a copy of the GNU Affero General Public License along with Etherna Gateway CLI.
// If not, see .
+using Etherna.CliHelper.Models.Commands;
+using Etherna.CliHelper.Services;
using Etherna.GatewayCli.Commands;
-using Etherna.GatewayCli.Models.Commands;
-using Etherna.GatewayCli.Services;
using Etherna.Sdk.Users.Native;
using Microsoft.Extensions.DependencyInjection;
using System;
diff --git a/src/EthernaGatewayCli/ServiceCollectionExtensions.cs b/src/EthernaGatewayCli/ServiceCollectionExtensions.cs
index cad0e65..df9c252 100644
--- a/src/EthernaGatewayCli/ServiceCollectionExtensions.cs
+++ b/src/EthernaGatewayCli/ServiceCollectionExtensions.cs
@@ -12,11 +12,11 @@
// You should have received a copy of the GNU Affero General Public License along with Etherna Gateway CLI.
// If not, see .
-using Etherna.BeeNet;
using Etherna.BeeNet.Services;
+using Etherna.CliHelper.Services;
using Etherna.GatewayCli.Services;
using Microsoft.Extensions.DependencyInjection;
-using System.Net.Http;
+using System.Reflection;
namespace Etherna.GatewayCli
{
@@ -31,6 +31,9 @@ public static void AddCoreServices(
services.AddTransient();
services.AddTransient();
services.AddTransient();
+
+ // Add singleton services.
+ services.AddSingleton(typeof(Program).GetTypeInfo().Assembly);
}
}
}
\ No newline at end of file
diff --git a/src/EthernaGatewayCli/Services/AuthenticationService.cs b/src/EthernaGatewayCli/Services/AuthenticationService.cs
index c50dd2f..6870cfb 100644
--- a/src/EthernaGatewayCli/Services/AuthenticationService.cs
+++ b/src/EthernaGatewayCli/Services/AuthenticationService.cs
@@ -14,6 +14,7 @@
using Etherna.Authentication;
using Etherna.Authentication.Native;
+using Etherna.CliHelper.Services;
using System;
using System.ComponentModel;
using System.Threading.Tasks;
diff --git a/src/EthernaGatewayCli/Services/ConsoleIoService.cs b/src/EthernaGatewayCli/Services/ConsoleIoService.cs
deleted file mode 100644
index 8bae018..0000000
--- a/src/EthernaGatewayCli/Services/ConsoleIoService.cs
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright 2024-present Etherna SA
-// This file is part of Etherna Gateway CLI.
-//
-// Etherna Gateway CLI is free software: you can redistribute it and/or modify it under the terms of the
-// GNU Affero General Public License as published by the Free Software Foundation,
-// either version 3 of the License, or (at your option) any later version.
-//
-// Etherna Gateway CLI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
-// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-// See the GNU Affero General Public License for more details.
-//
-// You should have received a copy of the GNU Affero General Public License along with Etherna Gateway CLI.
-// If not, see .
-
-using System;
-
-namespace Etherna.GatewayCli.Services
-{
- public class ConsoleIoService : IIoService
- {
- // Consts.
- private const ConsoleColor ErrorForegroundColor = ConsoleColor.DarkRed;
-
- // Methods.
- public ConsoleKeyInfo ReadKey() => Console.ReadKey();
-
- public string? ReadLine() => Console.ReadLine();
-
- public void Write(string? value) => Console.Write(value);
-
- public void WriteError(string value)
- {
- Console.ForegroundColor = ErrorForegroundColor;
- Console.Write(value);
- Console.ResetColor();
- }
-
- public void WriteErrorLine(string value)
- {
- Console.ForegroundColor = ErrorForegroundColor;
- Console.WriteLine(value);
- Console.ResetColor();
- }
-
- public void WriteLine(string? value = null) => Console.WriteLine(value);
- }
-}
\ No newline at end of file
diff --git a/src/EthernaGatewayCli/Services/GatewayService.cs b/src/EthernaGatewayCli/Services/GatewayService.cs
index 7bcfadc..3d7ac83 100644
--- a/src/EthernaGatewayCli/Services/GatewayService.cs
+++ b/src/EthernaGatewayCli/Services/GatewayService.cs
@@ -15,6 +15,7 @@
using Etherna.BeeNet.Hasher.Postage;
using Etherna.BeeNet.Models;
using Etherna.BeeNet.Services;
+using Etherna.CliHelper.Services;
using Etherna.Sdk.Common.GenClients.Gateway;
using Etherna.Sdk.Users.Clients;
using System;
diff --git a/src/EthernaGatewayCli/Services/IIoService.cs b/src/EthernaGatewayCli/Services/IIoService.cs
deleted file mode 100644
index 444fa8c..0000000
--- a/src/EthernaGatewayCli/Services/IIoService.cs
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright 2024-present Etherna SA
-// This file is part of Etherna Gateway CLI.
-//
-// Etherna Gateway CLI is free software: you can redistribute it and/or modify it under the terms of the
-// GNU Affero General Public License as published by the Free Software Foundation,
-// either version 3 of the License, or (at your option) any later version.
-//
-// Etherna Gateway CLI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
-// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-// See the GNU Affero General Public License for more details.
-//
-// You should have received a copy of the GNU Affero General Public License along with Etherna Gateway CLI.
-// If not, see .
-
-using System;
-
-namespace Etherna.GatewayCli.Services
-{
- public interface IIoService
- {
- ConsoleKeyInfo ReadKey();
- string? ReadLine();
- void Write(string? value);
- void WriteError(string value);
- void WriteErrorLine(string value);
- void WriteLine(string? value = null);
- }
-}
\ No newline at end of file
diff --git a/src/EthernaGatewayCli/Utilities/EthernaVersionControl.cs b/src/EthernaGatewayCli/Utilities/EthernaVersionControl.cs
index a7085ee..98b1e73 100644
--- a/src/EthernaGatewayCli/Utilities/EthernaVersionControl.cs
+++ b/src/EthernaGatewayCli/Utilities/EthernaVersionControl.cs
@@ -12,8 +12,8 @@
// You should have received a copy of the GNU Affero General Public License along with Etherna Gateway CLI.
// If not, see .
+using Etherna.CliHelper.Services;
using Etherna.GatewayCli.Models.GitHubDto;
-using Etherna.GatewayCli.Services;
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;