mirror of https://github.com/xrehpicx/pee.git
108 lines
3.7 KiB
Go
108 lines
3.7 KiB
Go
|
package controller
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"os/exec"
|
||
|
"strings"
|
||
|
|
||
|
"github.com/charmbracelet/log"
|
||
|
projectconfig "github.com/xrehpicx/pee/config"
|
||
|
)
|
||
|
|
||
|
// RunShellCommand executes a shell command and logs it.
|
||
|
func RunShellCommand(cmd *exec.Cmd) error {
|
||
|
log.Debug("Running command:", "command", cmd.String())
|
||
|
output, err := cmd.CombinedOutput()
|
||
|
if err != nil {
|
||
|
log.Error("Error running command:", "command", cmd.String(), "error", err)
|
||
|
log.Info("Command output:", "output", string(output))
|
||
|
return err
|
||
|
}
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
// CreateScreenSession creates a new screen session based on the given Configuration.
|
||
|
func CreateScreenSession(config *projectconfig.Configuration) error {
|
||
|
sessionName := config.SessionName
|
||
|
|
||
|
// Check if the session already exists
|
||
|
checkSessionCmd := exec.Command("screen", "-S", sessionName, "-Q", "windows")
|
||
|
_, err := checkSessionCmd.CombinedOutput()
|
||
|
if err == nil {
|
||
|
// If it exists, attach to the session
|
||
|
attachSessionCmd := exec.Command("screen", "-d", "-r", sessionName)
|
||
|
RunShellCommand(attachSessionCmd)
|
||
|
} else {
|
||
|
// If it doesn't exist, create the session
|
||
|
createSessionCmd := exec.Command("screen", "-S", sessionName, "-d", "-m")
|
||
|
RunShellCommand(createSessionCmd)
|
||
|
|
||
|
// Create and run commands for windows
|
||
|
for i, window := range config.Windows {
|
||
|
windowName := fmt.Sprintf("%s-%d", sessionName, i+1)
|
||
|
|
||
|
// Create a new window within the session
|
||
|
createWindowCmd := exec.Command("screen", "-S", sessionName, "-X", "screen", "-t", windowName)
|
||
|
RunShellCommand(createWindowCmd)
|
||
|
|
||
|
// Change the working directory for the window
|
||
|
changeDirCmd := exec.Command("screen", "-S", sessionName, "-p", fmt.Sprint(i), "-X", "chdir", config.WorkingDir)
|
||
|
RunShellCommand(changeDirCmd)
|
||
|
|
||
|
// Send commands to the window
|
||
|
sendCommandsCmd := exec.Command("screen", "-S", sessionName, "-p", fmt.Sprint(i), "-X", "stuff", strings.Join(window.Panes[0].ShellCommand, " && ")+"\n")
|
||
|
RunShellCommand(sendCommandsCmd)
|
||
|
|
||
|
// Rename the window to the specified name
|
||
|
renameWindowCmd := exec.Command("screen", "-S", sessionName, "-p", fmt.Sprint(i), "-X", "title", window.WindowName)
|
||
|
RunShellCommand(renameWindowCmd)
|
||
|
|
||
|
// warn user of compatibility issues using more than one pane with screen
|
||
|
if len(window.Panes) > 1 {
|
||
|
log.Warn("Screen does not support multiple panes. Only the first pane will be used.")
|
||
|
}
|
||
|
|
||
|
// Create and run commands for additional panes in the window
|
||
|
for _, pane := range window.Panes[1:] {
|
||
|
// Split the window vertically
|
||
|
splitPaneCmd := exec.Command("screen", "-S", sessionName, "-p", fmt.Sprint(i), "-X", "split")
|
||
|
RunShellCommand(splitPaneCmd)
|
||
|
|
||
|
// Select the new pane
|
||
|
selectPaneCmd := exec.Command("screen", "-S", sessionName, "-p", fmt.Sprint(i+1)) // Select the next pane
|
||
|
RunShellCommand(selectPaneCmd)
|
||
|
|
||
|
// Send commands to the new pane
|
||
|
sendCommandsCmd := exec.Command("screen", "-S", sessionName, "-X", "stuff", strings.Join(pane.ShellCommand, " && ")+"\n")
|
||
|
RunShellCommand(sendCommandsCmd)
|
||
|
}
|
||
|
|
||
|
if window.Layout != "" {
|
||
|
layoutCmd := exec.Command("screen", "-S", sessionName, "-p", fmt.Sprint(i), "-X", "layout", window.Layout)
|
||
|
RunShellCommand(layoutCmd)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if config.Attach {
|
||
|
// Attach to the session
|
||
|
attachSessionCmd := exec.Command("screen", "-d", "-r", sessionName)
|
||
|
RunShellCommand(attachSessionCmd)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
// KillScreenSession kills a screen session by name.
|
||
|
func KillScreenSession(sessionName string) error {
|
||
|
// Kill the screen session
|
||
|
killSessionCmd := exec.Command("screen", "-S", sessionName, "-X", "quit")
|
||
|
err := killSessionCmd.Run()
|
||
|
if err != nil {
|
||
|
log.Error("Error killing screen session:", "sessionName", sessionName, "error", err)
|
||
|
return err
|
||
|
}
|
||
|
log.Info("Killed screen session:", "sessionName", sessionName)
|
||
|
return nil
|
||
|
}
|