From: Karel Zak Date: Thu, 2 Oct 2025 12:07:53 +0000 (+0200) Subject: tools: rewrite checkcompletion.sh to be source-based X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=31ffdd82b20303c920c1bd32be0ea5e95734d6a8;p=thirdparty%2Futil-linux.git tools: rewrite checkcompletion.sh to be source-based The original checkcompletion.sh checked compiled binaries in the build directory, which was unreliable and build-dependent. The new version performs comprehensive source-based verification by: 1. Extracting program names from */Makemodule.am files (bin_PROGRAMS, sbin_PROGRAMS, usrbin_exec_PROGRAMS, usrsbin_exec_PROGRAMS) 2. Verifying three-way consistency: - Programs defined in Makemodule.am files - bash-completion files in bash-completion/ directory - Entries in bash-completion/Makemodule.am - Entries in meson.build 3. Properly handling special cases: - Programs that don't need completion (system tools like login, agetty) - Programs with special install hooks (runuser, lastb symlinks) The script now provides clear categorized output: - Programs missing bash-completion files - bash-completion files not registered in Makemodule.am - Orphaned bash-completion files without programs This makes it easier to maintain bash-completion consistency and catch issues before release. Signed-off-by: Karel Zak --- diff --git a/tools/checkcompletion.sh b/tools/checkcompletion.sh index f3fdda486..58e1f7a08 100755 --- a/tools/checkcompletion.sh +++ b/tools/checkcompletion.sh @@ -1,45 +1,156 @@ #!/bin/bash # -# This script checks if we have bash-completion scripts for the all compiled -# binaries. +# This script verifies bash-completion consistency by checking: +# 1. All user-facing programs have bash-completion files +# 2. All bash-completion files are registered in bash-completion/Makemodule.am +# 3. All bash-completion files are registered in meson.build +# 4. All bash-completion files correspond to actual programs # -# Copyright (C) 2016 Karel Zak +# Copyright (C) 2025 Karel Zak # +set -e die() { - echo "error: $1" + echo "error: $1" >&2 exit 1 } usage() { - echo "Usage:" - echo " $0 []" + echo "Usage: $0 []" + echo + echo "Verifies bash-completion consistency across:" + echo " - Program definitions in */Makemodule.am" + echo " - bash-completion/ directory contents" + echo " - bash-completion/Makemodule.am registrations" + echo " - meson.build registrations" + exit 1 } -# unwanted scripts -- use grep -E, e.g. (aaa|bbb|ccc) -completion_exclude="(nologin)" +# Programs that don't need bash completion: +# - nologin: no interactive use +# - agetty: terminal setup, no user interaction +# - login: authentication, no command-line arguments +# - sulogin: emergency login, no arguments +# - switch_root: initramfs utility, internal use +# - vipw: wrapper around editor +# - line: deprecated, simple utility +# - kill: conflicts with bash built-in kill command +exclude_programs="nologin|agetty|login|sulogin|switch_root|vipw|line|kill" + +# Programs with special handling in bash-completion/Makemodule.am (symlinks/aliases) +# These are handled via install-data-hook-bashcomp-* rules +# - runuser: symlinked to su completion +# - lastb: symlinked to last completion +special_handling="runuser|lastb" + +top_srcdir=${1:-.} +[ -d "${top_srcdir}" ] || die "directory '${top_srcdir}' not found" -top_srcdir=${1-"."} -completion_dir="${top_srcdir}/bash-completion" +cd "${top_srcdir}" || die "cannot cd to ${top_srcdir}" +completion_dir="bash-completion" [ -d "${completion_dir}" ] || die "not found ${completion_dir}" -bin_files=$(cd ${top_srcdir} && find * -maxdepth 0 -perm /u+x \ - \! -type d \ - \! -name \*.sh \! -name \*.cache \! -name \*.status \ - \! -name configure \! -name libtool | sort) +# Extract all user-facing programs from Makemodule.am files +# We look for: bin_PROGRAMS, sbin_PROGRAMS, usrbin_exec_PROGRAMS, usrsbin_exec_PROGRAMS +extract_programs() { + find . -name "Makemodule.am" -type f -exec grep -h \ + -E "^(bin|sbin|usrbin_exec|usrsbin_exec)_PROGRAMS \+=" {} \; \ + | sed 's/.*+= *//' \ + | tr ' ' '\n' \ + | sed 's/\\//' \ + | grep -v '^$' \ + | grep -v '\.static$' \ + | sort -u +} + +# Extract programs from bash-completion/Makemodule.am +extract_completion_registered() { + grep 'bash-completion/' "${completion_dir}/Makemodule.am" \ + | sed -e 's/.*bash-completion\///' \ + -e 's/\s.*//' \ + | sort -u +} + +# Get actual bash-completion files +get_completion_files() { + ls "${completion_dir}" \ + | grep -v '^Makemodule.am$' \ + | sort +} + +# Extract programs from meson.build +extract_meson_registered() { + if [ -f "meson.build" ]; then + grep "bashcompletions +=" meson.build \ + | sed -e "s/.*bashcompletions += //" \ + -e "s/\[//" \ + -e "s/\]//" \ + -e "s/'//g" \ + | tr ',' '\n' \ + | sed -e 's/^ *//' \ + -e 's/ *$//' \ + | grep -v '^$' \ + | sort -u + fi +} + +# Get programs that should have completions +programs=$(extract_programs | grep -v -w -E "(${exclude_programs}|${special_handling})") + +# Get registered completions +registered=$(extract_completion_registered) -completion_files=$(cd ${completion_dir}/ && find * ! -name '*.am' | sort -u) -completion_missing=$(comm -3 <(echo "$completion_files") <(echo "$bin_files")) +# Get meson registered completions +meson_registered=$(extract_meson_registered) -if [ -n "$completion_missing" -a -n "$completion_exclude" ]; then - completion_missing=$(echo "$completion_missing" | grep -v -E "$completion_exclude") +# Get actual completion files +files=$(get_completion_files) + +# Find programs without completion files +missing_files=$(comm -23 <(echo "$programs") <(echo "$files")) + +# Find completion files not registered in Makemodule.am +unregistered=$(comm -23 <(echo "$files") <(echo "$registered")) + +# Find completion files without corresponding programs +orphaned=$(comm -23 <(echo "$files") <(echo "$programs")) + +# Find completion files not registered in meson.build +meson_unregistered=$(comm -23 <(echo "$files") <(echo "$meson_registered")) + +# Report findings +errors=0 + +if [ -n "$missing_files" ]; then + echo "Programs missing bash-completion files:" + echo "$missing_files" | sed 's/^/ /' + errors=$((errors + 1)) fi -if [ -n "$completion_missing" ]; then - echo "Missing completion scripts:" - echo "$completion_missing" +if [ -n "$unregistered" ]; then + echo "bash-completion files not registered in bash-completion/Makemodule.am:" + echo "$unregistered" | sed 's/^/ /' + errors=$((errors + 1)) fi +if [ -n "$orphaned" ]; then + echo "bash-completion files without corresponding programs:" + echo "$orphaned" | sed 's/^/ /' + errors=$((errors + 1)) +fi + +if [ -n "$meson_unregistered" ]; then + echo "bash-completion files not registered in meson.build:" + echo "$meson_unregistered" | sed 's/^/ /' + errors=$((errors + 1)) +fi + +if [ $errors -eq 0 ]; then + echo "All bash-completion files are consistent." + exit 0 +else + exit 1 +fi