package org.elixir_lang.mix.runner; import com.intellij.execution.ExecutionException; import com.intellij.execution.configurations.GeneralCommandLine; import com.intellij.execution.configurations.ParametersList; import com.intellij.execution.process.OSProcessHandler; import com.intellij.notification.Notification; import com.intellij.notification.NotificationType; import com.intellij.notification.Notifications; import com.intellij.openapi.module.Module; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.ModuleRootManager; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.ObjectUtils; import org.elixir_lang.jps.model.JpsElixirSdkType; import org.elixir_lang.mix.settings.MixSettings; import org.elixir_lang.sdk.ElixirSdkType; import org.elixir_lang.utils.ElixirExternalToolsNotificationListener; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.List; import static org.apache.commons.lang.StringUtils.isBlank; import static org.apache.commons.lang.StringUtils.stripEnd; /** * Created by zyuyou on 15/7/8. * https://github.com/ignatov/intellij-erlang/blob/master/src/org/intellij/erlang/rebar/runner/RebarRunningStateUtil.java */ public class MixRunningStateUtil { private static final String SKIP_DEPENDENCIES_PARAMETER = "--no-deps-check"; // @NotNull // public static GeneralCommandLine mixCommandLine(@NotNull MixRunConfigurationBase configuration, // @Nullable List<String> elixirParams, // @Nullable List<String> mixParams) { // // GeneralCommandLine commandLine = getBaseMixCommandLine(configuration); // // Project project = configuration.getProject(); // String mixPath = mixPath(project); // // String sdkPath = ElixirSdkType.getSdkPath(project); // String elixirPath = elixirPath(sdkPath); // // commandLine.setExePath(elixirPath); // if (elixirParams != null) commandLine.addParameters(elixirParams); // commandLine.addParameter(mixPath); // addNewSkipDependencies(commandLine, configuration); // if (mixParams != null) commandLine.addParameters(mixParams); // // return commandLine; // } @NotNull private static GeneralCommandLine withEnvironment(@NotNull GeneralCommandLine commandLine, @NotNull MixRunConfigurationBase configuration) { return commandLine.withEnvironment(configuration.getEnvs()); } @NotNull public static GeneralCommandLine withWorkDirectory(@NotNull GeneralCommandLine commandLine, @NotNull MixRunConfigurationBase configuration) { return commandLine.withWorkDirectory(getWorkingDirectory(configuration)); } @NotNull static String mixPath(@NotNull Project project) { MixSettings mixSettings = MixSettings.getInstance(project); return mixSettings.getMixPath(); } @NotNull public static GeneralCommandLine addNewSkipDependencies(@NotNull GeneralCommandLine commandLine, @NotNull MixRunConfigurationBase configuration) { if (configuration.isSkipDependencies()) { ParametersList parametersList = commandLine.getParametersList(); if (!parametersList.hasParameter(SKIP_DEPENDENCIES_PARAMETER)) { parametersList.add(SKIP_DEPENDENCIES_PARAMETER); } } return commandLine; } @NotNull public static GeneralCommandLine addProgramParameters(@NotNull GeneralCommandLine commandLine, @NotNull MixRunConfigurationBase configuration) { String programParameters = configuration.getProgramParameters(); if (programParameters != null) { for (String programParameter : programParameters.split("\\s+")) { commandLine.addParameter(programParameter); } } return commandLine; } @NotNull public static GeneralCommandLine getBaseMixCommandLine(@NotNull MixRunConfigurationBase configuration) { GeneralCommandLine commandLine = withEnvironment(new GeneralCommandLine(), configuration); return withWorkDirectory(commandLine, configuration); } @NotNull public static String elixirPath(String sdkPath) { return sdkPath != null ? JpsElixirSdkType.getScriptInterpreterExecutable(sdkPath).getAbsolutePath() : JpsElixirSdkType.getExecutableFileName(JpsElixirSdkType.SCRIPT_INTERPRETER); } @NotNull public static OSProcessHandler runMix(Project project, GeneralCommandLine commandLine) throws ExecutionException { try{ return new OSProcessHandler(commandLine.createProcess(), commandLine.getCommandLineString()); }catch (ExecutionException e){ String message = e.getMessage(); boolean isEmpty = "Executable is not specified".equals(message); boolean notCorrect = message.startsWith("Cannot run program"); if(isEmpty || notCorrect){ Notifications.Bus.notify( new Notification( "Mix run configuration", // groudDisplayId "Mix settings", // title "Mix executable path is " + (isEmpty ? "empty" : "not specified correctly") + "<br><a href='configure'>Configure</a></br>", // content NotificationType.ERROR, // errorType new ElixirExternalToolsNotificationListener(project) // listener ) ); } throw e; } } @NotNull private static String getWorkingDirectory(@NotNull MixRunConfigurationBase configuration){ String workingDirectory = configuration.getWorkingDirectory(); if (isBlank(workingDirectory)) { Module module = configuration.getConfigurationModule().getModule(); if (module != null) { VirtualFile[] contentRoots = ModuleRootManager.getInstance(module).getContentRoots(); if (contentRoots.length >= 1) { workingDirectory = contentRoots[0].getPath(); } } if (isBlank(workingDirectory)) { workingDirectory = ObjectUtils.assertNotNull(configuration.getProject().getBasePath()); } } return workingDirectory; } public static GeneralCommandLine commandLine(@NotNull MixRunConfigurationBase configuration, @NotNull List<String> elixirParams, @NotNull List<String> mixParams) { GeneralCommandLine commandLine = getBaseMixCommandLine(configuration); Project project = configuration.getProject(); String mixPath = mixPath(project); if (mixPath.endsWith(".bat") && elixirParams.isEmpty()) { commandLine.setExePath(mixPath); } else { mixPath = stripEnd(mixPath, ".bat"); String sdkPath = ElixirSdkType.getSdkPath(project); String elixirPath = elixirPath(sdkPath); commandLine.setExePath(elixirPath); commandLine.addParameters(elixirParams); commandLine.addParameter(mixPath); } commandLine.addParameters(mixParams); return addNewSkipDependencies(commandLine, configuration); } }