package com.haskforce.run;
import com.haskforce.settings.HaskellBuildSettings;
import com.haskforce.utils.ExecUtil;
import com.haskforce.utils.NotificationUtil;
import com.haskforce.utils.EitherUtil;
import com.intellij.execution.configuration.AbstractRunConfiguration;
import com.intellij.execution.configurations.ConfigurationFactory;
import com.intellij.execution.configurations.GeneralCommandLine;
import com.intellij.execution.configurations.RuntimeConfigurationError;
import com.intellij.execution.configurations.RuntimeConfigurationException;
import com.intellij.notification.NotificationType;
import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NotNull;
import scala.util.Either;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public abstract class HaskellRunConfigurationBase extends AbstractRunConfiguration {
public HaskellRunConfigurationBase(Project project, ConfigurationFactory factory) {
super(project, factory);
}
public static final Pattern EXTRACT_CABAL_VERSION_REGEX = Pattern.compile("(\\d+\\.\\d+).*");
protected void requireCabal1_18() throws RuntimeConfigurationException {
requireCabalVersionMinimum(1.18, "Run configurations require cabal 1.18 or higher.");
}
protected void requireCabalVersionMinimum(double minimumVersion, @NotNull String errorMessage) throws RuntimeConfigurationException {
final HaskellBuildSettings buildSettings = HaskellBuildSettings.getInstance(getProject());
final String cabalPath = buildSettings.getCabalPath();
if (cabalPath.isEmpty()) {
throw new RuntimeConfigurationError("Path to cabal is not set.");
}
GeneralCommandLine cabalCmdLine = new GeneralCommandLine(cabalPath, "--numeric-version");
Either<ExecUtil.ExecError, String> result = ExecUtil.readCommandLine(cabalCmdLine);
if (result.isLeft()) {
//noinspection ThrowableResultOfMethodCallIgnored
ExecUtil.ExecError e = EitherUtil.unsafeGetLeft(result);
NotificationUtil.displaySimpleNotification(
NotificationType.ERROR, getProject(), "cabal", e.getMessage()
);
throw new RuntimeConfigurationError("Failed executing cabal to check its version: " + e.getMessage());
}
final String out = EitherUtil.unsafeGetRight(result);
final Matcher m = EXTRACT_CABAL_VERSION_REGEX.matcher(out);
if (!m.find()) {
throw new RuntimeConfigurationError("Could not parse cabal version: '" + out + "'");
}
final Double actualVersion = Double.parseDouble(m.group(1));
if (actualVersion < minimumVersion) {
throw new RuntimeConfigurationError(errorMessage);
}
}
}