Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add "bundle search" subcommand #360

Merged
merged 1 commit into from
May 8, 2015
Merged

Add "bundle search" subcommand #360

merged 1 commit into from
May 8, 2015

Conversation

derekprior
Copy link
Contributor

Bundler 1.8+ added support for git-style subcommands. Any scripts
starting with bundler- in your path are executable as bundler
subcommands.

This adds search as a subcommand that uses ag to search for a string
among all gems in your bundle (default) or optionally a specific gem.
I've found this useful for finding the source of puzzling deprecations,
finding what gem provides a method, and other various things.

This script isn't nearly perfect. It fails confusingly when bundle show --paths
fails (if, for instance, you are not in bundler project). shellcheck complains
about quoting but providing the quotes it wants breaks the command.
But, it works. Pushing this up now to see if others might find it useful and to
recruit help in making it a bit more robust.

@gylaz
Copy link
Contributor

gylaz commented Mar 13, 2015

I like this!

Is it possible to fallback to grep if ag isn't stalled? Or maybe just use grep?

@derekprior
Copy link
Contributor Author

Should be possible but I think grep might find things in directories ag would ignore - like the .git directory of any git dependencies.

# Arguments:
# 1. What to search for
# 2. Which gem names to search (defaults to all gems)
ag "$1" $(bundle show --paths $2)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The unquoted $2 only works by coincidence because gems names rarely (never?) contain spaces. I would do the following anyway:

pattern="$1"; shift
ag "$pattern" $(bundle show --paths "$@")

It still relies on the implicit word-splitting of $(bundle show ...), but there's not a great (read: POSIX) way around that. It'll break if bundle show reports directories with spaces.

@derekprior
Copy link
Contributor Author

Updated to better handle parameters. When bundle show fails, the command fails spectacularly:


thoughtbot.com dp-just-buy % bundle search foo bar
ERR: Error stat()ing: Could
ERR: Error opening directory Could: No such file or directory
ERR: Error stat()ing: not
ERR: Error opening directory not: No such file or directory
ERR: Error stat()ing: find
ERR: Error opening directory find: No such file or directory
ERR: Error stat()ing: gem
ERR: Error opening directory gem: No such file or directory
ERR: Error stat()ing: 'Bundler::CLI::Common'.
ERR: Error opening directory 'Bundler::CLI::Common'.: No such file or directory

@pbrisbin
Copy link

Nice job bundler printing errors on stdout...

@ianks
Copy link

ianks commented Apr 25, 2015

Gosh dangit, I got a little too inspired by this after listening the bikeshed.fm podcast. I now know more Bash than I ever wanted to know 😆. Oh well, maybe someone can enjoy the fruits of my labor.

Caveats:

  • I have no idea if this works on OSX. I only tested on a Linux machine, so any feedback would be loved!
  • Instead of providing the gems to seach for, I just pass the arguments down to the search command. I did this because I like passing options like -l to ag so it can list the files that the pattern occurs in.

❤️

#!/usr/bin/env sh

set -e

if [ "$1" == "--help" ] || [ "$1" == "-h" ]; then
    echo "
Usage: $(basename "$0") [options] pattern

Search your bundle for the provided pattern
  * Requires bundler 1.8+ for execution as a bundler subcommand.

bundle-search tries to find a proper backend for you. It attempts to use:
    1. ag
    2. grep

Examples:
    - bundle search Kernel.warn
    - bundle search current_user clearance

Arguments:
    1. What to search for
    2. Whichever options you want passed to you search backend.

Credits:
        - @derekprior for the idea, inspiration and initial implementation
        - @ianks for the Bash tom-foolery
    "

    exit
fi

search_path() {
    if SEARCH_PATH=$(bundle show --paths "$@"); then
        echo $SEARCH_PATH
    else
        echo $(/usr/bin/env ruby -rubygems -e 'puts Gem.user_dir')
    fi
}

search_cmd() {
    if hash ag 2>/dev/null; then
        echo "ag -G .*\.rb"
    else
        echo "grep -R --color --include=\*.rb"
    fi
}

eval "$(search_cmd) "$@" "$PATTERN" $(search_path)"

# Requires bundler 1.8+ for execution as a bundler subcommand.
# Examples:
# bundle search Kernal.warn
# bundle search current_user clearance
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I wanted to search for a query that has multiple words, do I just quote it?

bundle search "Change your password" clearance

Might be worth adding to the example.

@croaky
Copy link
Contributor

croaky commented Apr 25, 2015

This seems cool and helpful. 👍

Is there any Vim integration we can add, too, like filling and opening the quickfix list?

http://vim.wikia.com/wiki/Automatically_open_the_quickfix_window_on_:make
http://stackoverflow.com/questions/1747091/how-do-you-use-vims-quickfix-feature

@ianks
Copy link

ianks commented Apr 25, 2015

Good idea @croaky. I have some other things I am working on so I cant explore the VIM integration yet, but I would love to have something like this in VIM.

Bundler 1.8+ added support for git-style subcommands. Any scripts
starting with `bundler-` in your path are executable as bundler
subcommands.

This adds `search` as a subcommand that uses `ag` to search for a string
among all gems in your bundle (default) or optionally a specific gem.
I've found this useful for finding the source of puzzling deprecations,
finding what gem provides a method, and other various things.
@gylaz gylaz merged commit 734c130 into master May 8, 2015
@gylaz
Copy link
Contributor

gylaz commented May 8, 2015

Thanks @derekprior!

@gylaz gylaz deleted the dp-bundler-search branch May 8, 2015 21:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants