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;