Skip to content

Commit

Permalink
removing obsolete warnings, little code formatting
Browse files Browse the repository at this point in the history
  • Loading branch information
Jeremy D. Miller authored and Jeremy D. Miller committed Nov 27, 2021
1 parent cd41b06 commit 5920c3c
Show file tree
Hide file tree
Showing 8 changed files with 135 additions and 140 deletions.
195 changes: 100 additions & 95 deletions src/Oakton/CommandFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,26 @@ namespace Oakton
{
public class CommandFactory : ICommandFactory
{
private static readonly string[] _helpCommands = new []{"help", "?"};
private readonly LightweightCache<string, Type> _commandTypes = new LightweightCache<string, Type>();
private static readonly string[] _helpCommands = {"help", "?"};


private static readonly Regex regex = new("(?<name>.+)Command", RegexOptions.Compiled);
private readonly ICommandCreator _commandCreator;
private readonly LightweightCache<string, Type> _commandTypes = new();
private string _appName;

private Type _defaultCommand;

/// <summary>
/// Perform some operation based on command inputs, before command construction
/// </summary>
public Action<string, object> BeforeBuild = null;

/// <summary>
/// Alter the input object or the command object just before executing the command
/// </summary>
public Action<CommandRun> ConfigureRun = run => { };

public CommandFactory()
{
_commandCreator = new ActivatorCommandCreator();
Expand All @@ -29,14 +44,20 @@ public CommandFactory(ICommandCreator creator)
}

/// <summary>
/// Perform some operation based on command inputs, before command construction
/// Optionally designates the default command type. Useful if your console app only has one command
/// </summary>
public Action<string, object> BeforeBuild = null;

/// <summary>
/// Alter the input object or the command object just before executing the command
/// </summary>
public Action<CommandRun> ConfigureRun = run => { };
public Type DefaultCommand
{
get => _defaultCommand ?? (_commandTypes.Count == 1 ? _commandTypes.GetAll().Single() : null);
set
{
_defaultCommand = value;
if (value != null)
{
_commandTypes[CommandNameFor(value)] = value;
}
}
}

public CommandRun BuildRun(string commandLine)
{
Expand All @@ -46,7 +67,6 @@ public CommandRun BuildRun(string commandLine)

public CommandRun BuildRun(IEnumerable<string> args)
{

if (!args.Any())
{
if (DefaultCommand == null)
Expand All @@ -63,8 +83,7 @@ public CommandRun BuildRun(IEnumerable<string> args)
{
return buildRun(queue, CommandNameFor(DefaultCommand));
}




var firstArg = queue.Peek().ToLowerInvariant();

Expand All @@ -80,15 +99,30 @@ public CommandRun BuildRun(IEnumerable<string> args)
queue.Dequeue();
return buildRun(queue, firstArg);
}

if (DefaultCommand != null)
{
return buildRun(queue, CommandNameFor(DefaultCommand));
}
else
{
return InvalidCommandRun(firstArg);
}

return InvalidCommandRun(firstArg);
}

/// <summary>
/// Add all the IOaktonCommand classes in the given assembly to the command runner
/// </summary>
/// <param name="assembly"></param>
public void RegisterCommands(Assembly assembly)
{
assembly
.GetExportedTypes()
.Where(IsOaktonCommandType)
.Each(t => { _commandTypes[CommandNameFor(t)] = t; });
}

public IEnumerable<IOaktonCommand> BuildAllCommands()
{
return _commandTypes.Select(x => _commandCreator.CreateCommand(x));
}


Expand All @@ -99,10 +133,11 @@ public IEnumerable<Type> AllCommandTypes()

public CommandRun InvalidCommandRun(string commandName)
{
return new CommandRun()
return new()
{
Command = new HelpCommand(),
Input = new HelpInput(){
Input = new HelpInput
{
AppName = _appName,
Name = commandName,
CommandTypes = _commandTypes.GetAll(),
Expand All @@ -119,21 +154,18 @@ private CommandRun buildRun(Queue<string> queue, string commandName)

if (BeforeBuild != null)
{
input = tryBeforeBuild(queue, commandName);
input = tryBeforeBuild(queue, commandName);
}

var command = Build(commandName);

if (input == null)
{
input = command.Usages.BuildInput(queue, _commandCreator);
}
input ??= command.Usages.BuildInput(queue, _commandCreator);

var run = new CommandRun
{
Command = command,
Input = input
};
{
Command = command,
Input = input
};

ConfigureRun(run);

Expand All @@ -155,7 +187,7 @@ private CommandRun buildRun(Queue<string> queue, string commandName)
{
ConsoleWriter.Write(ConsoleColor.Red, "Error parsing input");
ConsoleWriter.Write(ConsoleColor.Yellow, e.ToString());

Console.WriteLine();
}

Expand All @@ -164,79 +196,55 @@ private CommandRun buildRun(Queue<string> queue, string commandName)

private object tryBeforeBuild(Queue<string> queue, string commandName)
{
var commandType = _commandTypes[commandName];

try
{
var defaultConstructorCommand = new ActivatorCommandCreator().CreateCommand(commandType);
var input = defaultConstructorCommand.Usages.BuildInput(queue, _commandCreator);

BeforeBuild?.Invoke(commandName, input);

return input;
}
catch (MissingMethodException)
{
// Command has no default constructor - not possible to pre-configure from inputs.
return null;
}
var commandType = _commandTypes[commandName];

try
{
var defaultConstructorCommand = new ActivatorCommandCreator().CreateCommand(commandType);
var input = defaultConstructorCommand.Usages.BuildInput(queue, _commandCreator);

BeforeBuild?.Invoke(commandName, input);

return input;
}
catch (MissingMethodException)
{
// Command has no default constructor - not possible to pre-configure from inputs.
return null;
}
}

/// <summary>
/// Add a single command type to the command runner
/// Add a single command type to the command runner
/// </summary>
/// <typeparam name="T"></typeparam>
public void RegisterCommand<T>()
{
RegisterCommand(typeof(T));
}

/// <summary>
/// Add a single command type to the command runner
/// Add a single command type to the command runner
/// </summary>
public void RegisterCommand(Type type)
{
if (!IsOaktonCommandType(type)) throw new ArgumentOutOfRangeException(nameof(type), $"Type '{type.FullName}' does not inherit from either OaktonCommannd or OaktonAsyncCommand");
_commandTypes[CommandNameFor(type)] = type;
}
if (!IsOaktonCommandType(type))
{
throw new ArgumentOutOfRangeException(nameof(type),
$"Type '{type.FullName}' does not inherit from either OaktonCommannd or OaktonAsyncCommand");
}

/// <summary>
/// Add all the IOaktonCommand classes in the given assembly to the command runner
/// </summary>
/// <param name="assembly"></param>
public void RegisterCommands(Assembly assembly)
{
assembly
.GetExportedTypes()
.Where(IsOaktonCommandType)
.Each(t => { _commandTypes[CommandNameFor(t)] = t; });
_commandTypes[CommandNameFor(type)] = type;
}

public static bool IsOaktonCommandType(Type type)
{
if (!type.IsConcrete()) return false;

return type.Closes(typeof(OaktonCommand<>)) || type.Closes(typeof(OaktonAsyncCommand<>));
}

private Type _defaultCommand = null;

/// <summary>
/// Optionally designates the default command type. Useful if your console app only has one command
/// </summary>
public Type DefaultCommand
{
get => _defaultCommand ?? (_commandTypes.Count == 1 ? _commandTypes.GetAll().Single() : null);
set
if (!type.IsConcrete())
{
_defaultCommand = value;
if (value != null) _commandTypes[CommandNameFor(value)] = value;
return false;
}
}

public IEnumerable<IOaktonCommand> BuildAllCommands()
{
return _commandTypes.Select(x => _commandCreator.CreateCommand(x));
return type.Closes(typeof(OaktonCommand<>)) || type.Closes(typeof(OaktonAsyncCommand<>));
}


Expand All @@ -246,15 +254,14 @@ public IOaktonCommand Build(string commandName)
}



public CommandRun HelpRun(string commandName)
{
return HelpRun(new Queue<string>(new []{commandName}));
return HelpRun(new Queue<string>(new[] {commandName}));
}

public virtual CommandRun HelpRun(Queue<string> queue)
{
var input = (HelpInput) (new HelpCommand().Usages.BuildInput(queue, _commandCreator));
var input = (HelpInput) new HelpCommand().Usages.BuildInput(queue, _commandCreator);
input.CommandTypes = _commandTypes.GetAll();

// Little hokey, but show the detailed help for the default command
Expand All @@ -273,29 +280,27 @@ public virtual CommandRun HelpRun(Queue<string> queue)
input.InvalidCommandName = false;
var cmd = _commandCreator.CreateCommand(type);
input.Usage = cmd.Usages;
});
}

return new CommandRun(){
return new CommandRun
{
Command = new HelpCommand(),
Input = input
};
}


static readonly Regex regex = new Regex("(?<name>.+)Command",RegexOptions.Compiled);
public static string CommandNameFor(Type type)
{

var match = regex.Match(type.Name);
var name = type.Name;
if(match.Success)
if (match.Success)
{
name = match.Groups["name"].Value;
}

type.ForAttribute<DescriptionAttribute>(att => name = att.Name ?? name);

return name.ToLower();
Expand All @@ -313,16 +318,16 @@ public void SetAppName(string appName)
{
_appName = appName;
}

/// <summary>
/// Automatically discover any Oakton commands in assemblies marked as
/// [assembly: OaktonCommandAssembly]. Also
/// Automatically discover any Oakton commands in assemblies marked as
/// [assembly: OaktonCommandAssembly]. Also
/// </summary>
/// <param name="applicationAssembly"></param>
public void RegisterCommandsFromExtensionAssemblies()
{
var assemblies = AssemblyFinder
.FindAssemblies(a => a.HasAttribute<OaktonCommandAssemblyAttribute>() && !a.IsDynamic,txt => { }, false)
.FindAssemblies(a => a.HasAttribute<OaktonCommandAssemblyAttribute>() && !a.IsDynamic, txt => { })
.Concat(AppDomain.CurrentDomain.GetAssemblies())
.Where(a => a.HasAttribute<OaktonCommandAssemblyAttribute>() && !a.IsDynamic)
.Distinct()
Expand Down
36 changes: 16 additions & 20 deletions src/Oakton/Commands/CheckEnvironmentCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,32 +19,28 @@ public class CheckEnvironmentCommand : OaktonAsyncCommand<CheckEnvironmentInput>
public override async Task<bool> Execute(CheckEnvironmentInput input)
{

AnsiConsole.Render(
AnsiConsole.Write(
new FigletText("Oakton")
.LeftAligned());


using (var host = input.BuildHost())
{
var results = await EnvironmentChecker.ExecuteAllEnvironmentChecks(host.Services);

if (input.FileFlag.IsNotEmpty())
{
results.WriteToFile(input.FileFlag);
Console.WriteLine("Writing environment checks to " + input.FileFlag);
}
using var host = input.BuildHost();
var results = await EnvironmentChecker.ExecuteAllEnvironmentChecks(host.Services);

if (results.Failures.Any())
{
ConsoleWriter.Write(ConsoleColor.Red, "Some environment checks failed!");
return false;
}
else
{
ConsoleWriter.Write(ConsoleColor.Green, "All environment checks are good!");
return true;
}
if (input.FileFlag.IsNotEmpty())
{
results.WriteToFile(input.FileFlag);
Console.WriteLine("Writing environment checks to " + input.FileFlag);
}

if (results.Failures.Any())
{
ConsoleWriter.Write(ConsoleColor.Red, "Some environment checks failed!");
return false;
}

ConsoleWriter.Write(ConsoleColor.Green, "All environment checks are good!");
return true;
}

}
Expand Down
Loading

0 comments on commit 5920c3c

Please sign in to comment.