Skip to content

Commit e70d60d

Browse files
committed
Support multiple option files in a single assembly
1 parent 347ccbe commit e70d60d

File tree

6 files changed

+62
-25
lines changed

6 files changed

+62
-25
lines changed

src/InEngine.Commands/InEngine.Commands.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
<Compile Include="Sample\ShowProgress.cs" />
3939
<Compile Include="Sample\SayHello.cs" />
4040
<Compile Include="Options.cs" />
41+
<Compile Include="MoreOptions.cs" />
4142
</ItemGroup>
4243
<ItemGroup>
4344
<Folder Include="Sample\" />
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
using CommandLine;
2+
using CommandLine.Text;
3+
using InEngine.Commands.Sample;
4+
using InEngine.Core;
5+
6+
namespace InEngine.Commands
7+
{
8+
public class MoreOptions : IOptions
9+
{
10+
[VerbOption("sample:show-progress")]
11+
public ShowProgress ShowProgress { get; set; }
12+
13+
[VerbOption("sample:say-hello")]
14+
public SayHello SayHello { get; set; }
15+
16+
[HelpVerbOption]
17+
public string GetUsage(string verb)
18+
{
19+
return HelpText.AutoBuild(this, verb);
20+
}
21+
}
22+
}

src/InEngine.Commands/Options.cs

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,6 @@ public class Options : IOptions
1010
[VerbOption("sample:minimal")]
1111
public Minimal Minimal { get; set; }
1212

13-
[VerbOption("sample:show-progress")]
14-
public ShowProgress ShowProgress { get; set; }
15-
16-
[VerbOption("sample:say-hello")]
17-
public SayHello SayHello { get; set; }
18-
1913
[HelpVerbOption]
2014
public string GetUsage(string verb)
2115
{

src/InEngine.Core/Plugin.cs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.Collections.Generic;
23
using System.Linq;
34
using System.Reflection;
45

@@ -14,12 +15,13 @@ public Plugin(Assembly assembly)
1415
Assembly = assembly;
1516
}
1617

17-
public IOptions MakeOptions()
18+
public List<IOptions> MakeOptions()
1819
{
19-
var optionType = Assembly.GetTypes().FirstOrDefault(x => x.IsClass && typeof(IOptions).IsAssignableFrom(x));
20-
if (optionType == null)
21-
Environment.Exit(CommandLine.Parser.DefaultExitCodeFail);
22-
return Assembly.CreateInstance(optionType.FullName) as IOptions;
20+
return Assembly
21+
.GetTypes()
22+
.Where(x => x.IsClass && typeof(IOptions).IsAssignableFrom(x))
23+
.Select(x => Assembly.CreateInstance(x.FullName) as IOptions)
24+
.ToList();
2325
}
2426
}
2527
}

src/InEngine.Net.userprefs

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,18 @@
11
<Properties StartupConfiguration="{DF1A45FD-4887-4D65-8BAD-EE17B70FE79D}|Default">
22
<MonoDevelop.Ide.ItemProperties.InEngineScheduler PreferredExecutionTarget="MonoDevelop.Default" />
3-
<MonoDevelop.Ide.Workbench ActiveDocument="InEngine.Commands/Options.cs">
3+
<MonoDevelop.Ide.Workbench ActiveDocument="InEngineCli/ArgumentInterpreter.cs">
44
<Files>
5-
<File FileName="InEngineCli/ArgumentInterpreter.cs" Line="46" Column="39" />
6-
<File FileName="InEngine.Core/Plugin.cs" Line="15" Column="10" />
7-
<File FileName="InEngine.Commands/Options.cs" Line="10" Column="22" />
5+
<File FileName="InEngineCli/ArgumentInterpreter.cs" Line="57" Column="52" />
6+
<File FileName="InEngine.Core/Plugin.cs" Line="17" Column="1" />
7+
<File FileName="InEngine.Commands/MoreOptions.cs" Line="10" Column="20" />
88
</Files>
99
<Pads>
1010
<Pad Id="ProjectPad">
1111
<State name="__root__">
1212
<Node name="InEngine.Net" expanded="True">
13-
<Node name="InEngine.Commands" expanded="True">
14-
<Node name="Options.cs" selected="True" />
15-
</Node>
13+
<Node name="InEngine.Commands" expanded="True" />
1614
<Node name="InEngine.Core" expanded="True" />
17-
<Node name="InEngineCli" expanded="True" />
18-
<Node name="InEngineScheduler" expanded="True" />
15+
<Node name="InEngineCli" expanded="True" selected="True" />
1916
</Node>
2017
</State>
2118
</Pad>

src/InEngineCli/ArgumentInterpreter.cs

Lines changed: 26 additions & 5 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;
78
using InEngine.Core.Exceptions;
89
using NLog;
@@ -35,17 +36,29 @@ public void Interpret(string[] args)
3536
{
3637
if (options == null)
3738
Environment.Exit(CommandLine.Parser.DefaultExitCodeFail);
39+
40+
var plugin = plugins.FirstOrDefault(x => x.Name == options.PlugInName);
41+
if (plugin == null)
42+
ExitWithFailure("Plugin does not exist: " + options.PlugInName);
3843

39-
var pluginOptions = plugins.FirstOrDefault(x => x.Name == options.PlugInName).MakeOptions();
44+
var pluginOptionList = plugin.MakeOptions();
45+
4046
var pluginArgs = args.Skip(1).ToArray();
4147
if (!pluginArgs.ToList().Any()) {
4248
// If the plugin's args are empty, print the plugin's help screen and exit.
43-
CommandLine.Parser.Default.ParseArguments(pluginArgs, pluginOptions);
44-
Console.WriteLine(pluginOptions.GetUsage(""));
49+
foreach(var pluginOptions in pluginOptionList) {
50+
CommandLine.Parser.Default.ParseArguments(pluginArgs, pluginOptions);
51+
Console.WriteLine(pluginOptions.GetUsage(""));
52+
}
4553
ExitWithSuccess();
4654
}
4755

48-
InterpretPluginArguments(pluginArgs, pluginOptions);
56+
var commandVerbName = pluginArgs.First();
57+
foreach (var ops in pluginOptionList)
58+
foreach (var prop in ops.GetType().GetProperties())
59+
foreach (object attr in prop.GetCustomAttributes(true))
60+
if (attr is VerbOptionAttribute commandVerb && (commandVerb.LongName == commandVerbName || commandVerb.ShortName.ToString() == commandVerbName))
61+
InterpretPluginArguments(pluginArgs, ops);
4962
}
5063
}
5164

@@ -57,6 +70,14 @@ public void ExitWithSuccess(string message = null)
5770
Environment.Exit(0);
5871
}
5972

73+
public void ExitWithFailure(string message = null)
74+
{
75+
if (string.IsNullOrWhiteSpace(message))
76+
message = "fail";
77+
Logger.Error($"✘ {message}");
78+
Environment.Exit(CommandLine.Parser.DefaultExitCodeFail);
79+
}
80+
6081
public void ExitWithFailure(Exception exception = null)
6182
{
6283
Logger.Error(exception ?? new CommandFailedException(), "✘ fail");
@@ -104,7 +125,7 @@ public void InterpretPluginArguments(string[] pluginArgs, IOptions pluginOptions
104125
});
105126

106127
if (!isSuccessful)
107-
ExitWithFailure();
128+
ExitWithFailure("Could not parse plugin arguments");
108129
}
109130
}
110131
}

0 commit comments

Comments
 (0)