@@ -43,6 +43,9 @@ version = 1
|
||||
# override shell: "bash", "zsh", "fish", keep empty for auto detection
|
||||
shell = ""
|
||||
|
||||
# run the selected shell as a login shell
|
||||
shell-login = false
|
||||
|
||||
# startup mode: "last", "spec", "history"
|
||||
# "last" = remember last mode used
|
||||
mode = "last"
|
||||
|
||||
+18
-3
@@ -3,8 +3,10 @@ package root
|
||||
import (
|
||||
"bytes"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/versenilvis/iris/internal/config"
|
||||
)
|
||||
|
||||
func TestConfigCommands(t *testing.T) {
|
||||
@@ -14,14 +16,27 @@ func TestConfigCommands(t *testing.T) {
|
||||
}
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
// UserConfigDir follows HOME on macOS and XDG_CONFIG_HOME on Unix.
|
||||
// Override both so the command cannot read or write the user's real config.
|
||||
t.Setenv("HOME", tmpDir)
|
||||
t.Setenv("XDG_CONFIG_HOME", tmpDir)
|
||||
|
||||
ConfigInitCmd.Run(ConfigInitCmd, []string{})
|
||||
|
||||
configPath := filepath.Join(tmpDir, "iris", "config.toml")
|
||||
if _, err := os.Stat(configPath); err != nil {
|
||||
configPath, err := config.ConfigPath()
|
||||
if err != nil {
|
||||
t.Fatalf("failed to get config path: %v", err)
|
||||
}
|
||||
if _, statErr := os.Stat(configPath); statErr != nil {
|
||||
t.Errorf("expected config file to be created at %s, but it was not", configPath)
|
||||
}
|
||||
content, err := os.ReadFile(configPath)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to read config file: %v", err)
|
||||
}
|
||||
if !strings.Contains(string(content), "shell-login = false") {
|
||||
t.Error("expected initialized config to include shell-login = false")
|
||||
}
|
||||
|
||||
buf := new(bytes.Buffer)
|
||||
ConfigShowCmd.SetOut(buf)
|
||||
|
||||
+4
-1
@@ -148,7 +148,7 @@ var setupCmd = &cobra.Command{
|
||||
|
||||
var shellName string
|
||||
if len(args) > 0 {
|
||||
shellName = args[0]
|
||||
shellName = filepath.Base(args[0])
|
||||
} else {
|
||||
shellPath := os.Getenv("SHELL")
|
||||
shellName = filepath.Base(shellPath)
|
||||
@@ -208,6 +208,9 @@ version = 1
|
||||
# override shell: "bash", "zsh", "fish", keep empty for auto detection
|
||||
shell = ""
|
||||
|
||||
# run the selected shell as a login shell
|
||||
shell-login = false
|
||||
|
||||
# startup mode: "last", "spec", "history"
|
||||
# "last" = remember last mode used
|
||||
mode = "last"
|
||||
|
||||
+8
-3
@@ -50,24 +50,29 @@ It works exactly like coding editor suggestion menu drop down.`,
|
||||
runWrapper()
|
||||
},
|
||||
}
|
||||
shellFlag string
|
||||
debugMode bool
|
||||
shellFlag string
|
||||
shellLoginFlag bool
|
||||
debugMode bool
|
||||
)
|
||||
|
||||
func init() {
|
||||
rootCmd.PersistentFlags().StringVarP(&shellFlag, "shell", "s", "", "shell to use (bash, zsh, fish)")
|
||||
rootCmd.PersistentFlags().BoolVar(&shellLoginFlag, "shell-login", false, "run the selected shell as a login shell")
|
||||
rootCmd.PersistentFlags().BoolVarP(&debugMode, "debug", "d", false, "enable debug logging to iris.log")
|
||||
|
||||
rootCmd.PersistentPreRun = func(cmd *cobra.Command, args []string) {
|
||||
if shellFlag != "" {
|
||||
config.Get().Core.Shell = shellFlag
|
||||
}
|
||||
if cmd.Flags().Changed("shell-login") {
|
||||
config.Get().Core.ShellLogin = shellLoginFlag
|
||||
}
|
||||
logDir, err := config.CachePath()
|
||||
if err == nil {
|
||||
logger.Init(filepath.Join(logDir, "iris.log"), debugMode || config.Get().Core.Debug)
|
||||
logger.Infof("IRIS session started: os=%s, arch=%s, go=%s, pid=%d", runtime.GOOS, runtime.GOARCH, runtime.Version(), os.Getpid())
|
||||
cfg := config.Get()
|
||||
logger.Debugf("IRIS loaded config: shell=%q, mode=%q, ghost-text=%v, max-suggestions=%d", cfg.Core.Shell, cfg.Core.Mode, cfg.UI.GhostText, cfg.UI.MaxSuggestions)
|
||||
logger.Debugf("IRIS loaded config: shell=%q, shell-login=%v, mode=%q, ghost-text=%v, max-suggestions=%d", cfg.Core.Shell, cfg.Core.ShellLogin, cfg.Core.Mode, cfg.UI.GhostText, cfg.UI.MaxSuggestions)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
package root
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestShellArgs(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
login bool
|
||||
want []string
|
||||
}{
|
||||
{name: "login", login: true, want: []string{"--login"}},
|
||||
{name: "non-login", login: false},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got := shellArgs(tt.login); !reflect.DeepEqual(got, tt.want) {
|
||||
t.Fatalf("shellArgs(%v) = %v, want %v", tt.login, got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestShellLoginFlagIsRegistered(t *testing.T) {
|
||||
flag := rootCmd.PersistentFlags().Lookup("shell-login")
|
||||
if flag == nil {
|
||||
t.Fatal("expected --shell-login flag to be registered")
|
||||
}
|
||||
if flag.DefValue != "false" {
|
||||
t.Fatalf("expected --shell-login to default to false, got %q", flag.DefValue)
|
||||
}
|
||||
}
|
||||
+8
-1
@@ -82,6 +82,13 @@ func saveMode(mode string) {
|
||||
_ = config.SaveState(state)
|
||||
}
|
||||
|
||||
func shellArgs(login bool) []string {
|
||||
if login {
|
||||
return []string{"--login"}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var (
|
||||
oldState *term.State
|
||||
oldStateFd int
|
||||
@@ -141,7 +148,7 @@ func runWrapper() {
|
||||
adapter := shell.Current
|
||||
|
||||
ctx := context.Background()
|
||||
c := exec.CommandContext(ctx, adapter.GetShellPath())
|
||||
c := exec.CommandContext(ctx, adapter.GetShellPath(), shellArgs(config.Get().Core.ShellLogin)...)
|
||||
c.ExtraFiles = make([]*os.File, 11)
|
||||
// pass write end of pipe to shell as fd 13 (since index 10 maps to 13)
|
||||
c.ExtraFiles[10] = w
|
||||
|
||||
Reference in New Issue
Block a user