Last active
April 10, 2017 23:05
-
-
Save nilium/44e88079820f680f94b4aba9d094b8fb to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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