spectre.console icon indicating copy to clipboard operation
spectre.console copied to clipboard

Allow empty arguments when using double dashed args (from https://github.com/cake-build/cake/issues/3277)

Open Nisha2015 opened this issue 4 years ago • 3 comments

Information

  • OS: Windows/Linux
  • Version: 0.42.0
  • Terminal: Windows cmd/Bash.

Describe the bug The issue was originally raised in Cake repository which is using Spectre.console.cli to parse the command line arguments.

A pattern that we've seen is to have use environment variables as values for Cake script arguments. e.g.

dotnet cake --argName=%ARG_NAME_VALUE% If the %ARG_NAME_VALUE% environment value exists and has a value, everything works as expected.

However, if the environment variable does not exist, or its value is empty, the user receives an error from the Cake runner: Expected an option value.

The current workaround is to use (space) instead of = if the value can be empty/null. e.g.

dotnet cake --argName %ARG_NAME_VALUE%

After investigating the, it is found that the issue is coming from Spectre.Console.Cli in ScanOptions method of CommandTreeTokenizer class. Below is the code throwing the exception, this is coming as the value of environment variable is empty or null, so the if condition i.e. if (!reader.TryPeek(out _)) is being satisfied and exception is thrown.

 if (reader.TryPeek(out character))
{
	// Encountered a separator?
	if (character == '=' || character == ':')
	{
		reader.Read(); // Consume
		context.AddRemaining(character);

		if (!reader.TryPeek(out _))
		{
			var token = new CommandTreeToken(CommandTreeToken.Kind.String, reader.Position, "=", "=");
			throw CommandParseException.OptionValueWasExpected(reader.Original, token);
		}

		result.Add(ScanString(context, reader));
	}
}

To Reproduce Run a cake script with an argument having an empty or null value i.e. dotnet cake --argName %ARG_NAME_VALUE%

Expected behavior User should be able to pass environment variables which has empty or null value.

Additional context Please look at https://github.com/cake-build/cake/issues/3277 for more information.

Nisha2015 avatar Oct 20 '21 12:10 Nisha2015

We could just remove the line throwing CommandParseException and it will allow users to pass empty/null arguments in the command line. Consumer of the library would check if a value of an argument is required and will fail if that's the case.

I did test it and all the test cases pass except 4 in CommandAppTests.Parsing.cs which are checking the exception text.

I could fix those and raise a PR.

Please let me know your thoughts on the same. Thanks.

Nisha2015 avatar Nov 06 '21 20:11 Nisha2015

@Nisha2015 If I've defined the following setting and passed an empty value, I expect it to fail since MyArg is required.

[CommandOption("--myarg <VALUE>")]
public string MyArg { get; set; }

To work around this, you need to use the FlagValue and set MyArg to optional.

[CommandOption("--myarg [VALUE]")]
public FlagValue<string> MyArg { get; set; }

patriksvensson avatar Nov 08 '21 08:11 patriksvensson

Please note that [CommandOption("--myarg [VALUE]")] => [VALUE] is important as well, will not without it.

tapika avatar Jan 19 '22 09:01 tapika

If I've defined the following setting and passed an empty value, I expect it to fail since MyArg is required. To work around this, you need to use the FlagValue and set MyArg to optional.

Hello @Nisha2015, did Patrik's explanation above fix this issue for you?

FrankRay78 avatar Mar 07 '24 09:03 FrankRay78