Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,14 @@ dotnet_diagnostic.IDE0057.severity = none
[*.cs]
dotnet_diagnostic.IDE0290.severity = none

# SYSLIB1045: Use GeneratedRegexAttribute to generate the regular expression implementation at compile time
[*.cs]
dotnet_diagnostic.SYSLIB1045.severity = none

# CA1019: Define accessors for attribute arguments
[*.cs]
dotnet_diagnostic.CA1019.severity = none

# CA1031: Do not catch general exception types
[*.cs]
dotnet_diagnostic.CA1031.severity = none
Expand All @@ -41,3 +49,7 @@ dotnet_diagnostic.CA1707.severity = none
# CA1813: Avoid unsealed attributes
[*.cs]
dotnet_diagnostic.CA1813.severity = none

# CA2263: Prefer generic overload when type is known
[*.cs]
dotnet_diagnostic.CA2263.severity = none
10 changes: 5 additions & 5 deletions .ruleset
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
<Rule Id="SA1027" Action="Warning" /> <!-- Use tabs correctly -->
<Rule Id="SA1028" Action="Warning" /> <!-- Code should not contain trailing whitespace -->
</Rules>

<Rules AnalyzerId="StyleCop.Analyzers" RuleNamespace="StyleCop.Analyzers.ReadabilityRules">
<Rule Id="SA1100" Action="Warning" /> <!-- Do not prefix calls with base unless local implementation exists -->
<Rule Id="SA1101" Action="None" /> <!-- Prefix local calls with this -->
Expand All @@ -55,7 +55,7 @@
<Rule Id="SA1115" Action="Warning" /> <!-- Parameter should follow comma -->
<Rule Id="SA1116" Action="Warning" /> <!-- Split parameters should start on line after declaration -->
<Rule Id="SA1117" Action="Warning" /> <!-- Parameters should be on same line or separate lines -->
<Rule Id="SA1118" Action="Warning" /> <!-- Parameter should not span multiple lines -->
<Rule Id="SA1118" Action="None" /> <!-- Parameter should not span multiple lines -->
<Rule Id="SA1120" Action="Warning" /> <!-- Comments should contain text -->
<Rule Id="SA1121" Action="Warning" /> <!-- Use built-in type alias -->
<Rule Id="SA1122" Action="Warning" /> <!-- Use string.Empty for empty strings -->
Expand All @@ -77,7 +77,7 @@
<Rule Id="SA1139" Action="Warning" /> <!-- Use literal suffix notation instead of casting -->
<Rule Id="SX1101" Action="None" /> <!-- Do not prefix local calls with 'this.' -->
</Rules>

<Rules AnalyzerId="StyleCop.Analyzers" RuleNamespace="StyleCop.Analyzers.OrderingRules">
<Rule Id="SA1200" Action="None" /> <!-- Using directives should be placed correctly -->
<Rule Id="SA1201" Action="Warning" /> <!-- Elements should appear in the correct order -->
Expand Down Expand Up @@ -135,7 +135,7 @@
<Rule Id="SA1412" Action="None" /> <!-- Store files as UTF-8 with byte order mark -->
<Rule Id="SA1413" Action="None" /> <!-- Use trailing comma in multi-line initializers -->
</Rules>

<Rules AnalyzerId="StyleCop.Analyzers" RuleNamespace="StyleCop.Analyzers.LayoutRules">
<Rule Id="SA1500" Action="Warning" /> <!-- Braces for multi-line statements should not share line -->
<Rule Id="SA1501" Action="Warning" /> <!-- Statement should not be on a single line -->
Expand All @@ -159,7 +159,7 @@
<Rule Id="SA1519" Action="Warning" /> <!-- Braces should not be omitted from multi-line child statement -->
<Rule Id="SA1520" Action="Warning" /> <!-- Use braces consistently -->
</Rules>

<Rules AnalyzerId="StyleCop.Analyzers" RuleNamespace="StyleCop.Analyzers.DocumentationRules">
<Rule Id="SA1600" Action="None" /> <!-- Elements should be documented -->
<Rule Id="SA1601" Action="None" /> <!-- Partial elements should be documented -->
Expand Down
9 changes: 6 additions & 3 deletions Core/NetArgumentParser/ArgumentParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
using NetArgumentParser.Options;
using NetArgumentParser.Options.Collections;
using NetArgumentParser.Options.Utils;
using NetArgumentParser.Options.Utils.Verifiers;
using NetArgumentParser.Options.Verifiers;
using NetArgumentParser.Subcommands;
using NetArgumentParser.Visitors;

Expand All @@ -22,7 +22,9 @@ public class ArgumentParser : ParserQuantum
public ArgumentParser(
IDescriptionGenerator? descriptionGenerator = null,
ITextWriter? outputWriter = null,
Func<Subcommand, IDescriptionGenerator>? subcommandDescriptionGeneratorCreator = null)
Func<Subcommand, IDescriptionGenerator>? subcommandDescriptionGeneratorCreator = null,
string name = nameof(ArgumentParser))
: base(name ?? throw new ArgumentNullException(nameof(name)))
{
_mutuallyExclusiveOptionGroups = [];
_programName = string.Empty;
Expand Down Expand Up @@ -157,7 +159,8 @@ public virtual ParseArgumentsResult ParseKnownArguments(
DynamicOptionInteractor.HandleDefaultValueBySuitableOptions(allOptions);
ReuiredOptionVerifier.VerifyRequiredOptionsIsHandled(allOptions);

ResetOptionsHandledState();
ResetOptionsHandledState(true);
ResetSubcommandsHandledState(true);

return new ParseArgumentsResult(handledOptions, handledSubcommands);
}
Expand Down
18 changes: 11 additions & 7 deletions Core/NetArgumentParser/Attributes/CannotCreateOptionException.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,17 @@ namespace NetArgumentParser.Generators;
[Serializable]
public class CannotCreateOptionException : Exception
{
public CannotCreateOptionException() { }
public CannotCreateOptionException()
: this(GetDefaultMessage()) { }

public CannotCreateOptionException(string? message)
: base(message) { }
: base(message ?? GetDefaultMessage()) { }

public CannotCreateOptionException(string? message, Exception? innerException)
: base(message, innerException) { }
: base(message ?? GetDefaultMessage(), innerException) { }

public CannotCreateOptionException(string? message, PropertyInfo optionConfig)
: this(message, optionConfig, null) { }
: this(message ?? GetDefaultMessage(optionConfig), optionConfig, null) { }

public CannotCreateOptionException(
string? message,
Expand Down Expand Up @@ -54,9 +55,12 @@ public override void GetObjectData(SerializationInfo info, StreamingContext cont
base.GetObjectData(info, context);
}

private static string GetDefaultMessage(PropertyInfo optionConfig)
private static string GetDefaultMessage(PropertyInfo? optionConfig = null)
{
ExtendedArgumentNullException.ThrowIfNull(optionConfig, nameof(optionConfig));
return $"Cannot create option using '{optionConfig.Name}' configuration.";
const string message = "Cannot create option";

return optionConfig is not null
? $"{message} using '{optionConfig.Name}' configuration."
: $"{message}.";
}
}
2 changes: 0 additions & 2 deletions Core/NetArgumentParser/Attributes/EnumValueOptionAttribute.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ namespace NetArgumentParser.Attributes;
public class EnumValueOptionAttribute<T> : ValueOptionAttribute<T>
where T : struct, Enum
{
#pragma warning disable CA1019 // Define accessors for attribute arguments
public EnumValueOptionAttribute(
T defaultValue,
string longName,
Expand Down Expand Up @@ -53,7 +52,6 @@ public EnumValueOptionAttribute(
{
UseDefaultChoices = useDefaultChoices;
}
#pragma warning restore CA1019 // Define accessors for attribute arguments

public EnumValueOptionAttribute(
string longName,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ namespace NetArgumentParser.Attributes;
]
public class MultipleValueOptionAttribute<T> : ValueOptionAttribute<IList<T>>
{
#pragma warning disable CA1019 // Define accessors for attribute arguments
public MultipleValueOptionAttribute(
T[] defaultValue,
string longName,
Expand Down Expand Up @@ -85,7 +84,6 @@ public MultipleValueOptionAttribute(
ContextCapture = CreateContextCapture(contextCaptureType, numberOfItemsToCapture);
ValueRestriction = CreateValueRestriction(valueRestriction);
}
#pragma warning restore CA1019 // Define accessors for attribute arguments

public bool IgnoreOrderInChoices { get; }
public IContextCapture? ContextCapture { get; }
Expand Down
2 changes: 0 additions & 2 deletions Core/NetArgumentParser/Attributes/ValueOptionAttribute.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ namespace NetArgumentParser.Attributes;
]
public class ValueOptionAttribute<T> : CommonOptionAttribute
{
#pragma warning disable CA1019 // Define accessors for attribute arguments
public ValueOptionAttribute(
T defaultValue,
string longName,
Expand Down Expand Up @@ -52,7 +51,6 @@ public ValueOptionAttribute(
{
DefaultValue = new DefaultOptionValue<T>(defaultValue);
}
#pragma warning restore CA1019 // Define accessors for attribute arguments

public ValueOptionAttribute(
string longName,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,17 @@ namespace NetArgumentParser.Converters;
[Serializable]
public class DefaultConverterNotFoundException : Exception
{
public DefaultConverterNotFoundException() { }
public DefaultConverterNotFoundException()
: this(GetDefaultMessage()) { }

public DefaultConverterNotFoundException(string? message)
: base(message) { }
: base(message ?? GetDefaultMessage()) { }

public DefaultConverterNotFoundException(string? message, Exception? innerException)
: base(message, innerException) { }
: base(message ?? GetDefaultMessage(), innerException) { }

public DefaultConverterNotFoundException(string? message, Type outputType)
: this(message, outputType, null) { }
: this(message ?? GetDefaultMessage(outputType), outputType, null) { }

public DefaultConverterNotFoundException(
string? message,
Expand Down Expand Up @@ -53,9 +54,12 @@ public override void GetObjectData(SerializationInfo info, StreamingContext cont
base.GetObjectData(info, context);
}

private static string GetDefaultMessage(Type outputType)
private static string GetDefaultMessage(Type? outputType = null)
{
ExtendedArgumentNullException.ThrowIfNull(outputType, nameof(outputType));
return $"Default converter for type '{outputType.Name}' not found.";
string outputTypePresenter = outputType is not null
? $" for type '{outputType.Name}'"
: string.Empty;

return $"Default converter{outputTypePresenter} not found.";
}
}
2 changes: 0 additions & 2 deletions Core/NetArgumentParser/Converters/EnumValueConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ namespace NetArgumentParser.Converters;
public class EnumValueConverter<T> : ValueConverter<T>
where T : struct, Enum
{
#pragma warning disable CA2263 // Prefer generic overload when type is known
public EnumValueConverter(bool ignoreCase = true)
: base(t => (T)Enum.Parse(typeof(T), t, ignoreCase)) { }
#pragma warning restore CA2263 // Prefer generic overload when type is known
}
18 changes: 11 additions & 7 deletions Core/NetArgumentParser/Generators/NullSubcommandConfigException.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,17 @@ namespace NetArgumentParser.Generators;
[Serializable]
public class NullSubcommandConfigException : Exception
{
public NullSubcommandConfigException() { }
public NullSubcommandConfigException()
: this(GetDefaultMessage()) { }

public NullSubcommandConfigException(string? message)
: base(message) { }
: base(message ?? GetDefaultMessage()) { }

public NullSubcommandConfigException(string? message, Exception? innerException)
: base(message, innerException) { }
: base(message ?? GetDefaultMessage(), innerException) { }

public NullSubcommandConfigException(string? message, PropertyInfo subcommandConfig)
: this(message, subcommandConfig, null) { }
: this(message ?? GetDefaultMessage(subcommandConfig), subcommandConfig, null) { }

public NullSubcommandConfigException(
string? message,
Expand Down Expand Up @@ -57,9 +58,12 @@ public override void GetObjectData(SerializationInfo info, StreamingContext cont
base.GetObjectData(info, context);
}

private static string GetDefaultMessage(PropertyInfo subcommandConfig)
private static string GetDefaultMessage(PropertyInfo? subcommandConfig = null)
{
ExtendedArgumentNullException.ThrowIfNull(subcommandConfig, nameof(subcommandConfig));
return $"Subcommand configuration '{subcommandConfig.Name}' is null.";
string subcommandConfigPresenter = subcommandConfig is not null
? $" '{subcommandConfig.Name}'"
: string.Empty;

return $"Subcommand configuration{subcommandConfigPresenter} is null.";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,17 @@ namespace NetArgumentParser.Generators;
[Serializable]
public class UnsupportedOptionConfigException : Exception
{
public UnsupportedOptionConfigException() { }
public UnsupportedOptionConfigException()
: this(GetDefaultMessage()) { }

public UnsupportedOptionConfigException(string? message)
: base(message) { }
: base(message ?? GetDefaultMessage()) { }

public UnsupportedOptionConfigException(string? message, Exception? innerException)
: base(message, innerException) { }
: base(message ?? GetDefaultMessage(), innerException) { }

public UnsupportedOptionConfigException(string? message, PropertyInfo optionConfig)
: this(message, optionConfig, null) { }
: this(message ?? GetDefaultMessage(optionConfig), optionConfig, null) { }

public UnsupportedOptionConfigException(
string? message,
Expand Down Expand Up @@ -54,9 +55,12 @@ public override void GetObjectData(SerializationInfo info, StreamingContext cont
base.GetObjectData(info, context);
}

private static string GetDefaultMessage(PropertyInfo optionConfig)
private static string GetDefaultMessage(PropertyInfo? optionConfig = null)
{
ExtendedArgumentNullException.ThrowIfNull(optionConfig, nameof(optionConfig));
return $"Option configuration '{optionConfig.Name}' isn't supported.";
string optionConfigPresenter = optionConfig is not null
? $" '{optionConfig.Name}'"
: string.Empty;

return $"Option configuration{optionConfigPresenter} isn't supported.";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,17 @@ namespace NetArgumentParser.Generators;
[Serializable]
public class UnsupportedParserConfigException : Exception
{
public UnsupportedParserConfigException() { }
public UnsupportedParserConfigException()
: this(GetDefaultMessage()) { }

public UnsupportedParserConfigException(string? message)
: base(message) { }
: base(message ?? GetDefaultMessage()) { }

public UnsupportedParserConfigException(string? message, Exception? innerException)
: base(message, innerException) { }
: base(message ?? GetDefaultMessage(), innerException) { }

public UnsupportedParserConfigException(string? message, object config)
: this(message, config, null) { }
: this(message ?? GetDefaultMessage(config), config, null) { }

public UnsupportedParserConfigException(
string? message,
Expand Down Expand Up @@ -54,14 +55,19 @@ public override void GetObjectData(SerializationInfo info, StreamingContext cont
base.GetObjectData(info, context);
}

private static string GetDefaultMessage(object config)
private static string GetDefaultMessage(object? config = null)
{
ExtendedArgumentNullException.ThrowIfNull(config, nameof(config));

string? configObjectName = config.GetType().FullName;
string? configObjectName = config?.GetType().FullName;
string? necessaryAttributeName = typeof(ParserConfigAttribute).FullName;

return $"Config '{configObjectName}' isn't supported. " +
$"It must be marked by {necessaryAttributeName} attribute.";
string configObjectNamePresenter = !string.IsNullOrEmpty(configObjectName)
? $" '{configObjectName}'"
: string.Empty;

string message = $"Config{configObjectNamePresenter} isn't supported.";

return !string.IsNullOrEmpty(necessaryAttributeName)
? $"{message} It must be marked by {necessaryAttributeName} attribute."
: message;
}
}
6 changes: 3 additions & 3 deletions Core/NetArgumentParser/NetArgumentParser.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,20 @@

<PropertyGroup>
<PackageId>NetArgumentParser</PackageId>
<Version>1.0.7</Version>
<Version>1.0.8</Version>
<Product>NetArgumentParser</Product>
<Title>NetArgumentParser</Title>
<Authors>yakovypg</Authors>
<Company>yakovypg</Company>
<Copyright>Copyright © yakovypg 2025</Copyright>
<Copyright>Copyright © yakovypg 2024–2026</Copyright>
<PackageTags>cli;options;args;command-line;argument-parser;arguments;cli-args;argument-parsing;subcommands;argparse;command-line-parser;flags;cli-parser;command-line-arguments;cli-arguments;net-argparse;csharp-argparse;subcommand-parser</PackageTags>
<Description>NetArgumentParser is a cross-platform, free and open source library for parsing command-line options, arguments and subcommands. It contains the main features of popular argument parsers such as argparse, as well as many of its own.</Description>
<PackageProjectUrl>https://github.com/yakovypg/NetArgumentParser</PackageProjectUrl>
<RepositoryUrl>https://github.com/yakovypg/NetArgumentParser</RepositoryUrl>
<RepositoryType>git</RepositoryType>
<PackageReadmeFile>README.md</PackageReadmeFile>
<PackageLicenseFile>LICENSE</PackageLicenseFile>
<!--<PackageLicenseExpression>GPL-3.0-or-later</PackageLicenseExpression>-->
<!--<PackageLicenseExpression>GPL-3.0-or-later</PackageLicenseExpression>-->
<RequireLicenseAcceptance>true</RequireLicenseAcceptance>
<PublishRepositoryUrl>true</PublishRepositoryUrl>
</PropertyGroup>
Expand Down
Loading
Loading