001/*
002 * Copyright (c) 2012-2017 Institut National des Sciences Appliquées de Lyon (INSA-Lyon)
003 *
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the Eclipse Public License v1.0
006 * which accompanies this distribution, and is available at
007 * http://www.eclipse.org/legal/epl-v10.html
008 */
009
010package org.eclipse.golo.cli;
011
012import com.beust.jcommander.*;
013
014import org.eclipse.golo.cli.command.spi.CliCommand;
015
016import java.io.*;
017import java.util.*;
018
019import static gololang.Messages.message;
020
021public final class Main {
022
023  private Main() {
024    // utility class
025  }
026
027  @Parameters(resourceBundle = "commands")
028  static class GlobalArguments {
029    @Parameter(names = {"--help"}, descriptionKey = "help", help = true)
030    boolean help;
031
032    @Parameter(names = {"--usage"}, descriptionKey = "usage", validateWith = UsageFormatValidator.class)
033    String usageCommand;
034  }
035
036  public static class UsageFormatValidator implements IParameterValidator {
037    static Set<String> commandNames;
038
039    @Override
040    public void validate(String name, String value) throws ParameterException {
041      if (!commandNames.contains(value)) {
042        throw new ParameterException(message("command_error", commandNames));
043      }
044    }
045  }
046
047  public static void main(String... args) throws Throwable {
048    GlobalArguments global = new GlobalArguments();
049    JCommander cmd = new JCommander(global);
050    cmd.setProgramName("golo");
051
052    ServiceLoader<CliCommand> commands = ServiceLoader.load(CliCommand.class);
053    for (CliCommand command : commands) {
054      cmd.addCommand(command);
055    }
056    UsageFormatValidator.commandNames = cmd.getCommands().keySet();
057
058    try {
059      cmd.parse(args);
060      if (global.usageCommand != null) {
061        cmd.usage(global.usageCommand);
062      } else if (global.help || cmd.getParsedCommand() == null) {
063        cmd.usage();
064      } else {
065        String parsedCommand = cmd.getParsedCommand();
066        JCommander parsedJCommander = cmd.getCommands().get(parsedCommand);
067        Object commandObject = parsedJCommander.getObjects().get(0);
068        if (commandObject instanceof CliCommand) {
069          ((CliCommand) commandObject).execute();
070        } else {
071          throw new AssertionError("WTF?");
072        }
073      }
074    } catch (ParameterException exception) {
075      System.err.println(exception.getMessage());
076      System.out.println();
077      if (cmd.getParsedCommand() != null) {
078        cmd.usage(cmd.getParsedCommand());
079      }
080    }
081  }
082}