Repository navigation
feat(cli): color help headers Voltage orange and honor FORCE_COLOR - #105
Conversation
tee8z
left a comment
There was a problem hiding this comment.
Approved 80f0dec against feat/cli-look-05-tables (#101 1ff530f). #101 has changes requested, and the stack needs a rebase onto master, which will dismiss this approval. I will compare the trees then.
The precedence, with the most specific first, is --color/--no-color, then a non-empty NO_COLOR, then FORCE_COLOR, then CLICOLOR_FORCE, then CLICOLOR, then terminal detection. That matches anstream's choice(), and an explicit --color auto still defers to the environment. Both the startup pre-scan and GlobalFlags::color() apply it. JSON stays plain, and the spinner and timeline still require stderr to be a terminal, so FORCE_COLOR cannot animate CI logs. Subcommand help gets the depth-based styles through app_ext.
Nonblocking:
- The description says the test harness now ignores the developer's color settings, but
typo_errors_are_human_by_default_and_json_when_requested(tests/cli_integration.rs:58) and the runtime-error prefix test start the binary with a bareCommand::newand do not removeFORCE_COLOR. A shell that exportsFORCE_COLOR=1, as many Node and CI setups do, colorserror:, and bothstarts_with("error:")asserts fail. Routing them through the helper that clears the color variables fixes it. - In
docs/reference/environment.md:- The
CLICOLORrow omits thatFORCE_COLOR=1beatsCLICOLOR=0. - The
CLICOLOR_FORCErow says "any non-zero value", but anstyle-query treats any non-empty value,0included, as on. - The
COLORTERMrow omits thatWT_SESSIONalso selects 24-bit color.
- The
Validation on this head, in nix develop: cargo fmt --check, cargo clippy --locked --all-targets -- -D warnings, cargo machete --with-metadata, cargo test --locked (155 unit, 126 integration) and python3 scripts/check-coverage.py passed. CRAP: 710 measured functions, none at or above 20, highest endpoint at 18.00; 181 functions were unmeasured. CI is green.
80f0dec to
32e5f2e
Compare
Help headers and usage use Voltage orange (#FF5000): 24-bit with COLORTERM=truecolor or FORCE_COLOR=3, color 202 on a 256-color terminal or with FORCE_COLOR=2, and bold elsewhere. Every other style stays on the 16 basic colors. FORCE_COLOR=0 or false turns color off and any other value turns it on when redirected; --color and NO_COLOR still win, and it wins over CLICOLOR_FORCE.
32e5f2e to
73ba6b3
Compare
tee8z
left a comment
There was a problem hiding this comment.
Re-approved 73ba6b3, a rebase onto #101 2ac8b2c. The patch matches 80f0dec, which I approved. Validation on this head, in nix develop: cargo fmt --check, cargo clippy --locked --all-targets -- -D warnings, cargo machete --with-metadata, cargo test --locked (169 unit, 133 integration) and python3 scripts/check-coverage.py passed. CRAP: 743 measured functions, none at or above 20, highest wait_for_payment at 17.05. CRAP passed on its second run, after the pseudo-terminal login tests timed out on the first, the flakiness that #104 addresses. CI is green.
Stack position: 6 of 13 in the look-and-feel stack. Base:
feat/cli-look-05-tables(#101).Problem
Help headers used cargo's green, so nothing tied
voltage --helpto Voltage. The CLI ignoredFORCE_COLOR, which many CI systems and tools use to ask for color.Behavior
Brand color. Help headers and the usage line are Voltage orange,
#FF5000(--orangein the web app's theme):COLORTERM=truecoloror24bit, Windows Terminal, orFORCE_COLOR=3#FF5000, boldTERMcontains256color, orFORCE_COLOR=2Every other style stays on the 16 basic colors, so the terminal theme keeps it legible. The brand color appears only on headers and usage; it never marks a status.
FORCE_COLOR. Precedence:--color/--no-color>NO_COLOR>FORCE_COLOR>CLICOLOR_FORCE>CLICOLOR> terminal detection.0orfalseturns color off, even overCLICOLOR_FORCE=1.JSON is never colored, as before.
Design notes
ColorChoice::with_environmentfoldsFORCE_COLORinto anAutochoice before clap and the writers see it. There's still no global: startup's pre-scan andGlobalFlags::colorboth apply it. WhenNO_COLORis set, the choice staysAuto, and anstream then turns color off.style::Depth::detectreads the environment once per help render.style::help(depth)replaces theHELPconstant;cli::command()keeps basic styles for completions and tests, andInvocation::from_envapplies the detected depth.style::brand(depth)is the one non-4-bit style, for the wordmark and card titles that PRs 7–8 add.Try it on staging
Setup: Try a pull request on staging (added by #97). Nothing here talks to the API.
Expect:
Usage:and the section headers in orange in the first three; the second is exactly#FF5000in a 24-bit terminal such as iTerm2. In the fourth, they are bold and white, and flags are still cyan.Expect: escape codes (
^[[) in the piped help withFORCE_COLOR=1. No color at all in the other three.FORCE_COLOR=1 voltage wallets list --account me --json | head -c 80Expect: plain JSON, never colored.
Validation
cargo fmt --check,cargo clippy --locked --all-targets -- -D warnings,cargo machete --with-metadata,cargo test --locked(155 unit and 126 integration tests), andpython3 scripts/check-coverage.pyall pass.FORCE_COLORtable: 1, 3, true, 0, false, empty,NO_COLORset and empty, and both flags. They also cover depth detection order (FORCE_COLOR1, 2, and 3,COLORTERM, andTERM), and the exact brand escape sequences at each depth.FORCE_COLOR=1,FORCE_COLOR=0withCLICOLOR_FORCE=1,FORCE_COLOR=1withNO_COLOR=1, and--color neverwithFORCE_COLOR=1.FORCE_COLOR=3.Usage:sequences, andFORCE_COLOR=3colors redirected help.FORCE_COLORandCOLORTERM, so a developer's settings cannot change compared bytes.src/cli.rsendpoint, untouched).Docs
docs/reference/environment.md(FORCE_COLOR,COLORTERM),docs/reference/output.md, andCHANGELOG.md.