Module: Moult::Formatters::FlagsTable

Defined in:
lib/moult/formatters/flags_table.rb

Overview

Human-readable table of OpenFeature flag references. Renders from the same Moult::FlagsReport as the JSON formatter so the two cannot disagree. Sorting already happened in Moult::Flags; this layer owns column formatting only.

The heading is deliberate. Without a provider snapshot these are flag usage facts (staleness needs a provider). With one, they are confidence-graded staleness candidates — never certainties; the STATUS/CONF columns and the heading say so.

Constant Summary collapse

MAX_LOCATIONS =
3
NO_DEFAULTS =
"-"
NO_STALENESS =
"-"
RIGHT_ALIGNED =

REFS (usage view)

[2].freeze
RIGHT_ALIGNED_GRADED =

CONF, REFS (staleness view)

[3, 4].freeze

Class Method Summary collapse

Class Method Details

.confidence(finding) ⇒ Object



61
62
63
# File 'lib/moult/formatters/flags_table.rb', line 61

def confidence(finding)
  finding.staleness ? format("%.2f", finding.staleness.confidence) : NO_STALENESS
end

.defaults(values) ⇒ Object



65
66
67
# File 'lib/moult/formatters/flags_table.rb', line 65

def defaults(values)
  values.empty? ? NO_DEFAULTS : values.join(", ")
end

.heading(summary, graded) ⇒ Object



35
36
37
38
39
40
41
42
43
44
# File 'lib/moult/formatters/flags_table.rb', line 35

def heading(summary, graded)
  dynamic = summary[:dynamic_references]
  tail = dynamic.positive? ? ", #{dynamic} dynamic (uncatalogued)" : ""
  lead = if graded
    "OpenFeature flag staleness candidates (confidence-graded, never certain): "
  else
    "OpenFeature flag references (usage facts, not staleness — that needs a live provider): "
  end
  "#{lead}#{summary[:flags]} flags, #{summary[:references]} references#{tail}"
end

.locations(occurrences) ⇒ Object



69
70
71
72
73
# File 'lib/moult/formatters/flags_table.rb', line 69

def locations(occurrences)
  shown = occurrences.first(MAX_LOCATIONS).map { |o| "#{o.path}:#{o.line}" }
  extra = occurrences.size - shown.size
  extra.positive? ? "#{shown.join(", ")} (+#{extra} more)" : shown.join(", ")
end

.render(report) ⇒ String

Parameters:

Returns:

  • (String)


24
25
26
27
28
29
30
31
32
33
# File 'lib/moult/formatters/flags_table.rb', line 24

def render(report)
  findings = report.findings
  return "No OpenFeature flag references found." if findings.empty?

  graded = !report.provider_source.nil?
  headers = graded ? %w[KEY TYPE STATUS CONF REFS DEFAULTS LOCATIONS] : %w[KEY TYPE REFS DEFAULTS LOCATIONS]
  right = graded ? RIGHT_ALIGNED_GRADED : RIGHT_ALIGNED
  rows = findings.map { |f| row(f, graded) }
  [heading(report.summary, graded), "", TextTable.render(headers, rows, right_aligned: right)].join("\n")
end

.row(finding, graded) ⇒ Object



46
47
48
49
50
51
52
53
54
55
# File 'lib/moult/formatters/flags_table.rb', line 46

def row(finding, graded)
  cells = [finding.flag_key, finding.value_type]
  cells.push(status(finding), confidence(finding)) if graded
  cells.push(
    finding.reference_count.to_s,
    defaults(finding.default_values),
    locations(finding.occurrences)
  )
  cells
end

.status(finding) ⇒ Object



57
58
59
# File 'lib/moult/formatters/flags_table.rb', line 57

def status(finding)
  finding.staleness&.status || NO_STALENESS
end