blob: 42ab4ac4a451440016ca099587d729f50a94a1b8 [file] [log] [blame]
Minos Galanakisf4ca6ac2017-12-11 02:39:21 +01001#!/bin/bash
2#-------------------------------------------------------------------------------
Xinyu Zhang726aaa52021-02-20 15:56:54 +08003# Copyright (c) 2018-2021, Arm Limited and Contributors. All rights reserved.
Minos Galanakisf4ca6ac2017-12-11 02:39:21 +01004#
5# SPDX-License-Identifier: BSD-3-Clause
6#
7#-------------------------------------------------------------------------------
8
9##
10##@file
11##@brief Execute checkpatch
12##
13##This bash script can be used to execute checkpatch for the tf-m project.
14##The script can be started with -h to give help on usage.
15##
16
17
18##@var SKIP_PATHS
19##@brief Folders and files to not be analysed by checkpatch
20##
21##This variable specifies the list of directories which shall not be analysed
22##by checkpatch.
23##This is a colon (:) separated list.
24##
25#This is needed for Doxygen for now.
26#!string SKIP_PATHS;
Antonio de Angelis732d2842024-09-19 16:58:54 +010027SKIP_PATHS='./build-\*:./platform/\*:*/tz_\*:./lib/\*:./platform/ext/\*:./bl2/ext/\*:./docs/\*:./tools/\*:./interface/include/mbedtls/\*:./interface/include/psa/\*'
Minos Galanakisf4ca6ac2017-12-11 02:39:21 +010028
29##@var TFM_DIRECTORY_NAME
30##@brief Default path to tf-m source code.
31##
32#This is needed for Doxygen for now.
33#!path TFM_DIRECTORY_NAME;
34TFM_DIRECTORY_NAME="./"
35
36##@var OUTPUT_FILE_PATH
37##@brief Default path to report file.
38##
39##This text file will hold the output report of checkpatch.
40##
41#This is needed for Doxygen for now.
42#!path OUTPUT_FILE_PATH;
43OUTPUT_FILE_PATH="tfm_checkpatch_report.txt"
44
45##@var CHECKPATCH_PATH_DEF
46##@brief Default Path to checkpatch executable.
47##
48#This is needed for Doxygen for now.
49#!path CHECKPATCH_PATH_DEF;
50CHECKPATCH_PATH_DEF=$(readlink -f $(dirname "$0")"/checkpatch")
51
52##@var CHECKPATCH_PATH
53##@brief Path to checkpatch executable.
54##
55## Checkpatch path can be overriden by user argument. Initialized with Default
56## value of ./checkpatch
57##
58#This is needed for Doxygen for now.
59#!path CHECKPATCH_PATH;
60CHECKPATCH_PATH=$CHECKPATCH_PATH_DEF
61
62##@fn usage(void)
63##@brief Print help text on usage.
64##@returns n/a
65##
66#This is needed for Doxygen for now.
67#!void usage(void){};
68usage() {
Antonio de Angelis9eb15a82024-12-13 10:49:53 +000069 echo "Usage: $(basename -- "$0") [-v] [-h] [-d <TF-M dir>] [-f <output_filename>] [-p <number>]"
Minos Galanakisf4ca6ac2017-12-11 02:39:21 +010070 echo " -v, Verbose output"
71 echo " -h, Script help"
72 echo " -d, <TF-M dir>, TF-M directory"
73 echo " -f, <output_filename>, Output filename"
Minos Galanakisf4ca6ac2017-12-11 02:39:21 +010074 echo " -l <number>, Check only the last <number> commits (HEAD~<number>)."
Dean Birch62c4f082020-01-17 16:13:26 +000075 echo " -p <path>, Provide location of directory containing checkpatch."
76 echo " -r, Print raw output. Implies verbose."
Minos Galanakisf4ca6ac2017-12-11 02:39:21 +010077 echo -e "\nNOTE: make sure checkpatch is located in '$CHECKPATCH_PATH'"
78}
79
80##@fn app_err(void)
81##@brief Print error massage.
82##@returns n/a
83##
84#This is needed for Doxygen for now.
85#!void app_err(void){};
86app_err() {
87 echo "Error: "$1 >&2
88}
89
Minos Galanakisf4ca6ac2017-12-11 02:39:21 +010090##@fn check_tree()
91##@brief Run checkpatch in directory tree checking mode
92##@returns status code
93##
94##Execute checkpatch to check the full content of all source files under the
95##directory specified in \ref TFM_DIRECTORY_NAME. Directory content specified in
96##\ref SKIP_PATHS will be excluded.
97##This function uses xargs to execute multiple checkpatch instances in parallel.
98##
99#This is needed for Doxygen for now.
100#!void check_tree(){};
101check_tree() {
102 # Find all files to execute checkpatch on
103 FIND_CMD="find $TFM_DIRECTORY_NAME -name '*.[ch]' -a -not \( -path "${SKIP_PATHS//:/ -o -path }" \)"
104 echo "Scanning "$TFM_DIRECTORY_NAME" dir to find all .c and .h files to check ..."
105 #Modify checkpatch command line to make checkpatch work on files.
106 CHECKPATCH_CMD="$CHECKPATCH_CMD -f "
107 if [ $VERBOSE -eq 1 ]; then
108 eval "$FIND_CMD" | xargs -n 1 -i -P 8 $CHECKPATCH_CMD {} |tee -a "$OUTPUT_FILE_PATH"
Dean Birch62c4f082020-01-17 16:13:26 +0000109 RETURN_CODE=${PIPESTATUS[1]}
Minos Galanakisf4ca6ac2017-12-11 02:39:21 +0100110 else
111 eval "$FIND_CMD" | xargs -n 1 -i -P 8 $CHECKPATCH_CMD {} >> $OUTPUT_FILE_PATH
Dean Birch62c4f082020-01-17 16:13:26 +0000112 RETURN_CODE=${PIPESTATUS[1]}
Minos Galanakisf4ca6ac2017-12-11 02:39:21 +0100113 fi
114}
115
116##@fn check_diff()
117##@brief Run checkpatch in git diff mode.
118##@returns status code
119##
120##Execute checkpatch to check the last N (\ref CHECK_LAST_COMMITS) commits of
121##the branch checked out at directory specified in \ref TFM_DIRECTORY_NAME.
122##Directory content specified in \ref SKIP_PATHS will be excluded.
123##
124#This is needed for Doxygen for now.
125#!void check_diff(){};
126check_diff() {
127 BASE_COMMIT="HEAD~$CHECK_LAST_COMMITS"
128 #use find to limit diff content to the same set of files as when checking
129 #the whole tree.
130 FIND_CMD="find ./ -name '*.[ch]' -a -not \( -path "${SKIP_PATHS//:/ -o -path }" \)"
131
132 #enter tf-m working copy to make git commands execute fine
133 pushd "$TFM_DIRECTORY_NAME" > /dev/null
134 #Execute popd when shell exits
135 trap popd 0
136
137 #List of files we care about. Filter out changed files from interesting
138 #list of files. This is needed to avoid GIT_CMD to break the argument
139 #list length.
140 CARE_LIST=$(eval $FIND_CMD | grep "$(git diff $BASE_COMMIT --name-only)" -)
Minos Galanakisf4ca6ac2017-12-11 02:39:21 +0100141
Minos Galanakisea421232019-06-20 17:11:28 +0100142 if [ ! -z "$CARE_LIST" ]; then
143 # Only run checkpatch if there are files to check
144 GIT_CMD="git diff $BASE_COMMIT -- $CARE_LIST"
145 echo "$GIT_CMD"
146 echo "Checking commits: $(git log "$BASE_COMMIT"..HEAD --format=%h | tr $"\n" " ")"
Minos Galanakisf4ca6ac2017-12-11 02:39:21 +0100147
Minos Galanakisea421232019-06-20 17:11:28 +0100148 #Modify checkpatch parameters to give more details when working on
149 #diff:s
150 CHECKPATCH_CMD="$CHECKPATCH_CMD --showfile -"
151 fi
Minos Galanakisf4ca6ac2017-12-11 02:39:21 +0100152
153 if [ $VERBOSE -eq 1 ]; then
154 $GIT_CMD | $CHECKPATCH_CMD | tee -a "$OUTPUT_FILE_PATH"
Dean Birch62c4f082020-01-17 16:13:26 +0000155 RETURN_CODE=${PIPESTATUS[1]}
Minos Galanakisf4ca6ac2017-12-11 02:39:21 +0100156 else
157 $GIT_CMD | $CHECKPATCH_CMD >> $OUTPUT_FILE_PATH
Dean Birch62c4f082020-01-17 16:13:26 +0000158 RETURN_CODE=${PIPESTATUS[1]}
Minos Galanakisf4ca6ac2017-12-11 02:39:21 +0100159 fi
160
161 popd > /dev/null
162 #Remove cleanup trap.
163 trap 0
164}
165
166#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
167#~~~~~~~~~~~~~~~~~~~~~~~~ Entry point ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
168#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
169#Internal variables not to be modified.
170VERBOSE=0
Minos Galanakisf4ca6ac2017-12-11 02:39:21 +0100171
172##@var CHECK_LAST_COMMITS
173##@brief Number of commits to check.
174##
175##Number of commits relative to HEAD to check. When set to 0 full file content
176##is checked instead of commit diffs.
177##
178#This is needed for Doxygen for now.
179#!path CHECK_LAST_COMMITS;
180CHECK_LAST_COMMITS=0
181
Dean Birch62c4f082020-01-17 16:13:26 +0000182# Whether to print the output to screen.
183RAW_OUTPUT=0
184
Minos Galanakisf4ca6ac2017-12-11 02:39:21 +0100185# Getting options and setting variables required to execute the script. This
186# script starts executing from here.
Antonio de Angelis9eb15a82024-12-13 10:49:53 +0000187while getopts "vhd:f:l:p:r" opt
Minos Galanakisf4ca6ac2017-12-11 02:39:21 +0100188do
189 case $opt in
190 v) VERBOSE=1 ;;
191 h) usage ; exit 0 ;;
192 d) TFM_DIRECTORY_NAME="$OPTARG" ;;
193 f) OUTPUT_FILE_PATH="$OPTARG" ;;
Minos Galanakisf4ca6ac2017-12-11 02:39:21 +0100194 l) CHECK_LAST_COMMITS="$OPTARG" ;;
195 p) CHECKPATCH_PATH="$OPTARG" ;;
Dean Birch62c4f082020-01-17 16:13:26 +0000196 r) RAW_OUTPUT=1
197 VERBOSE=1 ;;
Minos Galanakisf4ca6ac2017-12-11 02:39:21 +0100198 \?) usage ; exit 1 ;;
199 esac
200done
201
Minos Galanakisf4ca6ac2017-12-11 02:39:21 +0100202#Convert checkpath override path to full path
203CHECKPATCH_PATH=$(readlink -f "$CHECKPATCH_PATH")
204
205#Convert output file name to full path
206OUTPUT_FILE_PATH=$(readlink -f "$OUTPUT_FILE_PATH")
207
Xinyu Zhang27449ac2021-12-29 12:01:49 +0800208# Convert TF-M specific type defs file to full path
209TFM_TYPE_DEF_FILE=$CHECKPATCH_PATH"/tfm_type_defs.txt"
210
211# Prepare CheckPatch config file
212CHECKPATCH_CONFG_FILENAME=$CHECKPATCH_PATH_DEF"/checkpatch.conf"
213sed -i "s#TFM_TYPE_DEF_FILE#$TFM_TYPE_DEF_FILE#g" $CHECKPATCH_CONFG_FILENAME
214
Minos Galanakisf4ca6ac2017-12-11 02:39:21 +0100215# Create checkpatch command
216CHECKPATCH_APP=$CHECKPATCH_PATH"/checkpatch.pl"
Minos Galanakisf4ca6ac2017-12-11 02:39:21 +0100217CHECKPATCH_CMD=$CHECKPATCH_APP" $(grep -o '^[^#]*' $CHECKPATCH_CONFG_FILENAME)"
218
219# Check if checkpatch is present
220if ! [ -f "$CHECKPATCH_APP" ]; then
221 app_err "checkpatch.pl was not found. checkpatch.pl has to be located in $CHECKPATCH_PATH"
222 exit 1
223fi
224
225#Truncate previous content
226: > $OUTPUT_FILE_PATH
227
228#Do we need to work on a git diff?
229if [ $CHECK_LAST_COMMITS -eq 0 ]
230then
231 #Working on files
232 check_tree
233else
234 #Working on git diff
235 check_diff
236fi
237
Dean Birch62c4f082020-01-17 16:13:26 +0000238if [ "$RAW_OUTPUT" == "1" ] ; then
239 rm $OUTPUT_FILE_PATH
240 exit $RETURN_CODE
241else
242 echo "checkpatch report \"$OUTPUT_FILE_PATH\" is ready!"
243fi