Module: PryRemoteEm::Client::InteractiveMenu

Included in:
PryRemoteEm::Client
Defined in:
lib/pry-remote-em/client/interactive_menu.rb

Instance Method Summary collapse

Instance Method Details

#choose_server(list) ⇒ Object



6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/pry-remote-em/client/interactive_menu.rb', line 6

def choose_server(list)
  highline    = HighLine.new
  choice      = nil
  url         = nil
  nm_col_len  = list.map { |id, server| server['name'].size }.max
  sc_col      = list.map { |id, server| second_column_for_server(server) }
  sc_col_name = opts[:show_details] == '@' ? 'details' : opts[:show_details] || 'url'
  sc_col_len  = [sc_col.flatten.map(&:size).max || 1, sc_col_name.size].max
  show_th_col = opts[:show_metrics] || list.any? { |id, server| server.has_key?('metrics') && server['metrics']['errors'] }
  if show_th_col
    th_col      = list.map { |id, server| third_column_for_server(server) }
    th_col_name = opts[:show_metrics] == '@' ? 'metrics' : opts[:show_metrics] || 'errors'
    th_col_len  = [th_col.flatten.map(&:size).max || 1, th_col_name.size].max
  end
  formatter   = "| %-3s |  %-#{nm_col_len}s  |  %-#{sc_col_len}s  |#{"  %-#{th_col_len}s  |" if show_th_col}"
  header      = sprintf(formatter, '', 'name', sc_col_name, *th_col_name)
  border      = ('-' * header.length)
  table       = [border, header, border]
  list        = list.to_a
  list        = filter_server_list(list)
  list        = sort_server_list(list)
  list.each.with_index do |(id, server), index|
    index_column = [(index + 1).to_s]
    first_column = [server['name']]
    second_column = second_column_for_server(server)
    third_column = third_column_for_server(server) if show_th_col

    lines = show_th_col ? [second_column.size, third_column.size].max : second_column.size

    lines.times do |index|
      table << sprintf(formatter, index_column[index] || '', first_column[index] || '', second_column[index] || '', *(show_th_col ? third_column[index] || '' : nil))
    end
  end
  table << border
  table = table.join("\n")
  Kernel.puts table

  proxy = if (choice = opts.delete(:proxy))
    true
  elsif (choice = opts.delete(:connect))
    false
  elsif opts.delete(:proxy_by_default)
    true
  else
    false
  end

  while url.nil?
    if proxy
      question = "(q) to quit; (r) to refresh; (c) to connect without proxy\nproxy to: "
    else
      question = "(q) to quit; (r) to refresh; (p) to proxy\nconnect to: "
    end

    choice = highline.ask(question)

    return close_connection if ['q', 'quit', 'exit'].include?(choice.downcase)
    if ['r', 'reload', 'refresh'].include?(choice.downcase)
      send_server_reload_list
      return nil
    end
    if ['c', 'connect'].include?(choice.downcase)
      proxy = false
      choice = nil
      next
    end
    if ['p', 'proxy'].include?(choice.downcase)
      proxy = true
      choice = nil
      next
    end

    choice = choice[/^\d+$/] ?
      list[choice.to_i - 1] :
      list.detect { |(id, server)| choice == id || choice == server['name'] || server['urls'].include?(choice) }

    if choice
      id, server = *choice
      urls = filtered_urls_list_for_server(server)
      url = if urls.size > 1
        choose_url(urls)
      elsif urls.size == 1
        urls.first
      else
        log.error("\033[31mno #{'non-localhost ' if opts[:ignore_localhost]}urls for this server\033[0m")
        nil
      end
    else
      log.error("\033[31mserver not found\033[0m")
    end
  end

  return url, proxy
end

#choose_url(urls) ⇒ Object



101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
# File 'lib/pry-remote-em/client/interactive_menu.rb', line 101

def choose_url(urls)
  highline = HighLine.new
  url      = nil
  length   = urls.map(&:size).max
  border   = '-' * (length + 8)
  Kernel.puts border
  urls.each.with_index do |url, index|
    Kernel.puts sprintf("| %d | %-#{length}s |", index + 1, url)
  end
  Kernel.puts border

  choice = highline.ask('select url: ')

  url = if choice && choice[/^\d+$/]
    urls[choice.to_i - 1]
  elsif urls.include?(choice)
    choice
  end

  log.error("\033[31mno url selected\033[0m") unless url

  return url
end

#filter_server_list(list) ⇒ Object



142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
# File 'lib/pry-remote-em/client/interactive_menu.rb', line 142

def filter_server_list(list)
  if opts[:filter_host]
    list = list.select { |(id, server)| server['urls'].any? { |url| URI.parse(url).host =~ opts[:filter_host] } }
  end
  if opts[:filter_name]
    list = list.select { |(id, server)| server['name'] =~ opts[:filter_name] }
  end
  if opts.has_key?(:filter_ssl)
    target_scheme = opts[:filter_ssl] ? 'pryems' : 'pryem'
    list = list.select { |(id, server)| server['urls'].any? { |url| URI.parse(url).scheme == target_scheme } }
  end
  if list.empty?
    log.info("\033[33m[pry-remote-em] no registered servers match the given filter\033[0m")
    Process.exit
  end
  list
end

#filtered_urls_list_for_server(server) ⇒ Object



170
171
172
# File 'lib/pry-remote-em/client/interactive_menu.rb', line 170

def filtered_urls_list_for_server(server)
  opts[:ignore_localhost] ? server['urls'].reject { |url| %w[localhost 127.0.0.1 ::1].include?(URI.parse(url).host) } : server['urls']
end

#prepare_data_for_table(data) ⇒ Object



184
185
186
187
188
189
190
# File 'lib/pry-remote-em/client/interactive_menu.rb', line 184

def prepare_data_for_table(data)
  case data
  when Array then data.map(&:to_s)
  when Hash then data.map { |key, value| "#{key}: #{value}" }
  else [data.to_s]
  end
end

#second_column_for_server(server) ⇒ Object



160
161
162
163
164
165
166
167
168
# File 'lib/pry-remote-em/client/interactive_menu.rb', line 160

def second_column_for_server(server)
  data = case opts[:show_details]
  when nil then filtered_urls_list_for_server(server)
  when '@' then server['details']
  else server['details'][opts[:show_details]]
  end

  prepare_data_for_table(data)
end

#sort_by_uri(part) ⇒ Object



138
139
140
# File 'lib/pry-remote-em/client/interactive_menu.rb', line 138

def sort_by_uri(part)
  -> a, b { URI.parse(a[1]['urls'].first).send(part) <=> URI.parse(b[1]['urls'].first).send(part) }
end

#sort_server_list(list) ⇒ Object



125
126
127
128
129
130
131
132
133
134
135
136
# File 'lib/pry-remote-em/client/interactive_menu.rb', line 125

def sort_server_list(list)
  case opts[:sort]
  when :name
    list.sort { |(_, a), (_, b)| a['name'] <=> b['name'] }
  when :ssl
    list.sort &sort_by_uri(:scheme)
  when :port
    list.sort &sort_by_uri(:port)
  else # :host or default
    list.sort &sort_by_uri(:host)
  end
end

#third_column_for_server(server) ⇒ Object



174
175
176
177
178
179
180
181
182
# File 'lib/pry-remote-em/client/interactive_menu.rb', line 174

def third_column_for_server(server)
  data = case opts[:show_metrics]
  when nil then server['metrics']['errors']
  when '@' then server['metrics']
  else server['metrics'][opts[:show_metrics]]
  end

  prepare_data_for_table(data)
end