Skip to content

Commit 6b1380b

Browse files
authored
Add readline to meeting_stats (#76)
Rather than numbers, you can now just tab complete the name Signed-off-by: Phil Dibowitz <phil@ipom.com>
1 parent f739f8a commit 6b1380b

File tree

1 file changed

+72
-42
lines changed

1 file changed

+72
-42
lines changed

bin/meeting_stats

Lines changed: 72 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ require 'date'
55
require 'sqlite3'
66
require 'fileutils'
77
require 'gruff'
8+
require 'readline'
89

910
require_relative '../lib/oss_stats/log'
1011
require_relative '../lib/oss_stats/config/meeting_stats'
@@ -46,33 +47,64 @@ def prompt_yes_no(question)
4647
end
4748

4849
def prompt_team_or_q(teams)
49-
# it's length, not length-1 because we add one for <other>
50-
max_num = teams.length
50+
# Setup readline completion with team names
51+
all_options = teams + %w{other finish f abort}
52+
53+
comp = proc do |s|
54+
# Case-insensitive completion
55+
all_options.select { |opt| opt.downcase.start_with?(s.downcase) }
56+
end
57+
58+
Readline.completion_append_character = nil
59+
Readline.completion_proc = comp
60+
61+
# Make readline case-insensitive
62+
if Readline.respond_to?(:completion_case_fold=)
63+
Readline.completion_case_fold = true
64+
end
65+
66+
# Remove space from word break characters so "Chef Client" is treated as one
67+
# word
68+
if Readline.respond_to?(:completer_word_break_characters=)
69+
original_word_break = Readline.completer_word_break_characters
70+
Readline.completer_word_break_characters = original_word_break.delete(' ')
71+
end
72+
5173
loop do
52-
log.info("Choose a team that was present:\n")
53-
(teams + ['<Other>']).each_with_index do |team, idx|
54-
log.info(" [#{idx}] #{team}")
74+
log.info(
75+
'Choose a team that was present (type to search, TAB to complete):',
76+
)
77+
teams.each do |team|
78+
log.info(" - #{team}")
5579
end
56-
log.info(' [q] <quit>')
57-
print "\nTeam?> "
58-
response = gets.strip.downcase
59-
return false if response == 'q'
60-
begin
61-
i = Integer(response)
62-
if i < max_num
63-
return teams[i]
64-
end
80+
log.info("\n - other (for a team not in the list)")
81+
log.info(' - abort (to quit without saving)')
82+
log.info(' - [f]inish (to save)')
83+
log.info('')
84+
response = Readline.readline('Team?> ', true)
6585

66-
if i == max_num
67-
print 'Team name: '
68-
response = gets.strip
69-
return response
70-
end
86+
# Handle Ctrl-C or Ctrl-D
87+
return false if response.nil?
88+
89+
response = response.strip
90+
return false if %w{f finish}.include?(response.downcase)
91+
92+
exit(0) if response.downcase == 'abort'
7193

72-
log.error("Invalid response: #{response}")
73-
rescue ArgumentError
74-
log.error("Invalid response: #{response}")
94+
# Check if it's an exact match for a known team (case-insensitive)
95+
matched_team = teams.find { |t| t.downcase == response.downcase }
96+
return matched_team if matched_team
97+
98+
if response.downcase == 'other'
99+
print 'Team name: '
100+
new_team = gets.strip
101+
return new_team unless new_team.empty?
102+
103+
log.error('Team name cannot be empty')
104+
next
75105
end
106+
107+
log.error('Please enter a valid options')
76108
end
77109
end
78110

@@ -94,28 +126,28 @@ def collect_team_data(meeting_date)
94126
)
95127
confirm = prompt_yes_no('Is that correct?')
96128
end
97-
if confirm
98-
missing_teams.each do |mt|
99-
team_data[mt] = {
100-
'present' => false,
101-
'current_work' => false,
102-
'build_status' => '',
103-
'fix_pointers' => '-',
104-
'extra' => '-',
105-
}
106-
end
107-
break
108-
else
109-
next
129+
next unless confirm
130+
131+
missing_teams.each do |mt|
132+
team_data[mt] = {
133+
'present' => false,
134+
'current_work' => false,
135+
'build_status' => '',
136+
'fix_pointers' => '-',
137+
'extra' => '-',
138+
}
110139
end
140+
break
141+
111142
end
112143

113144
if team_data[team]
114-
if prompt_yes_no("WARNING: #{team} data already input - overwrite?")
115-
log.info("OK, overwriting data for #{team} on #{meeting_date}")
116-
else
145+
unless prompt_yes_no("WARNING: #{team} data already input - overwrite?")
117146
next
118147
end
148+
149+
log.info("OK, overwriting data for #{team} on #{meeting_date}")
150+
119151
end
120152

121153
log.info("\nTeam: #{team}")
@@ -212,9 +244,7 @@ end
212244
def format_build_status(status)
213245
return ':x:' if status.nil? || status.strip.empty?
214246

215-
if %w{red green}.include?(status)
216-
status = "main:#{status}"
217-
end
247+
status = "main:#{status}" if %w{red green}.include?(status)
218248
status.gsub('red', ' :red_circle:').gsub('green', ' :white_check_mark:')
219249
end
220250

@@ -354,7 +384,7 @@ OptionParser.new do |opts|
354384
options[:date] =
355385
begin
356386
Date.parse(v)
357-
rescue
387+
rescue StandardError
358388
nil
359389
end
360390
end

0 commit comments

Comments
 (0)