Lean  $LEAN_TAG$
ApplicationParser.cs
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Reflection;
5 using McMaster.Extensions.CommandLineUtils;
6 
8 {
9  /// <summary>
10  /// Command Line application parser
11  /// </summary>
12  public static class ApplicationParser
13  {
14  /// <summary>
15  /// This function will parse args based on options and will show application name, version, help
16  /// </summary>
17  /// <param name="applicationName">The application name to be shown</param>
18  /// <param name="applicationDescription">The application description to be shown</param>
19  /// <param name="applicationHelpText">The application help text</param>
20  /// <param name="args">The command line arguments</param>
21  /// <param name="options">The applications command line available options</param>
22  /// <param name="noArgsShowHelp">To show help when no command line arguments were provided</param>
23  /// <returns>The user provided options. Key is option name</returns>
24  public static Dictionary<string, object> Parse(string applicationName, string applicationDescription, string applicationHelpText,
25  string[] args, List<CommandLineOption> options, bool noArgsShowHelp = false)
26  {
27  var application = new CommandLineApplication
28  {
29  Name = applicationName,
30  Description = applicationDescription,
31  ExtendedHelpText = applicationHelpText
32  };
33 
34  application.HelpOption("-?|-h|--help");
35 
36  // This is a helper/shortcut method to display version info - it is creating a regular Option, with some defaults.
37  // The default help text is "Show version Information"
38  application.VersionOption("-v|-V|--version",
39  () =>
40  $"Version {Assembly.GetEntryAssembly().GetCustomAttribute<AssemblyInformationalVersionAttribute>()?.InformationalVersion}");
41 
42  var optionsObject = new Dictionary<string, object>();
43 
44  var listOfOptions = new List<CommandOption>();
45 
46  foreach (var option in options)
47  {
48  listOfOptions.Add(application.Option($"--{option.Name}", option.Description, option.Type));
49  }
50 
51  application.OnExecute(() =>
52  {
53  foreach (var commandOption in listOfOptions.Where(option => option.HasValue()))
54  {
55  var optionKey = commandOption.Template.Replace("--", "");
56  var matchingOption = options.Find(o => o.Name == optionKey);
57  switch (matchingOption.Type)
58  {
59  // Booleans
60  case CommandOptionType.NoValue:
61  optionsObject[optionKey] = true;
62  break;
63 
64  // Strings and numbers
65  case CommandOptionType.SingleValue:
66  optionsObject[optionKey] = commandOption.Value();
67  break;
68 
69  // Parsing nested objects
70  case CommandOptionType.MultipleValue:
71  var keyValuePairs = commandOption.Value().Split(',');
72  var subDictionary = new Dictionary<string, string>();
73  foreach (var keyValuePair in keyValuePairs)
74  {
75  var subKeys = keyValuePair.Split(':');
76  subDictionary[subKeys[0]] = subKeys.Length > 1 ? subKeys[1] : "";
77  }
78 
79  optionsObject[optionKey] = subDictionary;
80  break;
81  default:
82  throw new ArgumentOutOfRangeException();
83  }
84  }
85 
86  return 0;
87  });
88 
89  application.Execute(args);
90  if (noArgsShowHelp && args.Length == 0)
91  {
92  application.ShowHelp();
93  }
94  return optionsObject;
95  }
96 
97  /// <summary>
98  /// Prints a message advising the user to use the --help parameter for more information
99  /// </summary>
100  public static void PrintMessageAndExit(int exitCode = 0, string message = "")
101  {
102  if (!string.IsNullOrEmpty(message))
103  {
104  Console.WriteLine("\n" + message);
105  }
106  Console.WriteLine("\nUse the '--help' parameter for more information");
107  Console.WriteLine("Press any key to quit");
108  Console.ReadLine();
109  Environment.Exit(exitCode);
110  }
111 
112  /// <summary>
113  /// Gets the parameter object from the given parameter (if it exists)
114  /// </summary>
115  public static string GetParameterOrExit(IReadOnlyDictionary<string, object> optionsObject, string parameter)
116  {
117  if (!optionsObject.ContainsKey(parameter))
118  {
119  PrintMessageAndExit(1, "ERROR: REQUIRED parameter --" + parameter + "= is missing");
120  }
121  return optionsObject[parameter].ToString();
122  }
123 
124  /// <summary>
125  /// Gets the parameter object from the given parameter. If it does not exists, it returns a default parameter object
126  /// </summary>
127  public static string GetParameterOrDefault(IReadOnlyDictionary<string, object> optionsObject, string parameter, string defaultValue)
128  {
129  object value;
130  if (!optionsObject.TryGetValue(parameter, out value))
131  {
132  Console.WriteLine($"'{parameter}' was not specified. Using default value: '{defaultValue}'");
133  return defaultValue;
134  }
135 
136  return value.ToString();
137  }
138  }
139 }