aboutsummaryrefslogtreecommitdiff
path: root/weed/shell/shell_liner.go
diff options
context:
space:
mode:
Diffstat (limited to 'weed/shell/shell_liner.go')
-rw-r--r--weed/shell/shell_liner.go143
1 files changed, 143 insertions, 0 deletions
diff --git a/weed/shell/shell_liner.go b/weed/shell/shell_liner.go
new file mode 100644
index 000000000..e86220134
--- /dev/null
+++ b/weed/shell/shell_liner.go
@@ -0,0 +1,143 @@
+package shell
+
+import (
+ "context"
+ "fmt"
+ "github.com/chrislusf/seaweedfs/weed/wdclient"
+ "os"
+ "regexp"
+ "strings"
+
+ "github.com/peterh/liner"
+ "sort"
+)
+
+var (
+ line *liner.State
+ historyPath = "/tmp/weed-shell"
+)
+
+func RunShell(options ShellOptions) {
+
+ line = liner.NewLiner()
+ defer line.Close()
+
+ line.SetCtrlCAborts(true)
+
+ setCompletionHandler()
+ loadHisotry()
+
+ defer saveHisotry()
+
+ reg, _ := regexp.Compile(`'.*?'|".*?"|\S+`)
+
+ commandEnv := &commandEnv{
+ env: make(map[string]string),
+ masterClient: wdclient.NewMasterClient(context.Background(),
+ options.GrpcDialOption, "shell", strings.Split(*options.Masters, ",")),
+ }
+
+ go commandEnv.masterClient.KeepConnectedToMaster()
+ commandEnv.masterClient.WaitUntilConnected()
+
+ for {
+ cmd, err := line.Prompt("> ")
+ if err != nil {
+ fmt.Printf("%v\n", err)
+ return
+ }
+
+ cmds := reg.FindAllString(cmd, -1)
+ if len(cmds) == 0 {
+ continue
+ } else {
+ line.AppendHistory(cmd)
+
+ args := make([]string, len(cmds[1:]))
+
+ for i := range args {
+ args[i] = strings.Trim(string(cmds[1+i]), "\"'")
+ }
+
+ cmd := strings.ToLower(cmds[0])
+ if cmd == "help" || cmd == "?" {
+ printHelp(cmds)
+ } else if cmd == "exit" || cmd == "quit" {
+ return
+ } else {
+ for _, c := range commands {
+ if c.Name() == cmd {
+ if err := c.Do(args, commandEnv, os.Stderr); err != nil {
+ fmt.Fprintf(os.Stderr, "error: %v\n", err)
+ }
+ }
+ }
+ }
+
+ }
+ }
+}
+
+func printGenericHelp() {
+ msg :=
+ `Type: "help <command>" for help on <command>
+`
+ fmt.Print(msg)
+
+ sort.Slice(commands, func(i, j int) bool {
+ return strings.Compare(commands[i].Name(), commands[j].Name()) < 0
+ })
+ for _, c := range commands {
+ fmt.Printf("\t%s %s \n", c.Name(), c.Help())
+ }
+}
+
+func printHelp(cmds []string) {
+ args := cmds[1:]
+ if len(args) == 0 {
+ printGenericHelp()
+ } else if len(args) > 1 {
+ fmt.Println()
+ } else {
+ cmd := strings.ToLower(args[0])
+
+ sort.Slice(commands, func(i, j int) bool {
+ return strings.Compare(commands[i].Name(), commands[j].Name()) < 0
+ })
+
+ for _, c := range commands {
+ if c.Name() == cmd {
+ fmt.Println()
+ fmt.Printf("\t%s %s \n", c.Name(), c.Help())
+ fmt.Println()
+ }
+ }
+ }
+}
+
+func setCompletionHandler() {
+ line.SetCompleter(func(line string) (c []string) {
+ for _, i := range commands {
+ if strings.HasPrefix(i.Name(), strings.ToLower(line)) {
+ c = append(c, i.Name())
+ }
+ }
+ return
+ })
+}
+
+func loadHisotry() {
+ if f, err := os.Open(historyPath); err == nil {
+ line.ReadHistory(f)
+ f.Close()
+ }
+}
+
+func saveHisotry() {
+ if f, err := os.Create(historyPath); err != nil {
+ fmt.Printf("Error writing history file: %v\n", err)
+ } else {
+ line.WriteHistory(f)
+ f.Close()
+ }
+}