package org.elixir_lang.mix.runner; import com.intellij.execution.CommonProgramRunConfigurationParameters; import com.intellij.execution.ExecutionException; import com.intellij.execution.Executor; import com.intellij.execution.ExternalizablePath; import com.intellij.execution.configuration.EnvironmentVariablesComponent; import com.intellij.execution.configurations.*; import com.intellij.execution.runners.ExecutionEnvironment; import com.intellij.execution.runners.RunConfigurationWithSuppressedDefaultRunAction; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleManager; import com.intellij.openapi.options.SettingsEditor; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.InvalidDataException; import com.intellij.openapi.util.WriteExternalException; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.util.containers.hash.LinkedHashMap; import com.intellij.util.xmlb.SerializationFilter; import com.intellij.util.xmlb.XmlSerializer; import org.elixir_lang.runconfig.ElixirModuleBasedConfiguration; import org.jdom.Attribute; import org.jdom.Element; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.*; /** * https://github.com/ignatov/intellij-erlang/blob/master/src/org/intellij/erlang/rebar/runner/RebarRunConfigurationBase.java */ public abstract class MixRunConfigurationBase extends ModuleBasedConfiguration<ElixirModuleBasedConfiguration> implements CommonProgramRunConfigurationParameters, RunConfigurationWithSuppressedDefaultRunAction, RunConfigurationWithSuppressedDefaultDebugAction { /* * CONSTANTS */ private static final SerializationFilter SERIALIZATION_FILTER = (accessor, bean) -> !accessor.getName().equals("envs"); /* * Fields */ @NotNull private final Map<String, String> envs = new LinkedHashMap<>(); private boolean mySkipDependencies = false; private boolean passParentEnvs = false; @Nullable private String programParameters = null; @Nullable private String workingDirectory; /* * Constructors */ protected MixRunConfigurationBase(@NotNull String name, @NotNull Project project, @NotNull ConfigurationFactory configurationFactory){ super(name, new ElixirModuleBasedConfiguration(project), configurationFactory); } /* * Public Instance Methods */ @Override public void checkConfiguration() throws RuntimeConfigurationException { // todo: parse mix command line to check if it is valid } @NotNull @Override public SettingsEditor<? extends RunConfiguration> getConfigurationEditor() { return new MixRunConfigurationEditorForm(); } @NotNull @Override public Map<String, String> getEnvs() { return envs; } @Nullable @Override public String getProgramParameters() { return programParameters; } /** * getModules changed to getSearchScope in * https://github.com/JetBrains/intellij-community/commit/4daac1c8cdb0cb98bbb26df7d4900c766626a742#diff-5fa0d6d7f6e6058e338ccec4efdb4596, * which affects IntelliJ 2016.* * * @return scope where to search sources for this configuration */ @Nullable public GlobalSearchScope getSearchScope() { return GlobalSearchScope.projectScope(getProject()); } @NotNull public List<String> getMixArgs() { String programParameters = getProgramParameters(); if (programParameters != null) { return Arrays.asList(programParameters.split("\\s+")); } else { return new ArrayList<>(0); } } @NotNull @Override public RunProfileState getState(@NotNull Executor executor, @NotNull ExecutionEnvironment environment) throws ExecutionException { return new MixRunningState(environment, this); } @Override public Collection<Module> getValidModules() { Module[] modules = ModuleManager.getInstance(getProject()).getModules(); return Arrays.asList(modules); } @Nullable @Override public String getWorkingDirectory() { return ExternalizablePath.localPathValue(workingDirectory); } @Override public boolean isPassParentEnvs() { return passParentEnvs; } @Override public void readExternal(Element element) throws InvalidDataException { super.readExternal(element); XmlSerializer.deserializeInto(this, element); EnvironmentVariablesComponent.readExternal(element, getEnvs()); /* * Reading <= 4.6.0 format */ List<Element> options = element.getChildren("option"); for (Element option : options) { Attribute nameAttribute = option.getAttribute("name"); if (nameAttribute.getValue().equals("command")) { Attribute valueAttribute = option.getAttribute("value"); setProgramParameters(valueAttribute.getValue()) ; break; } } } @Override public void setEnvs(@NotNull Map<String, String> envs) { this.envs.clear(); this.envs.putAll(envs); } @Override public void setPassParentEnvs(boolean passParentEnvs) { this.passParentEnvs = passParentEnvs; } @Override public void setProgramParameters(@Nullable String programParameters) { this.programParameters = programParameters; } @Override public void setWorkingDirectory(@Nullable String workingDirectory) { this.workingDirectory = ExternalizablePath.urlValue(workingDirectory); } @Override public void writeExternal(@NotNull Element element) throws WriteExternalException{ super.writeExternal(element); XmlSerializer.serializeInto( this, element, SERIALIZATION_FILTER ); EnvironmentVariablesComponent.writeExternal(element, getEnvs()); } // @NotNull // abstract public GeneralCommandLine commandLine(List<String> elixirParams); /* * Package Instance Methods */ boolean isSkipDependencies(){ return mySkipDependencies; } void setSkipDependencies(boolean skipDeps){ mySkipDependencies = skipDeps; } }