How Do I Run Multiple Terminal Processes From A Plugin?
Answered
I have a project that I test (I have separate unit tests too!) by running multiple java processes from the build directory to simulate a network.
These processes provide an interactive shell that I type commands into.
It would convenient if I could create these processes from an IDEA plugin.
Is this possible in the plugin framework?
Would I create multiple Terminal tool windows or use multiple Run tool windows?
Please sign in to leave a comment.
Use org.jetbrains.plugins.terminal.TerminalView#createNewSession(org.jetbrains.plugins.terminal.AbstractTerminalRunner) to create new tabs.
In addition, here is how "Shell Script" run/debug configuration opens a new tab in Terminal tool window and executes a command there (of course if Terminal plugin is installed): com.intellij.sh.run.ShTerminalRunner. If the plugin is not installed, a tab in Run tool window is created: com.intellij.sh.run.ShRunConfigurationProfileState#buildExecutionResult
So using the Shell plugin I have to create a script that contains:
I then create 3 run configs that call it with a different working directory.
I can then create a Compound Run Config that allows me to run all 3 at once.
It needs to run in a terminal and not in a Run ToolWindow because the jar creates an interactive console (which is why I can't use the Jar Application Run Config).
The downsides of this approach are:
I was thinking of extending/depending on the Shell plugin but that seems like it would be overkill and have a lot of extras that I'm not interested in.
On the other hand, when I look at the Shell plugin it seems to have quite a lot of code on top of the Terminal plugin to enable what I am looking to do.
Is there a simpler way to achieve this?
Seems this code will do the job:
private void runCommand(@NotNull String workingDir) {
TerminalView terminalView = TerminalView.getInstance(myProject);
ToolWindow window = ToolWindowManager.getInstance(myProject).getToolWindow(TerminalToolWindowFactory.TOOL_WINDOW_ID);
if (window == null) return;
try {
terminalView.createLocalShellWidget(workingDir).executeCommand("java -jar wrapper.jar");
}
catch (IOException e) {
LOG.warn("Cannot execute command", e);
}
}
runCommand("/path/to/working-dir1");
runCommand("/path/to/working-dir2");
runCommand("/path/to/working-dir3");
However, the approach based on a Compound run configuration is nice too. Why do you need to order run configs in the Compound run config? According to https://youtrack.jetbrains.com/issue/IDEA-158801#focus=streamItem-27-2230771.0-0, the order of run configurations is not specified.
Regarding ability to name the terminal session tab, it's not supported yet (https://youtrack.jetbrains.com/issue/IDEA-146714).
Thanks. I'll try that code when I'm back at my desk.
There is an option to manually rename tabs from the context menu, which implies that there is an API to set the tab name from a plugin.
The linked issue is just to set it automatically based on path.
I'd expect something like terminalView.setTabName("Database") but I'm on my phone right now so it's a bit tricky to check.
Ordering the run configs isn't crucial. It just makes it easier to read as there are some logical steps to the setup.
I'm fairly sure the code is robust enough to wait if a dependent process is not running but it makes it clearer to understand what is happening if you look at the config and it says run A then B then C.
E.g. start a database, start a message queue, start an application that connects to both.