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

The editor to invoke if ENV and ENV aren't set.

MULTILINE_PROMPT

Prompt for multiline input

Public Instance Methods

ansi_code( *attributes ) click to toggle source

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
ask_for_confirmation( description, abort_on_decline=true ) { || ... } click to toggle source

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
Also aliased as: prompt_for_confirmation
colorize( *args ) { || ... } click to toggle source

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
edit( filename ) click to toggle source

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
error( msg, details='' )
Alias for: error_message
error_message( msg, details='' ) click to toggle source

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
Also aliased as: error
get_target_args() click to toggle source

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
humanize_file_list( list, indent=FILE_INDENT ) click to toggle source

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
log( *msg ) click to toggle source

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_prompt_string( string ) click to toggle source

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
prompt( prompt_string, failure_msg="Try again." ) { |response| ... } click to toggle source

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_confirmation( description, abort_on_decline=true )
prompt_for_multiple_values( label, default=nil ) click to toggle source

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_with_default( prompt_string, default, failure_msg="Try again." ) { |response| ... } click to toggle source

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
quotelist( *args ) click to toggle source

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
read_command_output( cmd, *args ) click to toggle source

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( *cmd ) click to toggle source

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
trace( *msg ) click to toggle source

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