Argopt: Command line argument parsing in .NET[source]
xml
<glacius:metadata> | |
<title>Argopt: Command line argument parsing in .NET</title> | |
<description>Introduction post for my CLI argument parsing library for .NET</description> | |
<category>Legacy blog posts</category> | |
<category>Programming</category> | |
<category>C#</category> | |
</glacius:metadata> | |
<glacius:macro name="legacy blargh banner"> | |
<properties> | |
<originalUrl>https://tmont.com/blargh/2011/5/argopt-command-line-argument-parsing-in-net</originalUrl> | |
<originalDate>2011-05-11T22:51:05.000Z</originalDate> | |
</properties> | |
</glacius:macro> | |
<p> | |
So, I was writing a console app in C# the other day, and I needed to parse some command | |
line arguments. A quick google search gave me | |
<a href="http://www.ndesk.org/Options">NDesk.Options</a>, which I've used before. | |
However, it's quite old. Whenever I see a .NET project that talks about using "new" | |
features like lambda expressions, I get a little wary. It also doesn't help that the | |
author and maintainer of the project claims it is <em>UNSTABLE</em>, and hasn't been | |
updated since 2008. | |
</p> | |
<p>So, I wrote my own.</p> | |
<p> | |
This isn't new territory for me: I wrote one in PHP before the | |
dawn of PHP 5.3 and platform-independent <a href="https://www.php.net/getopt">getopt</a>. | |
And I thought it would be fun. | |
</p> | |
<p> | |
I also didn't really like the API of NDesk: too many magic strings, and the code was very | |
imperative. I want objects and generics and attributes and angle brackets, dammit. | |
</p> | |
<p> | |
Introducing <strong><a href="https://argopt.tmont.com/">Argopt</a></strong>, another | |
command line argument parsing library. And shut up, I like the name. It sounds like | |
a Greek warrior. | |
</p> | |
<p>What you do is:</p> | |
<ol> | |
<li>define the command line arguments in a class (a <em>contract</em>)</li> | |
<li>annotate the properties in that class with some special attributes</li> | |
<li> | |
Argopt uses that class definition to figure out how to parse things and | |
returns an instance of that class with the command line values injected | |
</li> | |
</ol> | |
<p>Here's the example from the main site:</p> | |
<glacius:code lang="csharp"><![CDATA[using System; | |
using Argopt; | |
// this will handle things like: | |
// greeting.exe --names=Bill,Hillary,Barack,Michelle -r 1 "What a nice day" | |
// greeting.exe -n Bill,Hillary,Barack,Michelle --repeat=1 "What a nice day " | |
// greeting.exe /Names:Bill,Hillary,Barack,Michelle /r 1 "What a nice day" | |
public class MyContract { | |
[ValueProperty] | |
[Description("The greeting to display")] | |
public string Greeting { get; set; } | |
[Alias("r")] | |
[Description("The number of times to repeat the greeting", ValueName = "times")] | |
public int Repeat { get; set; } | |
[Delimited(","), Alias("n")] | |
[Description("The names of the people to greet", Required = true, ValueName = "name1,name2...")] | |
public string[] Names { get; set; } | |
} | |
class Program { | |
static void Main(string[] args) { | |
var result = OptionParser.Parse<MyContract>(args); | |
if (!result.IsValid) { | |
foreach (var error in result.Errors) { | |
Console.WriteLine(error.ThrownException); | |
} | |
return; | |
} | |
var contract = result.Contract; // this is an instance of MyContract | |
if (contract.Names.Length == 0 || string.IsNullOrEmpty(contract.Greeting)) { | |
// print usage | |
Console.WriteLine(OptionParser.GetDescription<MyContract>()); | |
return; | |
} | |
foreach (var name in contract.Names) { | |
for (var i = 0; i < contract.Repeat; i++) { | |
Console.WriteLine(string.Format("{0}, {1}!", contract.Greeting, name)); | |
} | |
} | |
} | |
}]]></glacius:code> | |
<p> | |
More information can be found at the website: | |
<a href="https://argopt.tmont.com/">argopt.tmont.com</a>. | |
</p> | |