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