- Added pretty-printing for unhandled exceptions thrown from within the application. This makes the errors easier to parse visually and should help in troubleshooting. This change does not affect
CommandException
, as it already has special treatment. (Thanks @Mårten Åsberg) - Added support for custom value converters. You can now create a type that implements
CliFx.IArgumentValueConverter
and specify it as a converter for your parameters or options via theConverter
named property. This should enable conversion between raw argument values and custom types which are not string-initializable. (Thanks @Oleksandr Shustov) - Improved help text so that it also shows minimal usage examples for child and descendant commands, besides the actual command it was requested on. This should improve user experience for applications with many nested commands. (Thanks @Nikiforov Alexey)
- Added
VirtualConsole.CreateBuffered()
method to simplify test setup when using in-memory backing stores for output and error streams. Please refer to the readme for updated recommendations on how to test applications built with CliFx. - Added generic
CliApplicationBuilder.AddCommand<TCommand>()
. This overload simplifies adding commands one-by-one as it also checks that the type implementsICommand
.
- Fixed an issue where a command was incorrectly allowed to execute when the user did not specify any value for a non-scalar parameter. Since they are always required, a parameter needs to be bound to (at least) one value. (Thanks @Daniel Hix)
- Fixed an issue where
CliApplication.RunAsync(...)
threwArgumentException
if there were two environment variables, whose names differed only in case. Environment variable names are now treated case-sensitively. (Thanks @Ron Myers)
- Running the application with the debug directive (
myapp [debug]
) will now also try to launch a debugger instance. In most cases it will save time as you won't need to attach the debugger manually. (Thanks @Volodymyr Shkolka) - Fixed an issue where unhandled generic exceptions (i.e. not
CommandException
) sometimes caused the application to incorrectly return successful exit code due to an overflow issue on Unix systems. Starting from this version, all unhandled generic exceptions will produce1
as the exit code when thrown. Instances ofCommandException
can still be configured to return any specified exit code, but it's recommended to constrain the values between1
and255
to avoid overflow issues. (Thanks @Ihor Nechyporuk)
- Changed analyzers to report errors instead of warnings. If you find that some analyzer works incorrectly, please report it on GitHub. You can also configure inspection severity overrides in your project if you need to.
- Improved help text by showing default values for non-required options. This only works on types that have a custom override for
ToString()
method. Additionally, if the type implementsIFormattable
, the overload with a format provider will be used instead. (Thanks @Domn Werner) - Changed default version text to only show 3 version components instead of 4, if the last component (revision) is not specified or is zero. This makes the default version text compliant with semantic versioning.
- Fixed an issue where it was possible to define a command with an option that has the same name or short name as built-in help or version options. Previously it would lead to the user-defined option being ignored in favor of the built-in option. Now this will throw an exception instead.
- Changed the underlying representation of
StreamReader
/StreamWriter
objects used inSystemConsole
andVirtualConsole
to be thread-safe.
- Added built-in Roslyn analyzers that help catch incorrect usage of the library. Currently, all analyzers report issues as warnings so as to not prevent the project from building. In the future that may change.
- Added an optional parameter to
new CommandException(...)
calledshowHelp
which can be used to instruct CliFx to show help for the current command after printing the error. (Thanks @Domn Werner) - Improved help text shown for enum options and parameters by providing the list of valid values that the enum can accept. (Thanks @Domn Werner)
- Fixed an issue where it was possible to set an option without providing a value, while the option was marked as required.
- Fixed an issue where it was possible to configure an option with an empty name or a name consisting of a single character. If you want to use a single character as a name, you should set the option's short name instead.
- Added
CursorLeft
andCursorTop
properties toIConsole
and its implementations. InVirtualConsole
, these are just auto-properties. - Improved exception messages.
- Improved exceptions related to user input by also showing help text after the error message. (Thanks @Domn Werner)
- Changed
IConsole
interface (and as a result,SystemConsole
andVirtualConsole
) to support writing binary data. Instead ofTextReader
/TextWriter
instances, the streams are now exposed asStreamReader
/StreamWriter
which provide theBaseStream
property that allows raw access. Existing usages inside commands should remain the same becauseStreamReader
/StreamWriter
are compatible with their base classesTextReader
/TextWriter
, but if you were usingVirtualConsole
in tests, you may have to update it to the new API. Refer to the readme for more info. - Changed argument binding behavior so that an error is produced if the user provides an argument that doesn't match with any parameter or option. This is done in order to improve user experience, as otherwise the user may make a typo without knowing that their input wasn't taken into account.
- Changed argument binding behavior so that options can be set to multiple argument values while specifying them with mixed naming. For example,
--option value1 -o value2 --option value3
would result in the option being set to corresponding three values, assuming--option
and-o
match with the same option.