Skip to content

Commit

Permalink
Merge pull request #29 from SvenGroot/v4.1-dev
Browse files Browse the repository at this point in the history
Merge version 4.1 into main
  • Loading branch information
SvenGroot authored Jan 26, 2024
2 parents 83701ef + af6b8cb commit 9df03b6
Show file tree
Hide file tree
Showing 93 changed files with 3,857 additions and 1,485 deletions.
4 changes: 3 additions & 1 deletion .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,11 @@ updates:
patterns:
- "*"
ignore:
# 4.3 is the latest version that can work with the .Net 6.0 SDK.
# 4.3.x is the latest version that can work with the .Net 6.0 SDK for both of these.
- dependency-name: "Microsoft.CodeAnalysis.CSharp"
update-types: ["version-update:semver-major", "version-update:semver-minor"]
- dependency-name: "Microsoft.CodeAnalysis.Workspaces"
update-types: ["version-update:semver-major", "version-update:semver-minor"]
- package-ecosystem: "github-actions"
directory: "/"
schedule:
Expand Down
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,9 @@ when [source generation](docs/SourceGeneration.md) is used.
The .Net 7.0 version has additional support for `required` properties, and can utilize
`ISpanParsable<TSelf>` and `IParsable<TSelf>` for argument value conversions.

An assembly built for .Net 8.0 is also provided; this has no additional functionality over the
.Net 7.0 version, but is provided to ensure optimal compatibility and performance.

## Building and testing

To build Ookii.CommandLine, make sure you have the following installed:
Expand Down
105 changes: 65 additions & 40 deletions docs/Arguments.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,26 @@ value1 -Positional1 value2
This is because `-Positional1` is assigned to twice; first by position, and then by name. Duplicate
arguments cause an error by default, though this can be changed.

## The `--` argument

Optionally, when an argument is encountered that consists only of `--` without a name following it,
this indicates that all following values must be treated as positional values, even if they begin
with an argument name prefix.

For example, take the following command line:

```text
value1 -- --value2
```

In this example, the second positional argument would be set to the value "--value2". If there is
an argument named "value2", it would not be set.

This behavior is disabled by default, but can be enabled using the
[`ParseOptionsAttribute.PrefixTermination`][] or [`ParseOptions.PrefixTermination`][] property. It
can be used with both the default parsing mode and long/short mode. Alternatively, you can also set
it so that the `--` argument will [cancel parsing](DefiningArguments.md#arguments-that-cancel-parsing).

## Required arguments

A command line argument that is required must be supplied on all invocations of the application. If
Expand Down Expand Up @@ -289,33 +309,32 @@ upgrade code that relied on a [`TypeConverter`][].

### Enumeration conversion

The [`EnumConverter`][] used for enumeration types relies on the [`Enum.Parse()`][] method. It uses case
insensitive conversion, and allows both the names and underlying value of the enumeration to be
used. This means that e.g. for the [`DayOfWeek`][] enumeration, "Monday", "monday", and "1" can all
be used to indicate [`DayOfWeek.Monday`][].
The [`EnumConverter`][] used for enumeration types relies on the [`Enum.Parse()`][] method. Its
default behavior is to use case insensitive conversion, and to allow both the names and underlying
value of the enumeration to be used. This means that e.g. for the [`DayOfWeek`][] enumeration,
"Monday", "monday", and "1" can all be used to indicate [`DayOfWeek.Monday`][].

In the case of a numeric value, the converter does not check if the resulting value is valid for the
enumeration type, so again for [`DayOfWeek`][], a value of "9" would be converted to `(DayOfWeek)9`
even though there is no such value in the enumeration.

To ensure the result is constrained to only the defined values of the enumeration, use the
[`ValidateEnumValueAttribute` validator](Validation.md).
[`ValidateEnumValueAttribute` validator](Validation.md). This validator can also be used to alter
the conversion behavior. You can enable case sensitivity with the
[`ValidateEnumValueAttribute.CaseSensitive`][] property, and disallow numeric values with the
[`ValidateEnumValueAttribute.AllowNumericValues`][] property.

The converter allows the use of comma-separated values, which will be combined using a bitwise or
operation. This is allowed regardless of whether or not the [`FlagsAttribute`][] attribute is present on
the enumeration, which can have unexpected results. Using the [`DayOfWeek`][] example again,
"Monday,Tuesday" would result in the value `DayOfWeek.Monday | DayOfWeek.Tuesday`, which is actually
equivalent to [`DayOfWeek.Wednesday`][].
By default, the converter allows the use of comma-separated values, which will be combined using a
bitwise or operation. This is allowed regardless of whether or not the [`FlagsAttribute`][]
attribute is present on the enumeration, which can have unexpected results. Using the
[`DayOfWeek`][] example again, "Monday,Tuesday" would result in the value
`DayOfWeek.Monday | DayOfWeek.Tuesday`, which is actually equivalent to [`DayOfWeek.Wednesday`][].

One way to avoid this is to use the following pattern validator, which ensures that the
string value before conversion does not contain a comma:

```csharp
[ValidatePattern("^[^,]*$")]
```
Comma-separated values can be disabled by using the
[`ValidateEnumValueAttribute.AllowCommaSeparatedValues`][] property.

You can also use a pattern like `"^[a-zA-Z]"` to ensure the value starts with a letter, to disallow
the use of numeric values entirely.
These properties of the [`ValidateEnumValueAttribute`][] attribute only work if the default
[`EnumConverter`][] is used; a custom converter may or may not check them.

### Multi-value and dictionary value conversion

Expand Down Expand Up @@ -403,41 +422,47 @@ and case-sensitive argument names. For information on how to set these options,

Next, let's take a look at how to [define arguments](DefiningArguments.md).

[`AllowDuplicateDictionaryKeysAttribute`]: https://www.ookii.org/docs/commandline-4.0/html/T_Ookii_CommandLine_AllowDuplicateDictionaryKeysAttribute.htm
[`ArgumentConverter`]: https://www.ookii.org/docs/commandline-4.0/html/T_Ookii_CommandLine_Conversion_ArgumentConverter.htm
[`ArgumentConverterAttribute`]: https://www.ookii.org/docs/commandline-4.0/html/T_Ookii_CommandLine_Conversion_ArgumentConverterAttribute.htm
[`CommandLineArgument.AllowNull`]: https://www.ookii.org/docs/commandline-4.0/html/P_Ookii_CommandLine_CommandLineArgument_AllowNull.htm
[`CommandLineArgumentException`]: https://www.ookii.org/docs/commandline-4.0/html/T_Ookii_CommandLine_CommandLineArgumentException.htm
[`CommandLineParser`]: https://www.ookii.org/docs/commandline-4.0/html/T_Ookii_CommandLine_CommandLineParser.htm
[`AllowDuplicateDictionaryKeysAttribute`]: https://www.ookii.org/docs/commandline-4.1/html/T_Ookii_CommandLine_AllowDuplicateDictionaryKeysAttribute.htm
[`ArgumentConverter`]: https://www.ookii.org/docs/commandline-4.1/html/T_Ookii_CommandLine_Conversion_ArgumentConverter.htm
[`ArgumentConverterAttribute`]: https://www.ookii.org/docs/commandline-4.1/html/T_Ookii_CommandLine_Conversion_ArgumentConverterAttribute.htm
[`CommandLineArgument.AllowNull`]: https://www.ookii.org/docs/commandline-4.1/html/P_Ookii_CommandLine_CommandLineArgument_AllowNull.htm
[`CommandLineArgumentException`]: https://www.ookii.org/docs/commandline-4.1/html/T_Ookii_CommandLine_CommandLineArgumentException.htm
[`CommandLineParser`]: https://www.ookii.org/docs/commandline-4.1/html/T_Ookii_CommandLine_CommandLineParser.htm
[`CultureInfo.InvariantCulture`]: https://learn.microsoft.com/dotnet/api/system.globalization.cultureinfo.invariantculture
[`CultureInfo`]: https://learn.microsoft.com/dotnet/api/system.globalization.cultureinfo
[`DateTime`]: https://learn.microsoft.com/dotnet/api/system.datetime
[`DayOfWeek.Monday`]: https://learn.microsoft.com/dotnet/api/system.dayofweek
[`DayOfWeek.Wednesday`]: https://learn.microsoft.com/dotnet/api/system.dayofweek
[`DayOfWeek`]: https://learn.microsoft.com/dotnet/api/system.dayofweek
[`Enum.Parse()`]: https://learn.microsoft.com/dotnet/api/system.enum.parse
[`EnumConverter`]: https://www.ookii.org/docs/commandline-4.0/html/T_Ookii_CommandLine_Conversion_EnumConverter.htm
[`EnumConverter`]: https://www.ookii.org/docs/commandline-4.1/html/T_Ookii_CommandLine_Conversion_EnumConverter.htm
[`FileInfo`]: https://learn.microsoft.com/dotnet/api/system.io.fileinfo
[`FlagsAttribute`]: https://learn.microsoft.com/dotnet/api/system.flagsattribute
[`Int32`]: https://learn.microsoft.com/dotnet/api/system.int32
[`IParsable<TSelf>`]: https://learn.microsoft.com/dotnet/api/system.iparsable-1
[`ISpanParsable<TSelf>`]: https://learn.microsoft.com/dotnet/api/system.ispanparsable-1
[`KeyConverterAttribute`]: https://www.ookii.org/docs/commandline-4.0/html/T_Ookii_CommandLine_Conversion_KeyConverterAttribute.htm
[`KeyConverterAttribute`]: https://www.ookii.org/docs/commandline-4.1/html/T_Ookii_CommandLine_Conversion_KeyConverterAttribute.htm
[`KeyValuePair<TKey, TValue>`]: https://learn.microsoft.com/dotnet/api/system.collections.generic.keyvaluepair-2
[`KeyValuePairConverter<TKey, TValue>`]: https://www.ookii.org/docs/commandline-4.0/html/T_Ookii_CommandLine_Conversion_KeyValuePairConverter_2.htm
[`KeyValueSeparatorAttribute`]: https://www.ookii.org/docs/commandline-4.0/html/T_Ookii_CommandLine_Conversion_KeyValueSeparatorAttribute.htm
[`MultiValueSeparatorAttribute`]: https://www.ookii.org/docs/commandline-4.0/html/T_Ookii_CommandLine_MultiValueSeparatorAttribute.htm
[`ParseOptions.AllowWhiteSpaceValueSeparator`]: https://www.ookii.org/docs/commandline-4.0/html/P_Ookii_CommandLine_ParseOptions_AllowWhiteSpaceValueSeparator.htm
[`ParseOptions.ArgumentNameComparison`]: https://www.ookii.org/docs/commandline-4.0/html/P_Ookii_CommandLine_ParseOptions_ArgumentNameComparison.htm
[`ParseOptions.Culture`]: https://www.ookii.org/docs/commandline-4.0/html/P_Ookii_CommandLine_ParseOptions_Culture.htm
[`ParseOptions.NameValueSeparators`]: https://www.ookii.org/docs/commandline-4.0/html/P_Ookii_CommandLine_ParseOptions_NameValueSeparators.htm
[`ParseOptions`]: https://www.ookii.org/docs/commandline-4.0/html/T_Ookii_CommandLine_ParseOptions.htm
[`ParseOptionsAttribute.AllowWhiteSpaceValueSeparator`]: https://www.ookii.org/docs/commandline-4.0/html/P_Ookii_CommandLine_ParseOptionsAttribute_AllowWhiteSpaceValueSeparator.htm
[`ParseOptionsAttribute.CaseSensitive`]: https://www.ookii.org/docs/commandline-4.0/html/P_Ookii_CommandLine_ParseOptionsAttribute_CaseSensitive.htm
[`ParseOptionsAttribute.NameValueSeparators`]: https://www.ookii.org/docs/commandline-4.0/html/P_Ookii_CommandLine_ParseOptionsAttribute_NameValueSeparators.htm
[`ParseOptionsAttribute`]: https://www.ookii.org/docs/commandline-4.0/html/T_Ookii_CommandLine_ParseOptionsAttribute.htm
[`KeyValuePairConverter<TKey, TValue>`]: https://www.ookii.org/docs/commandline-4.1/html/T_Ookii_CommandLine_Conversion_KeyValuePairConverter_2.htm
[`KeyValueSeparatorAttribute`]: https://www.ookii.org/docs/commandline-4.1/html/T_Ookii_CommandLine_Conversion_KeyValueSeparatorAttribute.htm
[`MultiValueSeparatorAttribute`]: https://www.ookii.org/docs/commandline-4.1/html/T_Ookii_CommandLine_MultiValueSeparatorAttribute.htm
[`ParseOptions.AllowWhiteSpaceValueSeparator`]: https://www.ookii.org/docs/commandline-4.1/html/P_Ookii_CommandLine_ParseOptions_AllowWhiteSpaceValueSeparator.htm
[`ParseOptions.ArgumentNameComparison`]: https://www.ookii.org/docs/commandline-4.1/html/P_Ookii_CommandLine_ParseOptions_ArgumentNameComparison.htm
[`ParseOptions.Culture`]: https://www.ookii.org/docs/commandline-4.1/html/P_Ookii_CommandLine_ParseOptions_Culture.htm
[`ParseOptions.NameValueSeparators`]: https://www.ookii.org/docs/commandline-4.1/html/P_Ookii_CommandLine_ParseOptions_NameValueSeparators.htm
[`ParseOptions.PrefixTermination`]: https://www.ookii.org/docs/commandline-4.1/html/P_Ookii_CommandLine_ParseOptions_PrefixTermination.htm
[`ParseOptions`]: https://www.ookii.org/docs/commandline-4.1/html/T_Ookii_CommandLine_ParseOptions.htm
[`ParseOptionsAttribute.AllowWhiteSpaceValueSeparator`]: https://www.ookii.org/docs/commandline-4.1/html/P_Ookii_CommandLine_ParseOptionsAttribute_AllowWhiteSpaceValueSeparator.htm
[`ParseOptionsAttribute.CaseSensitive`]: https://www.ookii.org/docs/commandline-4.1/html/P_Ookii_CommandLine_ParseOptionsAttribute_CaseSensitive.htm
[`ParseOptionsAttribute.NameValueSeparators`]: https://www.ookii.org/docs/commandline-4.1/html/P_Ookii_CommandLine_ParseOptionsAttribute_NameValueSeparators.htm
[`ParseOptionsAttribute.PrefixTermination`]: https://www.ookii.org/docs/commandline-4.1/html/P_Ookii_CommandLine_ParseOptionsAttribute_PrefixTermination.htm
[`ParseOptionsAttribute`]: https://www.ookii.org/docs/commandline-4.1/html/T_Ookii_CommandLine_ParseOptionsAttribute.htm
[`String`]: https://learn.microsoft.com/dotnet/api/system.string
[`TypeConverter`]: https://learn.microsoft.com/dotnet/api/system.componentmodel.typeconverter
[`Uri`]: https://learn.microsoft.com/dotnet/api/system.uri
[`ValueConverterAttribute`]: https://www.ookii.org/docs/commandline-4.0/html/T_Ookii_CommandLine_Conversion_ValueConverterAttribute.htm
[NullArgumentValue_0]: https://www.ookii.org/docs/commandline-4.0/html/T_Ookii_CommandLine_CommandLineArgumentErrorCategory.htm
[`ValidateEnumValueAttribute.AllowCommaSeparatedValues`]: https://www.ookii.org/docs/commandline-4.1/html/P_Ookii_CommandLine_Validation_ValidateEnumValueAttribute_AllowCommaSeparatedValues.htm
[`ValidateEnumValueAttribute.AllowNumericValues`]: https://www.ookii.org/docs/commandline-4.1/html/P_Ookii_CommandLine_Validation_ValidateEnumValueAttribute_AllowNumericValues.htm
[`ValidateEnumValueAttribute.CaseSensitive`]: https://www.ookii.org/docs/commandline-4.1/html/P_Ookii_CommandLine_Validation_ValidateEnumValueAttribute_CaseSensitive.htm
[`ValidateEnumValueAttribute`]: https://www.ookii.org/docs/commandline-4.1/html/T_Ookii_CommandLine_Validation_ValidateEnumValueAttribute.htm
[`ValueConverterAttribute`]: https://www.ookii.org/docs/commandline-4.1/html/T_Ookii_CommandLine_Conversion_ValueConverterAttribute.htm
[NullArgumentValue_0]: https://www.ookii.org/docs/commandline-4.1/html/T_Ookii_CommandLine_CommandLineArgumentErrorCategory.htm
Loading

0 comments on commit 9df03b6

Please sign in to comment.