Ookii.CommandLine 4.0 and later have a number of breaking changes from version 3.x and earlier versions. This article explains what you need to know to migrate your code to the new version.
Although there are quite a few changes, it's likely your application will not require many modifications unless you used subcommands, heavily customized the usage help format, or used custom argument value conversion.
As of version 3.0, .Net Framework 2.0 is no longer supported. You can still target .Net Framework 4.6.1 and later using the .Net Standard 2.0 assembly. If you need to support an older version of .Net, please continue to use version 2.4.
- It's strongly recommended to apply the
GeneratedParserAttribute
to your arguments classes unless you cannot meet the requirements for source generation. - The
CommandLineArgumentAttribute.ValueDescription
property has been replaced by theValueDescriptionAttribute
attribute. This new attribute is not sealed, enabling derived attributes e.g. to load a value description from a localized resource. - Converting argument values from a string to their final type is no longer done using the
TypeConverter
class, but instead using a customArgumentConverter
class. Custom converters must be specified using theArgumentConverterAttribute
instead of theTypeConverterAttribute
.- If you have existing conversions that depend on a
TypeConverter
, use theWrappedTypeConverter<T>
andWrappedDefaultTypeConverter<T>
as a convenient way to keep using that conversion. - The
KeyValuePairConverter<TKey, TValue>
class has moved into theOokii.CommandLine.Conversion
namespace. - The
KeyValueSeparatorAttribute
has moved into theOokii.CommandLine.Conversion
namespace. - The
KeyTypeConverterAttribute
andValueTypeConverterAttribute
were renamed toKeyConverterAttribute
andValueConverterAttribute
respectively
- If you have existing conversions that depend on a
- Constructor parameters can no longer be used to define command line arguments. Instead, all arguments must be defined using properties.
ParseOptions.ArgumentNameComparer
andCommandOptions.CommandNameComparer
have been replaced byArgumentNameComparison
andCommandNameComparison
respectively, both now taking aStringComparison
value instead of anIComparer<string>
.- Overloads of the
CommandLineParser.Parse()
,CommandLineParser.ParseWithErrorHandling()
,CommandLineParser<T>.Parse()
,CommandLineParser<T>.ParseWithErrorHandling()
,CommandManager.CreateCommand()
andCommandManager.RunCommand()
methods that took an index have been replaced by overloads that take aReadOnlyMemory<string>
. - The
CommandInfo
type is now a class instead of a structure. - The
ICommandWithCustomParsing.Parse()
method signature has changed to use aReadOnlyMemory<string>
structure for the arguments and to receive a reference to the callingCommandManager
instance. - The
CommandLineArgumentAttribute.CancelParsing
property now takes aCancelMode
enumeration rather than a boolean. - The
ArgumentParsedEventArgs
class was changed to use theCancelMode
enumeration. - Canceling parsing using the
ArgumentParsed
event no longer automatically sets theHelpRequested
property; instead, you must set it manually in the event handler if desired. - The
ParseOptionsAttribute.NameValueSeparator
property was replaced withParseOptionsAttribute.NameValueSeparators
. - The
ParseOptions.NameValueSeparator
property was replaced withParseOptions.NameValueSeparators
. - Properties that previously returned a
ReadOnlyCollection<T>
now return anImmutableArray<T>
. - The
CommandLineArgument.MultiValueSeparator
andCommandLineArgument.AllowMultiValueWhiteSpaceSeparator
properties have been moved into theCommandLineArgument.MultiValueInfo
property. - The
CommandLineArgument.AllowsDuplicateDictionaryKeys
andCommandLineArgument.KeyValueSeparator
properties have been moved into theCommandLineArgument.DictionaryInfo
property. - The
CommandLineArgument.IsDictionary
andCommandLineArgument.IsMultiValue
properties have been removed; instead, checkCommandLineArgument.DictionaryInfo
orCommandLineArgument.MultiValueInfo
for null values, or use theCommandLineArgument.Kind
property. TextFormat
is now a structure with strongly-typed values for VT sequences, and that structure is used by theUsageWriter
class for the various color formatting options.
- By default, both
:
and=
are accepted as argument name/value separators. - The default value of
ParseOptions.ShowUsageOnError
has changed toUsageHelpRequest.SyntaxOnly
. - Automatic prefix aliases are enabled by default for both argument names and command names.
- The
CommandManager
, when using an assembly that is not the calling assembly, will only use public command classes, where before it would also use internal ones. This is to better respect access modifiers, and to make sure generated and reflection-based command managers behave the same.
- It's strongly recommended to switch to the static
CommandLineParser.Parse<T>()
method, if you were not already using it from version 2.4. - If you do need to manually handle errors, be aware of the following changes:
- If the instance
CommandLineParser.Parse()
method returns null, you should only show usage help if theCommandLineParser.HelpRequested
property is true. - Version 3.0 adds automatic "-Help" and "-Version" properties, which means the
Parse()
method can return null even if it previously wouldn't. - Recommended: use the
CommandLineParser<T>
class to get strongly typed instanceParse()
methods. - The
CommandLineParser
constructor now takes aParseOptions
instance. - Several properties of the
CommandLineParser
class that could be used to change parsing behavior are now read-only and can only be changed throughParseOptions
. - See manual parsing and error handling for an updated example.
- If the instance
- The
WriteUsageOptions
class has been replaced withUsageWriter
. - Usage options that previously were formatting strings now require creating a class that derives
from
UsageWriter
and overrides some of its methods. You have much more control over the formatting this way. See customizing the usage help. - The
CommandLineParser.WriteUsageToConsole()
method no longer exists; instead, theCommandLineParser.WriteUsage()
method will write to the console when invoked using aUsageWriter
with no explicitly set output. - The subcommand (formerly called "shell command") API has had substantial changes.
- Subcommand related functionality has moved into the
Ookii.CommandLine.Commands
namespace. - The
ShellCommand
class as a base class for command classes has been replaced with theICommand
interface. - The
ShellCommand.ExitCode
property has been replaced with the return value of theICommand.Run()
method. - The
ShellCommand
class's static methods have been replaced with theCommandManager
class. - The
ShellCommandAttribute
class has been renamed toCommandAttribute
. - The
ShellCommandAttribute.CustomParsing
property has been replaced with theICommandWithCustomParsing
interface.- Commands with custom parsing no longer need a special constructor, and must implement the
ICommandWithCustomParsing.Parse()
method instead.
- Commands with custom parsing no longer need a special constructor, and must implement the
- The
CreateShellCommandOptions
class has been renamed toCommandOptions
. - Usage related options have been moved into the
UsageWriter
class. - Recommended: use
IAsyncCommand
orAsyncCommandBase
, along withCommandManager.RunCommandAsync()
, if your commands need to run asynchronous code.
- Subcommand related functionality has moved into the
- A number of explicit method overloads have been removed in favor of optional parameters.
- The
CommandLineArgument.ElementType
property now returns the underlying type for arguments using theNullable<T>
type.
- Argument type conversion now defaults to
CultureInfo.InvariantCulture
, instead ofCurrentCulture
. This change was made to ensure a consistent parsing experience regardless of the user's regional settings. Only change it if you have a good reason. CommandLineParser
automatically adds-Help
and-Version
arguments by default. If you had arguments with these names, this will not affect you. The-Version
argument is not added for subcommands.CommandManager
automatically adds aversion
command by default. If you had a command with this name, this will not affect you.- The usage help now includes aliases and default values by default.
- The default format for showing aliases in the usage help has changed.
- Usage help uses color output by default (where supported).
- The
LineWrappingTextWriter
class does not count virtual terminal sequences as part of the line length by default.