Module: Wisco::Commands::List

Defined in:
lib/wisco/commands/list.rb

Constant Summary collapse

TREE_FORK =
'├── '
TREE_LAST =
'└── '
TREE_PIPE =
''
TREE_BLANK =
'    '
EXPANDABLE_KEYS =
%i[actions triggers object_definitions methods pick_lists].freeze
SORT_FIELDS =
%w[key title].freeze

Class Method Summary collapse

Class Method Details

.humanise_key(key) ⇒ Object



104
105
106
# File 'lib/wisco/commands/list.rb', line 104

def humanise_key(key)
  key.to_s.split('_').map(&:capitalize).join(' ')
end

.render_children_tree(value, prefix) ⇒ Object



183
184
185
186
187
188
189
# File 'lib/wisco/commands/list.rb', line 183

def render_children_tree(value, prefix)
  child_keys = value.keys.sort
  child_keys.each_with_index do |ck, ci|
    cl = ci == child_keys.size - 1
    puts "#{prefix}#{cl ? TREE_LAST : TREE_FORK}#{ck}"
  end
end

.render_connection_tree(conn, prefix) ⇒ Object



161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
# File 'lib/wisco/commands/list.rb', line 161

def render_connection_tree(conn, prefix)
  keys = conn.keys
  keys.each_with_index do |key, idx|
    last = idx == keys.size - 1
    connector = last ? TREE_LAST : TREE_FORK
    child_prefix = prefix + (last ? TREE_BLANK : TREE_PIPE)
    value = conn[key]

    if value.is_a?(Hash)
      puts "#{prefix}#{connector}#{key}"
      sub_keys = value.keys
      sub_keys.each_with_index do |sk, si|
        sl = si == sub_keys.size - 1
        sc = sl ? TREE_LAST : TREE_FORK
        puts "#{child_prefix}#{sc}#{sk}"
      end
    else
      puts "#{prefix}#{connector}#{key} #{value_label(value)}"
    end
  end
end

.render_markdown_table(headers, rows) ⇒ Object



120
121
122
123
124
125
126
127
128
129
130
131
132
# File 'lib/wisco/commands/list.rb', line 120

def render_markdown_table(headers, rows)
  all_rows = [headers] + rows
  widths = headers.length.times.map do |i|
    all_rows.map { |r| r[i].to_s.length }.max
  end

  fmt = widths.map { |w| "%-#{w}s" }.join(' | ')
  sep = widths.map { |w| '-' * w }.join('-|-')

  puts "| #{format(fmt, *headers)} |"
  puts "|-#{sep}-|"
  rows.each { |r| puts "| #{format(fmt, *r)} |" }
end

.run(subcommand, target, sort: nil) ⇒ Object



15
16
17
18
19
20
21
22
23
24
25
26
27
28
# File 'lib/wisco/commands/list.rb', line 15

def run(subcommand, target, sort: nil)
  validate_sort!(sort)

  case subcommand
  when nil        then run_tree(target)
  when 'actions'  then run_actions(target, sort: sort)
  when 'triggers' then run_triggers(target, sort: sort)
  when 'all'      then run_all(target, sort: sort)
  else
    warn "Error: Unknown list subcommand '#{subcommand}'"
    warn "Run '#{Wisco::CLI_NAME} --help' for usage."
    exit 1
  end
end

.run_actions(target_dir, sort: nil) ⇒ Object



57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/wisco/commands/list.rb', line 57

def run_actions(target_dir, sort: nil)
  connector = Wisco::Connector.load_connector_from_config(target_dir)
  actions = connector[:actions]

  if actions.nil? || actions.empty?
    puts 'No actions defined.'
    return
  end

  rows = actions.map { |key, item| [key, title_for(key, item), subtitle_for(item)] }
  rows = sort_rows(rows, sort)
  render_markdown_table(%w[Key Title Subtitle], rows)
end

.run_all(target_dir, sort: nil) ⇒ Object



85
86
87
88
89
90
91
92
93
94
# File 'lib/wisco/commands/list.rb', line 85

def run_all(target_dir, sort: nil)
  puts '## Overview'
  run_tree(target_dir)
  puts
  puts '## Actions'
  run_actions(target_dir, sort: sort)
  puts
  puts '## Triggers'
  run_triggers(target_dir, sort: sort)
end

.run_tree(target_dir) ⇒ Object



30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/wisco/commands/list.rb', line 30

def run_tree(target_dir)
  connector = Wisco::Connector.load_connector_from_config(target_dir)
  puts connector[:title]

  keys = connector.keys
  keys.each_with_index do |key, idx|
    last = idx == keys.size - 1
    connector_str = last ? TREE_LAST : TREE_FORK
    child_prefix = last ? TREE_BLANK : TREE_PIPE
    value = connector[key]

    if key == :connection && value.is_a?(Hash)
      puts "#{connector_str}#{key}"
      render_connection_tree(value, child_prefix)
    elsif EXPANDABLE_KEYS.include?(key) && value.is_a?(Hash) && !value.empty?
      puts "#{connector_str}#{key} [#{value.size}]"
      render_children_tree(value, child_prefix)
    elsif value.is_a?(Hash)
      puts "#{connector_str}#{key} [#{value.size}]"
    elsif value.is_a?(Array)
      puts "#{connector_str}#{key} [#{value.size}]"
    else
      puts "#{connector_str}#{key}"
    end
  end
end

.run_triggers(target_dir, sort: nil) ⇒ Object



71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/wisco/commands/list.rb', line 71

def run_triggers(target_dir, sort: nil)
  connector = Wisco::Connector.load_connector_from_config(target_dir)
  triggers = connector[:triggers]

  if triggers.nil? || triggers.empty?
    puts 'No triggers defined.'
    return
  end

  rows = triggers.map { |key, item| [key, title_for(key, item), subtitle_for(item)] }
  rows = sort_rows(rows, sort)
  render_markdown_table(%w[Key Title Subtitle], rows)
end

.sort_rows(rows, sort) ⇒ Object



141
142
143
144
145
146
# File 'lib/wisco/commands/list.rb', line 141

def sort_rows(rows, sort)
  return rows if sort.nil?

  index = SORT_FIELDS.index(sort)
  rows.sort_by { |row| [row[index].to_s.downcase, row[0].to_s.downcase] }
end

.strip_html(str) ⇒ Object


List utilities




100
101
102
# File 'lib/wisco/commands/list.rb', line 100

def strip_html(str)
  str.to_s.gsub(/<[^>]+>/, '').squeeze(' ').strip
end

.subtitle_for(item) ⇒ Object



112
113
114
115
116
117
118
# File 'lib/wisco/commands/list.rb', line 112

def subtitle_for(item)
  return '' unless item.is_a?(Hash)
  return item[:subtitle] if item[:subtitle]

  strip_html(item[:description]) if item[:description]
  item[:subtitle] || strip_html(item[:description].to_s)
end

.title_for(key, item) ⇒ Object



108
109
110
# File 'lib/wisco/commands/list.rb', line 108

def title_for(key, item)
  item.is_a?(Hash) && item[:title] ? item[:title] : humanise_key(key)
end

.validate_sort!(sort) ⇒ Object



134
135
136
137
138
139
# File 'lib/wisco/commands/list.rb', line 134

def validate_sort!(sort)
  return if sort.nil? || SORT_FIELDS.include?(sort)

  warn "Error: Unsupported sort field '#{sort}'. Valid values: #{SORT_FIELDS.join(', ')}."
  exit 1
end

.value_label(value) ⇒ Object


Tree rendering




152
153
154
155
156
157
158
159
# File 'lib/wisco/commands/list.rb', line 152

def value_label(value)
  case value
  when Hash  then "[#{value.size}]"
  when Array then "[#{value.size}]"
  when Proc  then '(lambda)'
  else            value.to_s
  end
end