module Hoe::RakeHelpers
Prompting, command-execution, and other utility functions
Constants
- ANSI_ATTRIBUTES
Set some ANSI escape code constants (Shamelessly stolen from Perl's Term::ANSIColor by Russ Allbery <rra@stanford.edu> and Zenin <zenin@best.com>
- CLEAR_CURRENT_LINE
- CLEAR_TO_EOL
ANSI escapes for clearing to the end of the line and the entire line
- DEFAULT_EDITOR
- MULTILINE_PROMPT
Prompt for multiline input
Public Instance Methods
Create a string that contains the ANSI codes specified and return it
# File lib/hoe/mercurial.rb, line 67 def ansi_code( *attributes ) attributes.flatten! attributes.collect! {|at| at.to_s } # $stderr.puts "Returning ansicode for TERM = %p: %p" % # [ ENV['TERM'], attributes ] return '' unless /(?:vt10[03]|xterm(?:-color)?|linux|screen)/i =~ ENV['TERM'] attributes = ANSI_ATTRIBUTES.values_at( *attributes ).compact.join(';') # $stderr.puts " attr is: %p" % [attributes] if attributes.empty? return '' else return "\e[%sm" % attributes end end
Display a description of a potentially-dangerous task, and prompt for confirmation. If the user answers with anything that begins with 'y', yield to the block. If abort_on_decline
is true
, any non-'y' answer will fail with an error message.
# File lib/hoe/mercurial.rb, line 194 def ask_for_confirmation( description, abort_on_decline=true ) prompt = 'Continue?' # If the description looks like a question, use it for the prompt. Otherwise, # print it out and if description.strip.rindex( '?' ) prompt = description else log description end answer = prompt_with_default( prompt, 'n' ) do |input| input =~ /^[yn]/i end if answer =~ /^y/i return yield elsif abort_on_decline error "Aborted." fail end return false end
Colorize the given string
with the specified attributes
and return it, handling line-endings, color reset, etc.
# File lib/hoe/mercurial.rb, line 86 def colorize( *args ) string = '' if block_given? string = yield else string = args.shift end ending = string[/(\s)$/] || '' string = string.rstrip return ansi_code( args.flatten ) + string + ansi_code( 'reset' ) + ending end
Invoke the user's editor on the given filename
and return the exit code from doing so.
# File lib/hoe/mercurial.rb, line 266 def edit( filename ) editor = ENV['EDITOR'] || ENV['VISUAL'] || DEFAULT_EDITOR system editor, filename unless $?.success? || editor =~ /vim/i fail "Editor exited uncleanly." end end
Output the specified msg
as an ANSI-colored error message (white on red).
# File lib/hoe/mercurial.rb, line 104 def error_message( msg, details='' ) $stderr.puts colorize( 'bold', 'white', 'on_red' ) { msg } + details end
Extract all the non Rake-target arguments from ARGV and return them.
# File lib/hoe/mercurial.rb, line 286 def get_target_args args = ARGV.reject {|arg| arg =~ /^-/ || Rake::Task.task_defined?(arg) } return args end
Returns a human-scannable file list by joining and truncating the list if it's too long.
# File lib/hoe/mercurial.rb, line 293 def humanize_file_list( list, indent=FILE_INDENT ) listtext = list[0..5].join( "\n#{indent}" ) if list.length > 5 listtext << " (and %d other/s)" % [ list.length - 5 ] end return listtext end
Output a logging message
# File lib/hoe/mercurial.rb, line 222 def log( *msg ) output = colorize( msg.flatten.join(' '), 'cyan' ) $stderr.puts( output ) end
Make a prompt string that will always appear flush left.
# File lib/hoe/mercurial.rb, line 111 def make_prompt_string( string ) return CLEAR_CURRENT_LINE + colorize( 'bold', 'green' ) { string + ' ' } end
Output the specified prompt_string
as a prompt (in green) and return the user's input with leading and trailing spaces removed. If a test is provided, the prompt will repeat until the test returns true. An optional failure message can also be passed in.
# File lib/hoe/mercurial.rb, line 120 def prompt( prompt_string, failure_msg="Try again." ) # :yields: response prompt_string.chomp! prompt_string << ":" unless /\W$/.match( prompt_string ) response = nil begin prompt = make_prompt_string( prompt_string ) response = readline( prompt ) || '' response.strip! if block_given? && ! yield( response ) error_message( failure_msg + "\n\n" ) response = nil end end while response.nil? return response end
Prompt for an array of values
# File lib/hoe/mercurial.rb, line 168 def prompt_for_multiple_values( label, default=nil ) $stderr.puts( MULTILINE_PROMPT % [label] ) if default $stderr.puts "Enter a single blank line to keep the default:\n %p" % [ default ] end results = [] result = nil begin result = readline( make_prompt_string("> ") ) if result.nil? || result.empty? results << default if default && results.empty? else results << result end end until result.nil? || result.empty? return results.flatten end
Prompt the user with the given prompt_string
via prompt
, substituting the given default
if the user doesn't input anything. If a test is provided, the prompt will repeat until the test returns true. An optional failure message can also be passed in.
# File lib/hoe/mercurial.rb, line 143 def prompt_with_default( prompt_string, default, failure_msg="Try again." ) response = nil begin default ||= '~' response = prompt( "%s [%s]" % [ prompt_string, default ] ) response = default.to_s if !response.nil? && response.empty? trace "Validating response %p" % [ response ] # the block is a validator. We need to make sure that the user didn't # enter '~', because if they did, it's nil and we should move on. If # they didn't, then call the block. if block_given? && response != '~' && ! yield( response ) error_message( failure_msg + "\n\n" ) response = nil end end while response.nil? return nil if response == '~' return response end
Return the specified args as a string, quoting any that have a space.
# File lib/hoe/mercurial.rb, line 237 def quotelist( *args ) return args.flatten.collect {|part| part =~ /\s/ ? part.inspect : part} end
Run the given cmd
with the specified args
without interpolation by the shell and return anything written to its STDOUT.
# File lib/hoe/mercurial.rb, line 277 def read_command_output( cmd, *args ) # output = IO.read( '|-' ) or exec cmd, *args # No popen on some platforms. :( argstr = Shellwords.join( args ) output = `#{cmd} #{argstr}`.chomp return output end
Run the specified command cmd
with system(), failing if the execution fails. Doesn't invoke a subshell (unlike 'sh').
# File lib/hoe/mercurial.rb, line 244 def run( *cmd ) cmd.flatten! if cmd.length > 1 trace( "Running:", quotelist(*cmd) ) else trace( "Running:", cmd ) end if Rake.application.options.dryrun log "(dry run mode)" else system( *cmd ) unless $?.success? fail "Command failed: [%s]" % [cmd.join(' ')] end end end
Output a logging message if tracing is on
# File lib/hoe/mercurial.rb, line 229 def trace( *msg ) return unless Rake.application.options.trace output = colorize( msg.flatten.join(' '), 'yellow' ) $stderr.puts( output ) end