Rename OrchardCommand to CommandName attribute

Also workaround issue with commands registered twice

--HG--
branch : dev
rename : src/Orchard/Commands/OrchardCommandAttribute.cs => src/Orchard/Commands/CommandNameAttribute.cs
This commit is contained in:
Renaud Paquay
2010-04-12 17:49:16 -07:00
parent 304ff9814b
commit a86d6f8542
10 changed files with 82 additions and 33 deletions

View File

@@ -16,8 +16,8 @@ namespace Orchard.Tests.Commands {
Assert.That(descriptor.Commands.Count(), Is.EqualTo(4));
Assert.That(descriptor.Commands.Single(d => d.Name == "FooBar"), Is.Not.Null);
Assert.That(descriptor.Commands.Single(d => d.Name == "FooBar").MethodInfo, Is.EqualTo(typeof(MyCommand).GetMethod("FooBar")));
Assert.That(descriptor.Commands.Single(d => d.Name == "Whereslou"), Is.Not.Null);
Assert.That(descriptor.Commands.Single(d => d.Name == "Whereslou").MethodInfo, Is.EqualTo(typeof(MyCommand).GetMethod("FooBar2")));
Assert.That(descriptor.Commands.Single(d => d.Name == "MyCommand"), Is.Not.Null);
Assert.That(descriptor.Commands.Single(d => d.Name == "MyCommand").MethodInfo, Is.EqualTo(typeof(MyCommand).GetMethod("FooBar2")));
Assert.That(descriptor.Commands.Single(d => d.Name == "Foo Bar"), Is.Not.Null);
Assert.That(descriptor.Commands.Single(d => d.Name == "Foo Bar").MethodInfo, Is.EqualTo(typeof(MyCommand).GetMethod("Foo_Bar")));
Assert.That(descriptor.Commands.Single(d => d.Name == "Foo_Bar"), Is.Not.Null);
@@ -28,14 +28,14 @@ namespace Orchard.Tests.Commands {
public void FooBar() {
}
[OrchardCommand("Whereslou")]
[CommandName("MyCommand")]
public void FooBar2() {
}
public void Foo_Bar() {
}
[OrchardCommand("Foo_Bar")]
[CommandName("Foo_Bar")]
public void Foo_Bar3() {
}
}

View File

@@ -180,7 +180,7 @@ namespace Orchard.Tests.Commands {
return "Command Foo Executed";
}
[OrchardCommand("Bar")]
[CommandName("Bar")]
public string Hello() {
return "Hello World!";
}

View File

@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using Autofac.Features.Metadata;
using Orchard.Localization;
namespace Orchard.Commands.Builtin {
public class HelpCommand : DefaultOrchardCommandHandler {
@@ -11,13 +12,32 @@ namespace Orchard.Commands.Builtin {
_commandManager = commandManager;
}
[OrchardCommand("help commands")]
[CommandHelp("List all available commands")]
public void Commands() {
[CommandName("help commands")]
[CommandHelp("help commands: Display help text for all available commands")]
public void AllCommands() {
Context.Output.WriteLine(T("List of available commands:"));
Context.Output.WriteLine(T("---------------------------"));
var descriptors = _commandManager.GetCommandDescriptors();
foreach (var descriptor in descriptors) {
var helpText = string.IsNullOrEmpty(descriptor.HelpText) ? T("[no help text]") : T(descriptor.HelpText);
Context.Output.WriteLine("{0}: {1}", descriptor.Name, helpText);
Context.Output.WriteLine(GetHelpText(descriptor));
}
}
private LocalizedString GetHelpText(CommandDescriptor descriptor) {
return string.IsNullOrEmpty(descriptor.HelpText) ? T("[no help text]") : T(descriptor.HelpText);
}
[CommandName("help")]
[CommandHelp("help <command>: Display help text for <command>")]
public void SingleCommand(string[] commandNameStrings) {
string command = string.Join(" ", commandNameStrings);
var descriptor = _commandManager.GetCommandDescriptors().SingleOrDefault(d => string.Equals(command, d.Name, StringComparison.OrdinalIgnoreCase));
if (descriptor == null) {
Context.Output.WriteLine(T("Command {0} doesn't exist").ToString(), command);
}
else {
Context.Output.WriteLine(GetHelpText(descriptor));
}
}
}

View File

@@ -32,9 +32,9 @@ namespace Orchard.Commands {
}
private string GetCommandName(MethodInfo methodInfo) {
var attributes = methodInfo.GetCustomAttributes(typeof(OrchardCommandAttribute), false/*inherit*/);
var attributes = methodInfo.GetCustomAttributes(typeof(CommandNameAttribute), false/*inherit*/);
if (attributes != null && attributes.Any()) {
return attributes.Cast<OrchardCommandAttribute>().Single().Command;
return attributes.Cast<CommandNameAttribute>().Single().Command;
}
return methodInfo.Name.Replace('_', ' ');

View File

@@ -16,7 +16,7 @@ namespace Orchard.Commands {
/// executing a single command.
/// </summary>
public class CommandHostAgent {
public void RunSingleCommand(TextReader input, TextWriter output, string tenant, string[] args, Dictionary<string,string> switches) {
public int RunSingleCommand(TextReader input, TextWriter output, string tenant, string[] args, Dictionary<string,string> switches) {
try {
var hostContainer = OrchardStarter.CreateHostContainer(MvcSingletons);
var host = hostContainer.Resolve<IOrchardHost>();
@@ -37,11 +37,15 @@ namespace Orchard.Commands {
};
env.Resolve<ICommandManager>().Execute(parameters);
}
return 0;
}
catch (Exception e) {
for(; e != null; e = e.InnerException) {
Console.WriteLine("Error: {0}", e.Message);
output.WriteLine("Error: {0}", e.Message);
output.WriteLine("{0}", e.StackTrace);
}
return 5;
}
}

View File

@@ -2,10 +2,10 @@
namespace Orchard.Commands {
[AttributeUsage(AttributeTargets.Method)]
public class OrchardCommandAttribute : Attribute {
public class CommandNameAttribute : Attribute {
private readonly string _commandAlias;
public OrchardCommandAttribute(string commandAlias) {
public CommandNameAttribute(string commandAlias) {
_commandAlias = commandAlias;
}

View File

@@ -13,8 +13,7 @@ namespace Orchard.Commands {
}
public void Execute(CommandParameters parameters) {
var matches = _handlers.SelectMany(h => MatchCommands(parameters, GetDescriptor(h.Metadata), h.Value));
var matches = MatchCommands(parameters);
// Workaround autofac integration: module registration is currently run twice...
//if (matches.Count() == 1) {
@@ -32,18 +31,27 @@ namespace Orchard.Commands {
}
public IEnumerable<CommandDescriptor> GetCommandDescriptors() {
return _handlers.SelectMany(h => GetDescriptor(h.Metadata).Commands);
return _handlers
.SelectMany(h => GetDescriptor(h.Metadata).Commands)
// Workaround autofac integration: module registration is currently run twice...
.Distinct(new CommandsComparer());
}
private class Match {
public CommandContext Context { get; set; }
public Func<ICommandHandler> CommandHandlerFactory { get; set; }
private IEnumerable<Match> MatchCommands(CommandParameters parameters) {
foreach (var argCount in Enumerable.Range(1, parameters.Arguments.Count()).Reverse()) {
int count = argCount;
var matches = _handlers.SelectMany(h => MatchCommands(parameters, count, GetDescriptor(h.Metadata), h.Value));
if (matches.Any())
return matches;
}
return Enumerable.Empty<Match>();
}
private static IEnumerable<Match> MatchCommands(CommandParameters parameters, CommandHandlerDescriptor descriptor, Func<ICommandHandler> handlerFactory) {
private static IEnumerable<Match> MatchCommands(CommandParameters parameters, int argCount, CommandHandlerDescriptor descriptor, Func<ICommandHandler> handlerFactory) {
foreach (var commandDescriptor in descriptor.Commands) {
string[] names = commandDescriptor.Name.Split(' ');
if (!parameters.Arguments.Take(names.Count()).SequenceEqual(names, StringComparer.OrdinalIgnoreCase)) {
var names = commandDescriptor.Name.Split(' ');
if (!parameters.Arguments.Take(argCount).SequenceEqual(names, StringComparer.OrdinalIgnoreCase)) {
// leading arguments not equal to command name
continue;
}
@@ -51,7 +59,7 @@ namespace Orchard.Commands {
yield return new Match {
Context = new CommandContext {
Arguments = parameters.Arguments.Skip(names.Count()),
Command = string.Join(" ",names),
Command = string.Join(" ", names),
CommandDescriptor = commandDescriptor,
Input = parameters.Input,
Output = parameters.Output,
@@ -65,5 +73,20 @@ namespace Orchard.Commands {
private static CommandHandlerDescriptor GetDescriptor(IDictionary<string, object> metadata) {
return ((CommandHandlerDescriptor)metadata[typeof(CommandHandlerDescriptor).FullName]);
}
private class Match {
public CommandContext Context { get; set; }
public Func<ICommandHandler> CommandHandlerFactory { get; set; }
}
public class CommandsComparer : IEqualityComparer<CommandDescriptor> {
public bool Equals(CommandDescriptor x, CommandDescriptor y) {
return x.MethodInfo.Equals(y.MethodInfo);
}
public int GetHashCode(CommandDescriptor obj) {
return obj.MethodInfo.GetHashCode();
}
}
}
}

View File

@@ -146,7 +146,7 @@
<Compile Include="Commands\CommandModule.cs" />
<Compile Include="Commands\Builtin\HelpCommand.cs" />
<Compile Include="Commands\ICommandManager.cs" />
<Compile Include="Commands\OrchardCommandAttribute.cs" />
<Compile Include="Commands\CommandNameAttribute.cs" />
<Compile Include="Commands\CommandContext.cs" />
<Compile Include="Commands\DefaultOrchardCommandHandler.cs" />
<Compile Include="Commands\ICommandHandler.cs" />

View File

@@ -19,14 +19,16 @@ namespace Orchard.Host {
//TODO
}
public void RunCommand(OrchardParameters args) {
public int RunCommand(OrchardParameters args) {
var agent = Activator.CreateInstance("Orchard.Framework", "Orchard.Commands.CommandHostAgent").Unwrap();
agent.GetType().GetMethod("RunSingleCommand").Invoke(agent, new object[] {
int result = (int)agent.GetType().GetMethod("RunSingleCommand").Invoke(agent, new object[] {
Console.In,
Console.Out,
args.Tenant,
args.Arguments.ToArray(),
args.Switches});
return result;
}
}
}

View File

@@ -18,11 +18,11 @@ namespace Orchard {
_args = args;
}
static void Main(string[] args) {
new Program(args).Run();
static int Main(string[] args) {
return new Program(args).Run();
}
public void Run() {
public int Run() {
// Parse command line arguments
var arguments = new OrchardParametersParser().Parse(new CommandParametersParser().Parse(_args));
@@ -51,7 +51,7 @@ namespace Orchard {
if (arguments.Verbose) {
Console.WriteLine("Executing command in ASP.NET AppDomain");
}
host.RunCommand(arguments);
return host.RunCommand(arguments);
}
private DirectoryInfo GetOrchardDirectory(string directory) {