Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Detect whether we are writing to a terminal and conditionally enable color #58

Merged
merged 1 commit into from Nov 1, 2022

Conversation

dburgener
Copy link
Owner

Detect whether we are writing to a terminal and conditionally enable color on error output

I had assumed termcolor did this for us, but according to their documentation, they do not, and recommend using the atty crate for this purpose: https://docs.rs/termcolor/latest/termcolor/#detecting-presence-of-a-terminal

The approach in this commit lets casc determine whether or not to use color, and then error.rs translates that boolean decision into the appropriate termcolor commands. Casc makes its decision in turn based on atty detecting a terminal. This architecture allows for future binaries to make different decisions if needed (eg a --nocolor flag).

Reported-by: Matthew Sheets masheets@linux.microsoft.com

@dburgener dburgener force-pushed the dburgener/color-terminal-detection branch from c4b16c3 to 9fe6aa3 Compare October 18, 2022 18:39
src/bin/casc/main.rs Outdated Show resolved Hide resolved
@dburgener dburgener force-pushed the dburgener/color-terminal-detection branch 2 times, most recently from 21ccf29 to b08c7d2 Compare October 20, 2022 20:40
color on error output

Also include a --color argument

I had assumed termcolor did this for us, but according to their
documentation, they do not, and recommend using the atty crate for this
purpose: https://docs.rs/termcolor/latest/termcolor/#detecting-presence-of-a-terminal

The approach in this commit lets casc determine whether or not to use
color, and then error.rs translates that boolean decision into the
appropriate termcolor commands.  Casc makes its decision in turn based
on atty detecting a terminal.

Users may additionally use a --color=WHEN flag, as common for other
utilities.

Reported-by: Matthew Sheets <masheets@linux.microsoft.com>
@dburgener dburgener force-pushed the dburgener/color-terminal-detection branch from b08c7d2 to 0e291f7 Compare October 20, 2022 20:59
@matt-sheets
Copy link
Collaborator

Just for my own selfish learning are the #[clap & #[derive tags used for documentation like doxygen, or do they do more fancy things?

@dburgener
Copy link
Owner Author

They do fancy things. They are both attribute like macros, which transform into some code which is then compiled.

#[derive()] is a very common macro in rust programming that lets you automatically implement a trait with automatic implementation of its functions. You can read more about it here and here.

As an example, this PR derives the Debug trait, which allows an enum to be printed in a programmer-understandable format in debug output. In order to do that, all members of the struct or enum must also be Debug, and then rust can combine them all together to determine what a reasonable Debug output would be. Of course, rust's decisions may not be the ones the programmer would have made in every case, in which case the programmer would need to implement the trait themselves with an impl {} block to define their own implementation. You can see an example of that here. The default derivation of PartialEq would return true if all fields are equal and false otherwise. In our case, we want to say that two TypeInfos are equal if they share a name, regardless of the other fields. Implementing it ourselves also means that the children don't all need the trait. In this case, we would get a compiler error if we attempted to derive PartialEq, because in attempting to compare the equality of all fields, rust would see that BoundTypeInfo doesn't implement PartialEq, and therefore it doesn't know how to compare two BoundTypeInfos.

The #[clap()] attribute is defined by the clap library, which is a dependency. Unfortunately, their documentation is all on the syntax for version 4 of the library and we're still on version 3, so the docs no longer match what we have here. The clap library is evolving quickly and continues to change syntax aggressively. But in short, they've defined macros to implement the command line parsing functionality based on our attributes and struct defintions. The way that works in clap 4 is detailed in their "Derive Tutorial" at the above link. It's highly similar to clap 3, but has some syntactic differences, including not actually having a "clap" attribute anymore.

Migrating to clap 4 is on my todo list, but isn't urgent.

@dburgener dburgener merged commit aceea69 into main Nov 1, 2022
@dburgener dburgener deleted the dburgener/color-terminal-detection branch November 1, 2022 17:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants