{"id":30735703,"url":"https://github.com/jpdillingham/utility.commandline.arguments","last_synced_at":"2025-09-03T20:13:36.400Z","repository":{"id":19141183,"uuid":"86024176","full_name":"jpdillingham/Utility.CommandLine.Arguments","owner":"jpdillingham","description":"A C# .NET class library containing tools for parsing the command line arguments of console applications.","archived":false,"fork":false,"pushed_at":"2023-12-23T22:42:35.000Z","size":260,"stargazers_count":120,"open_issues_count":5,"forks_count":25,"subscribers_count":12,"default_branch":"master","last_synced_at":"2025-09-01T15:19:44.139Z","etag":null,"topics":["arguments-parser","command-line","command-line-parser","commandline","csharp","dotnet","flags"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jpdillingham.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-03-24T03:41:44.000Z","updated_at":"2025-08-16T18:14:30.000Z","dependencies_parsed_at":"2024-06-19T02:42:57.360Z","dependency_job_id":null,"html_url":"https://github.com/jpdillingham/Utility.CommandLine.Arguments","commit_stats":null,"previous_names":[],"tags_count":16,"template":false,"template_full_name":null,"purl":"pkg:github/jpdillingham/Utility.CommandLine.Arguments","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jpdillingham%2FUtility.CommandLine.Arguments","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jpdillingham%2FUtility.CommandLine.Arguments/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jpdillingham%2FUtility.CommandLine.Arguments/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jpdillingham%2FUtility.CommandLine.Arguments/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jpdillingham","download_url":"https://codeload.github.com/jpdillingham/Utility.CommandLine.Arguments/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jpdillingham%2FUtility.CommandLine.Arguments/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":273502352,"owners_count":25117173,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-03T02:00:09.631Z","response_time":76,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["arguments-parser","command-line","command-line-parser","commandline","csharp","dotnet","flags"],"created_at":"2025-09-03T20:13:23.607Z","updated_at":"2025-09-03T20:13:36.383Z","avatar_url":"https://github.com/jpdillingham.png","language":"C#","readme":"# Utility.CommandLine.Arguments\n\n[![Build status](https://ci.appveyor.com/api/projects/status/936bilffko47p63b?svg=true)](https://ci.appveyor.com/project/jpdillingham/utility-commandline-arguments)\n[![Build Status](https://travis-ci.org/jpdillingham/Utility.CommandLine.Arguments.svg?branch=master)](https://travis-ci.org/jpdillingham/Utility.CommandLine.Arguments)\n[![codecov](https://codecov.io/gh/jpdillingham/Utility.CommandLine.Arguments/branch/master/graph/badge.svg)](https://codecov.io/gh/jpdillingham/Utility.CommandLine.Arguments)\n[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=jpdillingham_Utility.CommandLine.Arguments\u0026metric=alert_status)](https://sonarcloud.io/dashboard?id=jpdillingham_Utility.CommandLine.Arguments)\n[![NuGet version](https://img.shields.io/nuget/v/Utility.CommandLine.Arguments.svg)](https://www.nuget.org/packages/Utility.CommandLine.Arguments/)\n[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://github.com/jpdillingham/Utility.CommandLine.Arguments/blob/master/LICENSE)\n\nA C# .NET Class Library containing tools for parsing the command line arguments of console applications.\n\n## Why?\n\nI needed a solution for parsing command line arguments and didn't like the existing options.\n\n## Installation\n\nInstall from the NuGet gallery GUI or with the Package Manager Console using the following command:\n\n```Install-Package Utility.CommandLine.Arguments```\n\nThe code is also designed to be incorporated into your project as a single source file (Arguments.cs).\n\n## Quick Start\n\nCreate private static properties in the class containing your ```Main()``` and mark them with the ```Argument``` attribute, assigning short and long names.  Invoke\nthe ```Arguments.Populate()``` method within ```Main()```, then implement the rest of your logic.  \n\nThe library will populate your properties with the values\nspecified in the command line arguments.\n\n```c#\ninternal class Program\n{\n    // [Argument(short name (char), long name (string), help text)]\n    [Argument('b', \"myBool\", \"a boolean value\")]\n    private static bool Bool { get; set; }\n\n    [Argument('f', \"someFloat\")]\n    private static double Double { get; set; }\n\n    [Argument('i', \"anInteger\")]\n    private static int Int { get; set; }\n\n    [Argument('s', \"aString\")]\n    private static string[] String { get; set; }\n\n    [Operands]\n    private static string[] Operands { get; set; }\n\n    private static void Main(string[] args)\n    {\n        Arguments.Populate();\n\n        Console.WriteLine(\"Bool: \" + Bool);\n        Console.WriteLine(\"Int: \" + Int);\n        Console.WriteLine(\"Double: \" + Double);\n\n        foreach (string s in String)\n        {\n            Console.WriteLine(\"String: \" + s);\n        }\n\n        foreach (string operand in Operands) \n        {\n            Console.WriteLine(\"\\r\\n Operand:\" + operand);\n        }\n    }\n}\n```\n\n## Grammar\n\nThe grammar supported by this library is designed to follow the guidelines set forth in the publication \n*The Open Group Base Specifications Issue 7*, specifically the content of Chapter 12, *Utility Conventions*, \nlocated [here](http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap12.html).\n\nEach argument is treated as a key-value pair, regardless of whether a value is present.  The general format is as follows:\n\n```\u003c-|--|/\u003eargument-name\u003c=|:| \u003e[\"|']value['|\"] [--] [operand] ... [operand]```\n\nThe key-value pair may begin with a single hyphen, a pair of hyphen, or a forward slash.  Single and double dashes indicate the use of short or long names, respectively, which are covered below.  The forward slash may represent either a sort or long name but does not allow for the grouping of parameterless arguments (e.g. /abc is not equivalent to -abc, but rather --abc).\n\nThe argument name may be a single character when using short names, or any alphanumeric sequence not including spaces if using long names.\n\nThe value delimiter may be an equals sign, a colon, or a space.\n\nValues may be any alphanumeric sequence, however if a value contains a space it must be enclosed in either single or double quotes.\n\nAny word, or phrase enclosed in single or double quotes, will be parsed as an operand.  The official specification requires operands to appear last, however this library will parse them in any position.\n\nA double-hyphen ```--``` not enclosed in single or double quotes and appearing with whitespace on either side designates the end of the argument list and beginning of the explicit operand list.  Anything appearing after this delimiter is treated as an operand, even if it begins with a hyphen, double-hyphen or forward slash.\n\n### Short Names\n\nShort names consist of a single character, and arguments without parameters may be grouped.  A grouping may be terminated with a single argument containing\na parameter.  Arguments using short names must be preceded by a single dash.\n\n#### Examples\n\nSingle argument with a parameter: ```-a foo```\n\nKey | Value\n--- | ---\na | foo\n\nTwo parameterless arguments: ```-ab```\n\nKey | Value\n--- | ---\na | \nb | \n\nThree arguments; two parameterless followed by a third argument with a parameter: ```-abc bar```\n\nKey | Value\n--- | ---\na | \nb | \nc | bar\n\n### Long Names\n\nLong names can consist of any alphanumeric string not containing a space.  Arguments using long names must be preceded by two dashes.\n\n#### Examples\n\nSingle argument with a parameter: ```--foo bar```\n\nKey | Value\n--- | ---\nfoo | bar\n\nTwo parameterless arguments: ```--foo --bar```\n\nKey | Value\n--- | ---\nfoo |\nbar |\n\nTwo arguments with parameters: ```--foo bar --hello world```\n\nKey | Value\n--- | ---\nfoo | bar\nhello | world\n\n### Mixed Naming\n\nAny combination of short and long names are supported.\n\n#### Example\n\n```-abc foo --hello world /new=\"slashes are ok too\"```\n\nKey | Value\n--- | ---\na |\nb | \nc | foo\nhello | world\nnew | slashes are ok too\n\n### Multiple Values\n\nArguments can accept multiple values, and when parsed a ```List\u003cobject\u003e``` is returned if more than one value is specified.  When using \nthe ```Populate()``` method the underlying property for an argument accepting multiple values must be an array or List, otherwise\nan ```InvalidCastException``` is thrown.\n\n#### Example\n\n```--list 1 --list 2 --list 3```\n\nKey | Value\n--- | ---\nlist | 1,2,3\n\n### Operands\n\nAny text in the string that doesn't match the argument-value format is considered an operand.  Any text which appears after a double-hyphen ```--``` not enclosed in single or double quotes and with spaces on either side is treated as an operand regardless of whether it matches the argument-value format.\n\n#### Example\n\n```-a foo bar \"hello world\" -b -- -explicit operand```\n\nKey | Value\n--- | ---\na | foo\nb | \n\nOperands\n1. bar\n2. \"hello world\"\n3. -explicit\n4. operand\n\n## Parsing\n\nArgument key-value pairs can be parsed from any string using the ```Parse(string)``` method.  This method returns a \n```Dictionary\u003cstring, object\u003e``` containing all argument-value pairs.\n\nIf the string parameter is omitted, the value of ```Environment.CommandLine``` is used.\n\nNote that passing the ```args``` variable, or the result of ```String.Join()``` on ```args```, will prevent the library\nfrom property handling quoted strings.  There are generally very few instance in which ```Environment.CommandLine``` should not be used.\n\n#### Example\n\n```c#\nDictionary\u003cstring, object\u003e args = Arguments.Parse(\"-ab --foo bar\");\n```\n\nThe example above would result in a dictionary ```args``` containing:\n\nKey | Value\n--- | ---\na | \nb |\nfoo | bar\n\nNote that boolean values should be checked with ```Dictionary.ContainsKey(\"name\")```; the result will indicate\nwhether the argument was encountered in the command line arguments.  All other values are retrieved with ```Dictionary[\"key\"]```.\n\n## Populating\n\nThe ```Populate()``` method uses reflection to populate private static properties in the target Type with the argument\nvalues matching properties marked with the ```Argument``` attribute.\n\nThe list of operands is placed into a single property marked with the ```Operands``` attribute.  This property must be\nof type ```string[]``` or ```List\u003cstring\u003e```.\n\n### Creating Target Properties\n\nUse the ```Argument``` attribute to designate properties to be populated.  The constructor of ```Argument``` accepts a ```char```, a \n```string```, and an additional ```string```, representing the short and long names of the argument, and help text, respectively.\n\nNote that the name of the property doesn't matter; only the attribute values are used to match an argument key to a property.\n\nThe Type of the property does matter; the code attempts to convert argument values from string to the specified Type, and if the conversion fails\nan ```ArgumentException``` is thrown.  \n\nProperties can accept lists of parameters, as long as they are backed by an array or ```List\u003c\u003e```.  Specifying multiple parameters for an argument backed \nby an atomic Type (e.g. not an array or List) will result in an ```InvalidCastException```.\n\nThe ```Operands``` property accepts no parameters.  If the property type is not ```string[]``` or ```List\u003cstring\u003e```, an \n```InvalidCastException``` will be thrown.\n\n#### Examples\n\n```c#\n[Argument('f', \"foo\", \"some help text\")]\nprivate static string Foo { get; set; }\n\n[Argument('n', \"number\")]\nprivate static integer MyNumber { get; set; }\n\n[Argument('b', \"bool\")]\nprivate static bool TrueOrFalse { get; set; }\n\n[Argument('l', \"list\")]\nprivate static string[] List { get; set; }\n\n[Operands]\nprivate static List\u003cstring\u003e Operands { get; set; }\n```\n\nGiven the argument string ```-bf \"bar\" --number=5 --list 1 --list 2```, the resulting property values would be as follows:\n\nProperty | Value\n--- | ---\nFoo | bar\nMyNumber | 5\nTrueOrFalse | true\nList | 1,2\n\n### Obtaining Help\n\nA collection of `ArgumentHelp` containing the short and long names and help text for each argument property can be fetched with `GetArgumentHelp()`:\n\n```c#\nprivate static void ShowHelp()\n{\n    var helpAttributes = Arguments.GetArgumentInfo(typeof(Program));\n\n    var maxLen = helpAttributes.Select(a =\u003e a.Property.Name).OrderByDescending(s =\u003e s.Length).FirstOrDefault()!.Length;\n\n    Console.WriteLine($\"Short\\tLong\\t{\"Type\".PadRight(maxLen)}\\tFunction\");\n    Console.WriteLine($\"-----\\t----\\t{\"----\".PadRight(maxLen)}\\t--------\");\n\n    foreach (var item in helpAttributes)\n    {\n        var result = item.ShortName + \"\\t\" + item.LongName + \"\\t\" + item.Property.PropertyType.ToColloquialString().PadRight(maxLen) + \"\\t\" + item.HelpText;\n        Console.WriteLine(result);\n    }\n}\n```\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjpdillingham%2Futility.commandline.arguments","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjpdillingham%2Futility.commandline.arguments","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjpdillingham%2Futility.commandline.arguments/lists"}