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.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"), 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 == "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 == "MyCommand"), 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").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"), 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").MethodInfo, Is.EqualTo(typeof(MyCommand).GetMethod("Foo_Bar")));
Assert.That(descriptor.Commands.Single(d => d.Name == "Foo_Bar"), Is.Not.Null); Assert.That(descriptor.Commands.Single(d => d.Name == "Foo_Bar"), Is.Not.Null);
@@ -28,14 +28,14 @@ namespace Orchard.Tests.Commands {
public void FooBar() { public void FooBar() {
} }
[OrchardCommand("Whereslou")] [CommandName("MyCommand")]
public void FooBar2() { public void FooBar2() {
} }
public void Foo_Bar() { public void Foo_Bar() {
} }
[OrchardCommand("Foo_Bar")] [CommandName("Foo_Bar")]
public void Foo_Bar3() { public void Foo_Bar3() {
} }
} }

View File

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

View File

@@ -2,6 +2,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using Autofac.Features.Metadata; using Autofac.Features.Metadata;
using Orchard.Localization;
namespace Orchard.Commands.Builtin { namespace Orchard.Commands.Builtin {
public class HelpCommand : DefaultOrchardCommandHandler { public class HelpCommand : DefaultOrchardCommandHandler {
@@ -11,13 +12,32 @@ namespace Orchard.Commands.Builtin {
_commandManager = commandManager; _commandManager = commandManager;
} }
[OrchardCommand("help commands")] [CommandName("help commands")]
[CommandHelp("List all available commands")] [CommandHelp("help commands: Display help text for all available commands")]
public void Commands() { public void AllCommands() {
Context.Output.WriteLine(T("List of available commands:"));
Context.Output.WriteLine(T("---------------------------"));
var descriptors = _commandManager.GetCommandDescriptors(); var descriptors = _commandManager.GetCommandDescriptors();
foreach (var descriptor in descriptors) { foreach (var descriptor in descriptors) {
var helpText = string.IsNullOrEmpty(descriptor.HelpText) ? T("[no help text]") : T(descriptor.HelpText); Context.Output.WriteLine(GetHelpText(descriptor));
Context.Output.WriteLine("{0}: {1}", descriptor.Name, helpText); }
}
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) { 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()) { if (attributes != null && attributes.Any()) {
return attributes.Cast<OrchardCommandAttribute>().Single().Command; return attributes.Cast<CommandNameAttribute>().Single().Command;
} }
return methodInfo.Name.Replace('_', ' '); return methodInfo.Name.Replace('_', ' ');

View File

@@ -16,7 +16,7 @@ namespace Orchard.Commands {
/// executing a single command. /// executing a single command.
/// </summary> /// </summary>
public class CommandHostAgent { 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 { try {
var hostContainer = OrchardStarter.CreateHostContainer(MvcSingletons); var hostContainer = OrchardStarter.CreateHostContainer(MvcSingletons);
var host = hostContainer.Resolve<IOrchardHost>(); var host = hostContainer.Resolve<IOrchardHost>();
@@ -37,11 +37,15 @@ namespace Orchard.Commands {
}; };
env.Resolve<ICommandManager>().Execute(parameters); env.Resolve<ICommandManager>().Execute(parameters);
} }
return 0;
} }
catch (Exception e) { catch (Exception e) {
for(; e != null; e = e.InnerException) { 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 { namespace Orchard.Commands {
[AttributeUsage(AttributeTargets.Method)] [AttributeUsage(AttributeTargets.Method)]
public class OrchardCommandAttribute : Attribute { public class CommandNameAttribute : Attribute {
private readonly string _commandAlias; private readonly string _commandAlias;
public OrchardCommandAttribute(string commandAlias) { public CommandNameAttribute(string commandAlias) {
_commandAlias = commandAlias; _commandAlias = commandAlias;
} }

View File

@@ -13,8 +13,7 @@ namespace Orchard.Commands {
} }
public void Execute(CommandParameters parameters) { 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... // Workaround autofac integration: module registration is currently run twice...
//if (matches.Count() == 1) { //if (matches.Count() == 1) {
@@ -32,18 +31,27 @@ namespace Orchard.Commands {
} }
public IEnumerable<CommandDescriptor> GetCommandDescriptors() { 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 { private IEnumerable<Match> MatchCommands(CommandParameters parameters) {
public CommandContext Context { get; set; } foreach (var argCount in Enumerable.Range(1, parameters.Arguments.Count()).Reverse()) {
public Func<ICommandHandler> CommandHandlerFactory { get; set; } 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) { foreach (var commandDescriptor in descriptor.Commands) {
string[] names = commandDescriptor.Name.Split(' '); var names = commandDescriptor.Name.Split(' ');
if (!parameters.Arguments.Take(names.Count()).SequenceEqual(names, StringComparer.OrdinalIgnoreCase)) { if (!parameters.Arguments.Take(argCount).SequenceEqual(names, StringComparer.OrdinalIgnoreCase)) {
// leading arguments not equal to command name // leading arguments not equal to command name
continue; continue;
} }
@@ -51,7 +59,7 @@ namespace Orchard.Commands {
yield return new Match { yield return new Match {
Context = new CommandContext { Context = new CommandContext {
Arguments = parameters.Arguments.Skip(names.Count()), Arguments = parameters.Arguments.Skip(names.Count()),
Command = string.Join(" ",names), Command = string.Join(" ", names),
CommandDescriptor = commandDescriptor, CommandDescriptor = commandDescriptor,
Input = parameters.Input, Input = parameters.Input,
Output = parameters.Output, Output = parameters.Output,
@@ -65,5 +73,20 @@ namespace Orchard.Commands {
private static CommandHandlerDescriptor GetDescriptor(IDictionary<string, object> metadata) { private static CommandHandlerDescriptor GetDescriptor(IDictionary<string, object> metadata) {
return ((CommandHandlerDescriptor)metadata[typeof(CommandHandlerDescriptor).FullName]); 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\CommandModule.cs" />
<Compile Include="Commands\Builtin\HelpCommand.cs" /> <Compile Include="Commands\Builtin\HelpCommand.cs" />
<Compile Include="Commands\ICommandManager.cs" /> <Compile Include="Commands\ICommandManager.cs" />
<Compile Include="Commands\OrchardCommandAttribute.cs" /> <Compile Include="Commands\CommandNameAttribute.cs" />
<Compile Include="Commands\CommandContext.cs" /> <Compile Include="Commands\CommandContext.cs" />
<Compile Include="Commands\DefaultOrchardCommandHandler.cs" /> <Compile Include="Commands\DefaultOrchardCommandHandler.cs" />
<Compile Include="Commands\ICommandHandler.cs" /> <Compile Include="Commands\ICommandHandler.cs" />

View File

@@ -19,14 +19,16 @@ namespace Orchard.Host {
//TODO //TODO
} }
public void RunCommand(OrchardParameters args) { public int RunCommand(OrchardParameters args) {
var agent = Activator.CreateInstance("Orchard.Framework", "Orchard.Commands.CommandHostAgent").Unwrap(); 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.In,
Console.Out, Console.Out,
args.Tenant, args.Tenant,
args.Arguments.ToArray(), args.Arguments.ToArray(),
args.Switches}); args.Switches});
return result;
} }
} }
} }

View File

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