mirror of
https://github.com/wavetermdev/waveterm.git
synced 2025-01-03 18:47:56 +01:00
118 lines
2.4 KiB
Go
118 lines
2.4 KiB
Go
// Copyright 2023, Command Line Inc.
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
package shellutil
|
|
|
|
import (
|
|
"context"
|
|
"os"
|
|
"os/exec"
|
|
"os/user"
|
|
"regexp"
|
|
"runtime"
|
|
"strings"
|
|
"sync"
|
|
"time"
|
|
|
|
"github.com/wavetermdev/thenextwave/pkg/wavebase"
|
|
)
|
|
|
|
const DefaultTermType = "xterm-256color"
|
|
const DefaultTermRows = 24
|
|
const DefaultTermCols = 80
|
|
|
|
var cachedMacUserShell string
|
|
var macUserShellOnce = &sync.Once{}
|
|
var userShellRegexp = regexp.MustCompile(`^UserShell: (.*)$`)
|
|
|
|
const DefaultShellPath = "/bin/bash"
|
|
|
|
func DetectLocalShellPath() string {
|
|
shellPath := GetMacUserShell()
|
|
if shellPath == "" {
|
|
shellPath = os.Getenv("SHELL")
|
|
}
|
|
if shellPath == "" {
|
|
return DefaultShellPath
|
|
}
|
|
return shellPath
|
|
}
|
|
|
|
func GetMacUserShell() string {
|
|
if runtime.GOOS != "darwin" {
|
|
return ""
|
|
}
|
|
macUserShellOnce.Do(func() {
|
|
cachedMacUserShell = internalMacUserShell()
|
|
})
|
|
return cachedMacUserShell
|
|
}
|
|
|
|
// dscl . -read /User/[username] UserShell
|
|
// defaults to /bin/bash
|
|
func internalMacUserShell() string {
|
|
osUser, err := user.Current()
|
|
if err != nil {
|
|
return DefaultShellPath
|
|
}
|
|
ctx, cancelFn := context.WithTimeout(context.Background(), 2*time.Second)
|
|
defer cancelFn()
|
|
userStr := "/Users/" + osUser.Username
|
|
out, err := exec.CommandContext(ctx, "dscl", ".", "-read", userStr, "UserShell").CombinedOutput()
|
|
if err != nil {
|
|
return DefaultShellPath
|
|
}
|
|
outStr := strings.TrimSpace(string(out))
|
|
m := userShellRegexp.FindStringSubmatch(outStr)
|
|
if m == nil {
|
|
return DefaultShellPath
|
|
}
|
|
return m[1]
|
|
}
|
|
|
|
func WaveshellEnvVars(termType string) map[string]string {
|
|
rtn := make(map[string]string)
|
|
if termType != "" {
|
|
rtn["TERM"] = termType
|
|
}
|
|
rtn["WAVETERM"], _ = os.Executable()
|
|
rtn["WAVETERM_VERSION"] = wavebase.WaveVersion
|
|
return rtn
|
|
}
|
|
|
|
func UpdateCmdEnv(cmd *exec.Cmd, envVars map[string]string) {
|
|
if len(envVars) == 0 {
|
|
return
|
|
}
|
|
found := make(map[string]bool)
|
|
var newEnv []string
|
|
for _, envStr := range cmd.Env {
|
|
envKey := GetEnvStrKey(envStr)
|
|
newEnvVal, ok := envVars[envKey]
|
|
if ok {
|
|
if newEnvVal == "" {
|
|
continue
|
|
}
|
|
newEnv = append(newEnv, envKey+"="+newEnvVal)
|
|
found[envKey] = true
|
|
} else {
|
|
newEnv = append(newEnv, envStr)
|
|
}
|
|
}
|
|
for envKey, envVal := range envVars {
|
|
if found[envKey] {
|
|
continue
|
|
}
|
|
newEnv = append(newEnv, envKey+"="+envVal)
|
|
}
|
|
cmd.Env = newEnv
|
|
}
|
|
|
|
func GetEnvStrKey(envStr string) string {
|
|
eqIdx := strings.Index(envStr, "=")
|
|
if eqIdx == -1 {
|
|
return envStr
|
|
}
|
|
return envStr[0:eqIdx]
|
|
}
|