Open CI Scripts: Initial Commit
* build_helper: Python script which builds sets
of configurations from a json file input
* checkpatch: Bash scripts helping with running checkpatch
* cppcheck: Bash script helping with running cppcheck
* lava_helper: Python script which generates a lava job
definition and parses the output of a lava dispatcher
* tfm_ci_pylib: Generic Python module for Open CI
* configs: Directory storing reference configurations
Change-Id: Ibda0cbfeb5b004b35fef3c2af4cb5c012f2672b4
Signed-off-by: Galanakis, Minos <minos.galanakis@linaro.org>
diff --git a/run-checkpatch.sh b/run-checkpatch.sh
new file mode 100755
index 0000000..60c3be9
--- /dev/null
+++ b/run-checkpatch.sh
@@ -0,0 +1,293 @@
+#!/bin/bash
+#-------------------------------------------------------------------------------
+# Copyright (c) 2018-2019, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+##
+##@file
+##@brief Execute checkpatch
+##
+##This bash script can be used to execute checkpatch for the tf-m project.
+##The script can be started with -h to give help on usage.
+##
+
+
+##@var SKIP_PATHS
+##@brief Folders and files to not be analysed by checkpatch
+##
+##This variable specifies the list of directories which shall not be analysed
+##by checkpatch.
+##This is a colon (:) separated list.
+##
+#This is needed for Doxygen for now.
+#!string SKIP_PATHS;
+SKIP_PATHS='./build-\*:./test/\*:./platform/\*:*/tz_\*'
+
+##@var TFM_DIRECTORY_NAME
+##@brief Default path to tf-m source code.
+##
+#This is needed for Doxygen for now.
+#!path TFM_DIRECTORY_NAME;
+TFM_DIRECTORY_NAME="./"
+
+##@var OUTPUT_FILE_PATH
+##@brief Default path to report file.
+##
+##This text file will hold the output report of checkpatch.
+##
+#This is needed for Doxygen for now.
+#!path OUTPUT_FILE_PATH;
+OUTPUT_FILE_PATH="tfm_checkpatch_report.txt"
+
+##@var CHECKPATCH_PATH_DEF
+##@brief Default Path to checkpatch executable.
+##
+#This is needed for Doxygen for now.
+#!path CHECKPATCH_PATH_DEF;
+CHECKPATCH_PATH_DEF=$(readlink -f $(dirname "$0")"/checkpatch")
+
+##@var CHECKPATCH_PATH
+##@brief Path to checkpatch executable.
+##
+## Checkpatch path can be overriden by user argument. Initialized with Default
+## value of ./checkpatch
+##
+#This is needed for Doxygen for now.
+#!path CHECKPATCH_PATH;
+CHECKPATCH_PATH=$CHECKPATCH_PATH_DEF
+
+##@fn usage(void)
+##@brief Print help text on usage.
+##@returns n/a
+##
+#This is needed for Doxygen for now.
+#!void usage(void){};
+usage() {
+ echo "Usage: $(basename -- "$0") [-v] [-h] [-d <TF-M dir>] [-f <output_filename>] [-u] [-p <number>]"
+ echo " -v, Verbose output"
+ echo " -h, Script help"
+ echo " -d, <TF-M dir>, TF-M directory"
+ echo " -f, <output_filename>, Output filename"
+ echo " -u, Update checkpatch files using curl"
+ echo " -l <number>, Check only the last <number> commits (HEAD~<number>)."
+ echo " -p <path>, Provide location of directory containing checkpath."
+ echo -e "\nNOTE: make sure checkpatch is located in '$CHECKPATCH_PATH'"
+}
+
+##@fn app_err(void)
+##@brief Print error massage.
+##@returns n/a
+##
+#This is needed for Doxygen for now.
+#!void app_err(void){};
+app_err() {
+ echo "Error: "$1 >&2
+}
+
+##@fn download_checkpatch_file(string f_name)
+##@brief Download the specified checkpatch file.
+##@param[in] f_name name of file to download.
+##@returns status code
+##
+##Download checkpatch files from raw.githubusercontent.com to the current
+##directory. Target files are truncated to avoid breaking links.
+##
+#This is needed for Doxygen for now.
+#!err download_checkpatch_file(string f_name){};
+download_checkpatch_file() {
+ # HTTPS address location to download checkpatch file
+ if [ $VERBOSE -eq 0 ]; then
+ REDIRECT=" >/dev/null"
+ fi
+
+ curl "https://raw.githubusercontent.com/torvalds/linux/master/scripts/$1" --output "$1.new" &>/dev/null
+
+ if [ $? != 0 ]; then
+ app_err "curl reported error while downloading $1"
+ exit 1
+ else
+ #Copy file and preserve links.
+ cat "$1.new" > "$1"
+ rm "$1.new"
+ fi
+}
+
+##@fn update_checkpatch()
+##@brief Download checkpatch files.
+##@returns status code
+##
+##Download checkpatch files from raw.githubusercontent.com to \ref CHECKPATCH_PATH
+##directory.
+##
+#This is needed for Doxygen for now.
+#!void update_checkpatch(){};
+update_checkpatch() {
+ echo "Updating checkpatch..."
+ if ! [ -x "$(command -v curl)" ]; then
+ app_err "curl was not found. Please, make sure curl command is available"
+ exit 1
+ fi
+
+ pushd $CHECKPATCH_PATH > /dev/null
+ #Execute popd when shell exits.
+ trap popd 0
+
+ # Download checkpatch.pl
+ download_checkpatch_file checkpatch.pl
+ chmod 750 $CHECKPATCH_PATH/checkpatch.pl
+
+ # Download const_structs.checkpatch
+ download_checkpatch_file const_structs.checkpatch
+ chmod 640 $CHECKPATCH_PATH/const_structs.checkpatch
+
+ # Download spelling.txt
+ download_checkpatch_file spelling.txt
+ chmod 640 $CHECKPATCH_PATH/spelling.txt
+
+ popd >/dev/null
+ #Remove cleanup trap
+ trap 0
+}
+
+##@fn check_tree()
+##@brief Run checkpatch in directory tree checking mode
+##@returns status code
+##
+##Execute checkpatch to check the full content of all source files under the
+##directory specified in \ref TFM_DIRECTORY_NAME. Directory content specified in
+##\ref SKIP_PATHS will be excluded.
+##This function uses xargs to execute multiple checkpatch instances in parallel.
+##
+#This is needed for Doxygen for now.
+#!void check_tree(){};
+check_tree() {
+ # Find all files to execute checkpatch on
+ FIND_CMD="find $TFM_DIRECTORY_NAME -name '*.[ch]' -a -not \( -path "${SKIP_PATHS//:/ -o -path }" \)"
+ echo "Scanning "$TFM_DIRECTORY_NAME" dir to find all .c and .h files to check ..."
+ #Modify checkpatch command line to make checkpatch work on files.
+ CHECKPATCH_CMD="$CHECKPATCH_CMD -f "
+ if [ $VERBOSE -eq 1 ]; then
+ eval "$FIND_CMD" | xargs -n 1 -i -P 8 $CHECKPATCH_CMD {} |tee -a "$OUTPUT_FILE_PATH"
+ else
+ eval "$FIND_CMD" | xargs -n 1 -i -P 8 $CHECKPATCH_CMD {} >> $OUTPUT_FILE_PATH
+ fi
+}
+
+##@fn check_diff()
+##@brief Run checkpatch in git diff mode.
+##@returns status code
+##
+##Execute checkpatch to check the last N (\ref CHECK_LAST_COMMITS) commits of
+##the branch checked out at directory specified in \ref TFM_DIRECTORY_NAME.
+##Directory content specified in \ref SKIP_PATHS will be excluded.
+##
+#This is needed for Doxygen for now.
+#!void check_diff(){};
+check_diff() {
+ BASE_COMMIT="HEAD~$CHECK_LAST_COMMITS"
+ #use find to limit diff content to the same set of files as when checking
+ #the whole tree.
+ FIND_CMD="find ./ -name '*.[ch]' -a -not \( -path "${SKIP_PATHS//:/ -o -path }" \)"
+
+ #enter tf-m working copy to make git commands execute fine
+ pushd "$TFM_DIRECTORY_NAME" > /dev/null
+ #Execute popd when shell exits
+ trap popd 0
+
+ #List of files we care about. Filter out changed files from interesting
+ #list of files. This is needed to avoid GIT_CMD to break the argument
+ #list length.
+ CARE_LIST=$(eval $FIND_CMD | grep "$(git diff $BASE_COMMIT --name-only)" -)
+ GIT_CMD="git diff $BASE_COMMIT -- $CARE_LIST"
+
+ echo "Checking commits: $(git log "$BASE_COMMIT"..HEAD --format=%h | tr $"\n" " ")"
+
+ #Modify checkpatch parameters to give more details when working on
+ #diff:s
+ CHECKPATCH_CMD="$CHECKPATCH_CMD --showfile -"
+
+ if [ $VERBOSE -eq 1 ]; then
+ $GIT_CMD | $CHECKPATCH_CMD | tee -a "$OUTPUT_FILE_PATH"
+ else
+ $GIT_CMD | $CHECKPATCH_CMD >> $OUTPUT_FILE_PATH
+ fi
+
+ popd > /dev/null
+ #Remove cleanup trap.
+ trap 0
+}
+
+#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#~~~~~~~~~~~~~~~~~~~~~~~~ Entry point ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#Internal variables not to be modified.
+VERBOSE=0
+UPDATE_CHECKPATCH_FILES=0
+
+##@var CHECK_LAST_COMMITS
+##@brief Number of commits to check.
+##
+##Number of commits relative to HEAD to check. When set to 0 full file content
+##is checked instead of commit diffs.
+##
+#This is needed for Doxygen for now.
+#!path CHECK_LAST_COMMITS;
+CHECK_LAST_COMMITS=0
+
+# Getting options and setting variables required to execute the script. This
+# script starts executing from here.
+while getopts "uvhd:f:l:p:" opt
+do
+ case $opt in
+ v) VERBOSE=1 ;;
+ h) usage ; exit 0 ;;
+ d) TFM_DIRECTORY_NAME="$OPTARG" ;;
+ f) OUTPUT_FILE_PATH="$OPTARG" ;;
+ u) UPDATE_CHECKPATCH_FILES=1 ;;
+ l) CHECK_LAST_COMMITS="$OPTARG" ;;
+ p) CHECKPATCH_PATH="$OPTARG" ;;
+ \?) usage ; exit 1 ;;
+ esac
+done
+
+# Update checkpatch files
+if [ $UPDATE_CHECKPATCH_FILES -eq 1 ]; then
+ update_checkpatch
+ echo "Checkpatch update was successfull."
+ exit 0
+fi
+
+#Convert checkpath override path to full path
+CHECKPATCH_PATH=$(readlink -f "$CHECKPATCH_PATH")
+
+#Convert output file name to full path
+OUTPUT_FILE_PATH=$(readlink -f "$OUTPUT_FILE_PATH")
+
+# Create checkpatch command
+CHECKPATCH_APP=$CHECKPATCH_PATH"/checkpatch.pl"
+CHECKPATCH_CONFG_FILENAME=$CHECKPATCH_PATH_DEF"/checkpatch.conf"
+CHECKPATCH_CMD=$CHECKPATCH_APP" $(grep -o '^[^#]*' $CHECKPATCH_CONFG_FILENAME)"
+
+# Check if checkpatch is present
+if ! [ -f "$CHECKPATCH_APP" ]; then
+ app_err "checkpatch.pl was not found. checkpatch.pl has to be located in $CHECKPATCH_PATH"
+ exit 1
+fi
+
+#Truncate previous content
+: > $OUTPUT_FILE_PATH
+
+#Do we need to work on a git diff?
+if [ $CHECK_LAST_COMMITS -eq 0 ]
+then
+ #Working on files
+ check_tree
+else
+ #Working on git diff
+ check_diff
+fi
+
+echo "checkpatch report \"$OUTPUT_FILE_PATH\" is ready!"