summary refs log tree commit diff
path: root/xlint
blob: 283ec48d74394e03c52ba3e935877ce2f06bcdd0 (plain) (blame)
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
180
181
182
#!/bin/sh
# xlint TEMPLATE - scan XBPS template for common mistakes

export LC_ALL=C

scan() {
	local rx="$1" msg="$2"
	grep -P -Hn -e "$rx" "$template" |
		sed "s/^\([^:]*:[^:]*:\)\(.*\)/\1 $msg/"
}

once() {
	head -n 1
}

variables=$(echo -n "#.*
_.*
.*_descr
.*_groups
.*_homedir
.*_pgroup
.*_shell
desc_option_.*
AR
AS
CC
CFLAGS
CPP
CPPFLAGS
CXX
CXXFLAGS
GCC
LD
LDFLAGS
LD_LIBRARY_PATH
NM
OBJCOPY
OBJDUMP
RANLIB
READELF
STRIP
allow_unknown_shlibs
alternatives
binfmts
bootstrap
broken
build_options
build_options_default
build_style
build_wrksrc
checksum
cmake_builddir
conf_files
configure_args
configure_script
conflicts
create_wrksrc
depends
depends
disable_parallel_build
distfiles
dkms_modules
font_dirs
force_debug_pkgs
go_build_tags
go_import_path
go_package
go_ldflags
homepage
hostmakedepends
keep_libtool_archives
kernel_hooks_version
lib32depends
lib32disabled
lib32files
lib32mode
lib32symlinks
license
maintainer
make_build_args
make_build_target
make_cmd
make_dirs
make_install_args
make_install_target
makedepends
mutable_files
noarch
nocross
nodebug
nopie
noshlibprovides
nostrip
nostrip_files
noverifyrdeps
only_for_archs
patch_args
pkgname
preserve
provides
pycompile_dirs
pycompile_module
pycompile_version
python_versions
register_shell
replaces
repository
restricted
reverts
revision
run_depends
sgml_catalogs
sgml_entries
shlib_provides
shlib_requires
short_desc
skip_extraction
stackage
subpackages
system_accounts
system_groups
systemd_services
tags
triggers
version
wrksrc
xml_catalogs
xml_entries" | tr '\n' '|')

ret=0
for template; do
	if [ -f "$template" ]; then
	scan 'short_desc=.*\."' "unwanted trailing dot in short_desc"
	scan 'short_desc=["'\''][a-z]' "short_desc should start uppercase"
	scan 'short_desc=["'\''].{73}' "short_desc should be less than 72 chars"
	scan 'license=.*[^L]GPL[^-]' "license GPL without version"
	scan 'license=.*LGPL[^-]' "license LGPL without version"
	if ! grep -q vlicense "$template"; then
		for l in custom MIT BSD ISC; do
			scan "license=.*$l" "license '$l', but no use of vlicense"
		done
	fi
	if ! sed -n '/^version=/{n;/revision=/b;q1}' "$template"; then
		scan 'revision=' "revision does not appear immediately after version"
	fi
	scan 'vinstall.* usr/bin' "use vbin"
	scan 'vinstall.* usr/share/man' "use vman"
	scan 'vinstall.* usr/share/licenses' "use vlicense"
	scan '^  ' "indent with tabs" | once
	scan '[\t ]$' "trailing whitespace"
	scan '[^\\]`' "use \$() instead of backticks"
	scan 'revision=0' "revision must not be zero"
	scan '^version=.*[:-].*' "version must not contain the characters : or -"
	scan 'replaces=(?=.*\w)[^<>]*$' "replaces needs depname with version"
	scan 'maintainer=(?!.*<.*@.*>).*' "maintainer needs email address"
	scan 'nonfree=' "use repository=nonfree"
	scan '^(?!\s*('"$variables"'))[^\s=-]+=' \
		"custom variables should use _ prefix: \2"
	scan '^[^ =]*=(""|''|)$' "variable set to empty string: \2"
	scan '^(.*)-docs_package().*' 'use <pkgname>-doc subpackage for documentation'
	scan 'distfiles=.*sourceforge\.net' 'use $SOURCEFORGE_SITE'
	scan 'distfiles=.*savannah.nongnu\.org' 'use $NONGNU_SITE'
	scan 'distfiles=.*archive\.ubuntu\.com' 'use $UBUNTU_SITE'
	scan 'distfiles=.*xorg\.freedesktop\.org' 'use $XORG_SITE'
	scan 'distfiles=.*ftp.*debian\.org' 'use $DEBIAN_SITE'
	scan 'distfiles=.*gnome\.org/pub' 'use $GNOME_SITE'
	scan 'distfiles=.*www\.kernel\.org/pub/linux' 'use $KERNEL_SITE'
	scan 'distfiles=.*cpan\.org/modules/by-module' 'use $CPAN_SITE'
	scan 'distfiles=.*pypi\.python\.org' 'use $PYPI_SITE'
	scan 'distfiles=.*ftp\.mozilla\.org' 'use $MOZILLA_SITE'
	scan 'distfiles=.*ftp\.gnu\.org/(pub/)?gnu' 'use $GNU_SITE'
	scan 'distfiles=.*freedesktop\.org/software' 'use $FREEDESKTOP_SITE'
	scan '^wrksrc=(\$\{[^}]+\}|[^${}/])*/.+' 'wrksrc should be a top-level directory'
	scan '^\t*function\b' 'do not use the function keyword'
	scan '^\t*[^ ]*  *\(\)' 'do not use space before function parenthesis'
	scan '^\t*[^ ]*\(\)(|   *){' 'use one space after function parenthesis'
	scan '^\t*[^ ]*\(\)$' 'do not use a newline before function opening brace'
	else
	echo no such template "$template" 1>&2
	fi | sort -t: -n -k2 | grep . && ret=1
done
exit $ret