Skip to content

Instantly share code, notes, and snippets.

@nilium
Last active April 10, 2017 23:05
Show Gist options
  • Save nilium/44e88079820f680f94b4aba9d094b8fb to your computer and use it in GitHub Desktop.
Save nilium/44e88079820f680f94b4aba9d094b8fb to your computer and use it in GitHub Desktop.
#!/usr/bin/env sh
# TROUBLESHOOTING:
# If /bin/echo doesn't exist _and_ echo -n doesn't work, then this
# script fails. A more graceful fallback to not dropping the trailing
# newline in pipes would also work, but this hasn't been necessary yet.
usage () { cat <<'EOF' 1>&2
lsowners [OPTIONS] [--] [DIRS...]
lsowners searches for OWNERS files in the given DIRS. If no DIRS are
named, it searches the current working directory. Unless --no-recursive
is passed, it will also search directories above each dir for OWNERS
files.
If you pass both --recursive and --no-recursive (or both --printlf and
--print0), the last flag in the arguments list is used.
Options:
-r, --recursive walk parent directories for OWNERS files (default)
-R, --no-recursive disable --recursive
-n, --printlf print output names separated by \n bytes (default)
-0, --print0 print output names separated by NUL bytes. this is
useful if passing the output to xargs (or similar).
EOF
}
# globals
owners=''
recursive=1
zerosep=0
parsed=0
while test $# -gt 0
do
case "$1" in
-h|--help) usage; exit 2;;
-R|--no-recursive) recursive=0 ;; # disable walk up the tree
-r|--recursive) recursive=1 ;; # default
-0|--print0) zerosep=1 ;; # print output with zero separators
-n|--printlf) zerosep=0 ;; # print output with \n separators
--) shift; parsed=1 ;; # remaining arguments are directories
*) break;;
esac
if test $parsed -eq 1
then
break
fi
shift
done
# make sure echo builtin actually supports the -n flag -- if it doesn't,
# fall back to /bin/echo -- if /bin/echo doesn't exist, then give up.
if test "$(echo -n test)" = "-n test"
then
if test -e /bin/echo && test -x /bin/echo
then
puts () { /bin/echo "$@"; }
else
echo '/bin/echo does not exist' 2>&1
exit 1
fi
else
puts () { echo "$@"; }
fi
strip_empty () {
sed -e '/^[[:space:]]*[#;]/d;/^[[:space:]]*$/d;s/^[[:space:]]*//;s/[[:space:]]*$//' |
tr -s $'\n'
}
owners_in () {
local dir="$1"
while :
do
if test -f "$dir/OWNERS"
then
owners="$({ echo "$owners"; cat "$dir/OWNERS"; } | strip_empty | sort | uniq)"
fi
if test $recursive -eq 0
then
break
fi
if test "$dir" = / || test "$(basename "$dir")" = vendor
then
break
fi
dir="$(cd -P "$(dirname "$dir")" && pwd)"
done
}
if test $# -eq 0
then
set -- "$PWD"
fi
for argdir in "$@"
do
owners_in "$argdir"
done
if test $zerosep -eq 1
then
puts -n "$owners" | tr -s '\n' '\0'
exit
fi
if ! test -t 1
then
puts -n "$owners"
exit
fi
puts "$owners"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment