chainlint: make error messages self-explanatory
The annotations emitted by chainlint to indicate detected problems are overly terse, so much so that developers new to the project -- those who should most benefit from the linting -- may find them baffling. For instance, although the author of chainlint and seasoned Git developers may understand that "?!AMP?!" is an abbreviation of "ampersand" and indicates a break in the &&-chain, this may not be obvious to newcomers. The "?!LOOP?!" case is particularly serious because that terse single word does nothing to convey that the loop body should end with "|| return 1" (or "|| exit 1" in a subshell) to ensure that a failing command in the body aborts the loop immediately. Moreover, unlike &&-chaining which is ubiquitous in Git tests, the "|| return 1" idiom is relatively infrequent, thus may be harder for a newcomer to discover by consulting nearby code. Address these shortcomings by emitting human-readable messages which both explain the problem and give a strong hint about how to correct it. Signed-off-by: Eric Sunshine <sunshine@sunshineco.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>maint
							parent
							
								
									588ef84ece
								
							
						
					
					
						commit
						e44f15ba3e
					
				|  | @ -9,9 +9,9 @@ | |||
| # Input arguments are pathnames of shell scripts containing test definitions, | ||||
| # or globs referencing a collection of scripts. For each problem discovered, | ||||
| # the pathname of the script containing the test is printed along with the test | ||||
| # name and the test body with a `?!FOO?!` annotation at the location of each | ||||
| # detected problem, where "FOO" is a tag such as "AMP" which indicates a broken | ||||
| # &&-chain. Returns zero if no problems are discovered, otherwise non-zero. | ||||
| # name and the test body with a `?!LINT: ...?!` annotation at the location of | ||||
| # each detected problem, where "..." is an explanation of the problem. Returns | ||||
| # zero if no problems are discovered, otherwise non-zero. | ||||
|  | ||||
| use warnings; | ||||
| use strict; | ||||
|  | @ -181,7 +181,7 @@ sub swallow_heredocs { | |||
| 			$self->{lineno} += () = $body =~ /\n/sg; | ||||
| 			next; | ||||
| 		} | ||||
| 		push(@{$self->{parser}->{problems}}, ['UNCLOSED-HEREDOC', $tag]); | ||||
| 		push(@{$self->{parser}->{problems}}, ['HEREDOC', $tag]); | ||||
| 		$$b =~ /(?:\G|\n).*\z/gc; # consume rest of input | ||||
| 		my $body = substr($$b, $start, pos($$b) - $start); | ||||
| 		$self->{lineno} += () = $body =~ /\n/sg; | ||||
|  | @ -238,6 +238,7 @@ sub new { | |||
| 		stop => [], | ||||
| 		output => [], | ||||
| 		heredocs => {}, | ||||
| 		insubshell => 0, | ||||
| 	} => $class; | ||||
| 	$self->{lexer} = Lexer->new($self, $s); | ||||
| 	return $self; | ||||
|  | @ -296,8 +297,11 @@ sub parse_group { | |||
|  | ||||
| sub parse_subshell { | ||||
| 	my $self = shift @_; | ||||
| 	return ($self->parse(qr/^\)$/), | ||||
| 	$self->{insubshell}++; | ||||
| 	my @tokens = ($self->parse(qr/^\)$/), | ||||
| 		      $self->expect(')')); | ||||
| 	$self->{insubshell}--; | ||||
| 	return @tokens; | ||||
| } | ||||
|  | ||||
| sub parse_case_pattern { | ||||
|  | @ -528,7 +532,7 @@ sub parse_loop_body { | |||
| 	return @tokens if ends_with(\@tokens, [qr/^\|\|$/, "\n", qr/^echo$/, qr/^.+$/]); | ||||
| 	# flag missing "return/exit" handling explicit failure in loop body | ||||
| 	my $n = find_non_nl(\@tokens); | ||||
| 	push(@{$self->{problems}}, ['LOOP', $tokens[$n]]); | ||||
| 	push(@{$self->{problems}}, [$self->{insubshell} ? 'LOOPEXIT' : 'LOOPRETURN', $tokens[$n]]); | ||||
| 	return @tokens; | ||||
| } | ||||
|  | ||||
|  | @ -620,6 +624,15 @@ sub unwrap { | |||
| 	return $s | ||||
| } | ||||
|  | ||||
| sub format_problem { | ||||
| 	local $_ = shift; | ||||
| 	/^AMP$/ && return "missing '&&'"; | ||||
| 	/^LOOPRETURN$/ && return "missing '|| return 1'"; | ||||
| 	/^LOOPEXIT$/ && return "missing '|| exit 1'"; | ||||
| 	/^HEREDOC$/ && return 'unclosed heredoc'; | ||||
| 	die("unrecognized problem type '$_'\n"); | ||||
| } | ||||
|  | ||||
| sub check_test { | ||||
| 	my $self = shift @_; | ||||
| 	my $title = unwrap(shift @_); | ||||
|  | @ -643,9 +656,10 @@ sub check_test { | |||
| 	for (sort {$a->[1]->[2] <=> $b->[1]->[2]} @$problems) { | ||||
| 		my ($label, $token) = @$_; | ||||
| 		my $pos = $token->[2]; | ||||
| 		my $err = format_problem($label); | ||||
| 		$checked .= substr($body, $start, $pos - $start); | ||||
| 		$checked .= ' ' unless $checked =~ /\s$/; | ||||
| 		$checked .= "$c->{rev}$c->{red}?!$label?!$c->{reset}"; | ||||
| 		$checked .= "$c->{rev}$c->{red}?!LINT: $err?!$c->{reset}"; | ||||
| 		$checked .= ' ' unless $pos >= length($body) || | ||||
| 		    substr($body, $pos, 1) =~ /^\s/; | ||||
| 		$start = $pos; | ||||
|  |  | |||
|  | @ -4,6 +4,6 @@ | |||
| 5 	baz | ||||
| 6 ) && | ||||
| 7 ( | ||||
| 8 	bar=$((42 + 1)) ?!AMP?! | ||||
| 8 	bar=$((42 + 1)) ?!LINT: missing '&&'?! | ||||
| 9 	baz | ||||
| 10 ) | ||||
|  |  | |||
|  | @ -1,20 +1,20 @@ | |||
| 2 ( | ||||
| 3 	foo && | ||||
| 4 	{ | ||||
| 5 		echo a ?!AMP?! | ||||
| 5 		echo a ?!LINT: missing '&&'?! | ||||
| 6 		echo b | ||||
| 7 	} && | ||||
| 8 	bar && | ||||
| 9 	{ | ||||
| 10 		echo c | ||||
| 11 	} ?!AMP?! | ||||
| 11 	} ?!LINT: missing '&&'?! | ||||
| 12 	baz | ||||
| 13 ) && | ||||
| 14  | ||||
| 15 { | ||||
| 16 	echo a; ?!AMP?! echo b | ||||
| 16 	echo a; ?!LINT: missing '&&'?! echo b | ||||
| 17 } && | ||||
| 18 { echo a; ?!AMP?! echo b; } && | ||||
| 18 { echo a; ?!LINT: missing '&&'?! echo b; } && | ||||
| 19  | ||||
| 20 { | ||||
| 21 	echo "${var}9" && | ||||
|  |  | |||
|  | @ -1,6 +1,6 @@ | |||
| 2 ( | ||||
| 3 	foo && | ||||
| 4 	bar ?!AMP?! | ||||
| 4 	bar ?!LINT: missing '&&'?! | ||||
| 5 	baz && | ||||
| 6 	wop | ||||
| 7 ) | ||||
|  |  | |||
|  | @ -9,11 +9,11 @@ | |||
| 10 	case "$x" in | ||||
| 11 	x) foo ;; | ||||
| 12 	*) bar ;; | ||||
| 13 	esac ?!AMP?! | ||||
| 13 	esac ?!LINT: missing '&&'?! | ||||
| 14 	foobar | ||||
| 15 ) && | ||||
| 16 ( | ||||
| 17 	case "$x" in 1) true;; esac && | ||||
| 18 	case "$y" in 2) false;; esac ?!AMP?! | ||||
| 18 	case "$y" in 2) false;; esac ?!LINT: missing '&&'?! | ||||
| 19 	foobar | ||||
| 20 ) | ||||
|  |  | |||
|  | @ -4,6 +4,6 @@ | |||
| 5 	echo failed! | ||||
| 6 	false | ||||
| 7 else | ||||
| 8 	echo it went okay ?!AMP?! | ||||
| 8 	echo it went okay ?!LINT: missing '&&'?! | ||||
| 9 	congratulate user | ||||
| 10 fi | ||||
|  |  | |||
|  | @ -1,5 +1,5 @@ | |||
| 2 echo nobody home && { | ||||
| 3 	test the doohicky ?!AMP?! | ||||
| 3 	test the doohicky ?!LINT: missing '&&'?! | ||||
| 4 	right now | ||||
| 5 } && | ||||
| 6  | ||||
|  |  | |||
|  | @ -1,10 +1,10 @@ | |||
| 2 mkdir sub && ( | ||||
| 3 	cd sub && | ||||
| 4 	foo the bar ?!AMP?! | ||||
| 4 	foo the bar ?!LINT: missing '&&'?! | ||||
| 5 	nuff said | ||||
| 6 ) && | ||||
| 7  | ||||
| 8 cut "-d " -f actual | (read s1 s2 s3 && | ||||
| 9 test -f $s1 ?!AMP?! | ||||
| 9 test -f $s1 ?!LINT: missing '&&'?! | ||||
| 10 test $(cat $s2) = tree2path1 && | ||||
| 11 test $(cat $s3) = tree3path1) | ||||
|  |  | |||
|  | @ -4,6 +4,6 @@ | |||
| 5 	baz | ||||
| 6 ) && | ||||
| 7 ( | ||||
| 8 	bar=$(gobble blocks) ?!AMP?! | ||||
| 8 	bar=$(gobble blocks) ?!LINT: missing '&&'?! | ||||
| 9 	baz | ||||
| 10 ) | ||||
|  |  | |||
|  | @ -4,6 +4,6 @@ | |||
| 5      : | ||||
| 6    else | ||||
| 7      echo >file | ||||
| 8    fi ?!LOOP?! | ||||
| 8    fi ?!LINT: missing '|| exit 1'?! | ||||
| 9  done) && | ||||
| 10 test ! -f file | ||||
|  |  | |||
|  | @ -2,7 +2,7 @@ | |||
| 3 	bar | ||||
| 4 ) && | ||||
| 5  | ||||
| 6 (cd foo ?!AMP?! | ||||
| 6 (cd foo ?!LINT: missing '&&'?! | ||||
| 7 	bar | ||||
| 8 ) && | ||||
| 9  | ||||
|  | @ -13,5 +13,5 @@ | |||
| 14 (cd foo && | ||||
| 15 	bar) && | ||||
| 16  | ||||
| 17 (cd foo ?!AMP?! | ||||
| 17 (cd foo ?!LINT: missing '&&'?! | ||||
| 18 	bar) | ||||
|  |  | |||
|  | @ -1,14 +1,14 @@ | |||
| 2 ( | ||||
| 3 	for i in a b c | ||||
| 4 	do | ||||
| 5 		echo $i ?!AMP?! | ||||
| 6 		cat <<-\EOF ?!LOOP?! | ||||
| 5 		echo $i ?!LINT: missing '&&'?! | ||||
| 6 		cat <<-\EOF ?!LINT: missing '|| exit 1'?! | ||||
| 7 		bar | ||||
| 8 		EOF | ||||
| 9 	done ?!AMP?! | ||||
| 9 	done ?!LINT: missing '&&'?! | ||||
| 10  | ||||
| 11 	for i in a b c; do | ||||
| 12 		echo $i && | ||||
| 13 		cat $i ?!LOOP?! | ||||
| 13 		cat $i ?!LINT: missing '|| exit 1'?! | ||||
| 14 	done | ||||
| 15 ) | ||||
|  |  | |||
|  | @ -4,8 +4,8 @@ | |||
| 5  | ||||
| 6 remove_object() { | ||||
| 7 	file=$(sha1_file "$*") && | ||||
| 8 	test -e "$file" ?!AMP?! | ||||
| 8 	test -e "$file" ?!LINT: missing '&&'?! | ||||
| 9 	rm -f "$file" | ||||
| 10 } ?!AMP?! | ||||
| 10 } ?!LINT: missing '&&'?! | ||||
| 11  | ||||
| 12 sha1_file arg && remove_object arg | ||||
|  |  | |||
|  | @ -1,2 +1,2 @@ | |||
| 2 	echo "we should find this" ?!AMP?! | ||||
| 2 	echo "we should find this" ?!LINT: missing '&&'?! | ||||
| 3 	echo "even though our heredoc has its indent stripped" | ||||
|  |  | |||
|  | @ -1,7 +1,7 @@ | |||
| 2 	echo "outer here-doc does not allow indented end-tag" ?!AMP?! | ||||
| 2 	echo "outer here-doc does not allow indented end-tag" ?!LINT: missing '&&'?! | ||||
| 3 	cat >file <<-\EOF && | ||||
| 4 	but this inner here-doc | ||||
| 5 	does allow indented EOF | ||||
| 6 	EOF | ||||
| 7 	echo "missing chain after" ?!AMP?! | ||||
| 7 	echo "missing chain after" ?!LINT: missing '&&'?! | ||||
| 8 	echo "but this line is OK because it's the end" | ||||
|  |  | |||
|  | @ -1,7 +1,7 @@ | |||
| 2 	echo "missing chain before" ?!AMP?! | ||||
| 2 	echo "missing chain before" ?!LINT: missing '&&'?! | ||||
| 3 	cat >file <<-\EOF && | ||||
| 4 	inside inner here-doc | ||||
| 5 	these are not shell commands | ||||
| 6 	EOF | ||||
| 7 	echo "missing chain after" ?!AMP?! | ||||
| 7 	echo "missing chain after" ?!LINT: missing '&&'?! | ||||
| 8 	echo "but this line is OK because it's the end" | ||||
|  |  | |||
|  | @ -1,2 +1,2 @@ | |||
| 8 	echo "actual test commands" ?!AMP?! | ||||
| 8 	echo "actual test commands" ?!LINT: missing '&&'?! | ||||
| 9 	echo "that should be checked" | ||||
|  |  | |||
|  | @ -4,7 +4,7 @@ | |||
| 5 chunks: oid_fanout oid_lookup commit_metadata generation_data bloom_indexes bloom_data | ||||
| 6 EOF | ||||
| 7  | ||||
| 8 cat >expect << -EOF ?!AMP?! | ||||
| 8 cat >expect << -EOF ?!LINT: missing '&&'?! | ||||
| 9 this is not indented | ||||
| 10 -EOF | ||||
| 11  | ||||
|  |  | |||
|  | @ -3,6 +3,6 @@ | |||
| 4 		fossil | ||||
| 5 		vegetable | ||||
| 6 		END | ||||
| 7 		wiffle) ?!AMP?! | ||||
| 7 		wiffle) ?!LINT: missing '&&'?! | ||||
| 8 	echo $x | ||||
| 9 ) | ||||
|  |  | |||
|  | @ -1,6 +1,6 @@ | |||
| 2 ( | ||||
| 3 	cat <<-\TXT && echo "multi-line | ||||
| 4 	string" ?!AMP?! | ||||
| 4 	string" ?!LINT: missing '&&'?! | ||||
| 5 	fizzle | ||||
| 6 	TXT | ||||
| 7 	bap | ||||
|  |  | |||
|  | @ -2,6 +2,6 @@ | |||
| 3    marcia || | ||||
| 4    kevin | ||||
| 5 then | ||||
| 6 	echo "nomads" ?!AMP?! | ||||
| 6 	echo "nomads" ?!LINT: missing '&&'?! | ||||
| 7 	echo "for sure" | ||||
| 8 fi | ||||
|  |  | |||
|  | @ -5,8 +5,8 @@ | |||
| 6 		then | ||||
| 7 			echo "err" | ||||
| 8 			exit 1 | ||||
| 9 		fi ?!AMP?! | ||||
| 9 		fi ?!LINT: missing '&&'?! | ||||
| 10 		foo | ||||
| 11 	done ?!AMP?! | ||||
| 11 	done ?!LINT: missing '&&'?! | ||||
| 12 	bar | ||||
| 13 ) | ||||
|  |  | |||
|  | @ -1,7 +1,7 @@ | |||
| 2 ( | ||||
| 3 	if test -n "" | ||||
| 4 	then | ||||
| 5 		echo very ?!AMP?! | ||||
| 5 		echo very ?!LINT: missing '&&'?! | ||||
| 6 		echo empty | ||||
| 7 	elif test -z "" | ||||
| 8 	then | ||||
|  | @ -11,7 +11,7 @@ | |||
| 12 		cat <<-\EOF | ||||
| 13 		bar | ||||
| 14 		EOF | ||||
| 15 	fi ?!AMP?! | ||||
| 15 	fi ?!LINT: missing '&&'?! | ||||
| 16 	echo poodle | ||||
| 17 ) && | ||||
| 18 ( | ||||
|  |  | |||
|  | @ -1,6 +1,6 @@ | |||
| 2 ( | ||||
| 3 	foobar && # comment 1 | ||||
| 4 	barfoo ?!AMP?! # wrong position for && | ||||
| 4 	barfoo ?!LINT: missing '&&'?! # wrong position for && | ||||
| 5 	flibble "not a # comment" | ||||
| 6 ) && | ||||
| 7  | ||||
|  |  | |||
|  | @ -11,5 +11,5 @@ | |||
| 12 do | ||||
| 13 	printf "%"$n"s" X > r2/large.$n && | ||||
| 14 	git -C r2 add large.$n && | ||||
| 15 	git -C r2 commit -m "$n" ?!LOOP?! | ||||
| 15 	git -C r2 commit -m "$n" ?!LINT: missing '|| return 1'?! | ||||
| 16 done | ||||
|  |  | |||
|  | @ -3,10 +3,10 @@ | |||
| 4 	then | ||||
| 5 		while true | ||||
| 6 		do | ||||
| 7 			echo "pop" ?!AMP?! | ||||
| 8 			echo "glup" ?!LOOP?! | ||||
| 9 		done ?!AMP?! | ||||
| 7 			echo "pop" ?!LINT: missing '&&'?! | ||||
| 8 			echo "glup" ?!LINT: missing '|| exit 1'?! | ||||
| 9 		done ?!LINT: missing '&&'?! | ||||
| 10 		foo | ||||
| 11 	fi ?!AMP?! | ||||
| 11 	fi ?!LINT: missing '&&'?! | ||||
| 12 	bar | ||||
| 13 ) | ||||
|  |  | |||
|  | @ -3,7 +3,7 @@ | |||
| 4 		line 2 | ||||
| 5 		line 3" && | ||||
| 6 	y="line 1 | ||||
| 7 		line2" ?!AMP?! | ||||
| 7 		line2" ?!LINT: missing '&&'?! | ||||
| 8 	foobar | ||||
| 9 ) && | ||||
| 10 ( | ||||
|  |  | |||
|  | @ -1,5 +1,5 @@ | |||
| 2 ! (foo && bar) && | ||||
| 3 ! (foo && bar) >baz && | ||||
| 4  | ||||
| 5 ! (foo; ?!AMP?! bar) && | ||||
| 6 ! (foo; ?!AMP?! bar) >baz | ||||
| 5 ! (foo; ?!LINT: missing '&&'?! bar) && | ||||
| 6 ! (foo; ?!LINT: missing '&&'?! bar) >baz | ||||
|  |  | |||
|  | @ -5,7 +5,7 @@ | |||
| 6  | ||||
| 7 	(cd foo && | ||||
| 8 		bar | ||||
| 9 	) ?!AMP?! | ||||
| 9 	) ?!LINT: missing '&&'?! | ||||
| 10  | ||||
| 11 	( | ||||
| 12 		cd foo && | ||||
|  | @ -13,13 +13,13 @@ | |||
| 14  | ||||
| 15 	( | ||||
| 16 		cd foo && | ||||
| 17 		bar) ?!AMP?! | ||||
| 17 		bar) ?!LINT: missing '&&'?! | ||||
| 18  | ||||
| 19 	(cd foo && | ||||
| 20 		bar) && | ||||
| 21  | ||||
| 22 	(cd foo && | ||||
| 23 		bar) ?!AMP?! | ||||
| 23 		bar) ?!LINT: missing '&&'?! | ||||
| 24  | ||||
| 25 	foobar | ||||
| 26 ) | ||||
|  |  | |||
|  | @ -18,7 +18,7 @@ | |||
| 19 	toink | ||||
| 20 	INPUT_END | ||||
| 21  | ||||
| 22 	cat <<-\EOT ?!AMP?! | ||||
| 22 	cat <<-\EOT ?!LINT: missing '&&'?! | ||||
| 23 	text goes here | ||||
| 24 	data <<EOF | ||||
| 25 		data goes here | ||||
|  |  | |||
|  | @ -2,8 +2,8 @@ | |||
| 3 do | ||||
| 4 	for j in 0 1 2 3 4 5 6 7 8 9; | ||||
| 5 	do | ||||
| 6 		echo "$i$j" >"path$i$j" ?!LOOP?! | ||||
| 7 	done ?!LOOP?! | ||||
| 6 		echo "$i$j" >"path$i$j" ?!LINT: missing '|| return 1'?! | ||||
| 7 	done ?!LINT: missing '|| return 1'?! | ||||
| 8 done && | ||||
| 9  | ||||
| 10 for i in 0 1 2 3 4 5 6 7 8 9; | ||||
|  | @ -18,7 +18,7 @@ | |||
| 19 do | ||||
| 20 	for j in 0 1 2 3 4 5 6 7 8 9; | ||||
| 21 	do | ||||
| 22 		echo "$i$j" >"path$i$j" ?!LOOP?! | ||||
| 22 		echo "$i$j" >"path$i$j" ?!LINT: missing '|| return 1'?! | ||||
| 23 	done || return 1 | ||||
| 24 done && | ||||
| 25  | ||||
|  |  | |||
|  | @ -6,6 +6,6 @@ | |||
| 7 		# minor numbers of cows (or do they?) | ||||
| 8 		baz && | ||||
| 9 		snaff | ||||
| 10 	) ?!AMP?! | ||||
| 10 	) ?!LINT: missing '&&'?! | ||||
| 11 	fuzzy | ||||
| 12 ) | ||||
|  |  | |||
|  | @ -7,7 +7,7 @@ | |||
| 8  | ||||
| 9 	cd foo && | ||||
| 10 	( | ||||
| 11 		echo a ?!AMP?! | ||||
| 11 		echo a ?!LINT: missing '&&'?! | ||||
| 12 		echo b | ||||
| 13 	) >file | ||||
| 14 ) | ||||
|  |  | |||
|  | @ -9,6 +9,6 @@ | |||
| 10 	echo ourside && | ||||
| 11 	echo "=======" && | ||||
| 12 	echo theirside && | ||||
| 13 	echo ">>>>>>> theirs" ?!AMP?! | ||||
| 13 	echo ">>>>>>> theirs" ?!LINT: missing '&&'?! | ||||
| 14 	poodle | ||||
| 15 ) >merged | ||||
|  |  | |||
|  | @ -3,7 +3,7 @@ | |||
| 4 	cd dir-rename-and-content && | ||||
| 5 	test_write_lines 1 2 3 4 5 >foo && | ||||
| 6 	mkdir olddir && | ||||
| 7 	for i in a b c; do echo $i >olddir/$i; ?!LOOP?! done ?!AMP?! | ||||
| 7 	for i in a b c; do echo $i >olddir/$i; ?!LINT: missing '|| exit 1'?! done ?!LINT: missing '&&'?! | ||||
| 8 	git add foo olddir && | ||||
| 9 	git commit -m "original" && | ||||
| 10 ) | ||||
|  |  | |||
|  | @ -2,8 +2,8 @@ | |||
| 3 (foo && bar) | | ||||
| 4 (foo && bar) >baz && | ||||
| 5  | ||||
| 6 (foo; ?!AMP?! bar) && | ||||
| 7 (foo; ?!AMP?! bar) | | ||||
| 8 (foo; ?!AMP?! bar) >baz && | ||||
| 6 (foo; ?!LINT: missing '&&'?! bar) && | ||||
| 7 (foo; ?!LINT: missing '&&'?! bar) | | ||||
| 8 (foo; ?!LINT: missing '&&'?! bar) >baz && | ||||
| 9  | ||||
| 10 (foo "bar; baz") | ||||
|  |  | |||
|  | @ -4,7 +4,7 @@ | |||
| 5 	baz && | ||||
| 6  | ||||
| 7 	fish | | ||||
| 8 	cow ?!AMP?! | ||||
| 8 	cow ?!LINT: missing '&&'?! | ||||
| 9  | ||||
| 10 	sunder | ||||
| 11 ) | ||||
|  |  | |||
|  | @ -1,19 +1,19 @@ | |||
| 2 ( | ||||
| 3 	cat foo ; ?!AMP?! echo bar ?!AMP?! | ||||
| 4 	cat foo ; ?!AMP?! echo bar | ||||
| 3 	cat foo ; ?!LINT: missing '&&'?! echo bar ?!LINT: missing '&&'?! | ||||
| 4 	cat foo ; ?!LINT: missing '&&'?! echo bar | ||||
| 5 ) && | ||||
| 6 ( | ||||
| 7 	cat foo ; ?!AMP?! echo bar && | ||||
| 8 	cat foo ; ?!AMP?! echo bar | ||||
| 7 	cat foo ; ?!LINT: missing '&&'?! echo bar && | ||||
| 8 	cat foo ; ?!LINT: missing '&&'?! echo bar | ||||
| 9 ) && | ||||
| 10 ( | ||||
| 11 	echo "foo; bar" && | ||||
| 12 	cat foo; ?!AMP?! echo bar | ||||
| 12 	cat foo; ?!LINT: missing '&&'?! echo bar | ||||
| 13 ) && | ||||
| 14 ( | ||||
| 15 	foo; | ||||
| 16 ) && | ||||
| 17 (cd foo && | ||||
| 18 	for i in a b c; do | ||||
| 19 		echo; ?!LOOP?! | ||||
| 19 		echo; ?!LINT: missing '|| exit 1'?! | ||||
| 20 	done) | ||||
|  |  | |||
|  | @ -6,7 +6,7 @@ | |||
| 7 	nevermore... | ||||
| 8 	EOF | ||||
| 9  | ||||
| 10 	cat <<EOF >bip ?!AMP?! | ||||
| 10 	cat <<EOF >bip ?!LINT: missing '&&'?! | ||||
| 11 	fish fly high | ||||
| 12 EOF | ||||
| 13  | ||||
|  |  | |||
|  | @ -3,17 +3,17 @@ | |||
| 4 	(foo && bar) | | ||||
| 5 	(foo && bar) >baz && | ||||
| 6  | ||||
| 7 	(foo; ?!AMP?! bar) && | ||||
| 8 	(foo; ?!AMP?! bar) | | ||||
| 9 	(foo; ?!AMP?! bar) >baz && | ||||
| 7 	(foo; ?!LINT: missing '&&'?! bar) && | ||||
| 8 	(foo; ?!LINT: missing '&&'?! bar) | | ||||
| 9 	(foo; ?!LINT: missing '&&'?! bar) >baz && | ||||
| 10  | ||||
| 11 	(foo || exit 1) && | ||||
| 12 	(foo || exit 1) | | ||||
| 13 	(foo || exit 1) >baz && | ||||
| 14  | ||||
| 15 	(foo && bar) ?!AMP?! | ||||
| 15 	(foo && bar) ?!LINT: missing '&&'?! | ||||
| 16  | ||||
| 17 	(foo && bar; ?!AMP?! baz) ?!AMP?! | ||||
| 17 	(foo && bar; ?!LINT: missing '&&'?! baz) ?!LINT: missing '&&'?! | ||||
| 18  | ||||
| 19 	foobar | ||||
| 20 ) | ||||
|  |  | |||
|  | @ -2,13 +2,13 @@ | |||
| 3 git config filter.rot13.clean ./rot13.sh && | ||||
| 4  | ||||
| 5 { | ||||
| 6     echo "*.t filter=rot13" ?!AMP?! | ||||
| 6     echo "*.t filter=rot13" ?!LINT: missing '&&'?! | ||||
| 7     echo "*.i ident" | ||||
| 8 } >.gitattributes && | ||||
| 9  | ||||
| 10 { | ||||
| 11     echo a b c d e f g h i j k l m ?!AMP?! | ||||
| 12     echo n o p q r s t u v w x y z ?!AMP?! | ||||
| 11     echo a b c d e f g h i j k l m ?!LINT: missing '&&'?! | ||||
| 12     echo n o p q r s t u v w x y z ?!LINT: missing '&&'?! | ||||
| 13     echo '$Id$' | ||||
| 14 } >test && | ||||
| 15 cat test >test.t && | ||||
|  | @ -19,7 +19,7 @@ | |||
| 20 git checkout -- test test.t test.i && | ||||
| 21  | ||||
| 22 echo "content-test2" >test2.o && | ||||
| 23 echo "content-test3 - filename with special characters" >"test3 'sq',$x=.o" ?!AMP?! | ||||
| 23 echo "content-test3 - filename with special characters" >"test3 'sq',$x=.o" ?!LINT: missing '&&'?! | ||||
| 24  | ||||
| 25 downstream_url_for_sed=$( | ||||
| 26 	printf "%sn" "$downstream_url" | | ||||
|  |  | |||
|  | @ -1,4 +1,4 @@ | |||
| 2 command_which_is_run && | ||||
| 3 cat >expect <<-\EOF ?!UNCLOSED-HEREDOC?! && | ||||
| 3 cat >expect <<-\EOF ?!LINT: unclosed heredoc?! && | ||||
| 4 we forget to end the here-doc | ||||
| 5 command_which_is_gobbled | ||||
|  |  | |||
|  | @ -1,5 +1,5 @@ | |||
| 2 command_which_is_run && | ||||
| 3 cat >expect <<\EOF ?!UNCLOSED-HEREDOC?! && | ||||
| 3 cat >expect <<\EOF ?!LINT: unclosed heredoc?! && | ||||
| 4 	we try to end the here-doc below, | ||||
| 5 	but the indentation throws us off | ||||
| 6 	since the operator is not "<<-". | ||||
|  |  | |||
|  | @ -1,14 +1,14 @@ | |||
| 2 ( | ||||
| 3 	while true | ||||
| 4 	do | ||||
| 5 		echo foo ?!AMP?! | ||||
| 6 		cat <<-\EOF ?!LOOP?! | ||||
| 5 		echo foo ?!LINT: missing '&&'?! | ||||
| 6 		cat <<-\EOF ?!LINT: missing '|| exit 1'?! | ||||
| 7 		bar | ||||
| 8 		EOF | ||||
| 9 	done ?!AMP?! | ||||
| 9 	done ?!LINT: missing '&&'?! | ||||
| 10  | ||||
| 11 	while true; do | ||||
| 12 		echo foo && | ||||
| 13 		cat bar ?!LOOP?! | ||||
| 13 		cat bar ?!LINT: missing '|| exit 1'?! | ||||
| 14 	done | ||||
| 15 ) | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 Eric Sunshine
						Eric Sunshine