Class: Dry::CLI::Help::Configuration

Inherits:
Object
  • Object
show all
Defined in:
lib/dry/cli/help/configuration.rb,
sig/dry/cli/help.rbs

Overview

Every help setting, made once for the whole process, two ways:

Dry::CLI::Help.configure do
title "MyCLI"            # as a DSL
end

Dry::CLI::Help.configure do |config|
config.title = "MyCLI"   # on the yielded object
end

Every element's look is declared in one #styles block. Anything not set reads from DEFAULTS, HEADINGS or STYLES.

Defined Under Namespace

Classes: StyleSheet

Constant Summary collapse

SECTIONS =

Every section, in default order.

Returns:

  • (Array[Symbol])
%i[
  banner usage description commands subcommands arguments options examples epilogue
].freeze
HEADINGS =

Default heading text. banner and epilogue print no heading.

Returns:

  • (Hash[Symbol, String])
{
  usage: "Usage",
  description: "Description",
  commands: "Commands",
  subcommands: "Subcommands",
  arguments: "Arguments",
  options: "Options",
  examples: "Examples"
}.freeze
STYLES =

Default styles of every element a screen paints.

Returns:

  • (Hash[Symbol, Array[Symbol]])
{
  title: %i[bold],
  heading: %i[bold yellow],
  usage: %i[green],
  command: %i[green],
  argument: %i[cyan],
  option: %i[cyan],
  example: %i[green],
  example_comment: %i[bold black]
}.freeze
HEADING_CASES =

How headings can be cased; each name is written the way it cases. :Capitalize raises only the first letter.

%i[UPPERCASE Capitalize lowercase as_is].freeze
DEFAULT_HEADING_CASE =
:UPPERCASE
COMMAND_ORDERS =
%i[registration alphabetical].freeze
MIN_WIDTH =

Narrowest column text wraps at, however small the terminal.

Returns:

  • (Integer)
20
BOOLEAN =
->(value) { [true, false].include?(value) }
TEXT =
->(value) { value.nil? || value.is_a?(String) }
SCALARS =

Single-value settings and what each accepts.

{
  title: TEXT,
  description: TEXT,
  epilogue: TEXT,
  color: ->(value) { Colors::SETTINGS.include?(value) },
  wrap: BOOLEAN,
  width: ->(value) { value == :terminal || (value.is_a?(Integer) && value.positive?) },
  margin: ->(value) { value.is_a?(Integer) && !value.negative? },
  exit_code_without_arguments: ->(value) { value.is_a?(Integer) && value.between?(0, 255) },
  banner_on_subcommands: BOOLEAN,
  command_order: ->(value) { COMMAND_ORDERS.include?(value) }
}.freeze
DEFAULTS =

Returns:

  • (Hash[Symbol, untyped])
{
  title: nil,
  description: nil,
  epilogue: nil,
  color: :auto,
  wrap: true,
  width: :terminal,
  margin: 0,
  exit_code_without_arguments: 1,
  banner_on_subcommands: false,
  command_order: :registration
}.freeze

Instance Method Summary collapse

Constructor Details

#initialize(values = {}) ⇒ Configuration

Returns a new instance of Configuration.

Parameters:

  • values (Hash) (defaults to: {}) —

    settings made on this instance only



91
92
93
# File 'lib/dry/cli/help/configuration.rb', line 91

def initialize(values = {})
  @values = values
end

Instance Method Details

Parameters:

  • value (Boolean)

Returns:

  • (Boolean)


58
# File 'sig/dry/cli/help.rbs', line 58

def banner_on_subcommands: (?bool value) -> bool

This method returns an undefined value.

Parameters:

  • (Boolean)


59
# File 'sig/dry/cli/help.rbs', line 59

def banner_on_subcommands=: (bool) -> void

#color ⇒ bool, Symbol

Parameters:

  • value (?(bool | Symbol))

Returns:

  • (bool, Symbol)


48
# File 'sig/dry/cli/help.rbs', line 48

def color: (?(bool | Symbol) value) -> (bool | Symbol)

#color= ⇒ void

This method returns an undefined value.

Parameters:

  • (bool, Symbol)


49
# File 'sig/dry/cli/help.rbs', line 49

def color=: (bool | Symbol) -> void

#command_order ⇒ Symbol

Parameters:

  • value (Symbol)

Returns:

  • (Symbol)


62
# File 'sig/dry/cli/help.rbs', line 62

def command_order: (?Symbol value) -> Symbol

#command_order= ⇒ void

This method returns an undefined value.

Parameters:

  • (Symbol)


63
# File 'sig/dry/cli/help.rbs', line 63

def command_order=: (Symbol) -> void

#description ⇒ String?

Parameters:

  • value (String, nil)

Returns:

  • (String, nil)


44
# File 'sig/dry/cli/help.rbs', line 44

def description: (?String? value) -> String?

#description= ⇒ void

This method returns an undefined value.

Parameters:

  • (String, nil)


45
# File 'sig/dry/cli/help.rbs', line 45

def description=: (String?) -> void

#epilogue ⇒ String?

Parameters:

  • value (String, nil)

Returns:

  • (String, nil)


46
# File 'sig/dry/cli/help.rbs', line 46

def epilogue: (?String? value) -> String?

#epilogue= ⇒ void

This method returns an undefined value.

Parameters:

  • (String, nil)


47
# File 'sig/dry/cli/help.rbs', line 47

def epilogue=: (String?) -> void

#exit_code_without_arguments ⇒ Integer

Parameters:

  • value (Integer)

Returns:

  • (Integer)


56
# File 'sig/dry/cli/help.rbs', line 56

def exit_code_without_arguments: (?Integer value) -> Integer

#exit_code_without_arguments= ⇒ void

This method returns an undefined value.

Parameters:

  • (Integer)


57
# File 'sig/dry/cli/help.rbs', line 57

def exit_code_without_arguments=: (Integer) -> void

#group(name, *commands) ⇒ Array<Array(String, Array<String>)>

List commands under a heading of their own, in the order given. Groups print in the order they are declared, after ungrouped commands.

Parameters:

  • name (String) —

    the heading

  • commands (Array<String>) —

    command paths, such as "compile" or "db migrate"

Returns:

  • (Array<Array(String, Array<String>)>) —

    every group

Raises:

  • (ArgumentError)


163
164
165
166
167
168
169
# File 'lib/dry/cli/help/configuration.rb', line 163

def group(name, *commands)
  commands = commands.flatten
  raise ArgumentError, "a group name must be a String" unless name.is_a?(String)
  raise ArgumentError, "group #{name.inspect} lists no commands" if commands.empty?

  @values[:groups] = groups + [[name, commands.map(&:to_s).freeze].freeze]
end

#groups ⇒ Array<Array(String, Array<String>)>

Returns:

  • (Array<Array(String, Array<String>)>)


172
173
174
# File 'lib/dry/cli/help/configuration.rb', line 172

def groups
  @values.fetch(:groups, [])
end

#heading(section, text) ⇒ String

Replace the text of one section's heading.

Parameters:

  • section (Symbol) —

    a key of HEADINGS

  • text (String)

Returns:

  • (String)

Raises:

  • (ArgumentError)


114
115
116
117
118
119
120
# File 'lib/dry/cli/help/configuration.rb', line 114

def heading(section, text)
  raise ArgumentError, "#{section.inspect} has no heading" unless HEADINGS.key?(section)
  raise ArgumentError, "a heading must be a String" unless text.is_a?(String)

  @values[:headings] = @values.fetch(:headings, {}).merge(section => text)
  text
end

#heading_case ⇒ Symbol

How every heading is cased, set by heading ..., case: in #styles.

Parameters:

  • value (Symbol)

Returns:



153
154
155
# File 'lib/dry/cli/help/configuration.rb', line 153

def heading_case
  @values.fetch(:heading_case, DEFAULT_HEADING_CASE)
end

#heading_case= ⇒ void

This method returns an undefined value.

Parameters:

  • (Symbol)


61
# File 'sig/dry/cli/help.rbs', line 61

def heading_case=: (Symbol) -> void

#headings ⇒ Hash{Symbol => String}

Returns every heading's text, before casing.

Returns:

  • (Hash{Symbol => String}) —

    every heading's text, before casing



123
124
125
# File 'lib/dry/cli/help/configuration.rb', line 123

def headings
  HEADINGS.merge(@values.fetch(:headings, {}))
end

#hidden ⇒ Array<Symbol>

Returns:

  • (Array<Symbol>)


201
202
203
# File 'lib/dry/cli/help/configuration.rb', line 201

def hidden
  @values.fetch(:hidden, [])
end

#hide(*names) ⇒ Array<Symbol>

Hide sections without restating the order.

Parameters:

  • names (Array<Symbol>) —

    names from SECTIONS

Returns:

  • (Array<Symbol>) —

    every hidden section



196
197
198
# File 'lib/dry/cli/help/configuration.rb', line 196

def hide(*names)
  @values[:hidden] = hidden | validate_sections(names.flatten)
end

#margin ⇒ Integer

Parameters:

  • value (Integer)

Returns:

  • (Integer)


54
# File 'sig/dry/cli/help.rbs', line 54

def margin: (?Integer value) -> Integer

#margin= ⇒ void

This method returns an undefined value.

Parameters:

  • (Integer)


55
# File 'sig/dry/cli/help.rbs', line 55

def margin=: (Integer) -> void

#merge ⇒ Configuration

Parameters:

Returns:



77
# File 'sig/dry/cli/help.rbs', line 77

def merge: (Configuration other) -> Configuration

#sections(*names) ⇒ Array<Symbol>

With names, set the order sections print in; a section left out is hidden. Without, read the order.

Parameters:

  • names (Array<Symbol>) —

    names from SECTIONS

Returns:

  • (Array<Symbol>)


181
182
183
184
185
# File 'lib/dry/cli/help/configuration.rb', line 181

def sections(*names)
  return @values.fetch(:sections, SECTIONS) if names.empty?

  self.sections = names
end

#sections=(names) ⇒ void

This method returns an undefined value.

Parameters:

  • names (Array<Symbol>)
  • (Array[Symbol])


188
189
190
# File 'lib/dry/cli/help/configuration.rb', line 188

def sections=(names)
  @values[:sections] = validate_sections(names.flatten)
end

#style ⇒ Array[Symbol]

Parameters:

  • element (Symbol)
  • names (Symbol)

Returns:

  • (Array[Symbol])


67
# File 'sig/dry/cli/help.rbs', line 67

def style: (Symbol element, *Symbol names) -> Array[Symbol]

#styles(&block) ⇒ Hash{Symbol => Array<Symbol>}

Declare how elements look, all in one place. Each line names an element from STYLES and its styles from Dry::CLI::Help::Colors::STYLES; no styles prints it plain. Elements left out keep their defaults. heading also takes case:, one of HEADING_CASES. A block taking an argument receives the declarations instead.

Examples:

styles do
  heading :bold, :blue, case: :Capitalize
  example_comment              # plain
end

Returns:

  • (Hash{Symbol => Array<Symbol>}) —

    every element's styles



140
141
142
143
144
145
146
147
148
# File 'lib/dry/cli/help/configuration.rb', line 140

def styles(&block)
  if block
    sheet = StyleSheet.new
    block.arity == 1 ? yield(sheet) : sheet.instance_eval(&block)
    @values[:styles] = @values.fetch(:styles, {}).merge(sheet.styles)
    @values[:heading_case] = sheet.heading_case if sheet.heading_case
  end
  STYLES.merge(@values.fetch(:styles, {}))
end

#title ⇒ String?

Parameters:

  • value (String, nil)

Returns:

  • (String, nil)


42
# File 'sig/dry/cli/help.rbs', line 42

def title: (?String? value) -> String?

#title= ⇒ void

This method returns an undefined value.

Parameters:

  • (String, nil)


43
# File 'sig/dry/cli/help.rbs', line 43

def title=: (String?) -> void

#visible_sections ⇒ Array<Symbol>

Returns the sections that print, in order.

Returns:

  • (Array<Symbol>) —

    the sections that print, in order



206
207
208
# File 'lib/dry/cli/help/configuration.rb', line 206

def visible_sections
  sections - hidden
end

#width ⇒ Integer, Symbol

Parameters:

  • value (?(Integer | Symbol))

Returns:

  • (Integer, Symbol)


52
# File 'sig/dry/cli/help.rbs', line 52

def width: (?(Integer | Symbol) value) -> (Integer | Symbol)

#width= ⇒ void

This method returns an undefined value.

Parameters:

  • (Integer, Symbol)


53
# File 'sig/dry/cli/help.rbs', line 53

def width=: (Integer | Symbol) -> void

#wrap ⇒ Boolean

Parameters:

  • value (Boolean)

Returns:

  • (Boolean)


50
# File 'sig/dry/cli/help.rbs', line 50

def wrap: (?bool value) -> bool

#wrap= ⇒ void

This method returns an undefined value.

Parameters:

  • (Boolean)


51
# File 'sig/dry/cli/help.rbs', line 51

def wrap=: (bool) -> void

#wrap_width(terminal_width) ⇒ Integer?

The column text wraps at, or nil when wrapping is off.

Parameters:

  • terminal_width (Integer)

Returns:

  • (Integer, nil)


214
215
216
217
218
219
# File 'lib/dry/cli/help/configuration.rb', line 214

def wrap_width(terminal_width)
  return unless wrap

  columns = width == :terminal ? terminal_width - margin : width
  [columns, MIN_WIDTH].max
end