File: check-perltidy

package info (click to toggle)
sbuild 0.91.6
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 1,832 kB
  • sloc: perl: 18,701; sh: 1,210; python: 823; sql: 797; lisp: 304; makefile: 293
file content (179 lines) | stat: -rwxr-xr-x 4,651 bytes parent folder | download | duplicates (6)
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