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
GeneratedParserAttributeto your arguments classes unless you cannot meet the requirements for source generation. - The
CommandLineArgumentAttribute.ValueDescriptionproperty has been replaced by theValueDescriptionAttributeattribute. 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
TypeConverterclass, but instead using a customArgumentConverterclass. Custom converters must be specified using theArgumentConverterAttributeinstead 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.Conversionnamespace. - The
KeyValueSeparatorAttributehas moved into theOokii.CommandLine.Conversionnamespace. - The
KeyTypeConverterAttributeandValueTypeConverterAttributewere renamed toKeyConverterAttributeandValueConverterAttributerespectively
- 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.ArgumentNameComparerandCommandOptions.CommandNameComparerhave been replaced byArgumentNameComparisonandCommandNameComparisonrespectively, both now taking aStringComparisonvalue 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
CommandInfotype 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 callingCommandManagerinstance. - The
CommandLineArgumentAttribute.CancelParsingproperty now takes aCancelModeenumeration rather than a boolean. - The
ArgumentParsedEventArgsclass was changed to use theCancelModeenumeration. - Canceling parsing using the
ArgumentParsedevent no longer automatically sets theHelpRequestedproperty; instead, you must set it manually in the event handler if desired. - The
ParseOptionsAttribute.NameValueSeparatorproperty was replaced withParseOptionsAttribute.NameValueSeparators. - The
ParseOptions.NameValueSeparatorproperty was replaced withParseOptions.NameValueSeparators. - Properties that previously returned a
ReadOnlyCollection<T>now return anImmutableArray<T>. - The
CommandLineArgument.MultiValueSeparatorandCommandLineArgument.AllowMultiValueWhiteSpaceSeparatorproperties have been moved into theCommandLineArgument.MultiValueInfoproperty. - The
CommandLineArgument.AllowsDuplicateDictionaryKeysandCommandLineArgument.KeyValueSeparatorproperties have been moved into theCommandLineArgument.DictionaryInfoproperty. - The
CommandLineArgument.IsDictionaryandCommandLineArgument.IsMultiValueproperties have been removed; instead, checkCommandLineArgument.DictionaryInfoorCommandLineArgument.MultiValueInfofor null values, or use theCommandLineArgument.Kindproperty. TextFormatis now a structure with strongly-typed values for VT sequences, and that structure is used by theUsageWriterclass for the various color formatting options.
- By default, both
:and=are accepted as argument name/value separators. - The default value of
ParseOptions.ShowUsageOnErrorhas 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.HelpRequestedproperty 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
CommandLineParserconstructor now takes aParseOptionsinstance. - Several properties of the
CommandLineParserclass 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
WriteUsageOptionsclass has been replaced withUsageWriter. - Usage options that previously were formatting strings now require creating a class that derives
from
UsageWriterand 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 aUsageWriterwith no explicitly set output. - The subcommand (formerly called "shell command") API has had substantial changes.
- Subcommand related functionality has moved into the
Ookii.CommandLine.Commandsnamespace. - The
ShellCommandclass as a base class for command classes has been replaced with theICommandinterface. - The
ShellCommand.ExitCodeproperty has been replaced with the return value of theICommand.Run()method. - The
ShellCommandclass's static methods have been replaced with theCommandManagerclass. - The
ShellCommandAttributeclass has been renamed toCommandAttribute. - The
ShellCommandAttribute.CustomParsingproperty has been replaced with theICommandWithCustomParsinginterface.- 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
CreateShellCommandOptionsclass has been renamed toCommandOptions. - Usage related options have been moved into the
UsageWriterclass. - Recommended: use
IAsyncCommandorAsyncCommandBase, 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.ElementTypeproperty 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. CommandLineParserautomatically adds-Helpand-Versionarguments by default. If you had arguments with these names, this will not affect you. The-Versionargument is not added for subcommands.CommandManagerautomatically adds aversioncommand 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
LineWrappingTextWriterclass does not count virtual terminal sequences as part of the line length by default.