blob: 3b8dbbead8675b6ecc0cfbbd3bb9a5618ec491af [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() {
69 echo "Usage: $(basename -- "$0") [-v] [-h] [-d <TF-M dir>] [-f <output_filename>] [-u] [-p <number>]"
70 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"
74 echo " -u, Update checkpatch files using curl"
75 echo " -l <number>, Check only the last <number> commits (HEAD~<number>)."
Dean Birch62c4f082020-01-17 16:13:26 +000076 echo " -p <path>, Provide location of directory containing checkpatch."
77 echo " -r, Print raw output. Implies verbose."
Minos Galanakisf4ca6ac2017-12-11 02:39:21 +010078 echo -e "\nNOTE: make sure checkpatch is located in '$CHECKPATCH_PATH'"
79}
80
81##@fn app_err(void)
82##@brief Print error massage.
83##@returns n/a
84##
85#This is needed for Doxygen for now.
86#!void app_err(void){};
87app_err() {
88 echo "Error: "$1 >&2
89}
90
Minos Galanakisf4ca6ac2017-12-11 02:39:21 +010091##@fn check_tree()
92##@brief Run checkpatch in directory tree checking mode
93##@returns status code
94##
95##Execute checkpatch to check the full content of all source files under the
96##directory specified in \ref TFM_DIRECTORY_NAME. Directory content specified in
97##\ref SKIP_PATHS will be excluded.
98##This function uses xargs to execute multiple checkpatch instances in parallel.
99##
100#This is needed for Doxygen for now.
101#!void check_tree(){};
102check_tree() {
103 # Find all files to execute checkpatch on
104 FIND_CMD="find $TFM_DIRECTORY_NAME -name '*.[ch]' -a -not \( -path "${SKIP_PATHS//:/ -o -path }" \)"
105 echo "Scanning "$TFM_DIRECTORY_NAME" dir to find all .c and .h files to check ..."
106 #Modify checkpatch command line to make checkpatch work on files.
107 CHECKPATCH_CMD="$CHECKPATCH_CMD -f "
108 if [ $VERBOSE -eq 1 ]; then
109 eval "$FIND_CMD" | xargs -n 1 -i -P 8 $CHECKPATCH_CMD {} |tee -a "$OUTPUT_FILE_PATH"
Dean Birch62c4f082020-01-17 16:13:26 +0000110 RETURN_CODE=${PIPESTATUS[1]}
Minos Galanakisf4ca6ac2017-12-11 02:39:21 +0100111 else
112 eval "$FIND_CMD" | xargs -n 1 -i -P 8 $CHECKPATCH_CMD {} >> $OUTPUT_FILE_PATH
Dean Birch62c4f082020-01-17 16:13:26 +0000113 RETURN_CODE=${PIPESTATUS[1]}
Minos Galanakisf4ca6ac2017-12-11 02:39:21 +0100114 fi
115}
116
117##@fn check_diff()
118##@brief Run checkpatch in git diff mode.
119##@returns status code
120##
121##Execute checkpatch to check the last N (\ref CHECK_LAST_COMMITS) commits of
122##the branch checked out at directory specified in \ref TFM_DIRECTORY_NAME.
123##Directory content specified in \ref SKIP_PATHS will be excluded.
124##
125#This is needed for Doxygen for now.
126#!void check_diff(){};
127check_diff() {
128 BASE_COMMIT="HEAD~$CHECK_LAST_COMMITS"
129 #use find to limit diff content to the same set of files as when checking
130 #the whole tree.
131 FIND_CMD="find ./ -name '*.[ch]' -a -not \( -path "${SKIP_PATHS//:/ -o -path }" \)"
132
133 #enter tf-m working copy to make git commands execute fine
134 pushd "$TFM_DIRECTORY_NAME" > /dev/null
135 #Execute popd when shell exits
136 trap popd 0
137
138 #List of files we care about. Filter out changed files from interesting
139 #list of files. This is needed to avoid GIT_CMD to break the argument
140 #list length.
141 CARE_LIST=$(eval $FIND_CMD | grep "$(git diff $BASE_COMMIT --name-only)" -)
Minos Galanakisf4ca6ac2017-12-11 02:39:21 +0100142
Minos Galanakisea421232019-06-20 17:11:28 +0100143 if [ ! -z "$CARE_LIST" ]; then
144 # Only run checkpatch if there are files to check
145 GIT_CMD="git diff $BASE_COMMIT -- $CARE_LIST"
146 echo "$GIT_CMD"
147 echo "Checking commits: $(git log "$BASE_COMMIT"..HEAD --format=%h | tr $"\n" " ")"
Minos Galanakisf4ca6ac2017-12-11 02:39:21 +0100148
Minos Galanakisea421232019-06-20 17:11:28 +0100149 #Modify checkpatch parameters to give more details when working on
150 #diff:s
151 CHECKPATCH_CMD="$CHECKPATCH_CMD --showfile -"
152 fi
Minos Galanakisf4ca6ac2017-12-11 02:39:21 +0100153
154 if [ $VERBOSE -eq 1 ]; then
155 $GIT_CMD | $CHECKPATCH_CMD | tee -a "$OUTPUT_FILE_PATH"
Dean Birch62c4f082020-01-17 16:13:26 +0000156 RETURN_CODE=${PIPESTATUS[1]}
Minos Galanakisf4ca6ac2017-12-11 02:39:21 +0100157 else
158 $GIT_CMD | $CHECKPATCH_CMD >> $OUTPUT_FILE_PATH
Dean Birch62c4f082020-01-17 16:13:26 +0000159 RETURN_CODE=${PIPESTATUS[1]}
Minos Galanakisf4ca6ac2017-12-11 02:39:21 +0100160 fi
161
162 popd > /dev/null
163 #Remove cleanup trap.
164 trap 0
165}
166
167#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
168#~~~~~~~~~~~~~~~~~~~~~~~~ Entry point ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
169#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
170#Internal variables not to be modified.
171VERBOSE=0
172UPDATE_CHECKPATCH_FILES=0
173
174##@var CHECK_LAST_COMMITS
175##@brief Number of commits to check.
176##
177##Number of commits relative to HEAD to check. When set to 0 full file content
178##is checked instead of commit diffs.
179##
180#This is needed for Doxygen for now.
181#!path CHECK_LAST_COMMITS;
182CHECK_LAST_COMMITS=0
183
Dean Birch62c4f082020-01-17 16:13:26 +0000184# Whether to print the output to screen.
185RAW_OUTPUT=0
186
Minos Galanakisf4ca6ac2017-12-11 02:39:21 +0100187# Getting options and setting variables required to execute the script. This
188# script starts executing from here.
Dean Birch62c4f082020-01-17 16:13:26 +0000189while getopts "uvhd:f:l:p:r" opt
Minos Galanakisf4ca6ac2017-12-11 02:39:21 +0100190do
191 case $opt in
192 v) VERBOSE=1 ;;
193 h) usage ; exit 0 ;;
194 d) TFM_DIRECTORY_NAME="$OPTARG" ;;
195 f) OUTPUT_FILE_PATH="$OPTARG" ;;
196 u) UPDATE_CHECKPATCH_FILES=1 ;;
197 l) CHECK_LAST_COMMITS="$OPTARG" ;;
198 p) CHECKPATCH_PATH="$OPTARG" ;;
Dean Birch62c4f082020-01-17 16:13:26 +0000199 r) RAW_OUTPUT=1
200 VERBOSE=1 ;;
Minos Galanakisf4ca6ac2017-12-11 02:39:21 +0100201 \?) usage ; exit 1 ;;
202 esac
203done
204
205# Update checkpatch files
206if [ $UPDATE_CHECKPATCH_FILES -eq 1 ]; then
Antonio de Angelisfbc6c422024-12-12 12:11:10 +0000207 echo "DEPRECATED: Discarding request to update checkpatch files."
Minos Galanakisf4ca6ac2017-12-11 02:39:21 +0100208 exit 0
209fi
210
211#Convert checkpath override path to full path
212CHECKPATCH_PATH=$(readlink -f "$CHECKPATCH_PATH")
213
214#Convert output file name to full path
215OUTPUT_FILE_PATH=$(readlink -f "$OUTPUT_FILE_PATH")
216
Xinyu Zhang27449ac2021-12-29 12:01:49 +0800217# Convert TF-M specific type defs file to full path
218TFM_TYPE_DEF_FILE=$CHECKPATCH_PATH"/tfm_type_defs.txt"
219
220# Prepare CheckPatch config file
221CHECKPATCH_CONFG_FILENAME=$CHECKPATCH_PATH_DEF"/checkpatch.conf"
222sed -i "s#TFM_TYPE_DEF_FILE#$TFM_TYPE_DEF_FILE#g" $CHECKPATCH_CONFG_FILENAME
223
Minos Galanakisf4ca6ac2017-12-11 02:39:21 +0100224# Create checkpatch command
225CHECKPATCH_APP=$CHECKPATCH_PATH"/checkpatch.pl"
Minos Galanakisf4ca6ac2017-12-11 02:39:21 +0100226CHECKPATCH_CMD=$CHECKPATCH_APP" $(grep -o '^[^#]*' $CHECKPATCH_CONFG_FILENAME)"
227
228# Check if checkpatch is present
229if ! [ -f "$CHECKPATCH_APP" ]; then
230 app_err "checkpatch.pl was not found. checkpatch.pl has to be located in $CHECKPATCH_PATH"
231 exit 1
232fi
233
234#Truncate previous content
235: > $OUTPUT_FILE_PATH
236
237#Do we need to work on a git diff?
238if [ $CHECK_LAST_COMMITS -eq 0 ]
239then
240 #Working on files
241 check_tree
242else
243 #Working on git diff
244 check_diff
245fi
246
Dean Birch62c4f082020-01-17 16:13:26 +0000247if [ "$RAW_OUTPUT" == "1" ] ; then
248 rm $OUTPUT_FILE_PATH
249 exit $RETURN_CODE
250else
251 echo "checkpatch report \"$OUTPUT_FILE_PATH\" is ready!"
252fi