#!/bin/bash # # Copyright (c) 2016-2017, Linaro Ltd. # All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Presubmit tests that should be run before every patch submission. # The check will be run against each .sh file from the git repository # from which the script is being run. readonly local_path=$(dirname "$0") source "${local_path}/utils/utils.sh" readonly shellcheck_path="${local_path}/shellcheck/shellcheck" readonly shellcheck_url="https://git.linaro.org/people/kevin.brodsky/shellcheck-prebuilt.git/plain/shellcheck" # Globally excluded shellcheck "checks" # SC1090: shellcheck can't source files whose path is determined at runtime # (we almost always use ${local_path} when sourcing) # SC2155: almost never an actual problem readonly shellcheck_exclude_list="SC1090,SC2155" declare -a shell_files find_shell_files() { # In case some filenames contain spaces local IFS=$'\n' shell_files=($(safe git ls-files '*.sh')) readonly shell_files } # Fetch shellcheck from our own prebuilt shellcheck repo. fetch_shellcheck() { # We use a sha1 checksum to know whether we need to download a newer version. local -r remote_sha1=$(safe curl -s "${shellcheck_url}.sha1") local -r sha1_regex='[0-9a-f]+\s+shellcheck' if ! [[ ${remote_sha1} =~ $sha1_regex ]]; then log E "Invalid remote sha1: ${remote_sha1}" abort fi if [[ -e "${shellcheck_path}" && -e "${shellcheck_path}.sha1" && \ $(< "${shellcheck_path}.sha1") == "${remote_sha1}" ]]; then # We already have the latest shellcheck return fi # Download the latest shellcheck mkdir -p "$(dirname "${shellcheck_path}")" log I "Downloading shellcheck to ${shellcheck_path}" safe curl -s -o "${shellcheck_path}" "${shellcheck_url}" chmod +x "${shellcheck_path}" # Update the sha1 echo "${remote_sha1}" > "${shellcheck_path}.sha1" } # Run shellcheck on all the .sh files. shellcheck_tests() { fetch_shellcheck "${shellcheck_path}" --color -e "${shellcheck_exclude_list}" "${shell_files[@]}" } # Check for invalid constructions regarding read-only variables and the local # scope. readonlyvars_tests() { local -r str_local="local" local -r str_ronly="readonly" ! grep -Hn --color -E "\<(${str_local} ${str_ronly}|${str_ronly} ${str_local})\>" "${shell_files[@]}" } main() { find_shell_files shellcheck_tests if_error "shellcheck presubmit test FAILED." readonlyvars_tests if_error "Scope/read-only variables presubmit test FAILED." log S "Presubmit tests PASSED." exit 0 } main "$@"