package main import ( "fmt" "gosh/cmd" "gosh/types" "gosh/utils" "os" "os/exec" "path/filepath" "strings" "github.com/chzyer/readline" "github.com/fatih/color" ) func gosh_print_output(cmdo types.CmdOutput) { switch cmdo.Id { case 0: fmt.Printf(cmdo.Output) case 1: fmt.Printf("Error: %s\n", cmdo.Output) } } func parse_flags(parts []string) (map[string]string, []string) { flags := make(map[string]string) args := []string{} i := 0 for i < len(parts) { if strings.HasPrefix(parts[i], "-") { key := parts[i] val := "" if i+1 < len(parts) && !strings.HasPrefix(parts[i+1], "-") { val = parts[i+1] i++ } flags[key] = val } else { args = append(args, parts[i]) } i++ } return flags, args } func process_golshscript(sh *types.Shell, file_path string) { data, err := os.ReadFile(file_path) if err != nil { fmt.Println("Error: ", err) return } lines := strings.Split(string(data), "\n") for _, line := range lines { gosh_process_input(sh, strings.TrimSpace(line)) } } func check_pathes(sh *types.Shell, name string, args []string) bool { var output types.CmdOutput program_found := false // Check Python Pathes for _, path := range sh.PyPaths { children, err := os.ReadDir(path) if err != nil { color.Red("Error reading path.") fmt.Println(err) } for _, child := range children { child_name := strings.TrimSpace(child.Name()) if !child.IsDir() && child_name == name { program_found = true full_path := filepath.Join(path, child.Name()) path_args := append([]string{full_path}, args...) comd := exec.Command("python3", path_args...) out, err := comd.Output() if err != nil { fmt.Print("Error: ") color.Red(err.Error()) } output = types.CmdOutput{Id: 0, Output: string(out)} } } } if program_found { gosh_print_output(output) } return program_found } func gosh_process_input(sh *types.Shell, input string) { // Split by pipe and trim spaces commands := strings.Split(input, "|") var prevOutput types.CmdOutput for _, cmdStr := range commands { cmdStr = strings.TrimSpace(cmdStr) parts := strings.Fields(cmdStr) if len(parts) == 0 { continue } switch parts[0] { case "pwd": prevOutput = cmd.GoshPwd(sh) case "cd": if len(parts) < 2 { fmt.Println("Usage: cd ") return } prevOutput = cmd.GoshCd(sh, parts[1]) case "ls": if len(parts) > 1 { prevOutput = cmd.GoshLs(sh, parts[1:]...) } else { prevOutput = cmd.GoshLs(sh) } case "cat": if len(parts) < 2 { fmt.Println("Usage: cat ") return } prevOutput = cmd.GoshCat(sh, parts[1]) case "grep": if len(parts) < 2 { fmt.Println("Usage: grep ") return } flags, args := parse_flags(parts) // Feed previous output to grep prevOutput = cmd.GoshGrep(sh, flags, prevOutput.Output, args[len(args)-1]) case "clear": cmd.GoshClear() case "apath": if len(parts) < 2 { fmt.Println(("Usage: apath ")) return } prevOutput = cmd.GolshPyapath(sh, parts[1]) default: if !check_pathes(sh, parts[0], parts[1:]) { fmt.Println("Unknown command:", parts[0]) return } } } gosh_print_output(prevOutput) } func main() { dir, _ := os.Getwd() // Init shell sh := types.Shell{ Cd: dir, PyPaths: []string{}} // Check for and execute .golshrc golshrc_path, _ := os.UserHomeDir() golshrc_path = golshrc_path + "/.golshrc" _, err := os.Stat(golshrc_path) golshrc_exists := err == nil if golshrc_exists { process_golshscript(&sh, golshrc_path) } // Set up readline rl, err := readline.NewEx(&readline.Config{ Prompt: sh.Cd + "> ", AutoComplete: &utils.AutoCompleter{Sh: &sh}, InterruptPrompt: "^C", EOFPrompt: "exit", }) if err != nil { panic(err) } defer rl.Close() cd_path_color := color.New(color.FgBlue) var should_exit = false for { rl.SetPrompt(cd_path_color.Sprint("GOLSH "+sh.Cd+"❯") + " ") input, err := rl.Readline() if err != nil { fmt.Println("Error reading input: ", err) } input = strings.TrimSpace(input) switch input { case "exit": should_exit = true default: gosh_process_input(&sh, input) } if should_exit { break } } }