Skip to content

Commit

Permalink
Merge pull request #1505 from ahmede41/master
Browse files Browse the repository at this point in the history
[#1380] Fix for requiredOptionMarker displayed on ArgGroup
  • Loading branch information
remkop committed Feb 10, 2022
2 parents df0474f + 020a770 commit 85cd899
Show file tree
Hide file tree
Showing 4 changed files with 167 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
package picocli;

import org.junit.Test;
import picocli.CommandLine.ArgGroup;
import picocli.CommandLine.Command;
import picocli.CommandLine.Option;

import java.io.ByteArrayOutputStream;
import java.io.PrintStream;

import static org.junit.Assert.assertEquals;

/**
* Testing class for exclusiveOptions
*/
class Issue1380ExclusiveOptions {
@Option(names = {"-s", "--silent"}, description = "Silent mode", required = false)
protected boolean silent;

@Option(names = {"-v", "--verbose"}, description = "Verbose mode", required = false)
protected boolean verbose;

@Option(names = {"-j", "--json"}, description = "JSON printing", required = false)
protected boolean json;
}

/**
* Testing class for creating a commandline with ArgGroup exclusive tree
*/
@Command(requiredOptionMarker = '*')
class TestingClassExclusiveTrue {

@ArgGroup(exclusive = true, multiplicity = "0..1")
protected Issue1380ExclusiveOptions exclusive;
}

/**
* Testing class for creating a commandline with ArgGroup exclusive false
*/
@Command(requiredOptionMarker = '*')
class TestingClassExclusiveFalse {

@ArgGroup(exclusive = false, multiplicity = "0..1")
protected Issue1380ExclusiveOptions exclusive;
}

/**
* JUnit testing class for issue#1380 // CS427 https://github.com/remkop/picocli/issues/1380
*/
public class Issue1380Test {

/**
* JUnit test class for issue#1380 with exclusive set to true // CS427 https://github.com/remkop/picocli/issues/1380
*/
@Test
public void testingWithExclusiveTrue() {
ByteArrayOutputStream tempOut = new ByteArrayOutputStream();
PrintStream printStream = new PrintStream(tempOut);
new CommandLine(new TestingClassExclusiveTrue()).usage(printStream);

String returnedText = tempOut.toString();
String expectedText = String.format(
"Usage: <main class> [-s | -v | -j]%n"+
" -j, --json JSON printing%n"+
" -s, --silent Silent mode%n"+
" -v, --verbose Verbose mode%n");

assertEquals(expectedText, returnedText);
}

/**
* JUnit test class for issue#1380 with exclusive set to false// CS427 https://github.com/remkop/picocli/issues/1380
*/
@Test
public void testingWithExclusiveFalse() {
ByteArrayOutputStream tempOut = new ByteArrayOutputStream();
PrintStream printStream = new PrintStream(tempOut);
new CommandLine(new TestingClassExclusiveFalse()).usage(printStream);

String returnedText = tempOut.toString();
String expectedText = String.format(
"Usage: <main class> [[-s] [-v] [-j]]%n" +
" -j, --json JSON printing%n" +
" -s, --silent Silent mode%n" +
" -v, --verbose Verbose mode%n");

assertEquals(expectedText, returnedText);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package picocli;

import org.junit.Ignore;
import org.junit.Test;
import picocli.CommandLine.ArgGroup;
import picocli.CommandLine.Command;
import picocli.CommandLine.Option;

import java.io.ByteArrayOutputStream;
import java.io.PrintStream;

import static org.junit.Assert.assertEquals;

/**
* Testing class for creating a commandline with resourceBundle
*/
@Command(name = "TestingCommand", resourceBundle = ("picocli.Message"))
class TestingClass {

@ArgGroup(exclusive = true, multiplicity = "0..1")
protected TestingClass.ExclusiveOptions exclusive;

public TestingClass.ExclusiveOptions getExclusive() {
return this.exclusive;
}
private static class ExclusiveOptions {
@Option(names = {"-h", "--help"}, descriptionKey = "help.message", required = false)
protected boolean showHelp;

@Option(names = {"-j", "--json"}, descriptionKey = "json.message", required = false)
protected boolean isJson;

}
}

@Ignore
/**
* JUnit testing class for issue#1420 // CS427 https://github.com/remkop/picocli/issues/1420
*/
public class Issue1420Test {

/**
* JUnit test class for issue#1420 with resourceBundle // CS427 https://github.com/remkop/picocli/issues/1420
*/
@Test
public void testingWithResourceBundle1() {
ByteArrayOutputStream tempOut = new ByteArrayOutputStream();
PrintStream printStream = new PrintStream(tempOut);
new CommandLine(new TestingClass()).usage(printStream);

String returnedText = tempOut.toString();
String expectedText = "Usage: TestingCommand [[-h] | [-j]]\n" +
" -h, --help Show help options\n" +
" -j, --json Set json export-on\n";

assertEquals(expectedText, returnedText);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/**
* Testing class for // CS427 https://github.com/remkop/picocli/issues/1420
*/
help.message=Show help options
json.message =Set json export-on

15 changes: 14 additions & 1 deletion src/main/java/picocli/CommandLine.java
Original file line number Diff line number Diff line change
Expand Up @@ -8587,6 +8587,7 @@ public abstract static class ArgSpec {

// parser fields
private boolean required;
private boolean originallyRequired;
private final boolean interactive;
private final boolean echo;
private final String prompt;
Expand Down Expand Up @@ -8641,6 +8642,7 @@ private <T extends Builder<T>> ArgSpec(Builder<T> builder) {
annotatedElement = builder.annotatedElement;
defaultValue = NO_DEFAULT_VALUE.equals(builder.defaultValue) ? null : builder.defaultValue;
required = builder.required;
originallyRequired = builder.originallyRequired;
toString = builder.toString;
getter = builder.getter;
setter = builder.setter;
Expand Down Expand Up @@ -8699,6 +8701,13 @@ void applyInitialValue(Tracer tracer) {
}
}

/** Returns the original value of the option's required attribute, regardless of whether the option is used in an exclusive group or not.
* @since 4.7.0
* @see Option#required() */
public boolean originallyRequired(){
return originallyRequired;
}

/** Returns whether this is a required option or positional parameter without a default value.
* If this argument is part of a {@linkplain ArgGroup group}, this method returns whether this argument is required <em>within the group</em> (so it is not necessarily a required argument for the command).
* @see Option#required() */
Expand Down Expand Up @@ -9251,6 +9260,7 @@ abstract static class Builder<T extends Builder<T>> {
private String[] description;
private String descriptionKey;
private boolean required;
private boolean originallyRequired;
private boolean interactive;
private boolean echo;
private String prompt;
Expand Down Expand Up @@ -9290,6 +9300,7 @@ abstract static class Builder<T extends Builder<T>> {
description = original.description;
descriptionKey = original.descriptionKey;
required = original.required;
originallyRequired = original.originallyRequired;
interactive = original.interactive;
echo = original.echo;
prompt = original.prompt;
Expand Down Expand Up @@ -10198,6 +10209,8 @@ public static class ArgGroupSpec implements IOrdered {
if (!arg.required()) {
modifiedArgs += sep + (arg.isOption() ? ((OptionSpec) arg).longestName() : (arg.paramLabel() + "[" + ((PositionalParamSpec) arg).index() + "]"));
sep = ",";
//Keep initial required as originallyRequired for Issue#1380 https://github.com/remkop/picocli/issues/1380
arg.originallyRequired = true;
arg.required = true;
}
}
Expand Down Expand Up @@ -16219,7 +16232,7 @@ public Text[][] render(OptionSpec option, IParamLabelRenderer paramLabelRenderer
String longOption = join(names, shortOptionCount, names.length - shortOptionCount, ", ");
Text longOptionText = createLongOptionText(option, paramLabelRenderer, scheme, longOption);

String requiredOption = option.required() ? requiredMarker : "";
String requiredOption = !option.originallyRequired() && option.required() ? requiredMarker : "";
return renderDescriptionLines(option, scheme, requiredOption, shortOption, longOptionText);
}

Expand Down

0 comments on commit 85cd899

Please sign in to comment.