Import Upstream version 20180207
[hcoop/debian/mlton.git] / bin / ls-ignore
1 #!/usr/bin/env bash
2
3 set -e
4
5 # List ignored files of current directory by constructing a "find"
6 # expression that matches names of ignored files.
7 #
8 # This script supports a reasonable subset of "gitignore(5)"
9 # semantics. Notably, it does support:
10 # * Patterns read from .gitignore files in current and parent directories
11 # * Blank line separators
12 # * Leading "#" comments
13 # * Trailing "/" directory patterns
14 # * Leading "/" this-directory patterns
15 # and it does not support:
16 # * Patterns read from $GIT_DIR/info/exclude
17 # (b/c inappropriate for a source release)
18 # * Patterns read from file specified by configuration variable core.excludesfile
19 # (b/c inappropriate for a source release)
20 # * Leading "!" negation patterns
21 # (b/c complex semantics)
22 # * Internal "/" FNM_PATHNAME patterns
23 # (b/c complex semantics incompatible with '-path' primary)
24
25 name=$(basename "$0")
26 dir=$(dirname "$0")
27 root=$(cd "$dir/.." && pwd)
28
29 ignore='.gitignore'
30
31 declare -a fargs
32 fargs+=("(")
33 fargs+=("-exec")
34 fargs+=("false")
35 fargs+=(";")
36 idir="."
37 while true; do
38 if [ -r "$idir/$ignore" ]; then
39 while IFS= read -r opat; do
40 pat="$opat"
41 ## Blank line: Separator -- supported
42 if [ -z "$pat" ]; then
43 continue
44 fi
45 ## Leading "#": Comment -- supported
46 if [ "${pat:0:1}" = "#" ]; then
47 continue
48 fi
49 ## Leading "\#": Pattern beginning with "#" -- supported
50 if [ "${pat:0:2}" = "\#" ]; then
51 pat="#${pat:2}"
52 fi
53 ## Leading "!": Negated pattern -- unsupported
54 if [ "${pat:0:1}" = "!" ]; then
55 echo "$name:: unsupported pattern: $opat"
56 exit 1
57 fi
58 ## Leading "\!": Pattern beginning with "!" -- supported
59 if [ "${pat:0:2}" = "\!" ]; then
60 pat="!${pat:2}"
61 fi
62 ## Trailing "/": Directory pattern -- supported
63 if [ "${pat:$((${#pat}-1)):1}" = "/" ]; then
64 dirPat="yes"
65 pat="${pat:0:$((${#pat}-1))}"
66 else
67 dirPat="no"
68 fi
69 ## Leading "/": This-directory pattern -- supported
70 if [ "${pat:0:1}" = "/" ]; then
71 if [ "$idir" = "." ]; then
72 pat="${pat:1}"
73 else
74 continue
75 fi
76 fi
77 ## Internal "/": FNM_PATHNAME pattern -- unsupported
78 if [ -z "${pat##*/*}" ]; then
79 echo "$name:: unsupported pattern: $opat"
80 exit 1
81 fi
82 fargs+=("-o")
83 fargs+=("(")
84 if [ "$dirPat" = "yes" ]; then
85 fargs+=("-type")
86 fargs+=("d")
87 fi
88 fargs+=("-name")
89 fargs+=("$pat")
90 fargs+=(")")
91 done < "$idir/$ignore"
92 fi
93 if [ "$(cd "$idir" && pwd)" != "$root" ]; then
94 idir="../$idir"
95 else
96 break
97 fi
98 done
99 fargs+=(")")
100
101 find . -mindepth 1 -maxdepth 1 "${fargs[@]}" -print