Skip to content

Commit

Permalink
Updates cbsh, restarts cbsh when exited
Browse files Browse the repository at this point in the history
  • Loading branch information
chedim committed Sep 16, 2024
1 parent 9a5a97a commit b761d0b
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 125 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -84,38 +84,38 @@ public Map<String, ToolSpec> getDownloadList(String os) {
Map<String, ToolSpec> map = new HashMap<>();

if (MACOS_64.equals(os)) {
map.put(TOOL_SHELL, getToolSpec("https://github.com/couchbaselabs/couchbase-shell/releases/download/v0.75.1/cbsh-x86_64-apple-darwin.zip", TOOL_SHELL, MACOS_64));
map.put(TOOL_SHELL, getToolSpec("https://github.com/couchbaselabs/couchbase-shell/releases/download/v1.0.0/cbsh-x86_64-apple-darwin.zip", TOOL_SHELL, MACOS_64));
map.put(TOOL_IMPORT_EXPORT, getToolSpec("https://packages.couchbase.com/releases/7.6.0/couchbase-server-tools_7.6.0-macos_x86_64.zip", TOOL_IMPORT_EXPORT, MACOS_64));
map.put(ALL_TOOLS, getToolSpec("https://intellij-plugin-dependencies.s3.us-east-2.amazonaws.com/7.2.0-macos_64.zip", ALL_TOOLS, MACOS_64));
map.put(CB_MIGRATE, getToolSpec("https://intellij-plugin-dependencies.s3.us-east-2.amazonaws.com/cbmigrate/cbmigrate_0.1.0_darwin_amd64.zip", CB_MIGRATE, MACOS_64));

} else if (MACOS_ARM.equals(os)) {
map.put(TOOL_SHELL, getToolSpec("https://github.com/couchbaselabs/couchbase-shell/releases/download/v0.75.1/cbsh-aarch64-apple-darwin.zip", TOOL_SHELL, MACOS_ARM));
map.put(TOOL_SHELL, getToolSpec("https://github.com/couchbaselabs/couchbase-shell/releases/download/v1.0.0/cbsh-aarch64-apple-darwin.zip", TOOL_SHELL, MACOS_ARM));
map.put(TOOL_IMPORT_EXPORT, getToolSpec("https://packages.couchbase.com/releases/7.6.0/couchbase-server-tools_7.6.0-macos_arm64.zip", TOOL_IMPORT_EXPORT, MACOS_ARM));
map.put(ALL_TOOLS, getToolSpec("https://intellij-plugin-dependencies.s3.us-east-2.amazonaws.com/7.2.0-macos_arm.zip", ALL_TOOLS, MACOS_ARM));
map.put(CB_MIGRATE, getToolSpec("https://intellij-plugin-dependencies.s3.us-east-2.amazonaws.com/cbmigrate/cbmigrate_0.1.0_darwin_arm64.zip", CB_MIGRATE, MACOS_ARM));


} else if (WINDOWS_64.equals(os)) {
map.put(TOOL_SHELL, getToolSpec("https://github.com/couchbaselabs/couchbase-shell/releases/download/v0.75.1/cbsh-x86_64-pc-windows-msvc.zip", TOOL_SHELL, WINDOWS_64));
map.put(TOOL_SHELL, getToolSpec("https://github.com/couchbaselabs/couchbase-shell/releases/download/v1.0.0/cbsh-x86_64-pc-windows-msvc.zip", TOOL_SHELL, WINDOWS_64));
map.put(TOOL_IMPORT_EXPORT, getToolSpec("https://packages.couchbase.com/releases/7.6.0/couchbase-server-tools_7.6.0-windows_amd64.zip", TOOL_IMPORT_EXPORT, WINDOWS_64));
map.put(ALL_TOOLS, getToolSpec("https://intellij-plugin-dependencies.s3.us-east-2.amazonaws.com/7.2.0-windows_64.zip", ALL_TOOLS, WINDOWS_64));
map.put(CB_MIGRATE, getToolSpec("https://intellij-plugin-dependencies.s3.us-east-2.amazonaws.com/cbmigrate/cbmigrate_0.1.0_windows_amd64.zip", CB_MIGRATE, WINDOWS_64));

} else if (WINDOWS_ARM.equals(os)) {
map.put(TOOL_SHELL, getToolSpec("https://github.com/couchbaselabs/couchbase-shell/releases/download/v0.75.1/cbsh-x86_64-pc-windows-msvc.zip", TOOL_SHELL, WINDOWS_ARM));
map.put(TOOL_SHELL, getToolSpec("https://github.com/couchbaselabs/couchbase-shell/releases/download/v1.0.0/cbsh-x86_64-pc-windows-msvc.zip", TOOL_SHELL, WINDOWS_ARM));
map.put(TOOL_IMPORT_EXPORT, getToolSpec("https://packages.couchbase.com/releases/7.6.0/couchbase-server-tools_7.6.0-windows_amd64.zip", TOOL_IMPORT_EXPORT, WINDOWS_ARM));
map.put(ALL_TOOLS, getToolSpec("https://intellij-plugin-dependencies.s3.us-east-2.amazonaws.com/7.2.0-windows_64.zip", ALL_TOOLS, WINDOWS_ARM));
map.put(CB_MIGRATE, getToolSpec("https://intellij-plugin-dependencies.s3.us-east-2.amazonaws.com/cbmigrate/cbmigrate_0.1.0_windows_amd64.zip", CB_MIGRATE, WINDOWS_ARM));

} else if (LINUX_64.equals(os)) {
map.put(TOOL_SHELL, getToolSpec("https://github.com/couchbaselabs/couchbase-shell/releases/download/v0.75.1/cbsh-x86_64-unknown-linux-gnu.tar.gz", TOOL_SHELL, LINUX_64));
map.put(TOOL_SHELL, getToolSpec("https://github.com/couchbaselabs/couchbase-shell/releases/download/v1.0.0/cbsh-x86_64-unknown-linux-gnu.tar.gz", TOOL_SHELL, LINUX_64));
map.put(TOOL_IMPORT_EXPORT, getToolSpec("https://packages.couchbase.com/releases/7.6.0/couchbase-server-tools_7.6.0-linux_x86_64.tar.gz", TOOL_IMPORT_EXPORT, LINUX_64));
map.put(ALL_TOOLS, getToolSpec("https://intellij-plugin-dependencies.s3.us-east-2.amazonaws.com/7.2.0-linux_64.zip", ALL_TOOLS, LINUX_64));
map.put(CB_MIGRATE, getToolSpec("https://intellij-plugin-dependencies.s3.us-east-2.amazonaws.com/cbmigrate/cbmigrate_0.1.0_linux_amd64.zip", CB_MIGRATE, LINUX_64));

} else if (LINUX_ARM.equals(os)) {
map.put(TOOL_SHELL, getToolSpec("https://github.com/couchbaselabs/couchbase-shell/releases/download/v0.75.1/cbsh-aarch64-unknown-linux-gnu.tar.gz", TOOL_SHELL, LINUX_ARM));
map.put(TOOL_SHELL, getToolSpec("https://github.com/couchbaselabs/couchbase-shell/releases/download/v1.0.0/cbsh-aarch64-unknown-linux-gnu.tar.gz", TOOL_SHELL, LINUX_ARM));
map.put(TOOL_IMPORT_EXPORT, getToolSpec("https://packages.couchbase.com/releases/7.6.0/couchbase-server-tools_7.6.0-linux_aarch64.tar.gz", TOOL_IMPORT_EXPORT, LINUX_ARM));
map.put(CB_MIGRATE, getToolSpec("https://intellij-plugin-dependencies.s3.us-east-2.amazonaws.com/cbmigrate/cbmigrate_0.1.0_linux_arm64.zip", CB_MIGRATE, LINUX_ARM));

Expand Down
166 changes: 47 additions & 119 deletions src/main/java/com/couchbase/intellij/workbench/CbShellEmulator.java
Original file line number Diff line number Diff line change
@@ -1,26 +1,21 @@
package com.couchbase.intellij.workbench;
import com.couchbase.intellij.database.ActiveCluster;
import com.couchbase.intellij.tools.CBTool;
import com.couchbase.intellij.tools.CBTools;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Disposer;
import com.intellij.terminal.JBTerminalSystemSettingsProviderBase;
import com.intellij.terminal.JBTerminalWidget;
import com.intellij.terminal.pty.PtyProcessTtyConnector;
import com.intellij.ui.speedSearch.ElementFilter;
import com.jediterm.core.util.TermSize;
import com.jediterm.terminal.ProcessTtyConnector;
import com.intellij.ui.components.panels.Wrapper;
import com.pty4j.PtyProcess;
import com.pty4j.PtyProcessBuilder;
import org.jetbrains.annotations.NotNull;

import javax.swing.*;
import java.awt.*;
import java.io.*;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.concurrent.TimeUnit;

public class CbShellEmulator {

Expand All @@ -29,12 +24,13 @@ public class CbShellEmulator {
private PtyProcess process;
private StringBuilder inputBuffer = new StringBuilder();
private PtyProcessTtyConnector connector;
private JPanel parentPanel;
private Wrapper wrapper;
private Project project;

public CbShellEmulator(Project project, JPanel parentPanel) {
this.project = project;
this.parentPanel = parentPanel;
this.wrapper = new Wrapper(new BorderLayout());
parentPanel.add(wrapper, BorderLayout.CENTER);
initTerminal();
ActiveCluster.subscribe(this::onClusterConnected);
}
Expand All @@ -47,10 +43,13 @@ private void initTerminal() {
terminalWidget = new JBTerminalWidget(project, settingsProvider, Disposer.newDisposable());

terminalWidget.getComponent().requestFocusInWindow();
parentPanel.add(terminalWidget.getComponent(), BorderLayout.CENTER);
parentPanel.invalidate();
wrapper.setContent(terminalWidget.getComponent());

terminalWidget.writePlainMessage(CONNECT_TO_A_CLUSTER_FOR_CBSHELL);
wrapper.invalidate();
terminalWidget.getComponent().invalidate();
wrapper.repaint();
wrapper.requestFocusInWindow();
}

private void onClusterConnected(ActiveCluster activeCluster) {
Expand All @@ -63,6 +62,7 @@ private void onClusterConnected(ActiveCluster activeCluster) {
command.add("-u");
command.add(activeCluster.getUsername());
command.add("-p");
command.add("-");
command.add("--no-motd");
command.add("--disable-config-prompt");

Expand All @@ -77,13 +77,35 @@ private void onClusterConnected(ActiveCluster activeCluster) {
byte[] buffer = new byte[9];
is.read(buffer);
os.write((activeCluster.getPassword() + "\r\n").getBytes(StandardCharsets.UTF_8));
// os.write(13);
os.flush();
is.read();
connector = new PtyProcessTtyConnector(process, Charset.defaultCharset());
terminalWidget.start(connector);
SwingUtilities.invokeLater(() -> {
clearTerminal();
terminalWidget.writePlainMessage("Connecting to cluster '" + activeCluster.getClusterURL()+"'...\n");
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8));
// read password back
while (true) {
String line = reader.readLine();
if (line.isEmpty()) {
break;
}
}

Thread.sleep(1000);
// os.write(3);
// os.write(3);
// os.write("clear".getBytes(Charset.defaultCharset()));
// os.write(13);
os.flush();
Thread.sleep(1000);
connector = new PtyProcessTtyConnector(process, Charset.defaultCharset());
terminalWidget.start(connector);
terminalWidget.getTerminalTextBuffer().clearHistory();
clearTerminal();
} catch (Exception e) {
throw new RuntimeException(e);
}
});
} catch (Exception e) {
e.printStackTrace();
Expand All @@ -93,124 +115,30 @@ private void onClusterConnected(ActiveCluster activeCluster) {
if (process != null) {
process.destroyForcibly();
terminalWidget.close();
parentPanel.remove(terminalWidget);
parentPanel.invalidate();
}
initTerminal();
});
});
}

private void clearTerminal() {
terminalWidget.getTerminal().clearScreen();
terminalWidget.writePlainMessage("\r");
}

public void requestFocus() {
SwingUtilities.invokeLater(() -> terminalWidget.getComponent().requestFocusInWindow());
}

private class Connector extends ProcessTtyConnector {

public Connector(@NotNull Process process, @NotNull Charset charset) {
super(process, charset);
}

@Override
public String getName() {
return "cbshell_terminal";
}

@Override
public void resize(TermSize termSize) {
System.out.println(
"Terminal resized to: " + termSize.getColumns() + " columns, " + termSize.getRows() + " rows");
}

@Override
public void write(byte[] bytes) throws IOException {
String typed = new String(bytes, StandardCharsets.UTF_8);

for (char ch : typed.toCharArray()) {
switch (ch) {
case '\b': // Backspace key
handleBackspace();
break;
case 127: // Delete key (ASCII 127)
handleDelete();
break;
case '\n': // Enter key
case '\r': // Carriage return
sendInputToProcess();
break;
default:
addCharacterToBuffer(ch);
break;
}
process.onExit().thenAccept(p -> {
// restart cbshell on `exit`
if (ActiveCluster.getInstance() != null && ActiveCluster.getInstance().get() != null) {
terminalWidget.close();
initTerminal();
onClusterConnected(ActiveCluster.getInstance());
}
}
}

private void handleBackspace() {
if (inputBuffer.length() > 0) {
// Remove the last character from the buffer
inputBuffer.deleteCharAt(inputBuffer.length() - 1);
// Simulate backspace effect: move cursor back, overwrite with space, then move back again
SwingUtilities.invokeLater(() -> terminalWidget.writePlainMessage("\b \b"));
}
}

private void handleDelete() {
if (inputBuffer.length() > 0) {
// Remove the last character from the input buffer
inputBuffer.deleteCharAt(inputBuffer.length() - 1);

SwingUtilities.invokeLater(() -> {
// Calculate the length of the current line (including the deleted character)
int lineLength = inputBuffer.length() + 1; // +1 for the deleted character

// Create a string of spaces to overwrite the current line
String clearLine = " ".repeat(lineLength);

// Write the string of spaces to clear the current content
terminalWidget.writePlainMessage(clearLine);

// Now, rewrite the updated content of the buffer
terminalWidget.writePlainMessage("\b" + inputBuffer.toString());
});
}
}

private void sendInputToProcess() throws IOException {
// Send the buffered input to the process
process.getOutputStream().write(inputBuffer.toString().getBytes(StandardCharsets.UTF_8));
process.getOutputStream().flush();
inputBuffer.setLength(0); // Clear the buffer after sending
});
}

private void addCharacterToBuffer(char ch) {
// Add the character to the input buffer
inputBuffer.append(ch);
// Echo the character to the terminal
SwingUtilities.invokeLater(() -> terminalWidget.writePlainMessage(Character.toString(ch)));
private void clearTerminal() {
terminalWidget.getTerminal().clearScreen();
terminalWidget.getTerminal().reset(true);
}

public void dispose() {
Disposer.dispose(terminalWidget);
if (process != null) {
process.destroy();
}
}

private void readStream(InputStream inputStream) {
try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) {
String line;
while ((line = reader.readLine()) != null) {
System.out.println("Process output: " + line); // Log the output for debugging
terminalWidget.writePlainMessage(line + "\n");
}
} catch (IOException e) {
e.printStackTrace();
if (process != null && process.isAlive()) {
process.destroyForcibly();
}
}
}

0 comments on commit b761d0b

Please sign in to comment.