1#!/bin/bash 2 3# Copyright (C) 2019 The Android Open Source Project 4# 5# Licensed under the Apache License, Version 2.0 (the "License"); 6# you may not use this file except in compliance with the License. 7# You may obtain a copy of the License at 8# 9# http://www.apache.org/licenses/LICENSE-2.0 10# 11# Unless required by applicable law or agreed to in writing, software 12# distributed under the License is distributed on an "AS IS" BASIS, 13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14# See the License for the specific language governing permissions and 15# limitations under the License. 16 17# Wrapper around checkpatch.pl to filter results. 18 19set -e 20 21export STATIC_ANALYSIS_SRC_DIR=$(dirname $(readlink -f $0)) 22 23ROOT_DIR="${STATIC_ANALYSIS_SRC_DIR}/../../" 24pushd ${ROOT_DIR} 25source ${STATIC_ANALYSIS_SRC_DIR}/../envsetup.sh 26export OUT_DIR=$(readlink -m ${OUT_DIR:-${ROOT_DIR}/out/${BRANCH}}) 27export DIST_DIR=$(readlink -m ${DIST_DIR:-${OUT_DIR}/dist}) 28mkdir -p ${DIST_DIR} 29 30export KERNEL_DIR=$(readlink -m ${KERNEL_DIR}) 31 32CHECKPATCH_PL_PATH="${KERNEL_DIR}/scripts/checkpatch.pl" 33GIT_SHA1="HEAD" 34PATCH_DIR="${OUT_DIR}/checkpatch/patches" 35BLACKLIST_FILE="${STATIC_ANALYSIS_SRC_DIR}/checkpatch_blacklist" 36RESULTS_PATH=${DIST_DIR}/checkpatch.log 37RETURN_CODE=0 38 39echoerr() { 40 echo "$@" 1>&2; 41} 42 43# Parse flags. 44CHECKPATCH_ARGS=(--show-types) 45while [[ $# -gt 0 ]]; do 46 next="$1" 47 case ${next} in 48 --git_sha1) 49 GIT_SHA1="$2" 50 shift 51 ;; 52 --blacklisted_checks) 53 BLACKLIST_FILE="$2" 54 shift 55 ;; 56 --help) 57 echo "Gets a patch from git, passes it checkpatch.pl, and then reports" 58 echo "the subset of violations we choose to enforce." 59 echo "" 60 echo "Usage: $0" 61 echo " <--git_sha1 nnn> (Defaults to HEAD)" 62 echo " <--blacklisted_checks path_to_file> (Defaults to checkpatch_blacklist)" 63 echo " <args for checkpatch.pl>" 64 exit 0 65 ;; 66 *) 67 CHECKPATCH_ARGS+=("$1") 68 ;; 69 esac 70 shift 71done 72 73 74# Clean up from any previous run. 75if [[ -d "${PATCH_DIR}" ]]; then 76 rm -fr "${PATCH_DIR}" 77fi 78mkdir -p "${PATCH_DIR}" 79 80# Update blacklist. 81if [[ -f "${BLACKLIST_FILE}" ]]; then 82 IGNORED_ERRORS=$(grep -v '^#' ${BLACKLIST_FILE} | paste -s -d,) 83 if [[ -n "${IGNORED_ERRORS}" ]]; then 84 CHECKPATCH_ARGS+=(--ignore) 85 CHECKPATCH_ARGS+=("${IGNORED_ERRORS}") 86 fi 87fi 88 89echo "========================================================" 90echo " Running static analysis..." 91echo "========================================================" 92echo "Using KERNEL_DIR: ${KERNEL_DIR}" 93echo "Using --git_sha1: ${GIT_SHA1}" 94 95# Generate patch file from git. 96cd ${KERNEL_DIR} 97git format-patch --quiet -o "${PATCH_DIR}" "${GIT_SHA1}^1..${GIT_SHA1}" 98PATCH_FILE="${PATCH_DIR}/*.patch" 99 100# Delay exit on non-zero checkpatch.pl return code so we can finish logging. 101 102# Note, it's tricky to ignore this exit code completely and instead return only 103# based on the log values. For example, if the log is not empty, but contains no 104# ERRORS, how do we reliabliy distinguish WARNINGS that were not blacklisted 105# (or other conditions we want to ignore), from legitimate errors running the 106# script itself (e.g. bad flags)? checkpatch.pl will return 1 in both cases. 107# For now, include all known warnings in the blacklist, and forward this code 108# unconditionally. 109 110set +e 111"${CHECKPATCH_PL_PATH}" ${CHECKPATCH_ARGS[*]} $PATCH_FILE > "${RESULTS_PATH}" 112CHECKPATCH_RC=$? 113set -e 114 115# Summarize errors in the build log (full copy included in dist dir). 116if [[ $CHECKPATCH_RC -ne 0 ]]; then 117 echoerr "Errors were reported from checkpatch.pl." 118 echoerr "" 119 echoerr "Summary:" 120 echoerr "" 121 { grep -r -h -E -A1 "^ERROR:" "${RESULTS_PATH}" 1>&2; } || true 122 echoerr "" 123 echoerr "See $(basename ${RESULTS_PATH}) for complete output." 124fi 125 126echo "========================================================" 127echo "Finished running static analysis." 128echo "========================================================" 129popd 130exit ${CHECKPATCH_RC} 131