System.InvalidOperationException: on parsing GUID command line option.
AlexeyEvlampiev opened this issue · 3 comments
Describe the bug
System.InvalidOperationException: Could not automatically determine how to convert string values into System.Guid is thrown when registering Guid- command line options.
To Reproduce
Steps to reproduce the behavior:
- Using this version of the library '2.5.0'
- Run this code
namespace ConsoleApp1
{
using System;
using System.Diagnostics;
using McMaster.Extensions.CommandLineUtils;
class Program
{
static void Main(string[] args)
{
var cmd = new CommandLineApplication();
var guidOption = cmd
.Option<Guid>("-g", "A GUID-option", CommandOptionType.SingleValue)
.IsRequired();
var expected = Guid.NewGuid().ToString();
cmd.OnExecute(() =>
{
var actual = guidOption.ParsedValue;
Debug.Assert(expected == actual.ToString());
});
cmd.Execute(new []{"-g", expected });
}
}
}
- See error "Could not automatically determine how to convert string values into System.Guid"
Expected behavior
Specifying command options of the Guid type should work seamlessly.
Additional context
I would suggest introducing a generic value parser that would cover most of the CLR standard library types:
using System;
using System.ComponentModel;
using System.Globalization;
using McMaster.Extensions.CommandLineUtils.Abstractions;
public class GenericValueParser : IValueParser {
private GenericValueParser(Type targetType, TypeConverter converter)
{
TargetType = targetType;
Converter = converter;
}
public static GenericValueParser Get<T>()
{
var targetType = typeof(T);
var converter = TypeDescriptor.GetConverter(targetType);
return converter.CanConvertFrom(typeof(string)) ? new GenericValueParser(targetType, converter) : null;
}
public Type TargetType { get; }
public TypeConverter Converter { get; }
public object Parse(string argName, string value, CultureInfo culture)
{
return Converter.ConvertFromString(null, culture, value);
}
}
The originally failing code would be fixed with e.g.
namespace ConsoleApp1
{
using System;
using System.Diagnostics;
using McMaster.Extensions.CommandLineUtils;
class Program
{
static void Main(string[] args)
{
var cmd = new CommandLineApplication();
cmd.ValueParsers.Add(GenericValueParser.Get<Guid>());
var guidOption = cmd
.Option<Guid>("-g", "A GUID-option", CommandOptionType.SingleValue)
.IsRequired();
var expected = Guid.NewGuid().ToString();
cmd.OnExecute(() =>
{
var actual = guidOption.ParsedValue;
Debug.Assert(expected == actual.ToString());
});
cmd.Execute(new []{"-g", expected });
}
}
}
Would you be willing to send a pull request to fix this? Seems like you have posted most of the solution already 😄
To be honest I have no experience in contributing to open source. If my PR is done not the right way, could someone help by picking up the change I made?
Congrats on your first PR! Yes, you did it correctly (kudos to you). I'll leave some comments on your PR, #345.