go-isatty
go-isatty copied to clipboard
Allow to check a `io.Writer` instead of raw file descriptor
The lib allows checking TTY versus a raw file descriptor. It would be convenient to allow checking of a given io.Writer
instead.
Related https://github.com/mattn/go-colorable/issues/65
Also: io.Reader
.
tty should always be checked with Writer.
Why can't pass raw file?
Why can't pass raw file?
When you can pass a io.Writer
, you can also pass any type that implements it, file as well.
You can do type assertion before pass to the function like:
isatty.IsTerminal(w.(*os.File).Fd())
@mattn wrote:
tty should always be checked with Writer.
I disagree. I usually check if os.Stdin
is a tty in programs that optionally accepts data on stdin. This allows to skip stdin or to show usage when the user didn't redirect stdin.
The time that I had a look at this package I also thought: why not an io.Writer?
But after that initial thought, I realized that the current API is very appropriate because:
- checking for tty and applying wrappers to handle is something that must be done early in the program, usually in the
main
package, where you have access to rawos
handles. The current API works fine for that use case. High level libraries (such as loggers) must instead work on abstractions such asio.Writer
and it should not be their responsability to do dirty stuff like applying wrappers to OS handles. - the fact that you need to have access to the raw file descriptors to use the functions of
go-isatty
IS a feature as it blocks bad uses ofgo-isatty
deeply in libraries. It forces users of the API to design the program in a way and that is a good thing because calls togo-isatty
are costly because of syscalls. - adding a wrapper to allow easy access to
io.Writer
/io.Reader
would just make it easy to usego-isatty
incorrectly (for example on every call to a log method of a logger object) and that would be just bad for the whole Go ecosystem. - the proposed wrappers for
io.Writer
/io.Reader
can easily be written outside ofgo-isatty
. Making them available in thego-isatty
module brings no benefits compared to making them available is a separate package, but brings the drawback of 3.
Thanks for your comments. I had the same issue as @cardil and was going to ask how to implement this.
Using isatty.IsTerminal(w.(*os.File).Fd())
is insane 😁 but it totally works 😮
And that's more than enough for me. My use case is simple: I just wish to check if I'm writing logs to a TTY or to a file, and use coloured output if it's a TTY. Many packages already do that; some don't, and so I have to check if the output is a TTY before using some of the features — but as @dolmen commented, this happens very early in main()
and is just requested once.