예제 #1
0
// IsTerminal determines if this process is attached to a TTY.
func IsTerminal() bool {
	// Windows is always a terminal
	if runtime.GOOS == "windows" {
		return true
	}

	// Same implementation as readline but with our custom fds
	return readline.IsTerminal(int(wrappedstreams.Stdin().Fd())) &&
		(readline.IsTerminal(int(wrappedstreams.Stdout().Fd())) ||
			readline.IsTerminal(int(wrappedstreams.Stderr().Fd())))
}
예제 #2
0
파일: console.go 프로젝트: BrianNewsom/harp
func startConsole(servers []*Server) {
	rl, err := readline.New("> ")
	if err != nil {
		panic(err)
	}
	defer rl.Close()

	type output struct {
		serv   *Server
		output string
	}

	isTerminal := readline.IsTerminal(int(os.Stdin.Fd()))
	for {
		var line string
		var err error
		if isTerminal {
			line, err = rl.Readline()
		} else {
			lineb, er := ioutil.ReadAll(os.Stdin)
			line, err = string(lineb), er
		}
		if err != nil { // io.EOF
			break
		}

		outputc := make(chan output)
		var mutex sync.Mutex
		var count int
		var wg sync.WaitGroup
		wg.Add(1)
		go func() {
			for {
				mutex.Lock()
				output := <-outputc
				prompt := output.serv.prompt()
				if isTerminal {
					prompt += " " + line
				}
				if count > 0 && strings.TrimSpace(output.output) != "" {
					prompt = "\n" + prompt
				}
				fmt.Println(prompt)
				if strings.TrimSpace(output.output) != "" {
					fmt.Printf(output.output)
				}
				if count++; count >= len(servers) {
					break
				}
				mutex.Unlock()
			}
			wg.Done()
		}()

		for _, serv := range servers {
			wg.Add(1)
			go func(serv *Server) {
				outputc <- output{serv: serv, output: serv.exec(line)}
				wg.Done()
			}(serv)
		}
		wg.Wait()

		if !isTerminal {
			return
		}
	}
}