1#!/bin/sh 2set -eu 3 4# Performs `cat` and `grep` simultaneously for `run-make` tests in the Rust CI. 5# 6# This program will read lines from stdin and print them to stdout immediately. 7# At the same time, it will check if the input line contains the substring or 8# regex specified in the command line. If any match is found, the program will 9# set the exit code to 0, otherwise 1. 10# 11# This is written to simplify debugging runmake tests. Since `grep` swallows all 12# output, when a test involving `grep` failed, it is impossible to know the 13# reason just by reading the failure log. While it is possible to `tee` the 14# output into another stream, it becomes pretty annoying to do this for all test 15# cases. 16 17USAGE=' 18cat-and-grep.sh [-v] [-e] [-i] s1 s2 s3 ... < input.txt 19 20Prints the stdin, and exits successfully only if all of `sN` can be found in 21some lines of the input. 22 23Options: 24 -v Invert match, exits successfully only if all of `sN` cannot be found 25 -e Regex search, search using extended Regex instead of fixed string 26 -i Case insensitive search. 27' 28 29GREPPER=fgrep 30INVERT=0 31GREPFLAGS='q' 32while getopts ':vieh' OPTION; do 33 case "$OPTION" in 34 v) 35 INVERT=1 36 ERROR_MSG='should not be found' 37 ;; 38 i) 39 GREPFLAGS="i$GREPFLAGS" 40 ;; 41 e) 42 GREPPER=egrep 43 ;; 44 h) 45 echo "$USAGE" 46 exit 2 47 ;; 48 *) 49 break 50 ;; 51 esac 52done 53 54shift $((OPTIND - 1)) 55 56# use gnu version of tool if available (for bsd) 57if command -v "g${GREPPER}"; then 58 GREPPER="g${GREPPER}" 59fi 60 61LOG=$(mktemp -t cgrep.XXXXXX) 62trap "rm -f $LOG" EXIT 63 64printf "[[[ begin stdout ]]]\n\033[90m" 65tee "$LOG" 66echo >> "$LOG" # ensure at least 1 line of output, otherwise `grep -v` may unconditionally fail. 67printf "\033[0m\n[[[ end stdout ]]]\n" 68 69HAS_ERROR=0 70for MATCH in "$@"; do 71 if "$GREPPER" "-$GREPFLAGS" -- "$MATCH" "$LOG"; then 72 if [ "$INVERT" = 1 ]; then 73 printf "\033[1;31mError: should not match: %s\033[0m\n" "$MATCH" 74 HAS_ERROR=1 75 fi 76 else 77 if [ "$INVERT" = 0 ]; then 78 printf "\033[1;31mError: cannot match: %s\033[0m\n" "$MATCH" 79 HAS_ERROR=1 80 fi 81 fi 82done 83 84exit "$HAS_ERROR" 85