module Hoe::RakeHelpers
def ansi_code( *attributes )
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
def ask_for_confirmation( description, abort_on_decline=true )
## with 'y', yield to the block. If +abort_on_decline+ is +true+,
## for confirmation. If the user answers with anything that begins
## Display a description of a potentially-dangerous task, and prompt
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
def colorize( *args )
## Colorize the given +string+ with the specified +attributes+ and return it, handling
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
def edit( filename )
## Invoke the user's editor on the given +filename+ and return the exit code
def edit( filename ) editor = ENV['EDITOR'] || ENV['VISUAL'] || DEFAULT_EDITOR system editor, filename unless $?.success? || editor =~ /vim/i fail "Editor exited uncleanly." end end
def error_message( msg, details='' )
## Output the specified msg as an ANSI-colored error message
def error_message( msg, details='' ) $stderr.puts colorize( 'bold', 'white', 'on_red' ) { msg } + details end
def get_target_args
def get_target_args args = ARGV.reject {|arg| arg =~ /^-/ || Rake::Task.task_defined?(arg) } return args end
def humanize_file_list( list, indent=FILE_INDENT )
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
def log( *msg )
def log( *msg ) output = colorize( msg.flatten.join(' '), 'cyan' ) $stderr.puts( output ) end
def make_prompt_string( string )
def make_prompt_string( string ) return CLEAR_CURRENT_LINE + colorize( 'bold', 'green' ) { string + ' ' } end
def prompt( prompt_string, failure_msg="Try again." ) # :yields: response
## An optional failure message can also be passed in.
## test is provided, the prompt will repeat until the test returns true.
## return the user's input with leading and trailing spaces removed. If a
## Output the specified prompt_string as a prompt (in green) and
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
def prompt_for_multiple_values( label, default=nil )
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
def prompt_with_default( prompt_string, default, failure_msg="Try again." )
## anything. If a test is provided, the prompt will repeat until the test
## substituting the given default if the user doesn't input
## Prompt the user with the given prompt_string via #prompt,
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
def quotelist( *args )
def quotelist( *args ) return args.flatten.collect {|part| part =~ /\s/ ? part.inspect : part} end
def read_command_output( cmd, *args )
## Run the given +cmd+ with the specified +args+ without interpolation by the shell and
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
def run( *cmd )
## Run the specified command +cmd+ with system(), failing if the execution
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
def trace( *msg )
def trace( *msg ) return unless Rake.application.options.trace output = colorize( msg.flatten.join(' '), 'yellow' ) $stderr.puts( output ) end