I have a poor memory, especially for things a computer should do for me. Frustrated with Rake commands (is it logs:clear or log:clear?) I turned to Bash completion. A web search found this basic implementation. Because it called rake -T on each invocation, it was unusably slow. Another search found Jonathan Palardy’s implementation with caching. Nice.
I worked on it a little more to be able to add it to Homebrew’s bash-completion package. Though it turns out that Homebrew’s package just grabs from the main bash-completion distribution so I’ll have to see about adding it there.
In any case, here in all its glory, a bash-completion for Rake. It caches automatically so all but the first use is fast. It also checks for a tmp/cache directory (present in Rails projects) and places the cache in there if available. This saves you from having to add the .rake_t_cache file to your SCM’s ignore list.
# bash completion for rake## some code from on Jonathan Palardy's http://technotales.wordpress.com/2009/09/18/rake-completion-cache/# and http://pastie.org/217324 found http://ragonrails.com/post/38905212/rake-bash-completion-ftw# # For details and discussion# http://turadg.aleahmad.net/2011/02/bash-completion-for-rake-tasks/## INSTALL## Place in your bash completions.d and/or source in your .bash_profile# If on a Mac with Homebrew, try "brew install bash-completion"# # USAGE## Type 'rake' and hit tab twice to get completions.# To clear the cache, run rake_cache_clear() in your shell.#
function _rake_cache_path() { # If in a Rails app, put the cache in the cache dir # so version control ignores it if [ -e 'tmp/cache' ]; then prefix='tmp/cache/' fi echo "${prefix}.rake_t_cache"}
function rake_cache_store() { rake --tasks --silent > "$(_rake_cache_path)"}
function rake_cache_clear() { rm -f .rake_t_cache rm -f tmp/cache/.rake_t_cache}
export COMP_WORDBREAKS=${COMP_WORDBREAKS/\:/}
function _rakecomplete() { # error if no Rakefile if [ ! -e Rakefile ]; then echo "missing Rakefile" return 1 fi
# build cache if missing if [ ! -e "$(_rake_cache_path)" ]; then rake_cache_store fi
local tasks=`awk '{print $2}' "$(_rake_cache_path)"` COMPREPLY=($(compgen -W "${tasks}" -- ${COMP_WORDS[COMP_CWORD]})) return 0}
complete -o default -o nospace -F _rakecomplete rake