Skip to content

Commit 64ee50c

Browse files
committed
Merge branch '3.4-dev'
2 parents 79723bf + 7cfb95c commit 64ee50c

File tree

9 files changed

+85
-60
lines changed

9 files changed

+85
-60
lines changed

src/InEngine.Core.Test/InEngine.Core.Test.csproj

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,13 @@
1111
<Description>Plugin-based queuing and scheduling command server.</Description>
1212
<Copyright>Copyright © 2017 Ethan Hann</Copyright>
1313
</PropertyGroup>
14-
<ItemGroup>
15-
<PackageReference Include="BeekmanLabs.UnitTesting" Version="0.0.0" />
16-
<PackageReference Include="Moq" Version="4.7.145" />
17-
<PackageReference Include="NUnit" Version="3.9.0" />
18-
<PackageReference Include="NUnit.Console" Version="3.7.0" />
19-
<PackageReference Include="NUnit.ConsoleRunner" Version="3.7.0" />
20-
<PackageReference Include="Quartz" Version="2.6.1" />
14+
<ItemGroup>
15+
<PackageReference Include="BeekmanLabs.UnitTesting" Version="0.0.0" />
16+
<PackageReference Include="Moq" Version="4.7.145" />
17+
<PackageReference Include="NUnit" Version="3.9.0" />
18+
<PackageReference Include="NUnit.Console" Version="3.7.0" />
19+
<PackageReference Include="NUnit.ConsoleRunner" Version="3.7.0" />
20+
<PackageReference Include="Quartz" Version="2.6.1" />
2121
</ItemGroup>
2222
<ItemGroup>
2323
<ProjectReference Include="..\InEngine.Core\InEngine.Core.csproj" />

src/InEngine.Core.Test/Queue/Commands/PublishTest.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ public void ShouldPublishCommandObject()
3030
public void ShouldPublishCommandByArgs()
3131
{
3232
var nullCommand = new AlwaysSucceed();
33-
Subject.CommandAssembly = nullCommand.GetType().Assembly.GetName().Name + ".dll";
33+
Subject.CommandPlugin = nullCommand.GetType().Assembly.GetName().Name + ".dll";
3434
Subject.CommandClass = nullCommand.GetType().FullName;
3535

3636
Subject.Run();
@@ -53,7 +53,7 @@ public void ShouldPublishManyCommands()
5353
[Test]
5454
public void ShouldFailWhenCommandDoesNotExist()
5555
{
56-
Subject.CommandAssembly = "foo";
56+
Subject.CommandPlugin = "foo";
5757
Subject.CommandClass = "bar";
5858
var expectedMessage = "Plugin not found at ";
5959

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
using System;
2+
namespace InEngine.Core.Exceptions
3+
{
4+
public class AmbiguousCommandException : Exception
5+
{
6+
public AmbiguousCommandException(string commandName)
7+
: base($"Command name found in multiple plugins: {commandName}")
8+
{
9+
}
10+
}
11+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
using System;
2+
3+
namespace InEngine.Core.Exceptions
4+
{
5+
public class CommandNotFoundException : Exception
6+
{
7+
public CommandNotFoundException(string command)
8+
: base($"Command not found: {command}")
9+
{}
10+
}
11+
}

src/InEngine.Core/Plugin.cs

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using System.IO;
44
using System.Linq;
55
using System.Reflection;
6+
using CommandLine;
67
using InEngine.Core.Exceptions;
78
using NLog;
89

@@ -67,9 +68,28 @@ public static List<Plugin> Discover<T>() where T : IPluginType
6768
return pluginList.OrderBy(x => x.Name).ToList();
6869
}
6970

70-
public ICommand CreateCommandInstance(string fullCommandName)
71+
public ICommand CreateCommandFromClass(string fullCommandName)
7172
{
72-
return Assembly.CreateInstance(fullCommandName) as ICommand;
73+
return Assembly.CreateInstance(fullCommandName) as ICommand;
74+
}
75+
76+
public ICommand CreateCommandFromVerb(string verbName)
77+
{
78+
var commandClassNames = new List<string>();
79+
var optionsList = Make<IOptions>();
80+
81+
foreach (var options in optionsList)
82+
foreach (var property in options.GetType().GetProperties())
83+
foreach (var attribute in property.GetCustomAttributes(true))
84+
if (attribute is VerbOptionAttribute && (attribute as VerbOptionAttribute).LongName == verbName)
85+
commandClassNames.Add(property.PropertyType.FullName);
86+
87+
var commandCount = commandClassNames.Count();
88+
if (commandCount > 1)
89+
throw new AmbiguousCommandException(verbName);
90+
if (commandCount == 0)
91+
throw new CommandNotFoundException(verbName);
92+
return Assembly.CreateInstance(commandClassNames.First()) as ICommand;
7393
}
7494
}
7595
}

src/InEngine.Core/Queue/Broker.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -168,8 +168,9 @@ public List<Message> PeekFailedMessages(long from, long to)
168168

169169
public List<Message> GetMessages(string queueName, long from, long to)
170170
{
171-
var redisValues = Redis.ListRange(queueName, from, to).ToStringArray();
172-
return redisValues.Select(x => x.DeserializeFromJson<Message>()).ToList();
171+
return Redis.ListRange(queueName, from, to)
172+
.ToStringArray()
173+
.Select(x => x.DeserializeFromJson<Message>()).ToList();
173174
}
174175
#endregion
175176
}

src/InEngine.Core/Queue/Commands/Publish.cs

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,23 +7,36 @@ namespace InEngine.Core.Queue.Commands
77
{
88
public class Publish : AbstractCommand
99
{
10-
[Option("command-assembly", Required = true, HelpText = "The name of a command plugin, e.g. InEngine.Core.dll")]
11-
public string CommandAssembly { get; set; }
10+
[Option("command-plugin", Required = true, HelpText = "The name of a command plugin file, e.g. InEngine.Core.dll")]
11+
public string CommandPlugin { get; set; }
1212

13-
[Option("command-class", Required = true, DefaultValue = "The name of a command class, e.g. InEngine.Core.Commands.AlwaysSucceed")]
13+
[Option("command-verb", HelpText = "A plugin command verb, e.g. echo")]
14+
public string CommandVerb { get; set; }
15+
16+
[Option("command-class", HelpText = "A command class name, e.g. InEngine.Core.Commands.AlwaysSucceed. Takes precedence over --command-verb if both are specified.")]
1417
public string CommandClass { get; set; }
1518

16-
[OptionArray("args", HelpText = "The list of arguments for the published command.")]
19+
[OptionArray("args", HelpText = "An optional list of arguments to publish with the command.")]
1720
public string[] Arguments { get; set; }
1821

19-
[Option("secondary", DefaultValue = false, HelpText = "Publish to a secondary queue.")]
22+
[Option("secondary", DefaultValue = false, HelpText = "Publish the command to the secondary queue.")]
2023
public bool UseSecondaryQueue { get; set; }
2124

2225
public ICommand Command { get; set; }
2326

2427
public override void Run()
2528
{
26-
var command = Command ?? Plugin.LoadFrom(CommandAssembly).CreateCommandInstance(CommandClass);
29+
var command = Command;
30+
31+
if (command == null && !string.IsNullOrWhiteSpace(CommandPlugin)) {
32+
var plugin = Plugin.LoadFrom(CommandPlugin);
33+
if (!string.IsNullOrWhiteSpace(CommandClass))
34+
command = plugin.CreateCommandFromClass(CommandClass);
35+
else if (!string.IsNullOrWhiteSpace(CommandVerb)) {
36+
command = plugin.CreateCommandFromVerb(CommandVerb);
37+
}
38+
}
39+
2740
if (command == null)
2841
throw new CommandFailedException("Did not publish message. Could not load command from plugin.");
2942

src/InEngine.Net.sln

Lines changed: 3 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,11 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "SolutionItems", "SolutionIt
88
README.md = README.md
99
EndProjectSection
1010
EndProject
11-
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "InEngine.Core", "InEngine.Core\InEngine.Core.csproj", "{1C604C4F-3F98-483C-89E3-C951BE03366A}"
11+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "InEngine.Core", "InEngine.Core\InEngine.Core.csproj", "{1C604C4F-3F98-483C-89E3-C951BE03366A}"
1212
EndProject
13-
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "InEngine", "InEngine\InEngine.csproj", "{DF1A45FD-4887-4D65-8BAD-EE17B70FE79D}"
13+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "InEngine", "InEngine\InEngine.csproj", "{DF1A45FD-4887-4D65-8BAD-EE17B70FE79D}"
1414
EndProject
15-
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "InEngine.Commands", "InEngine.Commands\InEngine.Commands.csproj", "{5EDAF024-3BD1-4D22-A6E5-9EF808DB14C8}"
15+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "InEngine.Commands", "InEngine.Commands\InEngine.Commands.csproj", "{5EDAF024-3BD1-4D22-A6E5-9EF808DB14C8}"
1616
EndProject
1717
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "InEngine.Core.Test", "InEngine.Core.Test\InEngine.Core.Test.csproj", "{030204D0-6469-4A46-827E-122B0215F47E}"
1818
EndProject
@@ -48,34 +48,5 @@ Global
4848
GlobalSection(MonoDevelopProperties) = preSolution
4949
Policies = $0
5050
$0.TextStylePolicy = $11
51-
$1.TabsToSpaces = True
52-
$1.scope = text/x-csharp
53-
$0.CSharpFormattingPolicy = $2
54-
$2.scope = text/x-csharp
55-
$3.TabsToSpaces = True
56-
$3.EolMarker = Unix
57-
$3.scope = text/plain
58-
$4.inheritsSet = null
59-
$4.scope = application/config+xml
60-
$0.XmlFormattingPolicy = $7
61-
$5.inheritsSet = null
62-
$5.scope = application/config+xml
63-
$6.TabsToSpaces = True
64-
$6.scope = application/xml
65-
$7.scope = application/xml
66-
$8.TabWidth = 2
67-
$8.TabsToSpaces = True
68-
$8.IndentWidth = 2
69-
$8.NoTabsAfterNonTabs = True
70-
$8.scope = text/x-json
71-
$0.JSONFormattingPolicy = $9
72-
$9.AutoStructureCompletion = True
73-
$9.BracePositions = SemiExpanded
74-
$9.FormatOnPaste = True
75-
$9.scope = text/x-json
76-
$10.inheritsSet = null
77-
$10.scope = text/x-web
78-
$11.inheritsSet = null
79-
$11.scope = text/x-vs
8051
EndGlobalSection
8152
EndGlobal

src/InEngine/ArgumentInterpreter.cs

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ protected string MakeErrorMessage(string message = null)
113113

114114
public void InterpretPluginArguments(string[] pluginArgs, IOptions pluginOptions)
115115
{
116-
var isSuccessful =Parser.Default.ParseArguments(pluginArgs, pluginOptions, (verb, subOptions) => {
116+
var isSuccessful = Parser.Default.ParseArguments(pluginArgs, pluginOptions, (verb, subOptions) => {
117117
try
118118
{
119119
var lastArg = pluginArgs.ToList().LastOrDefault();
@@ -152,18 +152,16 @@ public void PrintPluginHelpTextAndExit(Plugin plugin, List<IOptions> pluginOptio
152152
foreach (var pluginOptions in pluginOptionList)
153153
{
154154
Parser.Default.ParseArguments(pluginArgs, pluginOptions);
155-
156-
var verbs = pluginOptions
155+
pluginOptions
157156
.GetType()
158157
.GetProperties()
159158
.SelectMany(x => x.GetCustomAttributes(true))
160159
.Where(x => x is BaseOptionAttribute)
161-
.ToList();
162-
163-
verbs.ForEach(x => {
164-
var optionAttribute = (x as BaseOptionAttribute);
165-
Console.WriteLine($" {optionAttribute.LongName}\t{optionAttribute.HelpText}");
166-
});
160+
.ToList()
161+
.ForEach(x => {
162+
var optionAttribute = (x as BaseOptionAttribute);
163+
Console.WriteLine($" {optionAttribute.LongName}\t{optionAttribute.HelpText}");
164+
});
167165

168166
}
169167
ExitWithSuccess();

0 commit comments

Comments
 (0)