1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179
|
#!/bin/bash
# Copyright (C) 2025, Richard Lewis <richard.lewis.debian@googlemail.com>
# check-perltidy: Run perltidy on all perl files in sbuild
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
set -ue
usage() {
cat <<- EOF
check-perltidy [OPTIONS] [FILE_OR_DIR...]
Options:
-w, --write Update FILE_OF_DIR
-x, --exclude FILE Do not check FILENAME (can be a directory)
EOF
exit 1
}
# especially '--write' means we should be careful to run only from the
# top of the sbuild repos. However, the build process will run us from
# 'test/'
if [ -f "./lib/Sbuild.pm" ]; then
: # we are already in the top dir (eg: run by hand with --write)
elif [ -f "../lib/Sbuild.pm" ]; then
# we are in test (eg: run from 'make test')
if ! cd ..; then
echo "Failed to do 'cd ..' from $(pwd)" >&2
exit 1
fi
fi
if [ ! -f "./lib/Sbuild.pm" ]; then
# this should now work
echo "No file ./lib/Sbuild.pm - run $0 top of sbuild repos, not from $(pwd))" >&2
exit 1
fi
# nb: .perltidyrc sets the options to use
PERLTIDY=(perltidy --profile=.perltidyrc)
# use '$0 --write' to fix all issues at once
UPDATE=no
if ! OPTIONS=$(getopt --name check-perltidy --options "hwx:" --longoptions "help,write,exclude:" -- "$@"); then
echo "Error parsing options"
usage
fi
eval set -- "$OPTIONS"
# changed to 'fail' if we found issues (unless using --write)
STATUS=pass
## scripts not to check
# EXCLUDE_NAME is for excluding filenames from the search for '#!/usr/bin/perl',
# EXCLUDE_PATH is for excluding paths from the search for .pm extensions
EXCLUDE_NAME=(! -name '*.tdy' ! -name '*.ERR' ! -name '*~')
EXCLUDE_PATH=()
while :; do
case "$1" in
--)
shift
break
;;
-h | --help) usage ;;
-w | --write)
UPDATE=yes
STATUS=update
;;
-x | --exclude)
shift
echo "Excluding: ${1##*/}"
EXCLUDE_NAME+=(! -name "${1##*/}")
EXCLUDE_PATH+=("$1")
;;
esac
shift
done
shopt -s nullglob
shopt -s globstar
PERL_FILES=()
for file in "${@-.}"; do
if [ -d "$file" ]; then
## Find perl scripts in dir
# the awk prints FILENAME if the first line is a perl shebang,
# and then exits.
mapfile -t PERL_FILES_IN_DIR < <(
find "${file}" -name .git -prune -false -o "(" -type f "${EXCLUDE_NAME[@]}" -print0 ")" \
| xargs -0 -I@ \
awk '/^#![[:space:]]*\/(usr\/)?bin\/perl/{print FILENAME}{exit}' @
)
PERL_FILES+=("${PERL_FILES_IN_DIR[@]}")
PERL_FILES+=("$file"/**/*.p{m,l}) # extension .pm or .pl
else
PERL_FILES+=("$file")
fi
done
if [ -z "${PERL_FILES-}" ]; then
echo "check-perltidy: No perl files to check"
exit 1
fi
if [ -t 1 ]; then
COLOUR=always
else
COLOUR=never
fi
TAB="ยป "
compare_files() {
if ! output=$(diff --color=$COLOUR -u "$@" 2>&1); then
echo "${output//$'\t'/$TAB}"
return 1
fi
}
echo "Checking ${#PERL_FILES[@]} perl files for consistent style with: ${PERLTIDY[*]}"
for file in "${PERL_FILES[@]}"; do
case "$file" in
*.tdy | *.ERR | *~) continue ;;
*)
for exc in "${EXCLUDE_PATH[@]}"; do
if [ "$(realpath "$exc")" = "$(realpath "$file")" ]; then
echo "SKIP: $file"
continue 2
fi
done
;;
esac
tidied=$file.tdy # can be created even if an error occurs
if ! "${PERLTIDY[@]}" "$file"; then
STATUS=FAILED
echo "==== [ Inconsistencies in $file (may be incomplete) ==== ]"
compare_files "$file" "$tidied"
echo "==== [ End of inconsistencies in $file ==== ]"
echo "FAIL: $file: could not run ${PERLTIDY[*]}"
cat "$file.ERR"
rm "$file.ERR"
rm "$tidied" || :
elif output=$(compare_files "$file" "$tidied"); then
echo "OK: $file"
rm "$tidied"
elif [ "$UPDATE" = "yes" ]; then
mv -v "$tidied" "$file"
echo "UPDATED: $file"
else
echo
echo "FAIL: $file: to fix use: $0 --write $file"
echo "==== [ Inconsistencies in $file ==== ]"
echo "$output"
echo "==== [ End of inconsistencies in $file ==== ]"
rm "$tidied"
STATUS=failed
fi
done
if [ "$STATUS" = "pass" ]; then
echo "Checking perl files for consistent formatting: all OK"
exit 0
elif [ "$UPDATE" = "yes" ]; then
echo "Finished updating perl files"
exit 0
else
echo "FAIL: Some perl files have inconsistent formatting" >&2
echo "(Run '$0 --write' to fix everything at once)" >&2
exit 1
fi
|