.values()); for (final Set<Option> group : menu.groups) { openGroup(); for (final Option option : group) { final OptionParser exec = menu.optionMap.get(option .getShortName()); add(adapt(exec, shortPrefix, longPrefix)); newOptions.remove(exec); closeGroup(); add(adapt(exec, shortPrefix, longPrefix));
final Menu m = Menu .builder() .addHelpOption("h", "help", "Hi") .add(Option.builder("e", ArgumentParser.enumListParser("enum list", TestEnum.class)).build(), consumer, new AddToListHandler<List<TestEnum>>()) .build();
/** * Test for adding an entire sub menu. */ @Test public void testAddSubMenu() { final Menu m = Menu.builder() .addSubMenu("l", "list.", menu) .addHelpOption("d", "delp", "Help") .build(); // help options are not copied assertFalse(m.containsOption("h")); assertFalse(m.containsOption("lh")); assertEquals(m.getOptionNames().size(), menu.getOptionNames().size()); }
.add(Option.builder("a", ArgumentParser.longParser()).build(), list, new ArgHandler<List<Object>, Long>() { .add(Option.builder("aa", ArgumentParser.longListParser()) .longName("add-all") .description("Add all longs, and then some. Please note that " .add(Option.builder("asl", ArgumentParser.stringListParser()).build(), list, new ArgHandler<List<Object>, List<String>>() { .openGroup() .add(Option.builder("x").build(), list, dummyHandler()) .add(Option.builder("y").build(), list, dummyHandler()) .add(Option.builder("z").build(), list, dummyHandler()) .closeGroup() .add(Option.builder("as", ArgumentParser.stringParser()).build(), list, new ArgHandler<List<Object>, String>() { .addHelpOption("h", "help", "Print this message") .add(Option.builder("failure", ArgumentParser .booleanParser()) .build(), .add(Option.builder("happy", ArgumentParser.booleanParser()).build(), list, new ArgHandler<List<Object>, Boolean>() {
.commandLineSyntax("java -jar jarname.jar <options>") .header("RinSim Experiment command line interface.") .footer("For more information see http://github.com/rinde/RinSim") .openGroup() .add(createBatchesOpt(builder), builder, IntHandlers.BATCHES) .add(createThreadsOpt(builder), builder, IntHandlers.THREADS) .openGroup() .add(createIncludeOpt(cfgMap), builder, new IncludeHandler(cfgMap)) .add(createExcludeOpt(cfgMap), builder, new ExcludeHandler(cfgMap)) .openGroup() .add(createLocalOpt(builder), builder, NoArgHandlers.LOCAL) .add(createJppfOpt(builder), builder, NoArgHandlers.DISTRIBUTED) .closeGroup() .add(createDryRunOpt(builder), builder, StringHandler.DRY_RUN) .add(createRepetitionsOpt(builder), builder, IntHandlers.REPS) .add(createSeedRepetitionsOpt(builder), builder, IntHandlers.SEED_REPS) .add(createSeedOption(builder), builder, LongHandlers.SEED) .add(createGuiOpt(builder), builder, BooleanHandler.GUI) .add(createOrderingOption(builder), builder, OrderingHandler.INSTANCE) .add(createWarmupOption(builder), builder, LongHandlers.WARMUP) .add(createCompositeSizeOpt(builder), builder, IntHandlers.COMPOSITE_SIZE) .addHelpOption("h", "help", "Print this message."); menuBuilder.addSubMenu(S, "scenarios.", FileProviderCli .createDefaultMenu(builder.scenarioProviderBuilder
.commandLineSyntax("java -jar jarname.jar <options>") .header("RinSim Experiment command line interface.") .footer("For more information see http://github.com/rinde/RinSim") .openGroup() .add(createBatchesOpt(builder), builder, IntHandlers.BATCHES) .add(createThreadsOpt(builder), builder, IntHandlers.THREADS) .openGroup() .add(createIncludeOpt(cfgMap), builder, new IncludeHandler(cfgMap)) .add(createExcludeOpt(cfgMap), builder, new ExcludeHandler(cfgMap)) .openGroup() .add(createLocalOpt(builder), builder, NoArgHandlers.LOCAL) .add(createJppfOpt(builder), builder, NoArgHandlers.DISTRIBUTED) .closeGroup() .add(createDryRunOpt(builder), builder, StringHandler.DRY_RUN) .add(createRepetitionsOpt(builder), builder, IntHandlers.REPS) .add(createSeedRepetitionsOpt(builder), builder, IntHandlers.SEED_REPS) .add(createSeedOption(builder), builder, LongHandlers.SEED) .add(createGuiOpt(builder), builder, BooleanHandler.GUI) .add(createOrderingOption(builder), builder, OrderingHandler.INSTANCE) .add(createWarmupOption(builder), builder, LongHandlers.WARMUP) .add(createCompositeSizeOpt(builder), builder, IntHandlers.COMPOSITE_SIZE) .addHelpOption("h", "help", "Print this message."); menuBuilder.addSubMenu(S, "scenarios.", FileProviderCli .createDefaultMenu(builder.scenarioProviderBuilder
final List<String> consumer = new ArrayList<>(); final Menu m = Menu.builder() .addHelpOption("h", "help", "Hi") .add(Option.builder("i", ArgumentParser.prefixedIntList("t")).build(), consumer, new ArgHandler<List<String>, List<String>>() { .build();
/** * Tests correct parsing of enum. */ @Test public void testEnum() { final List<TestEnum> consumer = new ArrayList<>(); final Menu m = Menu.builder() .addHelpOption("h", "help", "Hi") .add(Option.builder("e", ArgumentParser.enumParser("testenum", TestEnum.class)).build(), consumer, new AddToListHandler<TestEnum>()) .build(); m.execute("-e", "A"); assertThat(consumer) .containsExactly(TestEnum.A); consumer.clear(); m.execute("-e", "B"); assertThat(consumer) .containsExactly(TestEnum.B); consumer.clear(); testFail(m, "e", CauseType.INVALID_ARG_FORMAT, "-e", "a"); testFail(m, "e", CauseType.INVALID_ARG_FORMAT, "-e", "NON_EXISTING_ENUM"); assertThat(consumer).isEmpty(); }
/** * Creates the default {@link com.github.rinde.rinsim.cli.Menu.Builder} for * creating the {@link Menu} instances. * @param builder The {@link FileProvider.Builder} that should be controlled * via CLI. * @return The new menu builder. */ public static Menu createDefaultMenu( FileProvider.Builder builder) { final Map<String, Path> pathMap = createPathMap(builder); final Menu.Builder cliBuilder = Menu.builder() .addHelpOption("h", "help", "Print this message") .add(createAddOption(), builder, ADD) .add(createFilterOption(builder), builder, FILTER); if (!pathMap.isEmpty()) { cliBuilder .openGroup() .add(createIncludeOption(pathMap, builder), builder, new IncludeHandler(pathMap)) .add(createExcludeOption(pathMap, builder), builder, new ExcludeHandler(pathMap)) .closeGroup(); } return cliBuilder.build(); }
/** * Creates the default {@link com.github.rinde.rinsim.cli.Menu.Builder} for * creating the {@link Menu} instances. * @param builder The {@link FileProvider.Builder} that should be controlled * via CLI. * @return The new menu builder. */ public static Menu createDefaultMenu( FileProvider.Builder builder) { final Map<String, Path> pathMap = createPathMap(builder); final Menu.Builder cliBuilder = Menu.builder() .addHelpOption("h", "help", "Print this message") .add(createAddOption(), builder, ADD) .add(createFilterOption(builder), builder, FILTER); if (!pathMap.isEmpty()) { cliBuilder .openGroup() .add(createIncludeOption(pathMap, builder), builder, new IncludeHandler(pathMap)) .add(createExcludeOption(pathMap, builder), builder, new ExcludeHandler(pathMap)) .closeGroup(); } return cliBuilder.build(); }
/** * Constructs a menu wilt multiple groups and tests the behavior. */ @Test public void multipleGroups() { final Menu m = Menu.builder() .openGroup() .add(Option.builder("a").build(), list, dummyHandler()) .add(Option.builder("b").build(), list, dummyHandler()) .openGroup() .add(Option.builder("c").build(), list, dummyHandler()) .add(Option.builder("d").build(), list, dummyHandler()) .add(Option.builder("e").build(), list, dummyHandler()) .closeGroup() .addHelpOption("h", "help", "Print me") .build(); assertFalse(m.execute("-a", "-c").isPresent()); assertFalse(m.execute("-b", "-d").isPresent()); testFail(m, "a", CauseType.ALREADY_SELECTED, "-b", "-a"); testFail(m, "b", CauseType.ALREADY_SELECTED, "-d", "-a", "-b"); testFail(m, "c", CauseType.ALREADY_SELECTED, "-d", "-a", "-c"); }
/** * Test for checking whether duplicate options are detected. */ @Test(expected = IllegalArgumentException.class) public void duplicateOptions() { final Object subject = new Object(); Menu .builder() .add(Option.builder("a").build(), subject, dummyHandler()) .add(Option.builder("aa", ArgumentParser.stringParser()) .longName("a") .build(), subject, CliTest.<Object, String>dummyArgHandler()); }
/** * Add a help option. A help option is a special option that will trigger * the display of the help menu. A help option may not be added to a group. * @param sn The short name of the help option. * @param ln The long name of the help option. * @param desc The description of the help option. * @return This, as per the builder pattern. */ public Builder addHelpOption(String sn, String ln, String desc) { checkState(!buildingGroup, "A help option can not be added to a group."); final OptionNoArg option = Option.builder(sn) .longName(ln) .description(desc) .buildHelpOption(); add(new HelpParser(option)); addedHelpOption = true; return this; }
/** * Test for setting a custom help formatter. */ @Test public void testCustomHelpFormatter() { final HelpFormatter defaultFormatter = DefaultHelpFormatter.INSTANCE; final HelpFormatter customFormatter = new DummyHelpFormatter(); final Menu m = Menu.builder() .addHelpOption("h", "help", "help") .commandLineSyntax("") .helpFormatter(customFormatter) .build(); assertEquals(" -h,--help help\n", defaultFormatter.format(m)); assertEquals("[h, help]", customFormatter.format(m)); assertNotEquals(defaultFormatter.format(m), m.printHelp()); assertEquals(customFormatter.format(m), m.printHelp()); }
/** * Add an command-line option that expects an argument. * @param option The option instance. * @param subject The subject which will be passed to the handler. * @param handler The handler which will be called when this option is * activated in the menu. The handler will receive all parsed * arguments belonging to this option. * @param <V> The type of argument. * @param <S> The type of the subject. * @return This, as per the builder pattern. */ public <V, S> Builder add(OptionArg<V> option, S subject, ArgHandler<S, V> handler) { add(new ArgParser<>(option, subject, handler)); return this; }
/** * Add an command-line option that does not expect an argument. * @param option The option instance. * @param subject The subject which will be passed to the handler. * @param handler The handler which will be called when this option is * activated in the menu. * @param <S> The type of the subject. * @return This, as per the builder pattern. */ public <S> Builder add(OptionNoArg option, S subject, NoArgHandler<S> handler) { add(new NoArgParser<>(option, subject, handler)); return this; }
/** * Empty short name is not allowed. */ @Test(expected = IllegalArgumentException.class) public void testAddSubMenuInvalidShortName() { Menu.builder().addSubMenu("", "long", menu); }
/** * Closing an empty group is not allowed. */ @Test(expected = IllegalArgumentException.class) public void failGroup1() { Menu.builder().openGroup().closeGroup(); }
/** * Creates a {@link Menu} for a {@link Experiment.Builder} instance. * @param builder The instance to create a {@link Menu} for. * @return A newly constructed {@link Menu}. */ public static Menu createMenu(Experiment.Builder builder) { return createMenuBuilder(builder).build(); }