Detect STDOUT isn't a TTY and disable color

This PR disables color output when the STDOUT is not a TTY. This makes
running commands under `watch` or other commands nicer.
This commit is contained in:
Alex Dadgar
2017-08-18 16:05:45 -07:00
parent 47b8c18fb0
commit 2bb5a057ad
7 changed files with 108 additions and 16 deletions

View File

@@ -8,6 +8,7 @@ import (
"strings"
"github.com/hashicorp/nomad/api"
isatty "github.com/mattn/go-isatty"
"github.com/mitchellh/cli"
"github.com/mitchellh/colorstring"
)
@@ -126,7 +127,7 @@ func (m *Meta) Client() (*api.Client, error) {
func (m *Meta) Colorize() *colorstring.Colorize {
return &colorstring.Colorize{
Colors: colorstring.DefaultColors,
Disable: m.noColor,
Disable: m.noColor || !isatty.IsTerminal(os.Stdout.Fd()),
Reset: true,
}
}

View File

@@ -1,5 +1,10 @@
# go-isatty
[![Godoc Reference](https://godoc.org/github.com/mattn/go-isatty?status.svg)](http://godoc.org/github.com/mattn/go-isatty)
[![Build Status](https://travis-ci.org/mattn/go-isatty.svg?branch=master)](https://travis-ci.org/mattn/go-isatty)
[![Coverage Status](https://coveralls.io/repos/github/mattn/go-isatty/badge.svg?branch=master)](https://coveralls.io/github/mattn/go-isatty?branch=master)
[![Go Report Card](https://goreportcard.com/badge/mattn/go-isatty)](https://goreportcard.com/report/mattn/go-isatty)
isatty for golang
## Usage
@@ -16,6 +21,8 @@ import (
func main() {
if isatty.IsTerminal(os.Stdout.Fd()) {
fmt.Println("Is Terminal")
} else if isatty.IsCygwinTerminal(os.Stdout.Fd()) {
fmt.Println("Is Cygwin/MSYS2 Terminal")
} else {
fmt.Println("Is Not Terminal")
}
@@ -28,10 +35,16 @@ func main() {
$ go get github.com/mattn/go-isatty
```
# License
## License
MIT
# Author
## Author
Yasuhiro Matsumoto (a.k.a mattn)
## Thanks
* k-takata: base idea for IsCygwinTerminal
https://github.com/k-takata/go-iscygpty

View File

@@ -1,9 +0,0 @@
// +build appengine
package isatty
// IsTerminal returns true if the file descriptor is terminal which
// is always false on on appengine classic which is a sandboxed PaaS.
func IsTerminal(fd uintptr) bool {
return false
}

View File

@@ -1,4 +1,4 @@
// +build darwin freebsd openbsd netbsd
// +build darwin freebsd openbsd netbsd dragonfly
// +build !appengine
package isatty

10
vendor/github.com/mattn/go-isatty/isatty_others.go generated vendored Normal file
View File

@@ -0,0 +1,10 @@
// +build !windows
// +build !appengine
package isatty
// IsCygwinTerminal() return true if the file descriptor is a cygwin or msys2
// terminal. This is also always false on this environment.
func IsCygwinTerminal(fd uintptr) bool {
return false
}

View File

@@ -4,12 +4,30 @@
package isatty
import (
"strings"
"syscall"
"unicode/utf16"
"unsafe"
)
var kernel32 = syscall.NewLazyDLL("kernel32.dll")
var procGetConsoleMode = kernel32.NewProc("GetConsoleMode")
const (
fileNameInfo uintptr = 2
fileTypePipe = 3
)
var (
kernel32 = syscall.NewLazyDLL("kernel32.dll")
procGetConsoleMode = kernel32.NewProc("GetConsoleMode")
procGetFileInformationByHandleEx = kernel32.NewProc("GetFileInformationByHandleEx")
procGetFileType = kernel32.NewProc("GetFileType")
)
func init() {
// Check if GetFileInformationByHandleEx is available.
if procGetFileInformationByHandleEx.Find() != nil {
procGetFileInformationByHandleEx = nil
}
}
// IsTerminal return true if the file descriptor is terminal.
func IsTerminal(fd uintptr) bool {
@@ -17,3 +35,60 @@ func IsTerminal(fd uintptr) bool {
r, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, fd, uintptr(unsafe.Pointer(&st)), 0)
return r != 0 && e == 0
}
// Check pipe name is used for cygwin/msys2 pty.
// Cygwin/MSYS2 PTY has a name like:
// \{cygwin,msys}-XXXXXXXXXXXXXXXX-ptyN-{from,to}-master
func isCygwinPipeName(name string) bool {
token := strings.Split(name, "-")
if len(token) < 5 {
return false
}
if token[0] != `\msys` && token[0] != `\cygwin` {
return false
}
if token[1] == "" {
return false
}
if !strings.HasPrefix(token[2], "pty") {
return false
}
if token[3] != `from` && token[3] != `to` {
return false
}
if token[4] != "master" {
return false
}
return true
}
// IsCygwinTerminal() return true if the file descriptor is a cygwin or msys2
// terminal.
func IsCygwinTerminal(fd uintptr) bool {
if procGetFileInformationByHandleEx == nil {
return false
}
// Cygwin/msys's pty is a pipe.
ft, _, e := syscall.Syscall(procGetFileType.Addr(), 1, fd, 0, 0)
if ft != fileTypePipe || e != 0 {
return false
}
var buf [2 + syscall.MAX_PATH]uint16
r, _, e := syscall.Syscall6(procGetFileInformationByHandleEx.Addr(),
4, fd, fileNameInfo, uintptr(unsafe.Pointer(&buf)),
uintptr(len(buf)*2), 0, 0)
if r == 0 || e != 0 {
return false
}
l := *(*uint32)(unsafe.Pointer(&buf))
return isCygwinPipeName(string(utf16.Decode(buf[2 : 2+l/2])))
}

4
vendor/vendor.json vendored
View File

@@ -980,8 +980,10 @@
"revisionTime": "2016-05-04T02:26:26Z"
},
{
"checksumSHA1": "trzmsZQDCc13zk/6qANox7Z/KCg=",
"path": "github.com/mattn/go-isatty",
"revision": "56b76bdf51f7708750eac80fa38b952bb9f32639"
"revision": "fc9e8d8ef48496124e79ae0df75490096eccf6fe",
"revisionTime": "2017-03-22T23:44:13Z"
},
{
"checksumSHA1": "ajImwVZHzsI+aNwsgzCSFSbmJqs=",