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.command.spi;
012
013import org.eclipse.golo.compiler.GoloCompilationException;
014import gololang.Messages;
015
016import java.lang.invoke.MethodHandle;
017
018import static java.lang.invoke.MethodHandles.publicLookup;
019import static java.lang.invoke.MethodType.methodType;
020
021
022public interface CliCommand {
023
024  class NoMainMethodException extends NoSuchMethodException {
025  }
026
027  void execute() throws Throwable;
028
029  default void callRun(Class<?> klass, String[] arguments) throws Throwable {
030    MethodHandle main;
031    try {
032      main = publicLookup().findStatic(klass, "main", methodType(void.class, String[].class));
033    } catch (NoSuchMethodException e) {
034      throw new NoMainMethodException().initCause(e);
035    }
036    main.invoke(arguments);
037  }
038
039  default void handleCompilationException(GoloCompilationException e) {
040    handleCompilationException(e, true);
041  }
042
043  default void handleCompilationException(GoloCompilationException e, boolean exit) {
044    Messages.error(e.getMessage());
045    for (GoloCompilationException.Problem problem : e.getProblems()) {
046      Messages.error(problem.getDescription(), "  ");
047      Throwable cause = problem.getCause();
048      if (cause != null) {
049        handleThrowable(cause, false, gololang.Runtime.debugMode() || gololang.Runtime.showStackTrace(), "    ");
050      }
051    }
052    if (exit) {
053      System.exit(1);
054    }
055  }
056
057  default void handleThrowable(Throwable e) {
058    handleThrowable(e, true);
059  }
060
061  default void handleThrowable(Throwable e, boolean exit) {
062    handleThrowable(e, exit, gololang.Runtime.debugMode() || gololang.Runtime.showStackTrace());
063  }
064
065  default void handleThrowable(Throwable e, boolean exit, boolean withStack) {
066    handleThrowable(e, exit, withStack, "");
067  }
068
069  default void handleThrowable(Throwable e, boolean exit, boolean withStack, String indent) {
070    Messages.error(e, indent);
071    if (e.getCause() != null) {
072      Messages.error(e.getCause().getMessage(), "  " + indent);
073    }
074    if (withStack) {
075      Messages.printStackTrace(e);
076    } else {
077      Messages.error(Messages.message("use_debug"));
078    }
079    if (exit) {
080      System.exit(1);
081    }
082  }
083}