From 193c69b5e74e16cc255986e797d80f10b24d0011 Mon Sep 17 00:00:00 2001 From: Denis Knauf Date: Wed, 14 Jan 2015 00:05:48 +0100 Subject: [PATCH] cave configs: auto-action, tab-completion, history * --auto-action for automatic actions for files, defined by /etc/paludis/configs_auto_action. * Readline for tab-completion and history support. --- cave_commands/configs | 344 ++++++++++++++++++++++++++++++++---------- 1 file changed, 267 insertions(+), 77 deletions(-) diff --git a/cave_commands/configs b/cave_commands/configs index bfaf243..f8f4466 100755 --- a/cave_commands/configs +++ b/cave_commands/configs @@ -1,9 +1,13 @@ #!/usr/bin/env ruby +Main = self +public + require 'Paludis' require 'getoptlong' require 'pathname' require 'shellwords' +require 'readline' begin require 'irb-pager' rescue LoadError @@ -42,8 +46,8 @@ class UsageError 'Help', - %w[\1 \2 ...] => 'Select file via index', - %w[FILENAME] => 'Select file via filename', - %w[\list] => 'List all files need updates', - %w[\diff] => 'Displays difference of selected file', - %w[\accept \yes] => 'Accepts selected file', - %w[\reject \no] => 'Rejects selected file', - %w[\quit \exit] => 'Quit', - }) - puts - when *%w[d diff] - raise NoSelection unless selected - puts - IRB::Pager::pager( pager: 'less -R') { diff selected, found[selected][0] } - puts - when *%w[l list] - list_cfgs selected, list if selected - when *%w[a accept y yes] - raise NoSelection unless selected - accept_cfg selected, found[selected][0] - selected = nil - when *%w[r reject n no] - raise NoSelection unless selected - reject_cfg selected, found[selected][0] - selected = nil - when *%w[q quit e exit] then exit(0) - when 'auto-action' - File.readlines '/etc/paludis/config_auto_action' do |line| - action, file = line.chomp!.split( "\t", 2) - file = Pathname.new file - case action - when *%w[a accept] - accept_cfg nil, nil if file.exist? - end - end + self.selected = nil unless found.has_key? selected + end + + def run + prepare + prompt.chomp.split( /\s+/).each &method( :execute) + instance_eval &cmds[:diff] if need_to_print + rescue Interrupt + rescue UsageError + puts $!.message + end + + def prompt + prompt = + if selected + "(cfg:\e[1m#{selected}\e[0m)# " else - m = Pathname.new x - if f = found[m] - selected = m - else - raise UsageError, "Uknown command #{x}" + puts + list_cfgs selected, list + puts + "(select?)# " + end + Readline.completion_proc = lambda do |str| + reg = /^#{Regexp.quote str}/ + list.keys.select {|i| reg =~ i.to_s } + + found.keys.grep( reg) + + cmds.keys.grep( reg) + + found.keys.select {|f| reg =~ f.basename.to_s } + end + line = Readline.readline( prompt, true) or exit + Readline::HISTORY.pop if /^\s*$/ =~ line or (Readline::HISTORY.length >= 2 && Readline::HISTORY[-2] == line) + line + end + + def execute x + case x + when /^\d+$/ + m = list[x.to_i] + raise UsageError, "Unknown index #{x}" unless m + self.selected = m + when cmds + instance_eval &cmds[x.to_sym] + else + m = Pathname.new x + unless (f = found[m]).empty? + self.selected = m + else + raise UsageError, "Unknown command #{x}" + end + end + end +end + +auto_action_file = Pathname.new '/etc/paludis/configs_auto_action' + +cmds = Commands.new do + help 'Help' + on %w[\help \?] do + puts + cmds.list_keys + puts + end + + help 'Displays difference of selected file' + on '\diff' do + raise NoSelection unless selected + puts + IRB::Pager::pager( pager: 'less -R') { diff selected, found[selected][0] } + puts + self.need_to_print = false + end + + help 'List all files need updates' + on '\list' do + list_cfgs selected, list if selected + end + + help 'Accepts selected file' + on %w[\accept \yes] do + raise NoSelection unless selected + accept_cfg selected, found[selected][0] + selected = nil + end + + help 'Rejects selected file' + on %w[\reject \no] do + raise NoSelection unless selected + reject_cfg selected, found[selected][0] + selected = nil + end + + help 'Quit' + on %w[\quit \exit] do + exit 0 + end + + on 'auto-action' do + unless auto_action_file.exist? + raise UsageError, "No config for auto-action found: #{auto_action_file}" + end + auto_action_file.each_line do |line| + next if /^\s*#/ =~ line + action, file = line.chomp!.split( "\t", 2) + file = Pathname.new file + if found.has_key? file + case action + when *%w[a accept] + accept_cfg file, found[file][-1] + found[file][0...-1].each {|f| reject_cfg file, f } + when *%w[r reject] + found[file].each {|f| reject_cfg file, f } end end end - rescue UsageError - puts $! end end + +ui = UI.new cmds, dirs + +opts = GetoptLong.new( + [ '-h', '--help', GetoptLong::NO_ARGUMENT ], + [ '-A', '--auto-action', GetoptLong::OPTIONAL_ARGUMENT ] +) +opts.ordering = GetoptLong::REQUIRE_ORDER +opts.each do |opt, arg| + case opt + when '-h' + puts <