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
475 476 477 478 479 480 |
# File 'lib/bugzyrb/common/cmdapp.rb', line 475 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.
456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 |
# File 'lib/bugzyrb/common/cmdapp.rb', line 456 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.
361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 |
# File 'lib/bugzyrb/common/cmdapp.rb', line 361 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.
414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 |
# File 'lib/bugzyrb/common/cmdapp.rb', line 414 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
97 98 99 100 |
# File 'lib/bugzyrb/common/cmdapp.rb', line 97 def add_action name, descr @actions ||= {} @actions[name.to_s] = desc end |
#alias_command(name, *args) ⇒ Object
93 94 95 96 |
# File 'lib/bugzyrb/common/cmdapp.rb', line 93 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
149 150 151 152 |
# File 'lib/bugzyrb/common/cmdapp.rb', line 149 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
405 406 407 |
# File 'lib/bugzyrb/common/cmdapp.rb', line 405 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
154 155 156 157 |
# File 'lib/bugzyrb/common/cmdapp.rb', line 154 def die text $stderr.puts text exit ERRCODE end |
#edit_text(text) ⇒ String?
edits given text using EDITOR
247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 |
# File 'lib/bugzyrb/common/cmdapp.rb', line 247 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
401 402 403 404 |
# File 'lib/bugzyrb/common/cmdapp.rb', line 401 def file_append filename, text filename = File. filename File.open(filename,"a"){ |f| f.write text } end |
#file_read(filename) ⇒ Object
———– file operations ————-
391 392 393 394 395 |
# File 'lib/bugzyrb/common/cmdapp.rb', line 391 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
396 397 398 399 400 |
# File 'lib/bugzyrb/common/cmdapp.rb', line 396 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
380 381 382 383 384 385 386 387 388 |
# File 'lib/bugzyrb/common/cmdapp.rb', line 380 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
436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 |
# File 'lib/bugzyrb/common/cmdapp.rb', line 436 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.
107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 |
# File 'lib/bugzyrb/common/cmdapp.rb', line 107 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
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
# File 'lib/bugzyrb/common/cmdapp.rb', line 73 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.
316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 |
# File 'lib/bugzyrb/common/cmdapp.rb', line 316 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
344 345 346 347 348 349 350 351 352 353 354 |
# File 'lib/bugzyrb/common/cmdapp.rb', line 344 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
515 516 517 518 519 520 521 522 |
# File 'lib/bugzyrb/common/cmdapp.rb', line 515 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
528 529 530 531 532 533 534 |
# File 'lib/bugzyrb/common/cmdapp.rb', line 528 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
182 183 184 185 186 187 188 189 190 191 |
# File 'lib/bugzyrb/common/cmdapp.rb', line 182 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
161 162 163 |
# File 'lib/bugzyrb/common/cmdapp.rb', line 161 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
226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 |
# File 'lib/bugzyrb/common/cmdapp.rb', line 226 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.
279 280 281 282 283 284 285 286 287 288 |
# File 'lib/bugzyrb/common/cmdapp.rb', line 279 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
175 176 177 |
# File 'lib/bugzyrb/common/cmdapp.rb', line 175 def print_green text "#{GREEN}#{text}#{CLEAR}" end |
#print_red(text) ⇒ Object
172 173 174 |
# File 'lib/bugzyrb/common/cmdapp.rb', line 172 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 71 |
# File 'lib/bugzyrb/common/cmdapp.rb', line 49 def run @action = @argv[0] || @app_default_action @action = @action.downcase init_defaults 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
195 196 197 198 199 200 201 202 |
# File 'lib/bugzyrb/common/cmdapp.rb', line 195 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
133 134 135 136 137 138 139 140 141 142 143 144 |
# File 'lib/bugzyrb/common/cmdapp.rb', line 133 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.
295 296 297 298 299 300 301 302 303 304 |
# File 'lib/bugzyrb/common/cmdapp.rb', line 295 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
537 538 539 540 541 542 |
# File 'lib/bugzyrb/common/cmdapp.rb', line 537 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
492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 |
# File 'lib/bugzyrb/common/cmdapp.rb', line 492 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
165 166 167 |
# File 'lib/bugzyrb/common/cmdapp.rb', line 165 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
208 209 210 211 212 213 214 215 216 217 218 219 220 |
# File 'lib/bugzyrb/common/cmdapp.rb', line 208 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
169 170 171 |
# File 'lib/bugzyrb/common/cmdapp.rb', line 169 def warning text print_red("WARNING: #{text}") end |