summaryrefslogtreecommitdiffstats
path: root/test/runLint
blob: 550995de14760301975413170090c4192b7dd327 (plain)
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
#!/usr/bin/env bash
set -u

gitgrep()
{
    local out=$(git grep -I -P -n "$1" |
        grep -E '^(bash_completion|completions/|test/)' |
        grep -Ev "^test/runLint\>${filter_out:+|$filter_out}")
    if [[ $out ]]; then
        printf '***** %s\n' "$2"
        printf '%s\n\n' "$out"
    fi
}

unset -v CDPATH
if ! cd "$(dirname "$0")/.."; then
    echo 'test/runLint: failed to cd into the working tree of bash-completion' >&2
    exit 1
fi

cmdstart='(^|[[:space:];&|]|\()'
filter_out=

# Note: Since we started to use _comp_awk, we do not have care about the small
# feature set of Solaris awk anymore.

gitgrep "${cmdstart}(_comp_)?awk\b.*\[:[a-z]*:\]" \
    'awk with POSIX character class not supported in mawk-1.3.3-20090705 (Debian/Ubuntu)'

gitgrep "$cmdstart"'sed\b.*\\[?+]' \
    'sed with ? or +, use POSIX BRE instead (\{m,n\})'

gitgrep "$cmdstart"'sed\b.*\\\|' \
    "sed with \|, use POSIX BRE (possibly multiple sed invocations) or another tool instead"

# TODO: really nonportable? appears to work fine in Linux, FreeBSD, Solaris
#gitgrep $cmdstart'sed\b.*;' \
#    'sed with ;, use multiple -e options instead (POSIX?) (false positives?)'

gitgrep "$cmdstart"'sed\b.*[[:space:]]-[^[:space:]]*[rE]' \
    'sed with -r or -E, drop and use POSIX BRE instead'

gitgrep "$cmdstart"'[ef]grep\b' \
    '[ef]grep, use grep -[EF] instead (historical/deprecated)'

# TODO: $ in sed subexpression used as an anchor (POSIX BRE optional, not in
#       Solaris/FreeBSD)

gitgrep '(?<!command)'"$cmdstart"'(grep|ls|sed|cd)(\s|$)' \
    'invoke grep, ls, sed, and cd through "command", e.g. "command grep"'

gitgrep '(?<!command)'"$cmdstart"'awk(\s|$)' \
    'invoke awk through "_comp_awk"'

#------------------------------------------------------------------------------
# Bash pitfalls/styles/compatibilities (which are not detected by shellcheck)

gitgrep '<<<' 'herestrings use temp files, use some other way'

filter_out='^(test/|bash_completion\.sh)' gitgrep ' \[ ' \
    'use [[ ]] instead of [ ]'

gitgrep "$cmdstart"'unset [^-]' 'Explicitly specify "unset -v/-f"'

gitgrep "$cmdstart"'((set|shopt)\s+[+-][a-z]+\s+posix\b|(local\s+)?POSIXLY_CORRECT\b)' \
    'fiddling with posix mode breaks keybindings with some bash versions'

gitgrep '\$\{([^{}\n]|\{.*\})+/([^{}\n]|\{.*\})+/([^{}"\n]|\{.*\})*\$.*\}' \
    '$rep of ${var/pat/$rep} needs to be double-quoted for shopt -s patsub_replacement (bash >= 5.2) [see Sec. of patsub_replacement in doc/styleguide.md]'

gitgrep '"([^"\n]|\\.)*\$\{([^{}\n]|\{.*\})+/([^{}\n]|\{.*\})+/([^{}"\n]|\{.*\})*"([^{}"\n]|\{.*\})*\$.*\}' \
    '$rep of "${var/pat/"$rep"}" should not be quoted for bash-4.2 or shopt -s compat42 (bash >= 4.3) [see Sec. of patsub_replacement in doc/styleguide.md]'