diff --git a/Jenkinsfile b/Jenkinsfile new file mode 100644 index 0000000..6ffaf98 --- /dev/null +++ b/Jenkinsfile @@ -0,0 +1,28 @@ +pipeline { + agent any + + stages { + stage('ShellCheck') { + steps { + sh "check/shellcheck.sh" + } + } + stage('IndentationCheck') { + steps { + sh "check/indentationcheck.sh" + } + } + } + post { + always { + script { + recordIssues enabledForFailure: true, failOnError: true, qualityGates: [[threshold: 1, type: 'TOTAL', unstable: false]], tools: [checkStyle(name: 'ShellCheck')], trendChartType: 'NONE' + } + } + //failure { + // mail to: 'some.user@domain.org', + // subject: "Failed Jenkins build: ${currentBuild.fullDisplayName}", + // body: "Something is wrong with ${env.BUILD_URL}" + //} + } +} diff --git a/check/indentationcheck.sh b/check/indentationcheck.sh new file mode 100755 index 0000000..df9ecbc --- /dev/null +++ b/check/indentationcheck.sh @@ -0,0 +1,31 @@ +#!/bin/bash + +# +# Use either WORKSPACE location for Jenkins or +# resolve path to scripts we need to check +# when executed manualy outside Jenkins. +# +if [[ -z "${WORKSPACE:-}" ]]; then + MYDIR="$(cd -P "$(dirname "${0}")" && pwd)" + WORKSPACE="$(dirname ${MYDIR})" +fi + +echo '#####################################################################################' +echo ' Bash code must be indented with TABs. Checking for lines indented with spaces ... ' +echo '#####################################################################################' +grep -n '^[[:space:]]* [[:space:]]*' "${WORKSPACE:-../}"/{bin,lib}/*.*sh +grep_exit_status="${?}" +if [[ "${grep_exit_status}" -eq 0 ]]; then + echo '#####################################################################################' + echo ' ERROR: found Bash files containing lines (partially) indented with spaces.' + echo '#####################################################################################' + exit 1 +elif [[ "${grep_exit_status}" -eq 1 ]]; then + echo ' Ok: all Bash files indented with TABs.' + echo '####################################################################################' + exit 0 +else + echo ' FAILED: indentation sanity check failed.' + echo '####################################################################################' + exit 1 +fi diff --git a/check/shellcheck.sh b/check/shellcheck.sh new file mode 100755 index 0000000..7c13b25 --- /dev/null +++ b/check/shellcheck.sh @@ -0,0 +1,104 @@ +#!/bin/bash + +# +# Disable some shellcheck warnings: +# * SC2004: $/${} is unnecessary on arithmetic variables. +# But for consistency we prefer to always use ${} anyway. +# * SC2015: Note that A && B || C is not if-then-else. C may run when A is true. +# We know and use this construct regularly to create "transactions" +# where C is only executed when both A and B have succeeded. +# +export SHELLCHECK_OPTS="-e SC2004 -e SC2015" + +function showHelp() { + # + # Display commandline help on STDOUT. + # + cat <&1 >/dev/null \ + || { + printf '%s\n' 'FATAL: cannot find shellcheck; make sure it is installed and can be found in ${PATH}.' + exit 1 + } + +# +# Run ShellCheck for all Bash scripts in the bin/ subdir. +# * Includes sourced files, so the libraries from the lib/ subfolder +# are checked too as long a they are used in at least one script. +# * Select format and output based on whether this script is +# executed by Jenkins or by a regular user. +# +if [[ -n "${WORKSPACE:-}" ]] +then + # + # Exclude SC2154 (warning for variables that are referenced but not assigned), + # because we cannot easily resolve variables sourced from etc/*.cfg config files. + # + export SHELLCHECK_OPTS="${SHELLCHECK_OPTS} -e SC2154" + # + # ShellCheck for Jenkins. + # + shellcheck -a -x -o all -f checkstyle "${WORKSPACE}"/bin/*.sh | tee checkstyle-result.xml + # + # Reformat the generated report to add hyperlinks to the ShellCheck issues on the wiki: + # https://github.com/koalaman/shellcheck/wiki/SC${ISSUENUMBER} + # explaining whatis wrong with the code / style and how to improve it. + # + perl -pi -e "s|message='([^']+)'\s+source='ShellCheck.(SC[0-9]+)'|message='<a href="https://github.com/koalaman/shellcheck/wiki/\$2">\$2: \$1</a>' source='ShellCheck.\$2'|" checkstyle-result.xml +else + # + # ShellCheck for regular user on the commandline. + # + MYDIR="$(cd -P "$(dirname "${0}")" && pwd)" + if [[ "${verbose:-0}" -eq 1 ]] + then + cd "${MYDIR}/.." + shellcheck -a -x -o all -f tty bin/*.sh # cannot use the printf construct used below for non-vebose output as it destroys the terminal colors. + cd '-' # Goes back to previous directory before we changed to ${MYDIR}. + else + printf '%s\n' "$(cd "${MYDIR}/.." && shellcheck -a -x -o all -f gcc bin/*.sh)" + fi +fi