Skip to content

Commit 63075ff

Browse files
committed
Updated some signature options for argument creation and such.
1 parent 739ce8e commit 63075ff

File tree

5 files changed

+66
-21
lines changed

5 files changed

+66
-21
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@ obj/
55
*.suo
66
*.sqlite
77
/.vs/CmdLineParserCore/DesignTimeBuild/.dtbcache.v2
8+
/.vs/CmdLineParserCore/v16/TestStore/0

source/Arguments/FlagArgument.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ namespace System.CommandLine.Arguments
1111
/// Represents a single flag argument of a command line parser. In contrast to named arguments, flag arguments, cannot be explicitly assigned a value, but rather get their value from their presence or absence.
1212
/// </summary>
1313
/// <typeparam name="T">
14-
/// The type of the argument. May only be a boolean, integer, or enumeration type. When the type is boolean, then only the presence or absence of the flag is determined. If the type is an integer type (i.e. byte, sbyte,
14+
/// The type of the argument may only be a boolean, integer, or enumeration type. When the type is boolean, then only the presence or absence of the flag is determined. If the type is an integer type (i.e. byte, sbyte,
1515
/// short, ushort, int, uint, long, or ulong), then the number of occurrences is determined. But if the type is an enumeration type, then the number of occurrences is interpreted as the enumeration value. For example
1616
/// consider the following enumeration type: <c>enum Severity { None = 0, Low = 1, Medium = 2, High = 3 }</c>, which is the type of the flag argument named "severity" with the alias "s", then the following command line
1717
/// argument "-sss" would parse to an enumeration value of <c>Severity.High</c>.

source/Arguments/PositionalArgument.cs

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
namespace System.CommandLine.Arguments
22
{
33
/// <summary>
4-
/// Represents a single positional argument of a command line parser. A positional argument, in contrast to a named or flag argument, is an argument, which is only comprised of a value. They are not optional and must
5-
/// be at the beginning of the command line arguments in exactly the same order as they were declared.
4+
/// Represents a single positional argument of a command line parser. A positional argument, in contrast to a named or flag argument, is an argument, which is only comprised of a value.
5+
/// They are not optional and must be at the beginning of the command line arguments in exactly the same order as they were declared.
66
/// </summary>
77
/// <typeparam name="T">The type of the positional argument.</param>
88
public class PositionalArgument<T> : Argument
@@ -18,7 +18,19 @@ public class PositionalArgument<T> : Argument
1818
/// </param>
1919
/// <param name="help">A descriptive help text for the argument, which is used in the help string.</param>
2020
/// <exception cref="ArgumentNullException">If either the name or the destination are <c>null</c>, empty, or only consist of white spaces then an <see cref="ArgumentNullException"/> is thrown.</exception>
21-
public PositionalArgument(string name, string destination, string help)
21+
public PositionalArgument(string name, string destination, string help) : this(name, name, destination, help) { }
22+
23+
/// <summary>
24+
/// Initializes a new <see cref="PositionalArgument"/> instance.
25+
/// </summary>
26+
/// <param name="name">The name of the positional argument, which is used in the help string.</param>
27+
/// <param name="alias">The alias name of the argument.</param>
28+
/// <param name="destination">
29+
/// The name that the positional argument will have in the result dictionary after parsing. This should adhere to normal C# naming standards. If it does not, it is automatically converted.
30+
/// </param>
31+
/// <param name="help">A descriptive help text for the argument, which is used in the help string.</param>
32+
/// <exception cref="ArgumentNullException">If either the name or the destination are <c>null</c>, empty, or only consist of white spaces then an <see cref="ArgumentNullException"/> is thrown.</exception>
33+
public PositionalArgument(string name, string alias, string destination, string help)
2234
{
2335
// Validates the arguments
2436
if (string.IsNullOrWhiteSpace(name))
@@ -28,7 +40,7 @@ public PositionalArgument(string name, string destination, string help)
2840

2941
// Stores the arguments for later use
3042
this.Name = name;
31-
this.Alias = name;
43+
this.Alias = alias;
3244
this.Destination = destination;
3345
this.Help = help;
3446
this.Type = typeof(T);

source/Parser.cs

Lines changed: 43 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -414,17 +414,19 @@ private ParsingResults Parse(Queue<string> tokenQueue)
414414
/// Adds a positional argument to the command line parser.
415415
/// </summary>
416416
/// <param name="name">The name of the positional argument, which is used in the help string.</param>
417+
/// <param name="alias">The alias name of the argument.</param>
417418
/// <param name="help">A descriptive help text for the argument, which is used in the help string.</param>
418419
/// <typeparam name="T">The type of the positional argument.</typeparam>
419420
/// <exception cref="ArgumentNullException">If the name is <c>null</c>, empty, or only consists of white spaces, then an <see cref="ArgumentNullException"/> is thrown.</exception>
420421
/// <exception cref="InvalidOperationException">If there already is an argument with the same name, then an <see cref="InvalidOperationException"/> is thrown.</exception>
421422
/// <returns>Returns this command line parser so that method invocations can be chained.</returns>
422-
public Parser AddPositionalArgument<T>(string name, string help) => this.AddPositionalArgument<T>(name, name, help);
423+
public Parser AddPositionalArgument<T>(string name, string alias, string help) => this.AddPositionalArgument<T>(name, alias, name, help);
423424

424425
/// <summary>
425426
/// Adds a positional argument to the command line parser.
426427
/// </summary>
427428
/// <param name="name">The name of the positional argument, which is used in the help string.</param>
429+
/// <param name="alias">The alias name of the argument.</param>
428430
/// <param name="destination">
429431
/// The name that the positional argument will have in the result dictionary after parsing. This should adhere to normal C# naming standards. If it does not, it is automatically converted.
430432
/// </param>
@@ -433,7 +435,7 @@ private ParsingResults Parse(Queue<string> tokenQueue)
433435
/// <exception cref="InvalidOperationException">If there already is an argument with the same name, then an <see cref="InvalidOperationException"/> is thrown.</exception>
434436
/// <typeparam name="T">The type of the positional argument.</typeparam>
435437
/// <returns>Returns this command line parser so that method invocations can be chained.</returns>
436-
public Parser AddPositionalArgument<T>(string name, string destination, string help)
438+
public Parser AddPositionalArgument<T>(string name, string alias, string destination, string help)
437439
{
438440
// Validates the arguments
439441
if (string.IsNullOrWhiteSpace(name))
@@ -442,7 +444,7 @@ public Parser AddPositionalArgument<T>(string name, string destination, string h
442444
throw new ArgumentNullException(nameof(destination));
443445

444446
// Checks if there is already an argument with the same name
445-
PositionalArgument<T> newPositionalArgument = new PositionalArgument<T>(name, destination, help);
447+
PositionalArgument<T> newPositionalArgument = new PositionalArgument<T>(name, alias, destination, help);
446448
this.AssertArgumentIsValidAndUnique(newPositionalArgument);
447449

448450
// Adds the positional argument to the parser
@@ -533,10 +535,21 @@ public Parser AddNamedArgument<T>(string name, string alias, string destination,
533535
if (string.IsNullOrWhiteSpace(destination))
534536
throw new ArgumentNullException(nameof(destination));
535537

538+
// Returns this parser, so that method invocations can be chained
539+
return AddNamedArgument<T>(new NamedArgument<T>(name, alias, destination, help, defaultValue, duplicateResolutionPolicy));
540+
}
541+
542+
/// <summary>
543+
/// Adds a named argument to the command line parser.
544+
/// </summary>
545+
/// <param name="newNamedArgument">An instance of a new named argument.</param>
546+
/// <exception cref="InvalidOperationException">If there already is an argument with the same name or the same alias, then an <see cref="InvalidOperationException"/> is thrown.</exception>
547+
/// <typeparam name="T">The type of the argument.</typeparam>
548+
/// <returns>Returns this command line parser so that method invocations can be chained.</returns>
549+
public Parser AddNamedArgument<T>(NamedArgument<T> newNamedArgument)
550+
{
536551
// Checks if there is already an argument with the same name or alias
537-
NamedArgument<T> newNamedArgument = new NamedArgument<T>(name, alias, destination, help, defaultValue, duplicateResolutionPolicy);
538552
this.AssertArgumentIsValidAndUnique(newNamedArgument);
539-
540553
// Adds the argument to the parser
541554
(this.NamedArguments as List<Argument>).Add(newNamedArgument);
542555

@@ -550,7 +563,7 @@ public Parser AddNamedArgument<T>(string name, string alias, string destination,
550563
/// <param name="name">The name of the argument, which is used for parsing and in the help string.</param>
551564
/// <exception cref="ArgumentNullException">If the name is <c>null</c>, empty, or only consists of white spaces, then an <see cref="ArgumentNullException"/> is thrown.</exception>
552565
/// <exception cref="InvalidOperationException">If there already is an argument with the same name, then an <see cref="InvalidOperationException"/> is thrown.</exception>
553-
/// <typeparam name="T">The type of the argument.</typeparam>
566+
/// <typeparam name="T">The type of the argument; see FlagArgument class for allowed types.</typeparam>
554567
/// <returns>Returns this command line parser so that method invocations can be chained.</returns>
555568
public Parser AddFlagArgument<T>(string name) => this.AddFlagArgument<T>(name, null, name, null);
556569

@@ -561,7 +574,7 @@ public Parser AddNamedArgument<T>(string name, string alias, string destination,
561574
/// <param name="alias">The alias name of the argument.</param>
562575
/// <exception cref="ArgumentNullException">If the name is <c>null</c>, empty, or only consists of white spaces, then an <see cref="ArgumentNullException"/> is thrown.</exception>
563576
/// <exception cref="InvalidOperationException">If there already is an argument with the same name or the same alias, then an <see cref="InvalidOperationException"/> is thrown.</exception>
564-
/// <typeparam name="T">The type of the argument.</typeparam>
577+
/// <typeparam name="T">The type of the argument; see FlagArgument class for allowed types.</typeparam>
565578
/// <returns>Returns this command line parser so that method invocations can be chained.</returns>
566579
public Parser AddFlagArgument<T>(string name, string alias) => this.AddFlagArgument<T>(name, alias, name, null);
567580

@@ -573,7 +586,7 @@ public Parser AddNamedArgument<T>(string name, string alias, string destination,
573586
/// <param name="help">A descriptive help text for the argument, which is used in the help string.</param>
574587
/// <exception cref="ArgumentNullException">If the name is <c>null</c>, empty, or only consists of white spaces, then an <see cref="ArgumentNullException"/> is thrown.</exception>
575588
/// <exception cref="InvalidOperationException">If there already is an argument with the same name or the same alias, then an <see cref="InvalidOperationException"/> is thrown.</exception>
576-
/// <typeparam name="T">The type of the argument.</typeparam>
589+
/// <typeparam name="T">The type of the argument; see FlagArgument class for allowed types.</typeparam>
577590
/// <returns>Returns this command line parser so that method invocations can be chained.</returns>
578591
public Parser AddFlagArgument<T>(string name, string alias, string help) => this.AddFlagArgument<T>(name, alias, name, help);
579592

@@ -586,7 +599,7 @@ public Parser AddNamedArgument<T>(string name, string alias, string destination,
586599
/// <param name="help">A descriptive help text for the argument, which is used in the help string.</param>
587600
/// <exception cref="ArgumentNullException">If either the name or the destination are <c>null</c>, empty, or only consist of white spaces, then an <see cref="ArgumentNullException"/> is thrown.</exception>
588601
/// <exception cref="InvalidOperationException">If there already is an argument with the same name or the same alias, then an <see cref="InvalidOperationException"/> is thrown.</exception>
589-
/// <typeparam name="T">The type of the argument.</typeparam>
602+
/// <typeparam name="T">The type of the argument; see FlagArgument class for allowed types.</typeparam>
590603
/// <returns>Returns this command line parser so that method invocations can be chained.</returns>
591604
public Parser AddFlagArgument<T>(string name, string alias, string destination, string help)
592605
{
@@ -596,8 +609,20 @@ public Parser AddFlagArgument<T>(string name, string alias, string destination,
596609
if (string.IsNullOrWhiteSpace(destination))
597610
throw new ArgumentNullException(nameof(destination));
598611

612+
// Returns this parser, so that method invocations can be chained
613+
return AddFlagArgument<T>(new FlagArgument<T>(name, alias, destination, help));
614+
}
615+
616+
/// <summary>
617+
/// Adds a flag argument to the command line parser.
618+
/// </summary>
619+
/// <param name="newFlagArgument">An instance of a FlagArgument.</param>
620+
/// <exception cref="InvalidOperationException">If there already is an argument with the same name or the same alias, then an <see cref="InvalidOperationException"/> is thrown.</exception>
621+
/// <typeparam name="T">The type of the argument; see FlagArgument class for allowed types.</typeparam>
622+
/// <returns>Returns this command line parser so that method invocations can be chained.</returns>
623+
public Parser AddFlagArgument<T>(FlagArgument<T> newFlagArgument)
624+
{
599625
// Checks if there is already an argument with the same name or alias
600-
FlagArgument<T> newFlagArgument = new FlagArgument<T>(name, alias, destination, help);
601626
this.AssertArgumentIsValidAndUnique(newFlagArgument);
602627

603628
// Adds the argument to the parser
@@ -761,7 +786,14 @@ public Parser AddCommand(Command command)
761786
/// </summary>
762787
/// <param name="commandLineArguments">The command line arguments that were retrieved by the application.</param>
763788
/// <returns>Returns the parsing results, which is a bag of arguments.</returns>
764-
public ParsingResults Parse(string[] commandLineArguments)
789+
public ParsingResults Parse(string[] commandLineArguments) => this.Parse(commandLineArguments.ToList());
790+
791+
/// <summary>
792+
/// Parses the command line arguments by matching them to the declared arguments and commands.
793+
/// </summary>
794+
/// <param name="commandLineArguments">The command line arguments that were retrieved by the application.</param>
795+
/// <returns>Returns the parsing results, which is a bag of arguments.</returns>
796+
public ParsingResults Parse(List<string> commandLineArguments)
765797
{
766798
// Copies the command line arguments into a queue so that they are easier to parse without having to do fancy indexing, the first token is dequeued right away, because it is the file name of the executable
767799
Queue<string> tokenQueue = new Queue<string>(commandLineArguments);

test/ParserTests.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -781,32 +781,32 @@ public void TestComplexScenario()
781781

782782
// Creates the parser for the add command
783783
Parser addCommandParser = parser.AddCommand("add", "Add a new package or reference to a .NET project.");
784-
addCommandParser.AddPositionalArgument<string>("project", "The project file to operate on.");
784+
addCommandParser.AddPositionalArgument<string>("project", "The project file to operate on.", null);
785785
addCommandParser.AddFlagArgument<bool>("help", "h", "Show command line help.");
786786

787787
// Creates the parser for the add package command
788788
Parser addPackageCommandParser = addCommandParser.AddCommand("package", "Add a NuGet package reference to the project.");
789-
addPackageCommandParser.AddPositionalArgument<string>("package-name", "The package reference to add.");
789+
addPackageCommandParser.AddPositionalArgument<string>("package-name", "The package reference to add.", null);
790790
addPackageCommandParser.AddFlagArgument<bool>("help", "h", "Show command line help.");
791791
addPackageCommandParser.AddNamedArgument<string>("version", "v", "The version of the package to add.");
792792
addPackageCommandParser.AddFlagArgument<bool>("interactive", null, "Show command line help.");
793793

794794
// Creates the parser for the add reference command
795795
Parser addReferenceCommandParser = addCommandParser.AddCommand("reference", "Add a project-to-project reference to the project.");
796-
addReferenceCommandParser.AddPositionalArgument<string>("project-path", "The paths to the projects to add as references.");
796+
addReferenceCommandParser.AddPositionalArgument<string>("project-path", "The paths to the projects to add as references.", null);
797797
addReferenceCommandParser.AddFlagArgument<bool>("help", "h", "Show command line help.");
798798
addReferenceCommandParser.AddNamedArgument<string>("framework", "f", "Add the reference only when targeting a specific framework.");
799799

800800
// Creates the parser for the build command
801801
Parser buildCommandParser = parser.AddCommand("build", "Add a new package or reference to a .NET project.");
802-
buildCommandParser.AddPositionalArgument<string>("project", "The project file to operate on.");
802+
buildCommandParser.AddPositionalArgument<string>("project", "The project file to operate on.", null);
803803
buildCommandParser.AddFlagArgument<bool>("help", "h", "Show command line help.");
804804
buildCommandParser.AddNamedArgument<VerbosityLevel>("verbosity", "v", "Set the MSBuild verbosity level. Allowed values are quiet, minimal, normal, detailed, and diagnostic.");
805805
buildCommandParser.AddNamedArgument<string>("framework", "f", "The target framework to build for. The target framework must also be specified in the project file.");
806806

807807
// Creates the parser for the new command
808808
Parser newCommandParser = parser.AddCommand("new", "Create a new .NET project or file.");
809-
newCommandParser.AddPositionalArgument<string>("template", "The project template to use.");
809+
newCommandParser.AddPositionalArgument<string>("template", "The project template to use.", null);
810810
newCommandParser.AddFlagArgument<bool>("help", "h", "Show command line help.");
811811
newCommandParser.AddNamedArgument<string>("name", "n", "The name for the output being created. If no name is specified, the name of the current directory is used.");
812812
newCommandParser.AddNamedArgument<string>("output", "o", "Location to place the generated output.");

0 commit comments

Comments
 (0)