autospec/tests/test00_specsyntax.in

293 lines
9.8 KiB
Plaintext
Raw Permalink Normal View History

#!/bin/bash
# test00_specsyntax -- @package@ test (syntax checks of a specfile)
# Copyright (C) 2012-2013 Davide Madrisan <davide.madrisan@gmail.com>
[ -z "$BASH" ] || [ ${BASH_VERSION:0:1} -lt 2 ] &&
echo $"this script requires bash version 2 or better" >&2 && exit 1
me=("test00_specsyntax" "@version@" "@date@")
[ -r @libdir@/libmsgmng.lib ] ||
{ echo "$me: "$"library not found"": @libdir@/libmsgmng.lib" 1>&2
exit 1; }
. @libdir@/libmsgmng.lib
[ -r @libdir@/libtranslate.lib ] ||
{ echo "$me: "$"library not found"": @libdir@/libtranslate.lib" 1>&2
exit 1; }
. @libdir@/libtranslate.lib
notify.debug $"loading"": \`test00_specsyntax'..."
# check if all the needed tools are available
for tool in cat file getopt grep sed; do
[ "$(type -p $tool)" ] ||
notify.error $"utility not found"": \`$tool'"
done
# function specfile.checksyntax()
# do some syntax checks in the specfile of the building package
# args:
# $1 : specfile name
# $2, ... : execute these check numbers (optional, default = all checks)
function specfile.checksyntax() {
local i rpmvar specfile="$1"
[[ "$specfile" ]] || notify.error $"\
(bug)"" -- $FUNCNAME: "$"missing mandatory arg"" (#1)"
notify.debug "$FUNCNAME: specfile = \"$specfile\""
notify.note " * $specfile"
local total_issues=0
local user_agent="Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Firefox/132.0"
# 0. checking if 'Source[0]' is a valid internet address
# (skip this test if no '%setup' section has been found)
test.skip $test_number || {
notify.note "$(test.num2str). ${NOTE}"\
"url""${NORM}..."
if [[ "$SPEC_URL" ]]; then
{ notify.debug "\
\`url': "$"checking Source URL with: ""\`curl -s -o /dev/null -w \"%{http_code}\" -A \"${user_agent}\" $SPEC_URL'"
}
http_code=`curl -s -o /dev/null -w "%{http_code}" -A "${user_agent}" $SPEC_URL`
if [ "$http_code" != "200" ]; then
if [ "${http_code:0:2}" == "30" ]; then
http_effective_url=`curl -w "%{url_effective}" -I -L -s -o /dev/null -A "${user_agent}" -S $SPEC_URL`
{ notify.warning "\
\`url': "$"redirect detected: replacing from \`$SPEC_URL' to \`${http_effective_url}'"
let "total_issues += 1";
}
sed -i "s|^\(URL:[[:space:]]*\)$SPEC_URL.*|\1${http_effective_url}|" $specfile
else
{ notify.error "\
\`url': "$"invalid return code for \`$SPEC_URL': $http_code"
let "total_issues += 1"; }
fi
fi
fi; }
test_number=$(($test_number + 1))
# 1. checking if 'Source[0]' is a valid internet address
# (skip this test if no '%setup' section has been found)
test.skip $test_number || {
grep -q "^%setup[ \t]*$\|^%setup[ \t]\+" $specfile
if [ $? -eq 0 ]; then
notify.note "$(test.num2str). ${NOTE}"\
"source0""${NORM}..."
if [[ "$source0_name_structure" ]]; then
specfile.getvars -s $specfile --verbatim SPEC_SOURCE0
if [[ "$SPEC_SOURCE0_VERBATIM" ]]; then
[[ "$(echo "$SPEC_SOURCE0_VERBATIM" | \
grep -e "$source0_name_structure")" ]] ||
{ notify.warning "\
\`Source[0]': "$"does not point to a valid internet address"
let "total_issues += 1"; }
fi
fi
fi; }
test_number=$(($test_number + 1))
# 2. check if the patches have standard names
# (see the 'patch_name_structure' var in the configure file)
test.skip $test_number || {
notify.note "$(test.num2str). ${NOTE}"\
$"patch""${NORM}..."
specfile.getvars -s $specfile --verbatim SPEC_PATCH
echo "${SPEC_PATCH_VERBATIM[@]}" | \
for i in `seq 1 1 ${#SPEC_PATCH_VERBATIM[@]}`; do
[[ "${SPEC_PATCH_VERBATIM[$i-1]}" =~ \
$patch_name_structure ]] ||
{ notify.warning "\
patch $i (\`${NOTE}${SPEC_PATCH_VERBATIM[$i-1]}${NORM}') "
notify.warning $"\
not a standard structure (see config file)";
let "total_issues += 1"; }
done; }
test_number=$(($test_number + 1))
# 3. check if `%setup' have `-D' and/or `-T' options
test.skip $test_number || {
notify.note "$(test.num2str). ${NOTE}"\
"%setup""${NORM}..."
[[ "$(cat $specfile | \
sed -n "/%setup/{/-D /p;/-T /p;/-D$/p;/-T$/p}")" ]] &&
{ notify.warning $"\
found \`-D' and/or \`-T' option(s) in the \`%setup' directive"
let "total_issues += 1"; }
}
test_number=$(($test_number + 1))
# 4. check if all the `%files' blocks have a `%defattr' line
# note: skip commented out blocks
test.skip $test_number || {
notify.note "$(test.num2str). ${NOTE}"\
"%defattr""${NORM}..."
[[ "$(sed -e '
# print paragraph if it contains "%files" and "%defattr"
/./{H;$!d;}' -e 'x;/%files/!d;/%defattr/!d' $specfile | \
grep "^[[:space:]]*%files")" != \
"$(grep "^[[:space:]]*%files" $specfile)" ]] &&
{ notify.error $"\
missing at least one \`%defattr' directive"
let "total_issues += 1"; }
}
test_number=$(($test_number + 1))
# 5. check if the rpm macros %configure, %make are used
# - look in the block : `%build' to `%install'
test.skip $test_number || {
notify.note "$(test.num2str). ${NOTE}"\
"%build, %install""${NORM}..."
local token tokens
sed -n '/%build/,/%install/p' $specfile | \
while read -a tokens; do
# ignore comments
[[ "${tokens[0]}" =~ ^\# ]] && continue
for token in ${tokens[*]}; do
case "$token" in
configure|./configure)
[[ "$rpm_macro_configure" ]] &&
{ notify.warning $"\
use rpm macros if possible:"" \`$token' --> \`$rpm_macro_configure'"
let "total_issues += 1"; }
;;
make)
[[ "$rpm_macro_make" ]] &&
{ notify.warning \
$"use rpm macros if possible:""${NORM}
$token --> $rpm_macro_make"
let "total_issues += 1"; }
;;
esac
done
done
# do check between`%install' and `%changelog'
sed -n '/%install/,/%changelog/p' $specfile | \
while read -a tokens; do
# ignore comments
[[ "${tokens[0]}" =~ ^\# ]] && continue
for token in ${tokens[*]}; do
case "$token" in
"make")
[[ "$rpm_macro_make" ]] &&
{ notify.warning \
$"use rpm macros if possible:""${NORM}
$([[ "$rpm_macro_makeinstall" ]] &&
echo " make install -> $rpm_macro_makeinstall"
[[ "$rpm_macro_makeoldinstall" ]] &&
echo " make install -> $rpm_macro_makeoldinstall" )"
} ;;
esac
done
done; }
test_number=$(($test_number + 1))
# 6. check if '%find_lang' is used when localization files are detected
test.skip $test_number || {
notify.note "$(test.num2str). ${NOTE}%find_lang${NORM}..."
# FIXME : the test should perhaps be improved...
grep -q "^[ ]*[^# ]*/share/locale/" $specfile &&
{ notify.error $"\
"$"localization files must be packaged via \`%find_lang'""${NORM}
---------------------------------------
${NOTE}"$"Hint"":${NORM}
%install
...
%find_lang %{name}
%files -f %{name}.lang
---------------------------------------
"
let "total_issues += 1"; }
}
test_number=$(($test_number + 1))
# 7. check for illegal 'Group's (see configuration file)
test.skip $test_number || {
if [ "${#rpm_allowed_groups[*]}" = 0 ]; then
# 'rpm_allowed_groups' unset in the configuration files
notify.note "$(test.num2str). ${NOTE}"\
$"package Groups""${NORM}..."" "$"skipped"
else
notify.note "$(test.num2str). ${NOTE}"\
$"package Groups""${NORM}..."
local i j match
for j in `seq 1 1 ${#SPEC_GROUP[*]}`; do
notify.debug "\
$FUNCNAME: checking if \"${SPEC_GROUP[$j-1]}\" is a known group ..."
let "match = 0"
for i in `seq 1 1 ${#rpm_allowed_groups[*]}`; do
notify.debug "\
$FUNCNAME: current group: \"${rpm_allowed_groups[$i-1]}\""
[ "${rpm_allowed_groups[$i-1]}" = \
"${SPEC_GROUP[$j-1]}" ] &&
{ let "match = 1"; break; }
done
[ "$match" = 1 ] ||
{ notify.error "\
"$"invalid \`Group'"" \"${SPEC_GROUP[$j-1]}\"""${NORM}
---------------------------------------
${NOTE}"$"Hint"":${NORM}""
"$"see configuration files"" (\`${NOTE}rpm_allowed_groups${NORM}')
"$"or enter the command"":
${NOTE}@package@ --eval=rpm_allowed_groups${NORM}
---------------------------------------
"
let "total_issues += 1"; }
done
fi; }
test_number=$(($test_number + 1))
# 8. check for no approved 'License's (see configuration file)
test.skip $test_number || {
if [ "${#rpm_approved_licenses[*]}" = 0 ]; then
# 'rpm_approved_licenses' unset in the configuration files
notify.note "$(test.num2str). ${NOTE}"\
$"approved License""${NORM}..."" "$"skipped"
else
notify.note "$(test.num2str). ${NOTE}"\
$"approved License""${NORM}..."
local i j match
for j in `seq 1 1 ${#SPEC_LICENSE[*]}`; do
notify.debug "\
$FUNCNAME: checking if \"${SPEC_LICENSE[$j-1]}\" is an approved license ..."
let "match = 0"
for i in `seq 1 1 ${#rpm_approved_licenses[*]}`; do
notify.debug "\
$FUNCNAME: current license: \"${rpm_approved_licenses[$i-1]}\""
[ "${rpm_approved_licenses[$i-1]}" = \
"${SPEC_LICENSE[$j-1]}" ] &&
{ let "match = 1"; break; }
done
[ "$match" = 1 ] ||
{ notify.warning "\
"$"not approved \`License'"" \"${NOTE}${SPEC_LICENSE[$j-1]}${NORM}\"""
---------------------------------------
${NOTE}"$"Hint"":${NORM}""
"$"see configuration files"" (\`${NOTE}rpm_approved_licenses${NORM}')
"$"or enter the command"":
${NOTE}@package@ --eval=rpm_approved_licenses${NORM}
---------------------------------------
"
let "total_issues += 1"; }
done
fi; }
test_number=$(($test_number + 1))
notify.note "
--> "$"${NOTE}Specfile checks: ${NORM}\
${WARN}$total_issues${NORM} ${NOTE}warnings.${NORM}""
"
return $total_issues
}