You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

253 lines
7.0 KiB
Bash

#!/usr/bin/env bash
#------------------------------------------------------------------------------
# Author E-Mail - terminalforlife@yahoo.com
# Author GitHub - https://github.com/terminalforlife
#------------------------------------------------------------------------------
Progrm=${0##*/}
Usage(){
while read; do
printf '%s\n' "$REPLY"
done <<-EOF
Usage: $Progrm [OPTS] [DIR_1 [DIR_2 ...]]
-h, --help - Display this help information.
-C, --no-color - Do not use ANSI color escape sequences.
-D, --no-subdirs - Ignore the 'sheets/_*' subdirectories.
-I, --no-lenchk-line - Ignore the special 'lenchk=.*' line.
-N, --no-preview - Omit the preview of each triggered line.
-P, --no-pager - Do not use less(1) or more(1) for paging.
-S, --no-summary - Omit the summary before $Progrm exits.
-W, --no-whilelist - Do not use the whitelist file.
-l, --limit [INT] - Override the limit of 80 columns.
-w, --wl-file [FILE] - Use an alternative whitelist file.
Additional directories can be appended to the argument string in
order to process directories otherwise not handled by $Progrm. You
can use '--' to let $Progrm know when to stop looking for flags.
Files to whitelist must be placed line-by-line; one path per line.
cheat.sheets/sheets/_perl/1line
cheat.sheets/sheets/find
The file paths to provide must begin with 'cheat.sheets/' to indicate
the root of the repository, otherwise this feature will fail.
The location of the whitelisting file ('$Progrm-excludes') must
remain in the same directory in which $Progrm is stored, unless
otherwise specified.
Alternatively, a file can be whitelisted by ensuring the very first
line contains only 'lenchk=disable', akin to a vim(1) modeline.
EOF
}
Err(){
printf 'ERROR: %s\n' "$2" 1>&2
[ $1 -gt 0 ] && exit $1
}
WLFile='lenchk-excludes'
MaxCols=80
while [ "$1" ]; do
case $1 in
--)
break ;;
--help|-h|-\?)
Usage; exit 0 ;;
--limit|-l)
shift; MaxCols=$1
if ! [[ $MaxCols =~ ^[0-9]+$ ]]; then
Err 1 'Invalid column maximum provided.'
fi ;;
--no-pager|-P)
NoPager='True' ;;
--no-preview|-N)
NoPreview='True' ;;
--no-color|-C)
NoColor='True' ;;
--no-summary|-S)
NoSummary='True' ;;
--no-subdirs|-D)
NoSubDirs='True' ;;
--no-whitelist|-W)
NoWhiteList='True' ;;
-I|--no-lenchk-line)
NoLenChkLine='True' ;;
--wl-file|-w)
shift
if [ -z "$1" ]; then
Err 1 'No alternative whitelist file provided.'
else
WLFile=$1
fi ;;
-*)
Err 1 'Incorrect option(s) specified.' ;;
*)
break ;;
esac
shift
done
# Thank you, Chubin. Feature apparently added in version 3.0 alpha, so should
# be OK, but if anyone is having issues, just `cd` to the 'tests' directory.
[ ${BASH_VERSINFO[0]:-0} -eq 3 ] || cd "${BASH_SOURCE[0]%/*}" &> /dev/null
# Confirm we are in the right place.
git rev-parse --is-inside-work-tree 1> /dev/null 2>&1 ||
Err 0 'Not inside a Git repository.'
case $PWD in
*/cheat.sheets/tests)
;;
'')
Err 1 'Unable to determine the CWD.' ;;
*)
Err 1 "Not within the 'cheat.sheets/tests' directory." ;;
esac
Dirs=(../sheets/*)
[ "$NoSubDirs" == 'True' ] || Dirs+=(../sheets/*/*)
# Add user's own directories to check, if they exist.
for ArgDir in "$@"; {
if [ -d "$ArgDir" ]; then
Dirs+=($ArgDir/*)
else
Err 1 "Directory '$ArgDir' not found."
fi
}
# If the whitelist file exists, use it, unless whitelisting is disabled.
# Keeping this test outside of the loop to avoid unnecessary processing.
if [ "$NoWhiteList" != 'True' ] && [ -f "$WLFile" ]; then
# Read the whitelist file, line-by-line, generating an array thereof.
Whitelisted=()
while read; do
Whitelisted+=("../${REPLY#cheat.sheets/}")
done < "$WLFile"
fi
# Using tput(1) for portability.
if type -fP tput &> /dev/null; then
C_Ellipses=`tput dim; tput setaf 7`
C_LineNums=`tput bold; tput setaf 2`
C_FileNames=`tput bold; tput setaf 1`
C_Reset=`tput sgr0`
else
Err 1 'Unable to colorize output -- tput(1) not found.'
fi
Main(){
for File in "${Dirs[@]}"; {
[ -f "$File" ] || continue
# Per chubin's desire to have an "in-bound flag"; see #134.
if [ "$NoLenChkLine" != 'True' ]; then
SkipFile='False'
readarray -t Buffer < "$File"
for BufferLine in "${Buffer[@]}"; {
if [[ $BufferLine == '# cheat.sh: '* ]]; then
CheatLine=${BufferLine#'# cheat.sh: '}
IFS=',' read -a Fields <<< "$CheatLine"
for Field in "${Fields[@]}"; {
[ "$Field" == "$Progrm=disable" ] && SkipFile='True'
}
fi
}
[ "$SkipFile" == 'True' ] && continue
fi
# If the current file matches one which is whitelisted, skip it.
for CurWL in "${Whitelisted[@]}"; {
[ "$File" == "$CurWL" ] && continue 2
}
LineNum=0
HaveBeenHit='False'
while read; do
let LineNum++
# Ignore non-comment lines for '#' and '//'.
case $REPLY in
'#'*|'//'*)
;;
*)
continue ;;
esac
if [ ${#REPLY} -gt 80 ]; then
# We only need to be informed of a hit just the once, per file.
if [ "$HaveBeenHit" == 'False' ]; then
# The leading newline character, if needed.
[ "$NoPreview" == 'True' ] || printf '\n'
# The filename containing problematic line lengths.
[ "$NoColor" == 'True' ] || printf "$C_FileNames"
printf '%s\n' "${File#../}"
[ "$NoColor" == 'True' ] || printf "$C_Reset"
HaveBeenHit='True'
let Hits++
fi
if ! [ "$NoPreview" == 'True' ]; then
# The line number of the problematic length.
[ "$NoColor" == 'True' ] || printf "$C_LineNums"
printf ' %7d ' $LineNum # <-- allows for 9,999,999 lines.
[ "$NoColor" == 'True' ] || printf "$C_Reset"
# Cannot make this 80 columns long, due to the indentation
# and padding, but if you need to test this, for the sake
# of checking lenchk is doing its job, set the 70 to 80, -
# then make sure the terminal window is wide enough.
printf '%s' "${REPLY:0:70}"
# Cut-off ellipses.
[ "$NoColor" == 'True' ] || printf "$C_Ellipses"
printf '...\n'
[ "$NoColor" == 'True' ] || printf "$C_Reset"
fi
fi
done < "$File"
}
if [ ${Hits:-0} -gt 0 -a "$NoSummary" != 'True' ]; then
printf '\nFound %d file(s) with comment length >%d.\n'\
$Hits $MaxCols 1>&2
fi
}
if [ -t 1 -a "$NoPager" != 'True' ]; then
# Prefer less(1), but have more(1) as a fallback.
if type -fP less &> /dev/null; then
Pager='less -R'
elif type -fP more &> /dev/null; then
Pager='more'
if [ "$NoColor" != 'True' ]; then
Err 1 'Only more(1) is available -- colors unsupported.'
fi
else
Err 1 'Neither less(1) nor more(1) were found.'
fi
# Redirecting STDERR to address less(1) bug causing summary to display
# where it shouldn't; only seems to happen when colorization is enabled.
Main 2>&1 | $Pager
else
Main
# Testing line for use when checking the summary lines up with wc(1). When
# using this, be sure previewing is disabled and the summary is enabled.
#printf '%d\n' $((`Main |& wc -l` - 2))
fi