diff --git a/jps-plugin/src/org/intellij/erlang/jps/model/ErlangCompilerOptions.java b/jps-plugin/src/org/intellij/erlang/jps/model/ErlangCompilerOptions.java index 37e355066..da86a0675 100644 --- a/jps-plugin/src/org/intellij/erlang/jps/model/ErlangCompilerOptions.java +++ b/jps-plugin/src/org/intellij/erlang/jps/model/ErlangCompilerOptions.java @@ -29,6 +29,7 @@ public ErlangCompilerOptions() { public ErlangCompilerOptions(ErlangCompilerOptions options) { myUseRebarCompiler = options.myUseRebarCompiler; myAddDebugInfoEnabled = options.myAddDebugInfoEnabled; + myCustomRebarConfig = options.myCustomRebarConfig; } @Tag("useRebarCompiler") @@ -37,6 +38,12 @@ public ErlangCompilerOptions(ErlangCompilerOptions options) { @Tag("useDebugInfo") public boolean myAddDebugInfoEnabled = true; + @Tag("customRebarConfig") + public String myCustomRebarConfig = ""; + + @Tag("customEunitRebarConfig") + public String myCustomEunitRebarConfig = ""; + @Tag("additionalErlcArguments") @AbstractCollection(elementTag = "arg", elementTypes = String.class) public List myAdditionalErlcArguments = ContainerUtil.newArrayList(); diff --git a/jps-plugin/src/org/intellij/erlang/jps/rebar/RebarBuilder.java b/jps-plugin/src/org/intellij/erlang/jps/rebar/RebarBuilder.java index ca4745218..5ec4eb17d 100644 --- a/jps-plugin/src/org/intellij/erlang/jps/rebar/RebarBuilder.java +++ b/jps-plugin/src/org/intellij/erlang/jps/rebar/RebarBuilder.java @@ -40,13 +40,18 @@ import java.io.File; import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URI; +import java.net.URISyntaxException; import java.net.URL; import java.nio.charset.Charset; +import java.nio.file.Paths; import java.util.Collections; public class RebarBuilder extends TargetBuilder { private static final String NAME = "rebar"; private static final String REBAR_CONFIG_FILE_NAME = "rebar.config"; + private static final String REBAR_CONFIG_SCRIPT_SUFFIX = ".script"; public RebarBuilder() { super(Collections.singleton(ErlangTargetType.INSTANCE)); @@ -57,7 +62,7 @@ public void build(@NotNull ErlangTarget target, @NotNull DirtyFilesHolder holder, @NotNull BuildOutputConsumer outputConsumer, @NotNull CompileContext context) throws ProjectBuildException, IOException { - if (!holder.hasDirtyFiles() && !holder.hasRemovedFiles()) return; + // Do not check for dirty files, delegate it to rebar JpsModule module = target.getModule(); JpsProject project = module.getProject(); @@ -73,13 +78,17 @@ public void build(@NotNull ErlangTarget target, JpsSdk sdk = ErlangTargetBuilderUtil.getSdk(context, module); String escriptPath = JpsErlangSdkType.getScriptInterpreterExecutable(sdk.getHomePath()).getAbsolutePath(); + String customRebarConfig = StringUtil.isEmptyOrSpaces(compilerOptions.myCustomRebarConfig) ? null : compilerOptions.myCustomRebarConfig; + String customEunitRebarConfig = StringUtil.isEmptyOrSpaces(compilerOptions.myCustomEunitRebarConfig) ? customRebarConfig : compilerOptions.myCustomEunitRebarConfig; + boolean isForcedBuild = context.getScope().isBuildForced(target); boolean isRebarRun = false; for (String contentRootUrl : module.getContentRootsList().getUrls()) { - String contentRootPath = new URL(contentRootUrl).getPath(); - File contentRootDir = new File(contentRootPath); - File rebarConfigFile = new File(contentRootDir, REBAR_CONFIG_FILE_NAME); - if (!rebarConfigFile.exists()) continue; - runRebar(escriptPath, rebarPath, contentRootPath, compilerOptions.myAddDebugInfoEnabled, context); + String contentRootPath = getPathFromURL(contentRootUrl); + if (customRebarConfig == null) { + if (!isRebarConfigExists(contentRootPath, REBAR_CONFIG_FILE_NAME)) continue; + } + runRebar(escriptPath, rebarPath, contentRootPath, customRebarConfig, false, compilerOptions.myAddDebugInfoEnabled, isForcedBuild, context); + runRebar(escriptPath, rebarPath, contentRootPath, customEunitRebarConfig, true, true, isForcedBuild, context); isRebarRun = true; } if (!isRebarRun) { @@ -97,13 +106,35 @@ public String getPresentableName() { private static void runRebar(@NotNull String escriptPath, @NotNull String rebarPath, @Nullable String contentRootPath, + @Nullable String customRebarConfig, + boolean isTest, boolean addDebugInfo, + boolean isForcedBuild, @NotNull CompileContext context) throws ProjectBuildException { GeneralCommandLine commandLine = new GeneralCommandLine(); commandLine.withWorkDirectory(contentRootPath); commandLine.setExePath(escriptPath); commandLine.addParameter(rebarPath); - commandLine.addParameter("compile"); + + if (isForcedBuild) { + commandLine.addParameter("clean"); + } + + if (isTest) { + commandLine.addParameter("eunit"); + commandLine.addParameter("compile_only=true"); + } else { + commandLine.addParameter("compile"); + } + + if (customRebarConfig != null) { + if (!isRebarConfigExists(contentRootPath, customRebarConfig)) { + throw new ProjectBuildException("Custom rebar config file is not found: '" + customRebarConfig + "'"); + } + + commandLine.addParameter("-C"); + commandLine.addParameter(customRebarConfig); + } if (addDebugInfo) { commandLine.getEnvironment().put("ERL_FLAGS", "+debug_info"); @@ -126,6 +157,38 @@ private static void runRebar(@NotNull String escriptPath, } } + private static boolean isRebarConfigExists(@Nullable String contentRootDir, String rebarConfigPath) { + return isFileExists(contentRootDir, rebarConfigPath) || + isFileExists(contentRootDir, rebarConfigPath + REBAR_CONFIG_SCRIPT_SUFFIX); + } + + private static boolean isFileExists(@Nullable String baseDir, String filePath) { + File file = new File(filePath); + File absoluteFile; + if (baseDir == null || file.isAbsolute()) { + absoluteFile = file; + } else { + absoluteFile = new File(baseDir, filePath); + } + + return absoluteFile.exists(); + } + + @Nullable + private static String getPathFromURL(String url) { + try { + URI uri = new URL(url).toURI(); + String authority = uri.getAuthority(); + if (!authority.isEmpty()) { + // Workaround for Windows UNC urls like file://C:/... + uri = new URI("file:///" + authority + uri.getPath()); + } + return Paths.get(uri).toString(); + } catch (URISyntaxException | MalformedURLException ignored) { + return null; + } + } + @Nullable private static String getRebarExecutablePath(@Nullable JpsProject project) { JpsRebarConfigurationExtension rebarConfigurationExtension = JpsRebarConfigurationExtension.getExtension(project); diff --git a/src/org/intellij/erlang/application/ErlangApplicationConfiguration.java b/src/org/intellij/erlang/application/ErlangApplicationConfiguration.java index 3a0aab639..4da5019a1 100644 --- a/src/org/intellij/erlang/application/ErlangApplicationConfiguration.java +++ b/src/org/intellij/erlang/application/ErlangApplicationConfiguration.java @@ -64,6 +64,11 @@ public boolean isUseTestCodePath() { return myUseTestCodePath; } + @Override + public boolean isUseRebarPaths() { + return false; + } + public void setUseTestCodePath(boolean useTestCodePath) { myUseTestCodePath = useTestCodePath; } diff --git a/src/org/intellij/erlang/application/ErlangApplicationRunningState.java b/src/org/intellij/erlang/application/ErlangApplicationRunningState.java index b620216b0..1f52e7350 100644 --- a/src/org/intellij/erlang/application/ErlangApplicationRunningState.java +++ b/src/org/intellij/erlang/application/ErlangApplicationRunningState.java @@ -43,6 +43,11 @@ protected boolean useTestCodePath() { return myConfiguration.isUseTestCodePath(); } + @Override + protected boolean useRebarOutputPaths() { + return false; + } + @Override protected boolean isNoShellMode() { return true; diff --git a/src/org/intellij/erlang/configuration/ErlangCompilerOptionsConfigurable.form b/src/org/intellij/erlang/configuration/ErlangCompilerOptionsConfigurable.form index de8eadfb5..99b37665d 100644 --- a/src/org/intellij/erlang/configuration/ErlangCompilerOptionsConfigurable.form +++ b/src/org/intellij/erlang/configuration/ErlangCompilerOptionsConfigurable.form @@ -1,6 +1,6 @@
- + @@ -23,7 +23,7 @@ - + @@ -57,6 +57,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/org/intellij/erlang/configuration/ErlangCompilerOptionsConfigurable.java b/src/org/intellij/erlang/configuration/ErlangCompilerOptionsConfigurable.java index cc37065e9..1794ccf8e 100644 --- a/src/org/intellij/erlang/configuration/ErlangCompilerOptionsConfigurable.java +++ b/src/org/intellij/erlang/configuration/ErlangCompilerOptionsConfigurable.java @@ -44,7 +44,11 @@ public class ErlangCompilerOptionsConfigurable extends CompilerConfigurable { private JCheckBox myAddDebugInfoCheckBox; private RawCommandLineEditor myAdditionalErlcArgumentsEditor; private JLabel myAdditionalErlcArgumentsLabel; - private final ErlangCompilerSettings mySettings; + private JLabel myCustomRebarConfigLabel; + private RawCommandLineEditor myCustomRebarConfigEditor; + private RawCommandLineEditor myCustomEunitRebarConfigEditor; + private JLabel myCustomEunitRebarConfigLabel; + private final ErlangCompilerSettings mySettings; private final Project myProject; public ErlangCompilerOptionsConfigurable(Project project) { @@ -95,6 +99,8 @@ public void reset() { myConfigureRebarButton.setVisible(!rebarPathIsSet); setUseRebarCompiler(rebarPathIsSet && mySettings.isUseRebarCompilerEnabled()); myAddDebugInfoCheckBox.setSelected(mySettings.isAddDebugInfoEnabled()); + myCustomRebarConfigEditor.setText(mySettings.getCustomRebarConfig()); + myCustomEunitRebarConfigEditor.setText(mySettings.getCustomEunitRebarConfig()); myAdditionalErlcArgumentsEditor.setText(argumentsString(mySettings.getAdditionalErlcArguments())); } @@ -102,6 +108,8 @@ public void reset() { public void apply() throws ConfigurationException { mySettings.setUseRebarCompilerEnabled(myUseRebarCompilerCheckBox.isSelected()); mySettings.setAddDebugInfoEnabled(myAddDebugInfoCheckBox.isSelected()); + mySettings.setCustomRebarConfig(myCustomRebarConfigEditor.getText()); + mySettings.setCustomEunitRebarConfig(myCustomEunitRebarConfigEditor.getText()); mySettings.setAdditionalErlcArguments(arguments(myAdditionalErlcArgumentsEditor.getText())); } @@ -109,6 +117,8 @@ public void apply() throws ConfigurationException { public boolean isModified() { return myUseRebarCompilerCheckBox.isSelected() != mySettings.isUseRebarCompilerEnabled() || myAddDebugInfoCheckBox.isSelected() != mySettings.isAddDebugInfoEnabled() || + !StringUtil.equals(myCustomRebarConfigEditor.getText(), mySettings.getCustomRebarConfig()) || + !StringUtil.equals(myCustomEunitRebarConfigEditor.getText(), mySettings.getCustomEunitRebarConfig()) || !StringUtil.equals(myAdditionalErlcArgumentsEditor.getText(), argumentsString(mySettings.getAdditionalErlcArguments())); } @@ -116,6 +126,10 @@ public boolean isModified() { private void setUseRebarCompiler(boolean useRebarCompiler) { myUseRebarCompilerCheckBox.setSelected(useRebarCompiler); + myCustomRebarConfigLabel.setVisible(useRebarCompiler); + myCustomRebarConfigEditor.setVisible(useRebarCompiler); + myCustomEunitRebarConfigLabel.setVisible(useRebarCompiler); + myCustomEunitRebarConfigEditor.setVisible(useRebarCompiler); myAdditionalErlcArgumentsLabel.setVisible(!useRebarCompiler); myAdditionalErlcArgumentsEditor.setVisible(!useRebarCompiler); } diff --git a/src/org/intellij/erlang/configuration/ErlangCompilerSettings.java b/src/org/intellij/erlang/configuration/ErlangCompilerSettings.java index 4b07681d8..e640bc9e9 100644 --- a/src/org/intellij/erlang/configuration/ErlangCompilerSettings.java +++ b/src/org/intellij/erlang/configuration/ErlangCompilerSettings.java @@ -55,6 +55,24 @@ public void setUseRebarCompilerEnabled(boolean useRebarCompiler) { myCompilerOptions.myUseRebarCompiler = useRebarCompiler; } + @NotNull + public String getCustomRebarConfig() { + return myCompilerOptions.myCustomRebarConfig; + } + + public void setCustomRebarConfig(@NotNull String customRebarConfig) { + myCompilerOptions.myCustomRebarConfig = customRebarConfig; + } + + @NotNull + public String getCustomEunitRebarConfig() { + return myCompilerOptions.myCustomEunitRebarConfig; + } + + public void setCustomEunitRebarConfig(@NotNull String customEunitRebarConfig) { + myCompilerOptions.myCustomEunitRebarConfig = customEunitRebarConfig; + } + public boolean isAddDebugInfoEnabled() { return myCompilerOptions.myAddDebugInfoEnabled; } diff --git a/src/org/intellij/erlang/console/ErlangConsoleCommandLineState.java b/src/org/intellij/erlang/console/ErlangConsoleCommandLineState.java index f3678cd3f..a7cb5ac92 100644 --- a/src/org/intellij/erlang/console/ErlangConsoleCommandLineState.java +++ b/src/org/intellij/erlang/console/ErlangConsoleCommandLineState.java @@ -58,7 +58,7 @@ protected ProcessHandler startProcess() throws ExecutionException { commandLine.setExePath(ErlangConsoleUtil.getErlPath(project, module)); String consoleArgs = myConfig.getConsoleArgs(); commandLine.addParameters(StringUtil.split(consoleArgs, " ")); - commandLine.addParameters(ErlangConsoleUtil.getCodePath(project, module, false)); + commandLine.addParameters(ErlangConsoleUtil.getCodePath(project, module, false, false)); commandLine.setWorkDirectory(ErlangConsoleUtil.getWorkingDirPath(project, myConfig.getWorkingDirPath())); OSProcessHandler handler = new OSProcessHandler(commandLine.createProcess(), commandLine.getCommandLineString()); ProcessTerminatedListener.attach(handler); diff --git a/src/org/intellij/erlang/console/ErlangConsoleUtil.java b/src/org/intellij/erlang/console/ErlangConsoleUtil.java index 8d2cf8eca..eb39a9f25 100644 --- a/src/org/intellij/erlang/console/ErlangConsoleUtil.java +++ b/src/org/intellij/erlang/console/ErlangConsoleUtil.java @@ -47,12 +47,13 @@ public static void attachFilters(@NotNull Project project, @NotNull ConsoleView } @NotNull - public static List getCodePath(@NotNull Module module, boolean forTests) { - return getCodePath(module.getProject(), module, forTests); + public static List getCodePath(@NotNull Module module, boolean forTests, boolean useRebarPaths) { + return getCodePath(module.getProject(), module, forTests, useRebarPaths); } @NotNull - public static List getCodePath(@NotNull Project project, @Nullable Module module, boolean useTestOutputPath) { + public static List getCodePath(@NotNull Project project, @Nullable Module module, boolean useTestOutputPath, + boolean useRebarPaths) { final Set codePathModules = new HashSet<>(); if (module != null) { ModuleRootManager moduleRootMgr = ModuleRootManager.getInstance(module); @@ -66,20 +67,35 @@ public static List getCodePath(@NotNull Project project, @Nullable Modul } List codePath = new ArrayList<>(codePathModules.size() * 2); - for (Module codePathModule : codePathModules) { - ModuleRootManager moduleRootManager = ModuleRootManager.getInstance(codePathModule); - CompilerModuleExtension compilerModuleExt = - moduleRootManager.getModuleExtension(CompilerModuleExtension.class); - VirtualFile buildOutput = useTestOutputPath && codePathModule == module ? - getCompilerOutputPathForTests(compilerModuleExt) : - compilerModuleExt.getCompilerOutputPath(); - if (buildOutput != null) { + + if (module != null) { + for (VirtualFile contentRoot : ModuleRootManager.getInstance(module).getContentRoots()) { codePath.add("-pa"); - codePath.add(buildOutput.getCanonicalPath()); + codePath.add(new File(contentRoot.getPath(), ".eunit").toString()); } - for (VirtualFile contentRoot : ModuleRootManager.getInstance(codePathModule).getContentRoots()) { - codePath.add("-pa"); - codePath.add(contentRoot.getPath()); + } + + for (Module codePathModule : codePathModules) { + if (useRebarPaths) { + for (VirtualFile contentRoot : ModuleRootManager.getInstance(codePathModule).getContentRoots()) { + codePath.add("-pa"); + codePath.add(new File(contentRoot.getPath(), "ebin").toString()); + } + } else { + ModuleRootManager moduleRootManager = ModuleRootManager.getInstance(codePathModule); + CompilerModuleExtension compilerModuleExt = + moduleRootManager.getModuleExtension(CompilerModuleExtension.class); + VirtualFile buildOutput = useTestOutputPath && codePathModule == module ? + getCompilerOutputPathForTests(compilerModuleExt) : + compilerModuleExt.getCompilerOutputPath(); + if (buildOutput != null) { + codePath.add("-pa"); + codePath.add(buildOutput.getCanonicalPath()); + } + for (VirtualFile contentRoot : ModuleRootManager.getInstance(codePathModule).getContentRoots()) { + codePath.add("-pa"); + codePath.add(contentRoot.getPath()); + } } } diff --git a/src/org/intellij/erlang/debugger/remote/ErlangRemoteDebugRunConfiguration.java b/src/org/intellij/erlang/debugger/remote/ErlangRemoteDebugRunConfiguration.java index eba17540f..3286235c2 100644 --- a/src/org/intellij/erlang/debugger/remote/ErlangRemoteDebugRunConfiguration.java +++ b/src/org/intellij/erlang/debugger/remote/ErlangRemoteDebugRunConfiguration.java @@ -43,6 +43,11 @@ public boolean isUseTestCodePath() { return false; } + @Override + public boolean isUseRebarPaths() { + return false; + } + @Override protected ErlangRemoteDebugRunningState newRunningState(ExecutionEnvironment env, Module module) { return new ErlangRemoteDebugRunningState(env, module, this); diff --git a/src/org/intellij/erlang/debugger/remote/ErlangRemoteDebugRunningState.java b/src/org/intellij/erlang/debugger/remote/ErlangRemoteDebugRunningState.java index 24aab72c6..aa3759eed 100644 --- a/src/org/intellij/erlang/debugger/remote/ErlangRemoteDebugRunningState.java +++ b/src/org/intellij/erlang/debugger/remote/ErlangRemoteDebugRunningState.java @@ -47,6 +47,11 @@ protected boolean useTestCodePath() { return false; } + @Override + protected boolean useRebarOutputPaths() { + return false; + } + @Override protected boolean isNoShellMode() { return true; diff --git a/src/org/intellij/erlang/debugger/xdebug/ErlangXDebugProcess.java b/src/org/intellij/erlang/debugger/xdebug/ErlangXDebugProcess.java index d274144e7..c3402a698 100644 --- a/src/org/intellij/erlang/debugger/xdebug/ErlangXDebugProcess.java +++ b/src/org/intellij/erlang/debugger/xdebug/ErlangXDebugProcess.java @@ -29,6 +29,7 @@ import com.intellij.openapi.fileEditor.FileDocumentManager; import com.intellij.openapi.fileTypes.FileType; import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.MessageType; import com.intellij.openapi.util.io.FileUtil; @@ -63,10 +64,7 @@ import java.io.*; import java.net.URL; -import java.util.Collection; -import java.util.HashSet; -import java.util.List; -import java.util.Set; +import java.util.*; import java.util.concurrent.ConcurrentHashMap; import static org.intellij.erlang.debugger.ErlangDebuggerLog.LOG; @@ -182,15 +180,52 @@ private XLineBreakpoint getLineBreakpoint(@Nulla private void setModulesToInterpret() { Project project = myExecutionEnvironment.getProject(); - Collection erlangModules = ErlangModulesUtil.getErlangModules(project); ErlangRunConfigurationBase runConfiguration = getRunConfiguration(); + + Collection erlangModules; + switch (runConfiguration.getDebugOptions().getInterpretModulesLevel()) { + case PROJECT: + erlangModules = ErlangModulesUtil.getErlangModules(project); + break; + case DEPENDENCIES: + erlangModules = new ArrayList<>(); + Module currentModule = runConfiguration.getConfigurationModule().getModule(); + if (currentModule != null) { + erlangModules.addAll(ErlangModulesUtil.getErlangModules(currentModule, false)); + ModuleManager moduleManager = ModuleManager.getInstance(project); + for (Module module : moduleManager.getModules()) { + if (moduleManager.isModuleDependent(currentModule, module)) { + erlangModules.addAll(ErlangModulesUtil.getErlangModules(module, false)); + } + } + } + break; + case MODULE: + Module module = runConfiguration.getConfigurationModule().getModule(); + if (module != null) { + erlangModules = ErlangModulesUtil.getErlangModules(module, false); + } else { + erlangModules = new ArrayList<>(); + } + break; + default: + erlangModules = new ArrayList<>(); + } + if (runConfiguration.isUseTestCodePath()) { - HashSet erlangTestModules = new HashSet<>(); - for (Module module : runConfiguration.getModules()) { - erlangTestModules.addAll(ErlangModulesUtil.getErlangModules(module, true)); + if (runConfiguration.isUseRebarPaths()) { + Module module = runConfiguration.getConfigurationModule().getModule(); + if (module != null) { + erlangModules.addAll(ErlangModulesUtil.getErlangModules(module, true)); + } + } else { + HashSet erlangTestModules = new HashSet<>(); + for (Module module : runConfiguration.getModules()) { + erlangTestModules.addAll(ErlangModulesUtil.getErlangModules(module, true)); + } + erlangTestModules.addAll(erlangModules); + erlangModules = erlangTestModules; } - erlangTestModules.addAll(erlangModules); - erlangModules = erlangTestModules; } Set notToInterpret = runConfiguration.getDebugOptions().getModulesNotToInterpret(); List moduleSourcePaths = ContainerUtil.newArrayListWithCapacity(erlangModules.size()); diff --git a/src/org/intellij/erlang/eunit/ErlangUnitRunConfiguration.java b/src/org/intellij/erlang/eunit/ErlangUnitRunConfiguration.java index 79e004eee..e453c5934 100644 --- a/src/org/intellij/erlang/eunit/ErlangUnitRunConfiguration.java +++ b/src/org/intellij/erlang/eunit/ErlangUnitRunConfiguration.java @@ -57,6 +57,11 @@ public boolean isUseTestCodePath() { return true; } + @Override + public boolean isUseRebarPaths() { + return myConfigData.isUseRebarPaths(); + } + @NotNull public ErlangUnitConfigData getConfigData() { return myConfigData; @@ -88,6 +93,8 @@ public static final class ErlangUnitConfigData { @NotNull private Set myFunctionNames = new LinkedHashSet<>(); + private boolean myUseRebarPaths; + @NotNull public ErlangUnitRunConfigurationKind getKind() { return myKind; @@ -114,5 +121,13 @@ public Set getFunctionNames() { public void setFunctionNames(@NotNull Set functionNames) { myFunctionNames = functionNames; } + + public boolean isUseRebarPaths() { + return myUseRebarPaths; + } + + public void setUseRebarPaths(boolean useRebarPaths) { + myUseRebarPaths = useRebarPaths; + } } } diff --git a/src/org/intellij/erlang/eunit/ErlangUnitRunningState.java b/src/org/intellij/erlang/eunit/ErlangUnitRunningState.java index 2a27fa57b..93eb25ab3 100644 --- a/src/org/intellij/erlang/eunit/ErlangUnitRunningState.java +++ b/src/org/intellij/erlang/eunit/ErlangUnitRunningState.java @@ -68,6 +68,11 @@ protected boolean useTestCodePath() { return true; } + @Override + protected boolean useRebarOutputPaths() { + return myConfiguration.getConfigData().isUseRebarPaths(); + } + @Override protected boolean isNoShellMode() { return true; diff --git a/src/org/intellij/erlang/eunit/ui/ErlangUnitRunConfigurationEditorForm.form b/src/org/intellij/erlang/eunit/ui/ErlangUnitRunConfigurationEditorForm.form index fdee13ce1..cdef21e70 100644 --- a/src/org/intellij/erlang/eunit/ui/ErlangUnitRunConfigurationEditorForm.form +++ b/src/org/intellij/erlang/eunit/ui/ErlangUnitRunConfigurationEditorForm.form @@ -1,9 +1,9 @@
- + - + @@ -103,12 +103,20 @@ - + + + + + + + + + - + diff --git a/src/org/intellij/erlang/eunit/ui/ErlangUnitRunConfigurationEditorForm.java b/src/org/intellij/erlang/eunit/ui/ErlangUnitRunConfigurationEditorForm.java index 71919e9b8..312fa0a9f 100644 --- a/src/org/intellij/erlang/eunit/ui/ErlangUnitRunConfigurationEditorForm.java +++ b/src/org/intellij/erlang/eunit/ui/ErlangUnitRunConfigurationEditorForm.java @@ -45,6 +45,7 @@ public class ErlangUnitRunConfigurationEditorForm extends ErlangDebuggableRunCon @SuppressWarnings("unused") private HideableTitledPanel myDebugOptionsHideablePanel; private TextFieldWithBrowseButton myWorkingDirectoryComponent; + private JCheckBox myUseRebarOutputPathsCheckbox; public ErlangUnitRunConfigurationEditorForm() { myTestKindComboBox.addActionListener(e -> onTestKindSwitch()); @@ -71,6 +72,7 @@ protected void doResetEditorFrom(ErlangUnitRunConfiguration configuration) { myErlangModulesField.setText(getCommaSeparatedNamesString(configData.getModuleNames())); myErlangFunctionsField.setText(getCommaSeparatedNamesString(configData.getFunctionNames())); myWorkingDirectoryComponent.setText(StringUtil.notNullize(configuration.getWorkDirectory())); + myUseRebarOutputPathsCheckbox.setSelected(configData.isUseRebarPaths()); } @Override @@ -82,6 +84,7 @@ protected void doApplyEditorTo(ErlangUnitRunConfiguration configuration) throws configData.setFunctionNames(parseCommaSeparatedNames(myErlangFunctionsField.getText())); configData.setModuleNames(parseCommaSeparatedNames(myErlangModulesField.getText())); configData.setKind((ErlangUnitRunConfiguration.ErlangUnitRunConfigurationKind) myTestKindComboBox.getSelectedItem()); + configData.setUseRebarPaths(myUseRebarOutputPathsCheckbox.isSelected()); } @NotNull diff --git a/src/org/intellij/erlang/runconfig/ErlangRunConfigurationBase.java b/src/org/intellij/erlang/runconfig/ErlangRunConfigurationBase.java index 9ecda47d9..74a2bbdff 100644 --- a/src/org/intellij/erlang/runconfig/ErlangRunConfigurationBase.java +++ b/src/org/intellij/erlang/runconfig/ErlangRunConfigurationBase.java @@ -122,11 +122,20 @@ public final RunningState getState(@NotNull Executor executor, @NotNull Executio public abstract boolean isUseTestCodePath(); + public abstract boolean isUseRebarPaths(); + protected abstract RunningState newRunningState(ExecutionEnvironment env, Module module); public static final class ErlangDebugOptions implements Serializable { + public enum InterpretModulesLevel { + PROJECT, + DEPENDENCIES, + MODULE + }; + private boolean myAutoUpdateModulesNotToInterpret = true; private Set myModulesNotToInterpret = new HashSet<>(); + private InterpretModulesLevel myInterpretModulesLevel = InterpretModulesLevel.PROJECT; public boolean isAutoUpdateModulesNotToInterpret() { return myAutoUpdateModulesNotToInterpret; @@ -145,6 +154,15 @@ public void setModulesNotToInterpret(@NotNull Set modulesNotToInterpret) myModulesNotToInterpret = modulesNotToInterpret; } + @NotNull + public InterpretModulesLevel getInterpretModulesLevel() { + return myInterpretModulesLevel; + } + + public void setInterpretModulesLevel(@NotNull InterpretModulesLevel myInterpretModulesLevel) { + this.myInterpretModulesLevel = myInterpretModulesLevel; + } + @Override public boolean equals(Object o) { if (this == o) return true; @@ -154,6 +172,7 @@ public boolean equals(Object o) { if (myAutoUpdateModulesNotToInterpret != that.myAutoUpdateModulesNotToInterpret) return false; if (!myModulesNotToInterpret.equals(that.myModulesNotToInterpret)) return false; + if (myInterpretModulesLevel.equals(that.myInterpretModulesLevel)) return false; return true; } @@ -161,7 +180,7 @@ public boolean equals(Object o) { @Override public int hashCode() { int result = (myAutoUpdateModulesNotToInterpret ? 1 : 0); - result = 31 * result + myModulesNotToInterpret.hashCode(); + result = 31 * result + (myModulesNotToInterpret.hashCode() ^ myInterpretModulesLevel.hashCode()); return result; } } diff --git a/src/org/intellij/erlang/runconfig/ErlangRunningState.java b/src/org/intellij/erlang/runconfig/ErlangRunningState.java index 90da1d00e..c22e0e2ad 100644 --- a/src/org/intellij/erlang/runconfig/ErlangRunningState.java +++ b/src/org/intellij/erlang/runconfig/ErlangRunningState.java @@ -70,7 +70,7 @@ private GeneralCommandLine getCommand() throws ExecutionException { } protected List getCodePath() throws ExecutionException { - return ErlangConsoleUtil.getCodePath(myModule, useTestCodePath()); + return ErlangConsoleUtil.getCodePath(myModule, useTestCodePath(), useRebarOutputPaths()); } public Module getModule() { @@ -79,6 +79,8 @@ public Module getModule() { protected abstract boolean useTestCodePath(); + protected abstract boolean useRebarOutputPaths(); + protected abstract boolean isNoShellMode(); protected abstract boolean isStopErlang(); diff --git a/src/org/intellij/erlang/runconfig/ui/ErlangDebugOptionsEditorForm.form b/src/org/intellij/erlang/runconfig/ui/ErlangDebugOptionsEditorForm.form index 2e12a2673..d15bad94a 100644 --- a/src/org/intellij/erlang/runconfig/ui/ErlangDebugOptionsEditorForm.form +++ b/src/org/intellij/erlang/runconfig/ui/ErlangDebugOptionsEditorForm.form @@ -1,6 +1,6 @@ - + @@ -11,7 +11,7 @@ - + @@ -19,7 +19,7 @@ - + @@ -27,6 +27,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/org/intellij/erlang/runconfig/ui/ErlangDebugOptionsEditorForm.java b/src/org/intellij/erlang/runconfig/ui/ErlangDebugOptionsEditorForm.java index 7736de842..db0bb314f 100644 --- a/src/org/intellij/erlang/runconfig/ui/ErlangDebugOptionsEditorForm.java +++ b/src/org/intellij/erlang/runconfig/ui/ErlangDebugOptionsEditorForm.java @@ -21,10 +21,7 @@ import com.intellij.openapi.ui.InputValidator; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.util.text.StringUtil; -import com.intellij.ui.CollectionListModel; -import com.intellij.ui.IdeBorderFactory; -import com.intellij.ui.ListUtil; -import com.intellij.ui.ToolbarDecorator; +import com.intellij.ui.*; import com.intellij.ui.components.JBCheckBox; import com.intellij.ui.components.JBList; import com.intellij.util.containers.ContainerUtil; @@ -40,6 +37,9 @@ public class ErlangDebugOptionsEditorForm extends SettingsEditor modules = erlangDebugOptions.isAutoUpdateModulesNotToInterpret() ? Collections.emptySet() : ContainerUtil.map2Set(myModulesNotToInterpretListModel.getItems(), @@ -112,4 +123,26 @@ public boolean canClose(String s) { .createPanel(); myModulesNotToInterpretPanel.setBorder(IdeBorderFactory.createTitledBorder("Modules not to interpret", true)); } + + private static ListCellRendererWrapper getInterpretModulesLevelListCellRendererWrapper() { + return new ListCellRendererWrapper() { + @Override + public void customize(JList list, ErlangRunConfigurationBase.ErlangDebugOptions.InterpretModulesLevel level, int index, boolean selected, boolean hasFocus) { + if (level == null) { + return; + } + switch (level) { + case PROJECT: + setText("All project"); + break; + case DEPENDENCIES: + setText("Dependencies"); + break; + case MODULE: + setText("Current module"); + break; + } + } + }; + } }