Skip to content

Honor NO_COLOR environment variable in MTP terminal output #8825

Description

@Evangelink

Summary

Honor the NO_COLOR environment variable in the Microsoft.Testing.Platform terminal output. Today MTP only suppresses ANSI escape sequences via --no-ansi, --ansi off, or the LLMEnvironmentDetector (see src/Platform/Microsoft.Testing.Platform/OutputDevice/TerminalOutputDevice.cs:147-184); it does not look at NO_COLOR at all.

Motivation

  • NO_COLOR is the de-facto cross-tool convention for "I am piped/redirected/aren't a fan of color, please don't emit ANSI." Tools that honor it include git, ripgrep, bat, gh, cargo, the .NET SDK itself, modern Node.js CLIs, and most coding-agent runtimes (Claude Code, Cursor, Codex, Aider).
  • Coding agents and CI systems commonly set NO_COLOR=1 rather than the MTP-specific --no-ansi flag. Today they get ANSI noise in failure output, which costs tokens and breaks log scraping.
  • The fix is small and matches existing precedence: --ansi on|off|auto still wins, then --no-ansi, then NO_COLOR, then LLMEnvironmentDetector, then CI detection.

Proposed behavior

In TerminalOutputDevice.cs (resolution of AnsiMode):

explicit --ansi on             -> AnsiMode.ForceAnsi
explicit --ansi off             -> AnsiMode.NoAnsi
--no-ansi (no --ansi override) -> AnsiMode.NoAnsi
NO_COLOR env var is non-empty   -> AnsiMode.NoAnsi  (NEW)
LLMEnvironmentDetector matches  -> AnsiMode.NoAnsi
in CI                           -> AnsiMode.SimpleAnsi
default                         -> AnsiMode.AnsiIfPossible

Per the NO_COLOR spec: "All command-line software which outputs text with ANSI color added should check for the presence of a NO_COLOR environment variable that, when present (regardless of its value), prevents the addition of ANSI color."

We treat any non-empty NO_COLOR value as enabling the behavior, matching the spec.

Notes

  • NO_COLOR only affects colors, not progress. Progress is independently controlled by --no-progress and the existing CI/LLM path that already forces AnsiMode.NoAnsi which in turn disables progress. We could choose to also disable progress when NO_COLOR is set, but that's a separate decision — open question in the umbrella.
  • Should use the injected IEnvironment.GetEnvironmentVariable("NO_COLOR") (not the static Environment.GetEnvironmentVariable) so the behavior is unit-testable.

Acceptance criteria

  • Setting NO_COLOR (any non-empty value) to a process running MTP causes terminal output to be plain text (no ANSI escapes).
  • --ansi on overrides NO_COLOR (forces ANSI on).
  • --ansi off, --no-ansi, and LLM-mode detection continue to work unchanged.
  • Unit test covers each precedence branch.
  • No XLF / help / info changes needed (env vars aren't surfaced in --help).

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    area/mtpMicrosoft.Testing.Platform core library.area/terminal-reporterConsole / terminal test reporter.

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions