Class: RepoTender::UI::Mode

Inherits:
Dry::Struct
  • Object
show all
Defined in:
lib/repo_tender/ui/mode.rb

Overview

Resolved output mode — immutable dry-struct constructed once per command invocation from (flags, env, out.tty?) using precedence: flag > env > autodetect.

Frozen contract (PRD §3.1):

format:  :pretty | :plain | :json
color:   true | false
animate: true | false  (always false in Slice A; Slice B gates on this)
quiet:   true | false

Color precedence: –no-color (flag) > CLICOLOR_FORCE (env-force) >

NO_COLOR/TERM=dumb/non-:pretty/non-TTY (env+autodetect).

Constant Summary collapse

FORMATS =
%i[pretty plain json].freeze

Class Method Summary collapse

Class Method Details

.resolve(flags:, env:, out:) ⇒ Object

Parameters:

  • flags (Hash)

    CLI flags: :plain, :json, :no_color, :quiet (truthy = set)

  • env (Hash)

    environment hash (use CLI.env for the injectable test seam)

  • out (IO)

    the output stream; tested with out.tty?



33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/repo_tender/ui/mode.rb', line 33

def self.resolve(flags:, env:, out:)
  json = !!flags[:json]
  plain = !!flags[:plain]
  no_color = !!flags[:no_color]
  quiet = !!flags[:quiet]

  format = if json
    :json
  elsif plain || !out.tty?
    :plain
  else
    :pretty
  end

  no_color_env = env["NO_COLOR"] && !env["NO_COLOR"].empty?
  clicolor_force = env["CLICOLOR_FORCE"] && !env["CLICOLOR_FORCE"].empty?
  term_dumb = env["TERM"] == "dumb"

  color = if no_color
    false
  elsif clicolor_force
    true
  elsif no_color_env || term_dumb || format != :pretty || !out.tty?
    false
  else
    true
  end

  ci = env["CI"] && !env["CI"].empty?
  animate = format == :pretty && out.tty? && !quiet && !ci

  new(color: color, animate: animate, quiet: quiet, format: format)
end