Skip to content

Commit

Permalink
fix for issue airlift#22
Browse files Browse the repository at this point in the history
  • Loading branch information
thombergs committed Oct 9, 2013
1 parent df13364 commit f9c3e47
Show file tree
Hide file tree
Showing 7 changed files with 121 additions and 46 deletions.
45 changes: 25 additions & 20 deletions src/main/java/io/airlift/command/Cli.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,7 @@
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
import io.airlift.command.model.ArgumentsMetadata;
import io.airlift.command.model.CommandGroupMetadata;
import io.airlift.command.model.CommandMetadata;
import io.airlift.command.model.GlobalMetadata;
import io.airlift.command.model.MetadataLoader;
import io.airlift.command.model.OptionMetadata;
import io.airlift.command.model.*;

import java.util.List;
import java.util.Map;
Expand Down Expand Up @@ -129,6 +124,7 @@ public C parse(Iterable<String> args)
private void validate(ParseState state)
{
CommandMetadata command = state.getCommand();

if (command == null) {
List<String> unparsedInput = state.getUnparsedInput();
if (unparsedInput.isEmpty()) {
Expand All @@ -139,23 +135,32 @@ private void validate(ParseState state)
}
}

ArgumentsMetadata arguments = command.getArguments();
if (state.getParsedArguments().isEmpty() && arguments != null && arguments.isRequired()) {
throw new ParseArgumentsMissingException(arguments.getTitle());
}

if (!state.getUnparsedInput().isEmpty()) {
throw new ParseArgumentsUnexpectedException(state.getUnparsedInput());
}
try{
ArgumentsMetadata arguments = command.getArguments();
if (state.getParsedArguments().isEmpty() && arguments != null && arguments.isRequired()) {
throw new ParseArgumentsMissingException(arguments.getTitle());
}

if (state.getLocation() == Context.OPTION) {
throw new ParseOptionMissingValueException(state.getCurrentOption().getTitle());
}
if (!state.getUnparsedInput().isEmpty()) {
throw new ParseArgumentsUnexpectedException(state.getUnparsedInput());
}

for (OptionMetadata option : command.getAllOptions()) {
if (option.isRequired() && !state.getParsedOptions().containsKey(option)) {
throw new ParseOptionMissingException(option.getOptions().iterator().next());
if (state.getLocation() == Context.OPTION) {
throw new ParseOptionMissingValueException(state.getCurrentOption().getTitle());
}

for (OptionMetadata option : command.getAllOptions()) {
if (option.isRequired() && !state.getParsedOptions().containsKey(option)) {
throw new ParseOptionMissingException(option.getOptions().iterator().next());
}
}
}catch(ParseException e){
if(command.isShowHelpOnError()){
System.out.println(e.getMessage());
System.out.println("Usage:");
Help.help(command);
}
throw e;
}
}

Expand Down
5 changes: 5 additions & 0 deletions src/main/java/io/airlift/command/Command.java
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,9 @@
* If true, this command won't appear in the usage().
*/
boolean hidden() default false;

/**
* If true, the help will be shown
*/
boolean showHelpOnError() default true;
}
44 changes: 27 additions & 17 deletions src/main/java/io/airlift/command/SingleCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,11 @@ public C parse(String... args)
{
return parse(ImmutableList.copyOf(args));
}

public C parse(Iterable<String> args)
{
checkNotNull(args, "args is null");

Parser parser = new Parser();
ParseState state = parser.parseCommand(commandMetadata, args);
validate(state);
Expand All @@ -74,10 +74,11 @@ public C parse(Iterable<String> args)
command.getMetadataInjections(),
ImmutableMap.<Class<?>, Object>of(CommandMetadata.class, commandMetadata));
}

private void validate(ParseState state)
{
CommandMetadata command = state.getCommand();

if (command == null) {
List<String> unparsedInput = state.getUnparsedInput();
if (unparsedInput.isEmpty()) {
Expand All @@ -88,23 +89,32 @@ private void validate(ParseState state)
}
}

ArgumentsMetadata arguments = command.getArguments();
if (state.getParsedArguments().isEmpty() && arguments != null && arguments.isRequired()) {
throw new ParseArgumentsMissingException(arguments.getTitle());
}

if (!state.getUnparsedInput().isEmpty()) {
throw new ParseArgumentsUnexpectedException(state.getUnparsedInput());
}
try{
ArgumentsMetadata arguments = command.getArguments();
if (state.getParsedArguments().isEmpty() && arguments != null && arguments.isRequired()) {
throw new ParseArgumentsMissingException(arguments.getTitle());
}

if (state.getLocation() == Context.OPTION) {
throw new ParseOptionMissingValueException(state.getCurrentOption().getTitle());
}
if (!state.getUnparsedInput().isEmpty()) {
throw new ParseArgumentsUnexpectedException(state.getUnparsedInput());
}

for (OptionMetadata option : command.getAllOptions()) {
if (option.isRequired() && !state.getParsedOptions().containsKey(option)) {
throw new ParseOptionMissingException(option.getOptions().iterator().next());
if (state.getLocation() == Context.OPTION) {
throw new ParseOptionMissingValueException(state.getCurrentOption().getTitle());
}

for (OptionMetadata option : command.getAllOptions()) {
if (option.isRequired() && !state.getParsedOptions().containsKey(option)) {
throw new ParseOptionMissingException(option.getOptions().iterator().next());
}
}
}catch(ParseException e){
if(command.isShowHelpOnError()){
System.out.println(e.getMessage());
System.out.println("Usage:");
Help.help(command);
}
throw e;
}
}
}
9 changes: 7 additions & 2 deletions src/main/java/io/airlift/command/model/CommandMetadata.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import com.google.common.collect.ImmutableList;
import io.airlift.command.Accessor;

import javax.annotation.Nullable;
import java.util.List;

public class CommandMetadata
Expand All @@ -18,6 +17,7 @@ public class CommandMetadata
private final ArgumentsMetadata arguments;
private final List<Accessor> metadataInjections;
private final Class<?> type;
private final boolean showHelpOnError;

public CommandMetadata(String name,
String description,
Expand All @@ -26,7 +26,7 @@ public CommandMetadata(String name,
Iterable<OptionMetadata> commandOptions,
ArgumentsMetadata arguments,
Iterable<Accessor> metadataInjections,
Class<?> type)
Class<?> type, boolean showHelpOnError)
{
this.name = name;
this.description = description;
Expand All @@ -37,6 +37,7 @@ public CommandMetadata(String name,
this.arguments = arguments;
this.metadataInjections = ImmutableList.copyOf(metadataInjections);
this.type = type;
this.showHelpOnError = showHelpOnError;
}

public String getName()
Expand Down Expand Up @@ -117,4 +118,8 @@ public String apply(CommandMetadata input)
}
};
}

public boolean isShowHelpOnError() {
return showHelpOnError;
}
}
10 changes: 3 additions & 7 deletions src/main/java/io/airlift/command/model/MetadataLoader.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,7 @@
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import com.google.common.collect.ListMultimap;
import io.airlift.command.Accessor;
import io.airlift.command.Arguments;
import io.airlift.command.Command;
import io.airlift.command.Option;
import io.airlift.command.OptionType;
import io.airlift.command.Suggester;
import io.airlift.command.*;

import javax.annotation.Nullable;
import javax.inject.Inject;
Expand Down Expand Up @@ -82,6 +77,7 @@ public static CommandMetadata loadCommand(Class<?> commandType)
String name = command.name();
String description = command.description().isEmpty() ? null : command.description();
boolean hidden = command.hidden();
boolean showHelpOnError = command.showHelpOnError();

InjectionMetadata injectionMetadata = loadInjectionMetadata(commandType);

Expand All @@ -93,7 +89,7 @@ public static CommandMetadata loadCommand(Class<?> commandType)
injectionMetadata.commandOptions,
Iterables.getFirst(injectionMetadata.arguments, null),
injectionMetadata.metadataInjections,
commandType);
commandType, showHelpOnError);

return commandMetadata;

Expand Down
33 changes: 33 additions & 0 deletions src/test/java/io/airlift/command/PingWithRequiredOption.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package io.airlift.command;

import javax.inject.Inject;

@Command(name = "ping", description = "network test utility")
public class PingWithRequiredOption
{
@Inject
public HelpOption helpOption;

@Option(name = {"-c", "--count"}, required=true, description = "Send count packets")
public int count = 1;

public static void main(String... args)
{
try{
PingWithRequiredOption ping = SingleCommand.singleCommand(PingWithRequiredOption.class).parse(args);
if (ping.helpOption.showHelpIfRequested()) {
return;
}

ping.run();
}catch(ParseException e){
System.out.println(e.getMessage());
return;
}
}

public void run()
{
System.out.println("Ping count: " + count);
}
}
21 changes: 21 additions & 0 deletions src/test/java/io/airlift/command/PingWithRequiredOptionTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package io.airlift.command;

import com.google.common.base.Joiner;
import org.testng.annotations.Test;

public class PingWithRequiredOptionTest {

@Test
public void test()
{
// missing parameter => show help
ping();
}

private void ping(String... args)
{
System.out.println("$ ping " + Joiner.on(' ').join(args));
PingWithRequiredOption.main(args);
System.out.println();
}
}

0 comments on commit f9c3e47

Please sign in to comment.