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
mainpackage, where you have access to rawoshandles. The current API works fine for that use case. High level libraries (such as loggers) must instead work on abstractions such asio.Writerand 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-isattyIS a feature as it blocks bad uses ofgo-isattydeeply in libraries. It forces users of the API to design the program in a way and that is a good thing because calls togo-isattyare costly because of syscalls. - adding a wrapper to allow easy access to
io.Writer/io.Readerwould just make it easy to usego-isattyincorrectly (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.Readercan easily be written outside ofgo-isatty. Making them available in thego-isattymodule 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.