func main() { flag.Parse() logSetup() // register CLI handlers for i := range cliHandlers { err := minicli.Register(&cliHandlers[i]) if err != nil { log.Fatal("invalid handler, `%v` -- %v", cliHandlers[i].HelpShort, err) } } var err error hostname, err = os.Hostname() if err != nil { log.Fatal("unable to get hostname: %v", hostname) } rond, err = ron.NewServer(*f_port, *f_path) if err != nil { log.Fatal("unable to create server: %v", err) } for { line, err := goreadline.Readline("rond$ ", true) if err != nil { return } command := string(line) log.Debug("got from stdin: `%s`", line) cmd, err := minicli.Compile(command) if err != nil { log.Error("%v", err) continue } // No command was returned, must have been a blank line or a comment // line. Either way, don't try to run a nil command. if cmd == nil { continue } for resp := range minicli.ProcessCommand(cmd) { minipager.DefaultPager.Page(resp.String()) errs := resp.Error() if errs != "" { fmt.Fprintln(os.Stderr, errs) } } } }
func (_ defaultPager) Page(output string) { if output == "" { return } size := termSize() if size == nil { fmt.Println(output) return } log.Debug("term height: %d", size.Row) prompt := "-- press [ENTER] to show more, EOF to discard --" scanner := bufio.NewScanner(strings.NewReader(output)) outer: for { for i := uint16(0); i < size.Row-1; i++ { if scanner.Scan() { fmt.Println(scanner.Text()) // Println will add back the final '\n' } else { break outer // finished consuming from scanner } } _, err := goreadline.Readline(prompt, false) if err != nil { fmt.Println() break outer // EOF } } if err := scanner.Err(); err != nil { log.Error("problem paging: %s", err) } }
// local command line interface, wrapping readline func cliLocal() { goreadline.FilenameCompleter = iomCompleter sig := make(chan os.Signal, 1) signal.Notify(sig, os.Interrupt) go func() { for range sig { goreadline.Signal() } }() defer signal.Stop(sig) for { namespace := GetNamespaceName() prompt := "minimega$ " if namespace != "" { prompt = fmt.Sprintf("minimega[%v]$ ", namespace) } line, err := goreadline.Readline(prompt, true) if err != nil { return } command := string(line) log.Debug("got from stdin: `%v`", command) cmd, err := minicli.Compile(command) if err != nil { log.Error("%v", err) //fmt.Printf("closest match: TODO\n") continue } // No command was returned, must have been a blank line or a comment // line. Either way, don't try to run a nil command. if cmd == nil { continue } // HAX: Don't record the read command if hasCommand(cmd, "read") { cmd.SetRecord(false) } // The namespace changed between when we prompted the user (and could // still change before we actually run the command). if namespace != GetNamespaceName() { // TODO: should we abort the command? log.Warn("namespace changed between prompt and execution") } for resp := range RunCommands(cmd) { // print the responses minipager.DefaultPager.Page(resp.String()) errs := resp.Error() if errs != "" { fmt.Fprintln(os.Stderr, errs) } } } }
// Attach creates a CLI interface to the dialed minimega instance func (mm *Conn) Attach() { // set up signal handling sig := make(chan os.Signal, 1) signal.Notify(sig, os.Interrupt, syscall.SIGTERM) go func() { for s := range sig { if s == os.Interrupt { goreadline.Signal() } else { log.Debug("caught term signal, disconnecting") goreadline.Rlcleanup() os.Exit(0) } } }() defer signal.Stop(sig) // start our own rlwrap fmt.Println("CAUTION: calling 'quit' will cause the minimega daemon to exit") fmt.Println("use 'disconnect' or ^d to exit just the minimega command line") fmt.Println() defer goreadline.Rlcleanup() var exitNext bool for { prompt := fmt.Sprintf("minimega:%v$ ", mm.url) line, err := goreadline.Readline(prompt, true) if err != nil { return } command := string(line) log.Debug("got from stdin: `%s`", line) // HAX: Shortcut some commands without using minicli if command == "disconnect" { log.Debugln("disconnecting") return } else if command == "quit" { if !exitNext { fmt.Println("CAUTION: calling 'quit' will cause the minimega daemon to exit") fmt.Println("If you really want to stop the minimega daemon, enter 'quit' again") exitNext = true continue } } exitNext = false cmd, err := minicli.Compile(command) if err != nil { log.Error("%v", err) //fmt.Println("closest match: TODO") continue } // No command was returned, must have been a blank line or a comment // line. Either way, don't try to run a nil command. if cmd == nil { continue } mm.RunAndPrint(cmd, true) if command == "quit" { return } } }