Skip to content
This repository has been archived by the owner on Sep 3, 2024. It is now read-only.

Commit

Permalink
Merge pull request #3 from julien-wff/feat-base-commands
Browse files Browse the repository at this point in the history
feat: version and help commands
  • Loading branch information
julien-wff authored Dec 2, 2023
2 parents 9ce2523 + 2992f5b commit b67bbed
Show file tree
Hide file tree
Showing 7 changed files with 242 additions and 31 deletions.
64 changes: 63 additions & 1 deletion EasyCLI/CommandRunner/CommandRunner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,32 @@ namespace EasyCLI.CommandRunner;
/// </summary>
public sealed class CommandRunner
{
/// <summary>
/// Contains the singleton instance of the CommandRunner.
/// </summary>
private static CommandRunner? _instance;

/// <summary>
/// Makes the constructor private to prevent instantiation outside of the class.
/// </summary>
private CommandRunner()
{
}

/// <summary>
/// Gets the collection of commands registered with the CommandRunner.
/// </summary>
public List<Command> Commands { get; } = new();

/// <summary>
/// Gets the singleton instance of the CommandRunner. If the instance does not exist, it is created.
/// </summary>
/// <returns>CommandRunner instance</returns>
public static CommandRunner GetInstance()
{
return _instance ??= new CommandRunner();
}

/// <summary>
/// Registers a command with the CommandRunner.
/// </summary>
Expand All @@ -30,11 +51,52 @@ public CommandRunner RegisterCommand(Command command)
/// <returns>True if the command was successfully run, false otherwise.</returns>
public bool RunWithArgs(IEnumerable<string> args)
{
return false;
var argsList = args.ToList();

if (argsList.Count == 0)
{
var helpCommand = Commands
.Find(cmd => cmd.Params.Name == "help");

if (helpCommand == null)
{
return false;
}

helpCommand.Run(argsList);
return true;
}

var command = GetCommandFromArgs(argsList);

if (command == null)
{
return false;
}

command.Run(argsList);
return true;
}

public Command? GetCommandFromArgs(IEnumerable<string> args)
{
var argsList = args.ToList();

if (argsList.Count < 1)
{
return null;
}

var argument = argsList[0];

foreach (var command in Commands)
{
if (command.Params.Name == argument || command.Params.Aliases.Contains(argument))
{
return command;
}
}

return null;
}
}
26 changes: 24 additions & 2 deletions EasyCLI/Commands/Command.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,31 @@ public abstract class Command
public void ShowHelp()
{
Console.WriteLine();
Console.WriteLine($"Usage: easysave {Params.Name}");
Console.Write($"Usage: easysave {Params.Name}");

foreach (var commandArg in Params.Args)
{
Console.Write(commandArg.Required ? $" <{commandArg.Name}>" : $" [{commandArg.Name}]");
}

if (Params.Flags.Count > 0)
{
Console.Write(" [flags]");
}

Console.WriteLine();
Console.WriteLine(Params.Description);
Console.WriteLine();
Console.WriteLine(Params.Description);

if (Params.Args.Count > 0)
{
Console.WriteLine();
Console.WriteLine("Arguments:");

foreach (var commandArg in Params.Args)
{
Console.WriteLine($" {commandArg.Name} - {commandArg.Description}");
}
}
}
}
78 changes: 78 additions & 0 deletions EasyCLI/Commands/HelpCommand.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
using EasyCLI.Commands.CommandFeatures;
using EasyCLI.Commands.CommandFeatures.CommandArgType;

namespace EasyCLI.Commands;

public class HelpCommand : Command
{
public override CommandBuilder.CommandBuilder Params { get; } = new CommandBuilder.CommandBuilder()
.SetName("help")
.SetDescription("Display help on other commands")
.SetAliases(new[] { "h", "-h", "--help" })
.AddArg(new CommandArg()
.SetName("command")
.SetDescription("Display help of a specific command")
.SetType(new CommandArgTypeString())
.SetRequired(false));

public override bool ValidateArgs(IEnumerable<string> args)
{
throw new NotImplementedException();
}

public override void Run(IEnumerable<string> args)
{
var argsList = args.ToList();

if (argsList.Count == 2)
{
var commandName = argsList[1];
var command = CommandRunner
.CommandRunner
.GetInstance()
.GetCommandFromArgs(argsList.GetRange(1, 1));

if (command is null)
{
Console.WriteLine($"Command {commandName} not found. Try 'easysave help' for more information.");
return;
}

command.ShowHelp();
}
else
{
PrintGeneralHelp();
}
}

private void PrintGeneralHelp()
{
Console.WriteLine("EasySave CLI Help Page");
Console.WriteLine();
Console.WriteLine("Usage: easysave [command] [arguments]");
Console.WriteLine();
Console.WriteLine("A CLI tool to backup your files");
Console.WriteLine();
Console.WriteLine("Available commands:");

var commands = CommandRunner
.CommandRunner
.GetInstance()
.Commands;

var longestCommandName = commands
.Select(command => command.Params.Name.Length)
.Max();

foreach (var cmdParams in commands.Select(cmd => cmd.Params))
{
var commandName = cmdParams.Name;
var commandDescription = cmdParams.Description;

Console.Write($" {commandName}");
Console.Write(new string(' ', longestCommandName - commandName.Length + 2));
Console.WriteLine(commandDescription);
}
}
}
32 changes: 32 additions & 0 deletions EasyCLI/Commands/VersionCommand.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using System.Reflection;

namespace EasyCLI.Commands;

public class VersionCommand : Command
{
public override CommandBuilder.CommandBuilder Params { get; } = new CommandBuilder.CommandBuilder()
.SetName("version")
.SetDescription("Get the version of the application")
.SetAliases(new List<string> { "ver", "v", "--version", "-v" });

public override bool ValidateArgs(IEnumerable<string> args)
{
var argsList = args.ToList();
var argsCount = argsList.Count;
if (argsCount != 0)
{
Console.WriteLine($"Command expects 0 arguments, {argsCount} given.");
ShowHelp();
return false;
}

return true;
}

public override void Run(IEnumerable<string> args)
{
var version = Assembly.GetEntryAssembly()?.GetName().Version;
var os = Environment.OSVersion;
Console.WriteLine($"EasySave CLI version {version} on {os.VersionString}");
}
}
11 changes: 9 additions & 2 deletions EasyCLI/Program.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
namespace EasyCLI;
using EasyCLI.Commands;

namespace EasyCLI;

public static class Program
{
public static void Main(string[] args)
{
throw new NotImplementedException();
CommandRunner
.CommandRunner
.GetInstance()
.RegisterCommand(new HelpCommand())
.RegisterCommand(new VersionCommand())
.RunWithArgs(args);
}
}
59 changes: 34 additions & 25 deletions EasySave.Tests/EasyCLI/CommandRunnerTests/CommandRunnerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,21 @@ public class CommandRunnerTests
public void RegisterCommand_ShouldAddCommandToCommands()
{
// Arrange
var commandRunner = new CommandRunner();
var commandRunner = CommandRunner.GetInstance();
var command = new Mock<MockCommand>();

// Act
commandRunner.RegisterCommand(command.Object);

// Assert
commandRunner.Commands.Should().Contain(command.Object);
CommandRunner.GetInstance().Commands.Should().Contain(command.Object);
}

[Fact]
public void RunWithArgs_ShouldReturnFalse_WhenNoCommandMatches()
{
// Arrange
var commandRunner = new CommandRunner();
var commandRunner = CommandRunner.GetInstance();
var args = new List<string> { "command" };

// Act
Expand All @@ -33,52 +33,61 @@ public void RunWithArgs_ShouldReturnFalse_WhenNoCommandMatches()
result.Should().BeFalse();
}

/*[Fact]
public void RunWithArgs_ShouldCallRun_WhenCommandMatches()
[Fact]
public void RunWithArgs_ShouldCallRun_WhenCommandNameMatches()
{
// Arrange
var commandRunner = new CommandRunner();
var command = new Mock<MockCommand>();
command.Setup(c => c.ValidateArgs(It.IsAny<IEnumerable<string>>())).Returns(true);
commandRunner.RegisterCommand(command.Object);
var commandRunner = CommandRunner.GetInstance();
var command = new MockCommand();
commandRunner.RegisterCommand(command);
var args = new List<string> { "mock" };

// Act
var result = commandRunner.RunWithArgs(args);

// Assert
command.Verify(c => c.Run(It.IsAny<IEnumerable<string>>()), Times.Once);
result.Should().BeTrue();
}*/
}

[Fact]
public void GetCommandFromArgs_ShouldReturnNull_WhenNoCommandMatches()
[Theory]
[InlineData("mock")]
[InlineData("mo")]
[InlineData("m")]
public void GetCommandFromArgs_ShouldReturnCommand_WhenCommandMatches(string input)
{
// Arrange
var commandRunner = new CommandRunner();
var args = new List<string> { "command" };
var commandRunner = CommandRunner.GetInstance();
var command = new MockCommand();
commandRunner.RegisterCommand(command);
var args = new List<string> { input };

// Act
var result = commandRunner.GetCommandFromArgs(args);

// Assert
result.Should().BeNull();
command.Params.Name.Should().Be(result?.Params.Name);
}

/*[Fact]
public void GetCommandFromArgs_ShouldReturnCommand_WhenCommandMatches()
[Theory]
[InlineData(null)]
[InlineData("moc")]
[InlineData("mockk")]
public void GetCommandFromArgs_ShouldReturnNull_WhenNoCommandMatches(string? input)
{
// Arrange
var commandRunner = new CommandRunner();
var command = new Mock<MockCommand>();
command.Setup(c => c.ValidateArgs(It.IsAny<IEnumerable<string>>())).Returns(true);
commandRunner.RegisterCommand(command.Object);
var args = new List<string> { "mock" };
var commandRunner = CommandRunner.GetInstance();
var command = new MockCommand();
commandRunner.RegisterCommand(command);
var args = new List<string>();
if (input != null)
{
args.Add(input);
}

// Act
var result = commandRunner.GetCommandFromArgs(args);

// Assert
result.Should().Be(command.Object);
}*/
result.Should().BeNull();
}
}
3 changes: 2 additions & 1 deletion EasySave.Tests/EasyCLI/CommandsTest/MockCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ public class MockCommand : Command
{
public override CommandBuilder Params { get; } = new CommandBuilder()
.SetName("mock")
.SetDescription("Mock command");
.SetDescription("Mock command")
.SetAliases(new[] { "mo", "m" });

public override bool ValidateArgs(IEnumerable<string> args)
{
Expand Down

0 comments on commit b67bbed

Please sign in to comment.