#!/bin/sh set -eu # Performs `cat` and `grep` simultaneously for `run-make` tests in the Rust CI. # # This program will read lines from stdin and print them to stdout immediately. # At the same time, it will check if the input line contains the substring or # regex specified in the command line. If any match is found, the program will # set the exit code to 0, otherwise 1. # # This is written to simplify debugging runmake tests. Since `grep` swallows all # output, when a test involving `grep` failed, it is impossible to know the # reason just by reading the failure log. While it is possible to `tee` the # output into another stream, it becomes pretty annoying to do this for all test # cases. USAGE=' cat-and-grep.sh [-v] [-e] [-i] s1 s2 s3 ... < input.txt Prints the stdin, and exits successfully only if all of `sN` can be found in some lines of the input. Options: -v Invert match, exits successfully only if all of `sN` cannot be found -e Regex search, search using extended Regex instead of fixed string -i Case insensitive search. ' GREPPER=grep INVERT=0 GREPFLAGS='q' while getopts ':vieh' OPTION; do case "$OPTION" in v) INVERT=1 ERROR_MSG='should not be found' ;; i) GREPFLAGS="i$GREPFLAGS" ;; e) GREPFLAGS="E$GREPFLAGS" ;; h) echo "$USAGE" exit 2 ;; *) break ;; esac done if ! echo "$GREPFLAGS" | grep -q E then # use F flag if there is not an E flag GREPFLAGS="F$GREPFLAGS" fi shift $((OPTIND - 1)) # use gnu version of tool if available (for bsd) if command -v "g${GREPPER}"; then GREPPER="g${GREPPER}" fi LOG=$(mktemp -t cgrep.XXXXXX) trap "rm -f $LOG" EXIT printf "[[[ begin stdout ]]]\n\033[90m" tee "$LOG" echo >> "$LOG" # ensure at least 1 line of output, otherwise `grep -v` may unconditionally fail. printf "\033[0m\n[[[ end stdout ]]]\n" HAS_ERROR=0 for MATCH in "$@"; do if "$GREPPER" "-$GREPFLAGS" -- "$MATCH" "$LOG"; then if [ "$INVERT" = 1 ]; then printf "\033[1;31mError: should not match: %s\033[0m\n" "$MATCH" HAS_ERROR=1 fi else if [ "$INVERT" = 0 ]; then printf "\033[1;31mError: cannot match: %s\033[0m\n" "$MATCH" HAS_ERROR=1 fi fi done exit "$HAS_ERROR"