| 1 | #!/bin/sh |
| 2 | |
| 3 | test_description='test git rev-parse --parseopt' |
| 4 | |
| 5 | . ./test-lib.sh |
| 6 | |
| 7 | check_invalid_long_option () { |
| 8 | spec="$1" |
| 9 | opt="$2" |
| 10 | test_expect_success "test --parseopt invalid switch $opt help output for $spec" ' |
| 11 | { |
| 12 | cat <<-\EOF && |
| 13 | error: unknown option `'${opt#--}\'' |
| 14 | EOF |
| 15 | sed -e 1d -e \$d <"$TEST_DIRECTORY/t1502/$spec.help" |
| 16 | } >expect && |
| 17 | test_expect_code 129 git rev-parse --parseopt -- $opt \ |
| 18 | 2>output <"$TEST_DIRECTORY/t1502/$spec" && |
| 19 | test_cmp expect output |
| 20 | ' |
| 21 | } |
| 22 | |
| 23 | test_expect_success 'setup optionspec' ' |
| 24 | sed -e "s/^|//" >optionspec <<\EOF |
| 25 | |some-command [options] <args>... |
| 26 | | |
| 27 | |some-command does foo and bar! |
| 28 | |-- |
| 29 | |h,help! show the help |
| 30 | | |
| 31 | |foo some nifty option --foo |
| 32 | |bar= some cool option --bar with an argument |
| 33 | |b,baz a short and long option |
| 34 | | |
| 35 | | An option group Header |
| 36 | |C? option C with an optional argument |
| 37 | |d,data? short and long option with an optional argument |
| 38 | | |
| 39 | | Argument hints |
| 40 | |B=arg short option required argument |
| 41 | |bar2=arg long option required argument |
| 42 | |e,fuz=with-space short and long option required argument |
| 43 | |s?some short option optional argument |
| 44 | |long?data long option optional argument |
| 45 | |g,fluf?path short and long option optional argument |
| 46 | |longest=very-long-argument-hint a very long argument hint |
| 47 | |pair=key=value with an equals sign in the hint |
| 48 | |aswitch help te=t contains? fl*g characters!` |
| 49 | |bswitch=hint hint has trailing tab character |
| 50 | |cswitch switch has trailing tab character |
| 51 | |short-hint=a with a one symbol hint |
| 52 | | |
| 53 | |Extras |
| 54 | |extra1 line above used to cause a segfault but no longer does |
| 55 | EOF |
| 56 | ' |
| 57 | |
| 58 | test_expect_success 'setup optionspec-no-switches' ' |
| 59 | sed -e "s/^|//" >optionspec_no_switches <<\EOF |
| 60 | |some-command [options] <args>... |
| 61 | | |
| 62 | |some-command does foo and bar! |
| 63 | |-- |
| 64 | EOF |
| 65 | ' |
| 66 | |
| 67 | test_expect_success 'setup optionspec-only-hidden-switches' ' |
| 68 | sed -e "s/^|//" >optionspec_only_hidden_switches <<\EOF |
| 69 | |some-command [options] <args>... |
| 70 | | |
| 71 | |some-command does foo and bar! |
| 72 | |-- |
| 73 | |hidden1* A hidden switch |
| 74 | EOF |
| 75 | ' |
| 76 | |
| 77 | test_expect_success 'test --parseopt help output' ' |
| 78 | test_expect_code 129 git rev-parse --parseopt -- -h > output < optionspec && |
| 79 | test_cmp "$TEST_DIRECTORY/t1502/optionspec.help" output |
| 80 | ' |
| 81 | |
| 82 | test_expect_success 'test --parseopt help output no switches' ' |
| 83 | sed -e "s/^|//" >expect <<\END_EXPECT && |
| 84 | |cat <<\EOF |
| 85 | |usage: some-command [options] <args>... |
| 86 | | |
| 87 | | some-command does foo and bar! |
| 88 | | |
| 89 | |EOF |
| 90 | END_EXPECT |
| 91 | test_expect_code 129 git rev-parse --parseopt -- -h > output < optionspec_no_switches && |
| 92 | test_cmp expect output |
| 93 | ' |
| 94 | |
| 95 | test_expect_success 'test --parseopt help output hidden switches' ' |
| 96 | sed -e "s/^|//" >expect <<\END_EXPECT && |
| 97 | |cat <<\EOF |
| 98 | |usage: some-command [options] <args>... |
| 99 | | |
| 100 | | some-command does foo and bar! |
| 101 | | |
| 102 | |EOF |
| 103 | END_EXPECT |
| 104 | test_expect_code 129 git rev-parse --parseopt -- -h > output < optionspec_only_hidden_switches && |
| 105 | test_cmp expect output |
| 106 | ' |
| 107 | |
| 108 | test_expect_success 'test --parseopt help-all output hidden switches' ' |
| 109 | sed -e "s/^|//" >expect <<\END_EXPECT && |
| 110 | |cat <<\EOF |
| 111 | |usage: some-command [options] <args>... |
| 112 | | |
| 113 | | some-command does foo and bar! |
| 114 | | |
| 115 | | --[no-]hidden1 A hidden switch |
| 116 | | |
| 117 | |EOF |
| 118 | END_EXPECT |
| 119 | test_expect_code 129 git rev-parse --parseopt -- --help-all > output < optionspec_only_hidden_switches && |
| 120 | test_cmp expect output |
| 121 | ' |
| 122 | |
| 123 | test_expect_success 'test --parseopt invalid switch help output' ' |
| 124 | { |
| 125 | cat <<-\EOF && |
| 126 | error: unknown option `does-not-exist'\'' |
| 127 | EOF |
| 128 | sed -e 1d -e \$d <"$TEST_DIRECTORY/t1502/optionspec.help" |
| 129 | } >expect && |
| 130 | test_expect_code 129 git rev-parse --parseopt -- --does-not-exist 1>/dev/null 2>output < optionspec && |
| 131 | test_cmp expect output |
| 132 | ' |
| 133 | |
| 134 | test_expect_success 'setup expect.1' " |
| 135 | cat > expect <<EOF |
| 136 | set -- --foo --bar 'ham' -b --aswitch -- 'arg' |
| 137 | EOF |
| 138 | " |
| 139 | |
| 140 | test_expect_success 'test --parseopt' ' |
| 141 | git rev-parse --parseopt -- --foo --bar=ham --baz --aswitch arg < optionspec > output && |
| 142 | test_cmp expect output |
| 143 | ' |
| 144 | |
| 145 | test_expect_success 'test --parseopt with mixed options and arguments' ' |
| 146 | git rev-parse --parseopt -- --foo arg --bar=ham --baz --aswitch < optionspec > output && |
| 147 | test_cmp expect output |
| 148 | ' |
| 149 | |
| 150 | test_expect_success 'setup expect.2' " |
| 151 | cat > expect <<EOF |
| 152 | set -- --foo -- 'arg' '--bar=ham' |
| 153 | EOF |
| 154 | " |
| 155 | |
| 156 | test_expect_success 'test --parseopt with --' ' |
| 157 | git rev-parse --parseopt -- --foo -- arg --bar=ham < optionspec > output && |
| 158 | test_cmp expect output |
| 159 | ' |
| 160 | |
| 161 | test_expect_success 'test --parseopt --stop-at-non-option' ' |
| 162 | git rev-parse --parseopt --stop-at-non-option -- --foo arg --bar=ham < optionspec > output && |
| 163 | test_cmp expect output |
| 164 | ' |
| 165 | |
| 166 | test_expect_success 'setup expect.3' " |
| 167 | cat > expect <<EOF |
| 168 | set -- --foo -- '--' 'arg' '--bar=ham' |
| 169 | EOF |
| 170 | " |
| 171 | |
| 172 | test_expect_success 'test --parseopt --keep-dashdash' ' |
| 173 | git rev-parse --parseopt --keep-dashdash -- --foo -- arg --bar=ham < optionspec > output && |
| 174 | test_cmp expect output |
| 175 | ' |
| 176 | |
| 177 | test_expect_success 'setup expect.4' " |
| 178 | cat >expect <<EOF |
| 179 | set -- --foo -- '--' 'arg' '--spam=ham' |
| 180 | EOF |
| 181 | " |
| 182 | |
| 183 | test_expect_success 'test --parseopt --keep-dashdash --stop-at-non-option with --' ' |
| 184 | git rev-parse --parseopt --keep-dashdash --stop-at-non-option -- --foo -- arg --spam=ham <optionspec >output && |
| 185 | test_cmp expect output |
| 186 | ' |
| 187 | |
| 188 | test_expect_success 'setup expect.5' " |
| 189 | cat > expect <<EOF |
| 190 | set -- --foo -- 'arg' '--spam=ham' |
| 191 | EOF |
| 192 | " |
| 193 | |
| 194 | test_expect_success 'test --parseopt --keep-dashdash --stop-at-non-option without --' ' |
| 195 | git rev-parse --parseopt --keep-dashdash --stop-at-non-option -- --foo arg --spam=ham <optionspec >output && |
| 196 | test_cmp expect output |
| 197 | ' |
| 198 | |
| 199 | test_expect_success 'setup expect.6' " |
| 200 | cat > expect <<EOF |
| 201 | set -- --foo --bar='z' --baz -C'Z' --data='A' -- 'arg' |
| 202 | EOF |
| 203 | " |
| 204 | |
| 205 | test_expect_success 'test --parseopt --stuck-long' ' |
| 206 | git rev-parse --parseopt --stuck-long -- --foo --bar=z -b arg -CZ -dA <optionspec >output && |
| 207 | test_cmp expect output |
| 208 | ' |
| 209 | |
| 210 | test_expect_success 'setup expect.7' " |
| 211 | cat > expect <<EOF |
| 212 | set -- --data='' -C --baz -- 'arg' |
| 213 | EOF |
| 214 | " |
| 215 | |
| 216 | test_expect_success 'test --parseopt --stuck-long and empty optional argument' ' |
| 217 | git rev-parse --parseopt --stuck-long -- --data= arg -C -b <optionspec >output && |
| 218 | test_cmp expect output |
| 219 | ' |
| 220 | |
| 221 | test_expect_success 'setup expect.8' " |
| 222 | cat > expect <<EOF |
| 223 | set -- --data --baz -- 'arg' |
| 224 | EOF |
| 225 | " |
| 226 | |
| 227 | test_expect_success 'test --parseopt --stuck-long and long option with unset optional argument' ' |
| 228 | git rev-parse --parseopt --stuck-long -- --data arg -b <optionspec >output && |
| 229 | test_cmp expect output |
| 230 | ' |
| 231 | |
| 232 | test_expect_success 'test --parseopt --stuck-long and short option with unset optional argument' ' |
| 233 | git rev-parse --parseopt --stuck-long -- -d arg -b <optionspec >output && |
| 234 | test_cmp expect output |
| 235 | ' |
| 236 | |
| 237 | test_expect_success 'test --parseopt help output: "wrapped" options normal "or:" lines' ' |
| 238 | sed -e "s/^|//" >spec <<-\EOF && |
| 239 | |cmd [--some-option] |
| 240 | | [--another-option] |
| 241 | |cmd [--yet-another-option] |
| 242 | |-- |
| 243 | |h,help! show the help |
| 244 | EOF |
| 245 | |
| 246 | sed -e "s/^|//" >expect <<-\END_EXPECT && |
| 247 | |cat <<\EOF |
| 248 | |usage: cmd [--some-option] |
| 249 | | or: [--another-option] |
| 250 | | or: cmd [--yet-another-option] |
| 251 | | |
| 252 | | -h, --help show the help |
| 253 | | |
| 254 | |EOF |
| 255 | END_EXPECT |
| 256 | |
| 257 | test_must_fail git rev-parse --parseopt -- -h <spec >actual && |
| 258 | test_cmp expect actual |
| 259 | ' |
| 260 | |
| 261 | test_expect_success 'test --parseopt invalid opt-spec' ' |
| 262 | test_write_lines x -- "=, x" >spec && |
| 263 | echo "fatal: missing opt-spec before option flags" >expect && |
| 264 | test_must_fail git rev-parse --parseopt -- <spec 2>err && |
| 265 | test_cmp expect err |
| 266 | ' |
| 267 | |
| 268 | test_expect_success 'test --parseopt help output: multi-line blurb after empty line' ' |
| 269 | sed -e "s/^|//" >spec <<-\EOF && |
| 270 | |cmd [--some-option] |
| 271 | | [--another-option] |
| 272 | | |
| 273 | |multi |
| 274 | |line |
| 275 | |blurb |
| 276 | |-- |
| 277 | |h,help! show the help |
| 278 | EOF |
| 279 | |
| 280 | sed -e "s/^|//" >expect <<-\END_EXPECT && |
| 281 | |cat <<\EOF |
| 282 | |usage: cmd [--some-option] |
| 283 | | or: [--another-option] |
| 284 | | |
| 285 | | multi |
| 286 | | line |
| 287 | | blurb |
| 288 | | |
| 289 | | -h, --help show the help |
| 290 | | |
| 291 | |EOF |
| 292 | END_EXPECT |
| 293 | |
| 294 | test_must_fail git rev-parse --parseopt -- -h <spec >actual && |
| 295 | test_cmp expect actual |
| 296 | ' |
| 297 | |
| 298 | test_expect_success 'test --parseopt help output for optionspec-neg' ' |
| 299 | test_expect_code 129 git rev-parse --parseopt -- \ |
| 300 | -h >output <"$TEST_DIRECTORY/t1502/optionspec-neg" && |
| 301 | test_cmp "$TEST_DIRECTORY/t1502/optionspec-neg.help" output |
| 302 | ' |
| 303 | |
| 304 | test_expect_success 'test --parseopt valid options for optionspec-neg' ' |
| 305 | cat >expect <<-\EOF && |
| 306 | set -- --foo --no-foo --no-bar --positive-only --no-negative -- |
| 307 | EOF |
| 308 | git rev-parse --parseopt -- <"$TEST_DIRECTORY/t1502/optionspec-neg" >output \ |
| 309 | --foo --no-foo --no-bar --positive-only --no-negative && |
| 310 | test_cmp expect output |
| 311 | ' |
| 312 | |
| 313 | test_expect_success 'test --parseopt positivated option for optionspec-neg' ' |
| 314 | cat >expect <<-\EOF && |
| 315 | set -- --no-no-bar --no-no-bar -- |
| 316 | EOF |
| 317 | git rev-parse --parseopt -- <"$TEST_DIRECTORY/t1502/optionspec-neg" >output \ |
| 318 | --no-no-bar --bar && |
| 319 | test_cmp expect output |
| 320 | ' |
| 321 | |
| 322 | check_invalid_long_option optionspec-neg --no-positive-only |
| 323 | check_invalid_long_option optionspec-neg --negative |
| 324 | check_invalid_long_option optionspec-neg --no-no-negative |
| 325 | |
| 326 | test_expect_success 'ambiguous: --no matches both --noble and --no-noble' ' |
| 327 | cat >spec <<-\EOF && |
| 328 | some-command [options] |
| 329 | -- |
| 330 | noble The feudal switch. |
| 331 | EOF |
| 332 | test_expect_code 129 env GIT_TEST_DISALLOW_ABBREVIATED_OPTIONS=false \ |
| 333 | git rev-parse --parseopt -- <spec 2>err --no && |
| 334 | grep "error: ambiguous option: no (could be --noble or --no-noble)" err |
| 335 | ' |
| 336 | |
| 337 | test_done |