2
0
mirror of https://github.com/chubin/cheat.sheets synced 2024-11-17 09:25:32 +00:00
cheat.sheets/tests/lenchk
terminalforlife a0c4be1552 Correct how less(1) is used, & catch more(1) bug
The `-r` flag isn't best here. Per the less(1) man page, it's best to
use `-R` to only display the ANSII color escape sequences.

It seems like more(1) doesn't support color escape sequences, or at
least not properly. The display is messed up when using more(1), so
I've just accounted for that. In this situation, just use the `-C`
flag(s).
2020-11-18 14:48:14 +00:00

253 lines
7.0 KiB
Bash
Executable File

#!/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 - Provide color via esscape 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