| 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 /EOF/d -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 | 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 | |exit 0 |
| 91 | END_EXPECT |
| 92 | git rev-parse --parseopt -- -h > output < optionspec_no_switches && |
| 93 | test_cmp expect output |
| 94 | ' |
| 95 | |
| 96 | test_expect_success 'test --parseopt help output hidden switches' ' |
| 97 | sed -e "s/^|//" >expect <<\END_EXPECT && |
| 98 | |cat <<\EOF |
| 99 | |usage: some-command [options] <args>... |
| 100 | | |
| 101 | | some-command does foo and bar! |
| 102 | | |
| 103 | |EOF |
| 104 | |exit 0 |
| 105 | END_EXPECT |
| 106 | git rev-parse --parseopt -- -h > output < optionspec_only_hidden_switches && |
| 107 | test_cmp expect output |
| 108 | ' |
| 109 | |
| 110 | test_expect_success 'test --parseopt help-all output hidden switches' ' |
| 111 | sed -e "s/^|//" >expect <<\END_EXPECT && |
| 112 | |cat <<\EOF |
| 113 | |usage: some-command [options] <args>... |
| 114 | | |
| 115 | | some-command does foo and bar! |
| 116 | | |
| 117 | | --[no-]hidden1 A hidden switch |
| 118 | | |
| 119 | |EOF |
| 120 | |exit 0 |
| 121 | END_EXPECT |
| 122 | git rev-parse --parseopt -- --help-all > output < optionspec_only_hidden_switches && |
| 123 | test_cmp expect output |
| 124 | ' |
| 125 | |
| 126 | test_expect_success 'test --parseopt invalid switch help output' ' |
| 127 | { |
| 128 | cat <<-\EOF && |
| 129 | error: unknown option `does-not-exist'\'' |
| 130 | EOF |
| 131 | sed -e 1d -e /EOF/d -e \$d <"$TEST_DIRECTORY/t1502/optionspec.help" |
| 132 | } >expect && |
| 133 | test_expect_code 129 git rev-parse --parseopt -- --does-not-exist 1>/dev/null 2>output < optionspec && |
| 134 | test_cmp expect output |
| 135 | ' |
| 136 | |
| 137 | test_expect_success 'setup expect.1' " |
| 138 | cat > expect <<EOF |
| 139 | set -- --foo --bar 'ham' -b --aswitch -- 'arg' |
| 140 | EOF |
| 141 | " |
| 142 | |
| 143 | test_expect_success 'test --parseopt' ' |
| 144 | git rev-parse --parseopt -- --foo --bar=ham --baz --aswitch arg < optionspec > output && |
| 145 | test_cmp expect output |
| 146 | ' |
| 147 | |
| 148 | test_expect_success 'test --parseopt with mixed options and arguments' ' |
| 149 | git rev-parse --parseopt -- --foo arg --bar=ham --baz --aswitch < optionspec > output && |
| 150 | test_cmp expect output |
| 151 | ' |
| 152 | |
| 153 | test_expect_success 'setup expect.2' " |
| 154 | cat > expect <<EOF |
| 155 | set -- --foo -- 'arg' '--bar=ham' |
| 156 | EOF |
| 157 | " |
| 158 | |
| 159 | test_expect_success 'test --parseopt with --' ' |
| 160 | git rev-parse --parseopt -- --foo -- arg --bar=ham < optionspec > output && |
| 161 | test_cmp expect output |
| 162 | ' |
| 163 | |
| 164 | test_expect_success 'test --parseopt --stop-at-non-option' ' |
| 165 | git rev-parse --parseopt --stop-at-non-option -- --foo arg --bar=ham < optionspec > output && |
| 166 | test_cmp expect output |
| 167 | ' |
| 168 | |
| 169 | test_expect_success 'setup expect.3' " |
| 170 | cat > expect <<EOF |
| 171 | set -- --foo -- '--' 'arg' '--bar=ham' |
| 172 | EOF |
| 173 | " |
| 174 | |
| 175 | test_expect_success 'test --parseopt --keep-dashdash' ' |
| 176 | git rev-parse --parseopt --keep-dashdash -- --foo -- arg --bar=ham < optionspec > output && |
| 177 | test_cmp expect output |
| 178 | ' |
| 179 | |
| 180 | test_expect_success 'setup expect.4' " |
| 181 | cat >expect <<EOF |
| 182 | set -- --foo -- '--' 'arg' '--spam=ham' |
| 183 | EOF |
| 184 | " |
| 185 | |
| 186 | test_expect_success 'test --parseopt --keep-dashdash --stop-at-non-option with --' ' |
| 187 | git rev-parse --parseopt --keep-dashdash --stop-at-non-option -- --foo -- arg --spam=ham <optionspec >output && |
| 188 | test_cmp expect output |
| 189 | ' |
| 190 | |
| 191 | test_expect_success 'setup expect.5' " |
| 192 | cat > expect <<EOF |
| 193 | set -- --foo -- 'arg' '--spam=ham' |
| 194 | EOF |
| 195 | " |
| 196 | |
| 197 | test_expect_success 'test --parseopt --keep-dashdash --stop-at-non-option without --' ' |
| 198 | git rev-parse --parseopt --keep-dashdash --stop-at-non-option -- --foo arg --spam=ham <optionspec >output && |
| 199 | test_cmp expect output |
| 200 | ' |
| 201 | |
| 202 | test_expect_success 'setup expect.6' " |
| 203 | cat > expect <<EOF |
| 204 | set -- --foo --bar='z' --baz -C'Z' --data='A' -- 'arg' |
| 205 | EOF |
| 206 | " |
| 207 | |
| 208 | test_expect_success 'test --parseopt --stuck-long' ' |
| 209 | git rev-parse --parseopt --stuck-long -- --foo --bar=z -b arg -CZ -dA <optionspec >output && |
| 210 | test_cmp expect output |
| 211 | ' |
| 212 | |
| 213 | test_expect_success 'setup expect.7' " |
| 214 | cat > expect <<EOF |
| 215 | set -- --data='' -C --baz -- 'arg' |
| 216 | EOF |
| 217 | " |
| 218 | |
| 219 | test_expect_success 'test --parseopt --stuck-long and empty optional argument' ' |
| 220 | git rev-parse --parseopt --stuck-long -- --data= arg -C -b <optionspec >output && |
| 221 | test_cmp expect output |
| 222 | ' |
| 223 | |
| 224 | test_expect_success 'setup expect.8' " |
| 225 | cat > expect <<EOF |
| 226 | set -- --data --baz -- 'arg' |
| 227 | EOF |
| 228 | " |
| 229 | |
| 230 | test_expect_success 'test --parseopt --stuck-long and long option with unset optional argument' ' |
| 231 | git rev-parse --parseopt --stuck-long -- --data arg -b <optionspec >output && |
| 232 | test_cmp expect output |
| 233 | ' |
| 234 | |
| 235 | test_expect_success 'test --parseopt --stuck-long and short option with unset optional argument' ' |
| 236 | git rev-parse --parseopt --stuck-long -- -d arg -b <optionspec >output && |
| 237 | test_cmp expect output |
| 238 | ' |
| 239 | |
| 240 | test_expect_success 'test --parseopt help output: "wrapped" options normal "or:" lines' ' |
| 241 | sed -e "s/^|//" >spec <<-\EOF && |
| 242 | |cmd [--some-option] |
| 243 | | [--another-option] |
| 244 | |cmd [--yet-another-option] |
| 245 | |-- |
| 246 | |h,help! show the help |
| 247 | EOF |
| 248 | |
| 249 | sed -e "s/^|//" >expect <<-\END_EXPECT && |
| 250 | |cat <<\EOF |
| 251 | |usage: cmd [--some-option] |
| 252 | | or: [--another-option] |
| 253 | | or: cmd [--yet-another-option] |
| 254 | | |
| 255 | | -h, --help show the help |
| 256 | | |
| 257 | |EOF |
| 258 | |exit 0 |
| 259 | END_EXPECT |
| 260 | |
| 261 | git rev-parse --parseopt -- -h <spec >actual && |
| 262 | test_cmp expect actual |
| 263 | ' |
| 264 | |
| 265 | test_expect_success 'test --parseopt invalid opt-spec' ' |
| 266 | test_write_lines x -- "=, x" >spec && |
| 267 | echo "fatal: missing opt-spec before option flags" >expect && |
| 268 | test_must_fail git rev-parse --parseopt -- <spec 2>err && |
| 269 | test_cmp expect err |
| 270 | ' |
| 271 | |
| 272 | test_expect_success 'test --parseopt help output: multi-line blurb after empty line' ' |
| 273 | sed -e "s/^|//" >spec <<-\EOF && |
| 274 | |cmd [--some-option] |
| 275 | | [--another-option] |
| 276 | | |
| 277 | |multi |
| 278 | |line |
| 279 | |blurb |
| 280 | |-- |
| 281 | |h,help! show the help |
| 282 | EOF |
| 283 | |
| 284 | sed -e "s/^|//" >expect <<-\END_EXPECT && |
| 285 | |cat <<\EOF |
| 286 | |usage: cmd [--some-option] |
| 287 | | or: [--another-option] |
| 288 | | |
| 289 | | multi |
| 290 | | line |
| 291 | | blurb |
| 292 | | |
| 293 | | -h, --help show the help |
| 294 | | |
| 295 | |EOF |
| 296 | |exit 0 |
| 297 | END_EXPECT |
| 298 | |
| 299 | git rev-parse --parseopt -- -h <spec >actual && |
| 300 | test_cmp expect actual |
| 301 | ' |
| 302 | |
| 303 | test_expect_success 'test --parseopt help output for optionspec-neg' ' |
| 304 | git rev-parse --parseopt -- \ |
| 305 | -h >output <"$TEST_DIRECTORY/t1502/optionspec-neg" && |
| 306 | test_cmp "$TEST_DIRECTORY/t1502/optionspec-neg.help" output |
| 307 | ' |
| 308 | |
| 309 | test_expect_success 'test --parseopt valid options for optionspec-neg' ' |
| 310 | cat >expect <<-\EOF && |
| 311 | set -- --foo --no-foo --no-bar --positive-only --no-negative -- |
| 312 | EOF |
| 313 | git rev-parse --parseopt -- <"$TEST_DIRECTORY/t1502/optionspec-neg" >output \ |
| 314 | --foo --no-foo --no-bar --positive-only --no-negative && |
| 315 | test_cmp expect output |
| 316 | ' |
| 317 | |
| 318 | test_expect_success 'test --parseopt positivated option for optionspec-neg' ' |
| 319 | cat >expect <<-\EOF && |
| 320 | set -- --no-no-bar --no-no-bar -- |
| 321 | EOF |
| 322 | git rev-parse --parseopt -- <"$TEST_DIRECTORY/t1502/optionspec-neg" >output \ |
| 323 | --no-no-bar --bar && |
| 324 | test_cmp expect output |
| 325 | ' |
| 326 | |
| 327 | check_invalid_long_option optionspec-neg --no-positive-only |
| 328 | check_invalid_long_option optionspec-neg --negative |
| 329 | check_invalid_long_option optionspec-neg --no-no-negative |
| 330 | |
| 331 | test_expect_success 'ambiguous: --no matches both --noble and --no-noble' ' |
| 332 | cat >spec <<-\EOF && |
| 333 | some-command [options] |
| 334 | -- |
| 335 | noble The feudal switch. |
| 336 | EOF |
| 337 | test_expect_code 129 env GIT_TEST_DISALLOW_ABBREVIATED_OPTIONS=false \ |
| 338 | git rev-parse --parseopt -- <spec 2>err --no && |
| 339 | test_grep "error: ambiguous option: no (could be --noble or --no-noble)" err |
| 340 | ' |
| 341 | |
| 342 | test_done |