#!/bin/sh

# Copyright 2004 Ben Reser <ben@reser.org>
# Licensed under the terms subversion ships under or GPLv2.

# Useful for greping in a subversion working copy.  
# Essentially it behaves the same way your grep command does (in fact it
# ultimately calls the grep command on your path) with a few exceptions.
# Ignores the subversion admin directories (.svn) and vi(m) backup files.
# Recursive is always on with or without -r.
# Always print filename and line numbers.
# Ignores binary files.
# If no path is given the current working directory is searched not stdin.
# Other than that it will take any parameter or pattern your standard grep
# does.
# 
# This script requires GNU findutils and by default GNU grep (though that
# can be changed with environment variables).
# 
# There are three environment variables you can set that modify the default
# behavior:
#
# WCGREP_GREP      Controls what command is used for the grep command.
#                  If unset or null wcgrep will check if ggrep (GNU grep)
#                  is available and use it; if "ggrep" could not be found
#                  in the path, "grep" will be used.
# WCGREP_GREPARGS  Controls what arguments are always passed to the grep
#                  command before the arguments given on the command line.
#                  If unset or null it defaults to -HnI (always print file
#                  names, line numbers and ignore binary files).  If you wish
#                  to set no default args set the variable to a space (" ").
# WCGREP_IGNORE    Controls what files are ignored by the grep command.
#                  This is a regex that is passed to the find command with
#                  -regex so see find's man page for details.  If unset or
#                  null defaults to '.*~$\|.*/\.svn\(/\|$\)', which will
#                  ignore vim backup files and subversion admin dirs.


grepargs=
pattern=

# When loop completes, $@ should contain only list of paths to traverse.
# If empty, set it to "." for compatibility (path list is not optional everywhere).
# This way we can use "$@" feature when calling find(1).
#
# XXX The grepargs handling is broken, unlike the handling of path arguments.

usage() {
    echo "usage: $(basename \"$0\") [grep-argument [...] [--]] pattern" >&2
    echo "       [path ...]" >&2
    exit 1
}

while [ $# -gt 0 ]; do
    if [ X"$1" = X-- ]; then
        grepargs="$grepargs $1"
        pattern="$2"
        shift 2
        break
    elif [ X"${1#-}" = X"$1" ]; then
        pattern="$1"
        shift
        break
    else
        grepargs="$grepargs $1"
    fi  
    shift
done
test -z "$pattern" && usage
if [ $# -eq 0 ]; then
	set -- .
fi

WCGREP_IGNORE=${WCGREP_IGNORE:-'.*~$\|.*/\.git/.*\|.*/\.svn\(/\|$\)'}
WCGREP_GREPARGS="${WCGREP_GREPARGS:--HnI}"

# Some OSes have GNU tools with "g" prefix, try that first
# TODO: check if:
#  a) this tool is still needed;
#  b) it is okay to break backward compatibility in future for
#     portability reasons (avoid GNU toolchain dependency).

WCGREP_GREP="${WCGREP_GREP:-$(command -v ggrep)}"
WCGREP_GREP="${WCGREP_GREP:-grep}"

WCGREP_FIND="$(command -v gfind)"
WCGREP_FIND="${WCGREP_FIND:-find}"

${WCGREP_FIND} "$@" -regex "${WCGREP_IGNORE}" -prune -o -type f -print0 | \
    xargs -r0 ${WCGREP_GREP} ${WCGREP_GREPARGS} $grepargs "$pattern"
