1 ## oils_failures_allowed: 14
2 ## compare_shells: bash
3 ## legacy_tmp_dir: true
4
5 #### Don't glob flags on file system with GLOBIGNORE
6 # This is a bash-specific extension.
7 expr $0 : '.*/osh$' >/dev/null && exit 99 # disabled until cd implemented
8 touch _tmp/-n _tmp/zzzzz
9 cd _tmp # this fail in osh
10 GLOBIGNORE=-*:zzzzz # colon-separated pattern list
11 echo -* hello zzzz?
12 ## STDOUT:
13 -* hello zzzz?
14 ## END
15 ## N-I dash/mksh/ash stdout-json: "hello zzzzz"
16 ## status: 0
17
18 #### basic star case -> ignore files with txt extension
19 touch {basic.md,basic.txt}
20 GLOBIGNORE=*.txt
21 echo *.*
22 ## STDOUT:
23 basic.md
24 ## END
25
26 #### basic question mark case -> ignore txt files with one char filename
27 touch {1.txt,10.txt}
28 GLOBIGNORE=?.txt
29 echo *.*
30 ## STDOUT:
31 10.txt
32 ## END
33
34 #### multiple patterns -> ignore files with o or h extensions
35 touch {hello.c,hello.h,hello.o,hello}
36 GLOBIGNORE=*.o:*.h
37 echo hello*
38 ## STDOUT:
39 hello hello.c
40 ## END
41
42 #### ignore specific file
43 mkdir src
44 touch src/{__init__.py,__main__.py}
45 GLOBIGNORE='src/__init__.py'
46 echo src/*
47 ## STDOUT:
48 src/__main__.py
49 ## END
50
51 #### ignore contents of specific directories
52 mkdir {src,compose,dist,node_modules}
53 touch src/{a.js,b.js}
54 touch compose/{base.compose.yaml,dev.compose.yaml}
55 touch dist/index.js
56 touch node_modules/package.js
57 GLOBIGNORE=dist/*:node_modules/*
58 echo */*
59 ## STDOUT:
60 compose/base.compose.yaml compose/dev.compose.yaml src/a.js src/b.js
61 ## END
62
63 #### find files in subdirectory but not the ignored pattern
64 mkdir {dir1,dir2}
65 touch dir1/{a.txt,ignore.txt}
66 touch dir2/{a.txt,ignore.txt}
67 GLOBIGNORE=*/ignore*
68 echo */*
69 ## STDOUT:
70 dir1/a.txt dir2/a.txt
71 ## END
72
73 #### basic range cases
74 rm -rf _tmp
75 touch {a,b,c,d,A,B,C,D}
76 GLOBIGNORE=*[ab]*
77 echo *
78 GLOBIGNORE=*[ABC]*
79 echo *
80 GLOBIGNORE=*[!ab]*
81 echo *
82 ## STDOUT:
83 A B C D c d
84 D a b c d
85 a b
86 ## END
87
88 #### range cases using character classes
89 touch {_testing.py,pyproject.toml,20231114.log,.env}
90 touch 'has space.docx'
91 GLOBIGNORE=[[:alnum:]]*
92 echo *.*
93 GLOBIGNORE=[![:alnum:]]*
94 echo *.*
95 GLOBIGNORE=*[[:space:]]*
96 echo *.*
97 GLOBIGNORE=[[:digit:]_.]*
98 echo *.*
99 ## STDOUT:
100 .env _testing.py
101 20231114.log has space.docx pyproject.toml
102 .env 20231114.log _testing.py pyproject.toml
103 has space.docx pyproject.toml
104 ## END
105
106 #### ignore everything
107 # This pattern appears in public repositories
108 touch {1.txt,2.log,3.md}
109 GLOBIGNORE=*
110 echo *
111 ## STDOUT:
112 *
113 ## END
114
115 #### treat escaped patterns literally
116 touch {escape-10.txt,escape*.txt}
117 GLOBIGNORE="escape\*.txt"
118 echo *.*
119 ## STDOUT:
120 escape-10.txt
121 ## END
122
123 #### resetting globignore reverts to default behaviour
124 touch reset.txt
125 GLOBIGNORE=*.txt
126 echo *.*
127 GLOBIGNORE=
128 echo *.*
129 ## STDOUT:
130 *.*
131 reset.txt
132 ## END
133
134 #### find dotfiles while ignoring . or ..
135 # globskipdots is enabled by default in bash >=5.2
136 # for bash <5.2 this pattern is a common way to match dotfiles but not . or ..
137 shopt -u globskipdots
138 touch .env
139 GLOBIGNORE=.:..
140 echo .*
141 GLOBIGNORE=
142 echo .* | sort
143 ## STDOUT:
144 .env
145 . .. .env
146 ## END
147
148 #### different styles
149 # each style of "ignore everything" spotted in a public repo
150 touch image.jpeg
151 GLOBIGNORE=*
152 echo *
153 GLOBIGNORE='*'
154 echo *
155 GLOBIGNORE="*"
156 echo *
157 GLOBIGNORE=\*
158 echo *
159 ## STDOUT:
160 *
161 *
162 *
163 *
164 ## END