Module: Cmdapp
- Defined in:
- lib/bugzyrb/common/cmdapp.rb
Instance Method Summary collapse
-
#_choice(prompt, choices) ⇒ Object
get choice from user from a list of options.
-
#_gets(column, prompt, default = nil) ⇒ Object
get a string from user, using readline or gets if readline, then manage column specific history FIXME: move to Cmdapp.
-
#_list_args(args) ⇒ Array
separates args to list-like operations +xxx means xxx should match in output -xxx means xxx should not exist in output that should not match.
-
#_separate(args, pattern = nil) ⇒ Object
separates args into tag or subcommand and items This allows user to pass e.g.
- #add_action(name, descr) ⇒ Object
- #alias_command(name, *args) ⇒ Object
-
#backup(filename = @app_file_path) ⇒ Object
backup file to filename.org use prior to a modification operation that could be dangerous or risky.
-
#check_aliases(action, args) ⇒ Boolean
external dependencies: @app_default_action - action to run if none specified @app_file_path - data file we are backing up, or reading into array @app_serial_path - serial_number file.
- #check_file(filename = @app_file_path) ⇒ Object
-
#die(text) ⇒ Object
exit after printing an error message.
-
#edit_text(text) ⇒ String?
edits given text using EDITOR.
-
#file_append(filename, text) ⇒ Object
if File.exists? filename.
-
#file_read(filename) ⇒ Object
———– file operations ————-.
-
#file_write(filename, text) ⇒ Object
if File.exists? filename.
-
#filter_rows(rows, incl) ⇒ Object
creates a regexp and for each row returns the row and the regexp you can use the regexp on whatever part of the row you want to match or reject.
-
#get_lines(prompt = nil) ⇒ String?
prompts user for multiline input NOTE: we do not take Ctrl-d as EOF then causes an error in next input in 1.9 (not 1.8) FIXME: move to Cmdapp.
-
#get_serial_number ⇒ Object
TODO: move to serial_number.rb or a file that deals with file_data as against sql data which should also have backup, load_array and save_array.
-
#help(args) ⇒ Object
not required if using Subcommand.
-
#history_read(column, default = nil) ⇒ Object
———————————————————— these 2 methods deal with with maintaining readline history for various columns.
-
#history_save(column, str) ⇒ Object
update our cache with str if not present in cache already.
-
#indent(str, n) ⇒ Object
indents given string, n spaces redmine.ruby-lang.org/issues/show/749 Thomas Sawyer.
-
#indent2(str, count) ⇒ Object
indents a string, indenting all but first line.
-
#load_array ⇒ Object
load data into array as item and task.
-
#message(text) ⇒ Object
prints messages to stderr All messages should go to stderr.
-
#old_get_lines ⇒ String?
reads multiple lines of input until EOF (Ctrl-d) and returns as a string.
-
#pipe_output(pipeto, str) ⇒ Object
pipes given string to command FIXME: not clear how to return error.
- #print_green(text) ⇒ Object
- #print_red(text) ⇒ Object
-
#run ⇒ 0, ERRCODE
runs method after checking if valid or alias.
-
#save_array ⇒ Object
saves the task array to disk Please use load_array to load, and not populate.
-
#set_serial_number(number) ⇒ Object
After doing a redo of the numbering, we need to reset the numbers for that app.
-
#template_replace(template, myhash) ⇒ String
reads up template, and substirutes values from myhash NOTE: probably better to use rdoc/template which can handle arrays as well.
-
#truncate(string, count) ⇒ Object
for updating in log file truncates long strings comments, descriptions, fix etc and removed newlines.
-
#user_input(column, prompt_flag, prompt_text = nil, choices = nil, default = nil) ⇒ String?
take user input based on value of flag TODO: should we not check for the ask_x methods and call them if present.
-
#verbose(text) ⇒ Object
print to stderr only if verbose set.
-
#version_info ⇒ String?
retrieve version info updated by jeweler.
-
#warning(text) ⇒ Object
print to stderr only if verbose set.
Instance Method Details
#_choice(prompt, choices) ⇒ Object
get choice from user from a list of options
474 475 476 477 478 479 |
# File 'lib/bugzyrb/common/cmdapp.rb', line 474 def _choice prompt, choices choose do || .prompt = prompt .choices(*choices) do |n| return n; end end end |
#_gets(column, prompt, default = nil) ⇒ Object
get a string from user, using readline or gets if readline, then manage column specific history FIXME: move to Cmdapp.
455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 |
# File 'lib/bugzyrb/common/cmdapp.rb', line 455 def _gets column, prompt, default=nil text = "#{prompt}? " text << "|#{default}|" if default puts text if $use_readline Cmdapp::history_read column, default str = Readline::readline('>', false) Cmdapp::history_save column, str str = default if str.nil? or str == "" return str else str = $stdin.gets.chomp str = default if str.nil? or str == "" return str end end |
#_list_args(args) ⇒ Array
separates args to list-like operations +xxx means xxx should match in output -xxx means xxx should not exist in output that should not match.
360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 |
# File 'lib/bugzyrb/common/cmdapp.rb', line 360 def _list_args args incl = [] excl = [] args.each do |e| if e[0] == '+' incl << e[1..-1] elsif e[0] == '-' excl << e[1..-1] else incl << e end end incl = nil if incl.empty? excl = nil if excl.empty? return incl, excl end |
#_separate(args, pattern = nil) ⇒ Object
separates args into tag or subcommand and items This allows user to pass e.g. a priority first and then item list or item list first and then priority. This can only be used if the tag or pri or status is non-numeric and the item is numeric.
413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 |
# File 'lib/bugzyrb/common/cmdapp.rb', line 413 def _separate args, pattern=nil #/^[a-zA-Z]/ tag = nil items = [] args.each do |arg| if arg =~ /^[0-9\.]+$/ items << arg else tag = arg if pattern die "#{@action}: #{arg} appears invalid." if arg !~ pattern end end end items = nil if items.empty? return tag, items end |
#add_action(name, descr) ⇒ Object
96 97 98 99 |
# File 'lib/bugzyrb/common/cmdapp.rb', line 96 def add_action name, descr @actions ||= {} @actions[name.to_s] = desc end |
#alias_command(name, *args) ⇒ Object
92 93 94 95 |
# File 'lib/bugzyrb/common/cmdapp.rb', line 92 def alias_command name, *args @aliases ||= {} @aliases[name.to_s] = args end |
#backup(filename = @app_file_path) ⇒ Object
backup file to filename.org use prior to a modification operation that could be dangerous or risky
148 149 150 151 |
# File 'lib/bugzyrb/common/cmdapp.rb', line 148 def backup filename=@app_file_path require 'fileutils' FileUtils.cp filename, "#{filename}.org" end |
#check_aliases(action, args) ⇒ Boolean
external dependencies:
@app_default_action - action to run if none specified
@app_file_path - data file we are backing up, or reading into array
@app_serial_path - serial_number file
check whether this action is mapped to some alias and changes variables@action and @argv if true. NOTE: some of these are relevant only if we are not using subcommand, so we should move out to another file.
32 33 34 35 36 37 38 39 40 41 42 43 44 |
# File 'lib/bugzyrb/common/cmdapp.rb', line 32 def check_aliases action, args return false unless @aliases ret = @aliases[action] if ret a = ret.shift b = [*ret, *args] @action = a @argv = b #puts " #{@action} ; argv: #{@argv} " return true end return false end |
#check_file(filename = @app_file_path) ⇒ Object
404 405 406 |
# File 'lib/bugzyrb/common/cmdapp.rb', line 404 def check_file filename=@app_file_path File.exists?(filename) or die "#{filename} does not exist in this dir. " end |
#die(text) ⇒ Object
exit after printing an error message
153 154 155 156 |
# File 'lib/bugzyrb/common/cmdapp.rb', line 153 def die text $stderr.puts text exit ERRCODE end |
#edit_text(text) ⇒ String?
edits given text using EDITOR
246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 |
# File 'lib/bugzyrb/common/cmdapp.rb', line 246 def edit_text text # 2010-06-29 10:24 require 'fileutils' require 'tempfile' ed = ENV['EDITOR'] || "vim" temp = Tempfile.new "tmp" File.open(temp,"w"){ |f| f.write text } mtime = File.mtime(temp.path) #system("#{ed} #{temp.path}") system(ed, temp.path) newmtime = File.mtime(temp.path) newstr = nil if mtime < newmtime # check timestamp, if updated .. newstr = File.read(temp) else #puts "user quit without saving" return nil end return newstr.chomp if newstr return nil end |
#file_append(filename, text) ⇒ Object
if File.exists? filename
400 401 402 403 |
# File 'lib/bugzyrb/common/cmdapp.rb', line 400 def file_append filename, text filename = File. filename File.open(filename,"a"){ |f| f.write text } end |
#file_read(filename) ⇒ Object
———– file operations ————-
390 391 392 393 394 |
# File 'lib/bugzyrb/common/cmdapp.rb', line 390 def file_read filename filename = File. filename return File.read(filename) #if File.exists? filename end |
#file_write(filename, text) ⇒ Object
if File.exists? filename
395 396 397 398 399 |
# File 'lib/bugzyrb/common/cmdapp.rb', line 395 def file_write filename, text filename = File. filename File.open(filename,"w"){ |f| f.write text } #if File.exists? filename end |
#filter_rows(rows, incl) ⇒ Object
creates a regexp and for each row returns the row and the regexp you can use the regexp on whatever part of the row you want to match or reject
379 380 381 382 383 384 385 386 387 |
# File 'lib/bugzyrb/common/cmdapp.rb', line 379 def filter_rows rows, incl if incl incl_str = incl.join "|" r = Regexp.new incl_str #rows = rows.select { |row| row['title'] =~ r } rows = rows.select { |row| yield(row, r) } end rows end |
#get_lines(prompt = nil) ⇒ String?
prompts user for multiline input NOTE: we do not take Ctrl-d as EOF then causes an error in next input in 1.9 (not 1.8) FIXME: move to Cmdapp
435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 |
# File 'lib/bugzyrb/common/cmdapp.rb', line 435 def get_lines prompt=nil #prompt ||= "Enter multiple lines, to quit enter . on empty line" prompt if prompt str = "" while $stdin.gets # reads from STDIN case $_.chomp when "." break when ".vim" return edit_text str end str << $_ #puts "Read: #{$_}" # writes to STDOUT end return nil if str == "" return str.chomp end |
#get_serial_number ⇒ Object
TODO: move to serial_number.rb or a file that deals with file_data as against sql data which should also have backup, load_array and save_array.
reads serial_number file, returns serialno for this app and increments the serial number and writes back.
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 |
# File 'lib/bugzyrb/common/cmdapp.rb', line 106 def get_serial_number require 'fileutils' appname = @appname filename = @app_serial_path || "serial_numbers" h = {} # check if serial file existing in curr dir. Else create if File.exists?(filename) File.open(filename).each { |line| #sn = $1 if line.match regex x = line.split ":" h[x[0]] = x[1].chomp } end sn = h[appname] || 1 # update the sn in file nsn = sn.to_i + 1 # this will create if not exists in addition to storing if it does h[appname] = nsn # write back to file File.open(filename, "w") do |f| h.each_pair {|k,v| f.print "#{k}:#{v}\n"} end return sn end |
#help(args) ⇒ Object
not required if using Subcommand
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
# File 'lib/bugzyrb/common/cmdapp.rb', line 72 def help args if @actions.nil? if defined? @commands unless @commands.empty? @actions = @commands end end end if @actions puts "Actions are " @actions.each_pair { |name, val| puts "#{name}\t#{val}" } end puts " " if @aliases puts "Aliases are " @aliases.each_pair { |name, val| puts "#{name}:\t#{val.join(' ')}" } end 0 end |
#history_read(column, default = nil) ⇒ Object
these 2 methods deal with with maintaining readline history for various columns. _read reads up any earlier values so user can select from them. _save saves the values for future use.
for a given column, check if there’s any previous data in our cache, and put in readlines history so user can use or edit. Also put default value in history.
315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 |
# File 'lib/bugzyrb/common/cmdapp.rb', line 315 def history_read column, default=nil values = [] oldstr = "" if !defined? $history_hash require 'readline' require 'yaml' filename = File. "~/.bugzy_history.yml" $history_filename = filename # if file exists with values push them into history if File.exists? filename $history_hash = YAML::load( File.open( filename ) ) else $history_hash = Hash.new end end values.push(*$history_hash[column]) if $history_hash.has_key? column # push existing value into history also, so it can be edited values.push(default) if default values.uniq! Readline::HISTORY.clear # else previous values of other fields also come in Readline::HISTORY.push(*values) unless values.empty? #puts Readline::HISTORY.to_a end |
#history_save(column, str) ⇒ Object
update our cache with str if not present in cache already
343 344 345 346 347 348 349 350 351 352 353 |
# File 'lib/bugzyrb/common/cmdapp.rb', line 343 def history_save column, str return if str.nil? or str == "" if $history_hash.has_key? column return if $history_hash[column].include? str end ($history_hash[column] ||= []) << str filename = $history_filename File.open( filename, 'w' ) do |f| f << $history_hash.to_yaml end end |
#indent(str, n) ⇒ Object
indents given string, n spaces redmine.ruby-lang.org/issues/show/749 Thomas Sawyer
514 515 516 517 518 519 520 521 |
# File 'lib/bugzyrb/common/cmdapp.rb', line 514 def indent(str,n) return '' unless str if n >= 0 str.gsub(/^/, ' ' * n) else str.gsub(/^ {0,#{-n}}/, "") end end |
#indent2(str, count) ⇒ Object
indents a string, indenting all but first line. This allows us to print a string as follows:
Description : The description starts here.
And continues here. The first line was not indented.
www.ralfebert.de/blog/ruby/string_helpers/ Ralf Ebert
527 528 529 530 531 532 533 |
# File 'lib/bugzyrb/common/cmdapp.rb', line 527 def indent2(str, count) if str char = ' ' #(char * count) + gsub(/(\n+)/) { $1 + (char * count) } str.gsub(/(\n+)/) { $1 + (char * count) } end end |
#load_array ⇒ Object
load data into array as item and task
181 182 183 184 185 186 187 188 189 190 |
# File 'lib/bugzyrb/common/cmdapp.rb', line 181 def load_array #return if $valid_array $valid_array = false @data = [] File.open(@app_file_path).each do |line| row = line.chomp.split( @app_delim ) @data << row end $valid_array = true end |
#message(text) ⇒ Object
prints messages to stderr All messages should go to stderr. Keep stdout only for output which can be used by other programs
160 161 162 |
# File 'lib/bugzyrb/common/cmdapp.rb', line 160 def text $stderr.puts text end |
#old_get_lines ⇒ String?
reads multiple lines of input until EOF (Ctrl-d) and returns as a string. Add newline after each line
225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 |
# File 'lib/bugzyrb/common/cmdapp.rb', line 225 def old_get_lines lines = nil #$stdin.flush $stdin.each_line do |line| line.chomp! if line =~ /^bye$/ break end if lines lines << "\n" + line else lines = line end end return lines end |
#pipe_output(pipeto, str) ⇒ Object
pipes given string to command FIXME: not clear how to return error. NOTE: this is obviously more portable than using system echo or system cat.
278 279 280 281 282 283 284 285 286 287 |
# File 'lib/bugzyrb/common/cmdapp.rb', line 278 def pipe_output (pipeto, str) #pipeto = '/usr/sbin/sendmail -t' #pipeto = %q{mail -s "my title" rahul} if pipeto != nil # i was taking pipeto from a hash, so checking proc = IO.popen(pipeto, "w+") proc.puts str proc.close_write #puts proc.gets end end |
#print_green(text) ⇒ Object
174 175 176 |
# File 'lib/bugzyrb/common/cmdapp.rb', line 174 def print_green text "#{GREEN}#{text}#{CLEAR}" end |
#print_red(text) ⇒ Object
171 172 173 |
# File 'lib/bugzyrb/common/cmdapp.rb', line 171 def print_red text "#{RED}#{text}#{CLEAR}" end |
#run ⇒ 0, ERRCODE
runs method after checking if valid or alias. If not found prints help.
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
# File 'lib/bugzyrb/common/cmdapp.rb', line 49 def run @action = @argv[0] || @app_default_action @action = @action.downcase ret = 0 @argv.shift if respond_to? @action ret = send(@action, @argv) else # check aliases if check_aliases @action, @argv ret = send(@action, @argv) else help @argv ret = ERRCODE end end ret ||= 0 ret = 0 if ret != ERRCODE return ret end |
#save_array ⇒ Object
saves the task array to disk Please use load_array to load, and not populate
194 195 196 197 198 199 200 201 |
# File 'lib/bugzyrb/common/cmdapp.rb', line 194 def save_array raise "Cannot save array! Please use load_array to load" if $valid_array == false File.open(@app_file_path, "w") do |file| #@data.each { |row| file.puts "#{row[0]}\t#{row[1]}" } @data.each { |row| file.puts row.join(@app_delim) } end end |
#set_serial_number(number) ⇒ Object
After doing a redo of the numbering, we need to reset the numbers for that app
132 133 134 135 136 137 138 139 140 141 142 143 |
# File 'lib/bugzyrb/common/cmdapp.rb', line 132 def set_serial_number number appname = @appname pattern = Regexp.new "^#{appname}:.*$" filename = @app_serial_path || "serial_numbers" # during testing redo this file does not exist, so i get errors if !File.exists? filename get_serial_number end backup filename # from Sed change_row filename, pattern, "#{appname}:#{number}" end |
#template_replace(template, myhash) ⇒ String
reads up template, and substirutes values from myhash NOTE: probably better to use rdoc/template which can handle arrays as well.
294 295 296 297 298 299 300 301 302 303 |
# File 'lib/bugzyrb/common/cmdapp.rb', line 294 def template_replace template, myhash #tmpltext=File::read(template); t = template.dup t.gsub!( /##(.*?)##/ ) { #raise "Key '#{$1}' found in template but the value has not been set" unless ( myhash.has_key?( $1 ) ) myhash[ $1 ].to_s } t end |
#truncate(string, count) ⇒ Object
for updating in log file truncates long strings comments, descriptions, fix etc and removed newlines
536 537 538 539 540 541 |
# File 'lib/bugzyrb/common/cmdapp.rb', line 536 def truncate string, count string = string.to_s string.tr!("\n",' ') return string if string.length <= count (string[0..(count-4)] + " ...") end |
#user_input(column, prompt_flag, prompt_text = nil, choices = nil, default = nil) ⇒ String?
take user input based on value of flag TODO: should we not check for the ask_x methods and call them if present. FIXME: move to Cmdapp
491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 |
# File 'lib/bugzyrb/common/cmdapp.rb', line 491 def user_input column, prompt_flag, prompt_text=nil, choices=nil, default=nil if prompt_flag == true prompt_flag = :freeform prompt_flag = :choice if choices end case prompt_flag when :freeform prompt_text ||= "#{column.capitalize}" #str = ask(prompt_text){ |q| q.default = default if default } str = _gets(column, prompt_text, default) return str when :choice prompt_text ||= "Select #{column}:" str = _choice(prompt_text, choices) return str when :multiline, :ml return Cmdapp::edit_text default when false return default end end |
#verbose(text) ⇒ Object
print to stderr only if verbose set
164 165 166 |
# File 'lib/bugzyrb/common/cmdapp.rb', line 164 def verbose text (text) if @options[:verbose] end |
#version_info ⇒ String?
retrieve version info updated by jeweler. Typically used by –version option of any command. FIXME: link VERSION to version.rb in lib/buzg.. and read from same dir
207 208 209 210 211 212 213 214 215 216 217 218 219 |
# File 'lib/bugzyrb/common/cmdapp.rb', line 207 def version_info # thanks to Roger Pack on ruby-forum for how to get to the version # file filename = File.open(File.dirname(__FILE__) + "/../../VERSION") v = nil if File.exists?(filename) v = File.open(filename).read.chomp if File.exists?(filename) #else #$stderr.puts "could not locate file #{filename}. " #puts `pwd` end v end |
#warning(text) ⇒ Object
print to stderr only if verbose set
168 169 170 |
# File 'lib/bugzyrb/common/cmdapp.rb', line 168 def warning text print_red("WARNING: #{text}") end |