#!/bin/bash -uE tagfiles='/usr/share/namcap/namcap-tags,/usr/share/libretools/librecheck-tags' ################################################################################ checkdir=/usr/share/libretools/librecheck _list_native_checks_machine() { local mode=$1 find "$checkdir/check-$mode" -type f -executable -printf '%f\n' } list_native_checks_machine() { for mode in pkgbuild src pkg; do _list_native_checks_machine $mode done | sort } list_native_checks_human() { for check in $(list_native_checks_machine); do printf '%-20s: %s\n' "$check" "$(get_native_check_desc "$check")" done } get_native_check_desc() { local check=$1 sed -n 's/#\s*Description:\s*//p' "$checkdir"/*/"$check" } run_native_checks() { local mode=$1 local filter_mode=$2 local filter_arg=($(echo -e "${3//,/\n}"|sort)) local file=$4 local checks case $filter_mode in -r) checks=("${checks[@]}");; -e) checks=($(comm -12 \ <(_list_native_checks_machine $mode|sort) \ <(printf '%s\n' "${checks[@]}")));; esac for check in "${checks[@]}"; do "$checkdir/check-$mode/$check" "$file" done } ################################################################################ list_namcap_checks_machine() { list_namcap_checks_human | sed 's/\s*:.*//' } list_namcap_checks_human() { namcap -L | sed 1d && [[ $PIPESTATUS == 2 ]] } get_namcap_check_desc() { local check=$1 list_namcap_checks | sed -n "s|^$check[ :]*||p" } run_namcap_checks() { local mode=$1; shift [[ $mode == src ]]; return 0; namcap -m "$@" | sed -r 's/[^:]*(.:)/\1/' \ | grep -v '^E: improper-checksum (md|sha)[0-9]*sums SKIP$' } ################################################################################ list_checks_machine() { { list_namcap_checks_machine list_native_checks_machine } | sort } list_checks_human() { { list_namcap_checks_human list_native_checks_human } | sort } get_check_desc() { local check=$1 if list_namcap_checks_machine | grep -q "^$check$"; then get_namcap_check_desc "$check" else get_native_check_desc "$check" fi } run_checks() { local filter_mode=$1 local filter_arg=($(echo -e "${2//,/\n}"|sort)) local file=$3 local namcap=$(echo $(comm -12 \ <(list_namcap_checks_machine) \ <(printf '%s\n' "${filter_arg[@]}"))) local native=$(echo $(comm -12 \ <(list_native_checks_machine) \ <(printf '%s\n' "${filter_arg[@]}"))) local mode [[ -f "$file" && "${file##*/}" == PKGBUILD ]] && mode=pkgbuild [[ -f "$file" && "${file##*/}" =~ \.pkg\.tar ]] && mode=pkg [[ -d "$file" ]] && mode=src run_namcap_checks "$mode" "$filter_mode" "${namcap// /,}" "$file" run_native_checks "$mode" "$filter_mode" "${native// /,}" "$file" } ################################################################################ humanize() { : todo } ################################################################################ cmd=${0##*/} usage() { echo "Usage: $cmd [OPTIONS] [FILE|DIRECTORY]" echo 'Checks a PKGBUILD, source directory, or compiled package.' echo '' echo 'This checks for freedom and technical issues.' echo '' echo 'Options:' echo ' Settings:' echo " -e Don't apply CHECKS (comma separated) (default='')" echo ' -r Only apply CHECKS (comma separated) (default=all)' echo '' echo ' -H Make the output human-readable' echo ' -t Use TAGS (comma separated) file(s) to make the' echo ' output human-readable' echo " (default=$tagfiles)" echo '' echo ' Alternate modes:' echo ' -L List available checks' echo ' -h Show this message' } main() { local mode=check-exclude local file='' local checks='' local human_readable=false while getopts 'e:r:Ht:Lh' arg; do case $arg in e) mode=check-exclude; checks=$OPTARG;; r) mode=check-restrict; checks=$OPTARG;; H) human_readable=true;; t) tagfiles=$OPTARG;; L) mode=list;; h) usage; exit 0;; *) usage; exit 1;; esac done shift $(($OPTIND - 1)) if [[ $mode =~ ^check- ]]; then if [[ $# != 1 ]]; then usage exit 1 fi file=$1 fi ######################################################################## local formatter=cat local list_checks=list_checks_machine if $human_readable; then formatter=humanize list_checks=list_checks_human fi case $mode in check-exclude) run_checks -e "$checks" "$file" | $formatter;; check-restrict) run_checks -r "$checks" "$file" | $formatter;; list) $list_checks;; esac } main "$@"