tfa-next: add static and lint checks
1. Copyright exists on new files (error) + are correctly dated
(warn)
2. Line endings are Unix style, not Windows
3. Cargo fmt --check - returns error if format issues found
4. Clippy - various lints, both error + warn
Checks 1+2 call the pre-existing scripts in the static-checks/ dir, 3+4
are newly implemented checks in the next-checks/ dir.
clippy is currently set to only fail on DENY level errors[1]. There are
many warnings currently in the prototype RF-A, however in future we
should look to enable the '-Dwarnings' flag to turn WARN into fail.
clippy is set to run twice for simplicity: once for fvp, once for qemu.
The '--all-features' flag to clippy exists and would allow a single run,
however rust/build.rs contains a check to ensure the Rust flag `--cfg
platform=${PLAT}` is set (where $PLAT is an env var passed to the make
command). This would mean some additional work is required to enable
'--all-features'. This work should be considered for future scaling to
additional platforms however is beyond the scope of this patch.
1: https://rust-lang.github.io/rust-clippy/master/index.html?levels=deny
Signed-off-by: Zachary Leaf <zachary.leaf@arm.com>
Change-Id: I31876f2d547d90c6d255ab1ebe8f8b205a6951fe
diff --git a/script/next-checks/next-checks-cargo-fmt.sh b/script/next-checks/next-checks-cargo-fmt.sh
new file mode 100755
index 0000000..4db97c9
--- /dev/null
+++ b/script/next-checks/next-checks-cargo-fmt.sh
@@ -0,0 +1,41 @@
+
+#!/usr/bin/env bash
+#
+# Copyright (c) 2024 Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+this_dir="$(readlink -f "$(dirname "$0")")"
+. $this_dir/../static-checks/common.sh
+
+TF_ROOT="$1"
+
+TEST_CASE="Rust cargo fmt checks"
+
+echo "# ${TEST_CASE}"
+
+LOG_FILE=`mktemp -t common.XXXX`
+
+EXIT_VALUE=0
+
+cargo fmt --manifest-path=${TF_ROOT}/rust/Cargo.toml --all -- --check &> "$LOG_FILE"
+
+if [ "$?" -ne 0 ]; then
+ EXIT_VALUE=1
+fi
+
+echo >> "$LOG_TEST_FILENAME"
+echo "****** $TEST_CASE ******" >> "$LOG_TEST_FILENAME"
+echo >> "$LOG_TEST_FILENAME"
+if [[ "$EXIT_VALUE" == 0 ]]; then
+ echo "Result : SUCCESS" >> "$LOG_TEST_FILENAME"
+else
+ echo "Result : FAILURE" >> "$LOG_TEST_FILENAME"
+fi
+echo >> "$LOG_TEST_FILENAME"
+cat "$LOG_FILE" >> "$LOG_TEST_FILENAME"
+
+rm "$LOG_FILE"
+
+exit "$EXIT_VALUE"
diff --git a/script/next-checks/next-checks-clippy.sh b/script/next-checks/next-checks-clippy.sh
new file mode 100755
index 0000000..b7a644a
--- /dev/null
+++ b/script/next-checks/next-checks-clippy.sh
@@ -0,0 +1,48 @@
+#!/usr/bin/env bash
+#
+# Copyright (c) 2024 Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+this_dir="$(readlink -f "$(dirname "$0")")"
+. $this_dir/../static-checks/common.sh
+
+TF_ROOT="$1"
+TEST_CASE="Rust clippy checks"
+LOG_FILE=`mktemp -t common.XXXX`
+EXIT_VALUE=0
+
+echo "# ${TEST_CASE}"
+echo >> "$LOG_TEST_FILENAME"
+echo "****** $TEST_CASE ******" >> "$LOG_TEST_FILENAME"
+echo >> "$LOG_TEST_FILENAME"
+echo "Platforms:" >> "$LOG_TEST_FILENAME"
+
+for plat in "fvp" "qemu"
+do
+ echo >> $LOG_FILE
+ echo "############### ${TEST_CASE} - platform: ${plat}" >> "$LOG_FILE"
+ echo >> $LOG_FILE
+ make -C ${TF_ROOT}/rust PLAT=${plat} clippy >> "$LOG_FILE" 2>&1
+
+ if [ "$?" -ne 0 ]; then
+ echo -e " ${plat}\t: FAIL" >> "$LOG_TEST_FILENAME"
+ EXIT_VALUE=1
+ else
+ echo -e " ${plat}\t: PASS" >> "$LOG_TEST_FILENAME"
+ fi
+done
+
+echo >> "$LOG_TEST_FILENAME"
+if [[ "$EXIT_VALUE" == 0 ]]; then
+ echo "Result : SUCCESS" >> "$LOG_TEST_FILENAME"
+else
+ echo "Result : FAILURE" >> "$LOG_TEST_FILENAME"
+fi
+echo >> "$LOG_TEST_FILENAME"
+cat "$LOG_FILE" >> "$LOG_TEST_FILENAME"
+
+rm "$LOG_FILE"
+
+exit "$EXIT_VALUE"
diff --git a/script/next-checks/next-checks.sh b/script/next-checks/next-checks.sh
new file mode 100755
index 0000000..89df456
--- /dev/null
+++ b/script/next-checks/next-checks.sh
@@ -0,0 +1,108 @@
+#!/usr/bin/env bash
+#
+# Copyright (c) 2024 Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+echo '----------------------------------------------'
+echo '-- Running Rust formatting and lint checks --'
+echo '----------------------------------------------'
+
+export LOG_TEST_FILENAME=$(pwd)/next-checks.log
+export RUSTUP_HOME=/usr/local/rustup
+
+# For local runs, we require GERRIT_BRANCH to be set to get the merge-base/diff
+# between the checked out commit and the tip of $GERRIT_BRANCH - for running
+# next tests, usually this will be tfa-next
+export GERRIT_BRANCH=${GERRIT_BRANCH:="tfa-next"}
+
+if [ "$IS_CONTINUOUS_INTEGRATION" == 1 ]; then
+ # git operations e.g. ${get_merge_base} rely on access to tfa-next branch,
+ # we need to access via SSH for that to work currently
+ SSH_PARAMS="-o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o PubkeyAcceptedKeyTypes=+ssh-rsa -p 29418 -i ${CI_BOT_KEY}"
+ REPO_SSH_URL="ssh://${CI_BOT_USERNAME}@review.trustedfirmware.org:29418/TF-A/trusted-firmware-a"
+ export GIT_SSH_COMMAND="ssh ${SSH_PARAMS}"
+ git remote set-url origin ${REPO_SSH_URL}
+ git fetch origin
+fi
+
+# Find the absolute path of the scripts' top directory
+cd "$(dirname "$0")/../.."
+export CI_ROOT=$(pwd)
+cd -
+
+. $CI_ROOT/script/static-checks/common.sh
+
+echo
+echo "###### Rust checks ######" > "$LOG_TEST_FILENAME"
+echo >> "$LOG_TEST_FILENAME"
+
+echo "Patch series being checked:" >> "$LOG_TEST_FILENAME"
+git log --oneline $(get_merge_base)..HEAD >> "$LOG_TEST_FILENAME"
+echo >> "$LOG_TEST_FILENAME"
+echo "Base branch reference commit:" >> "$LOG_TEST_FILENAME"
+git log --oneline -1 $(get_merge_base) >> "$LOG_TEST_FILENAME"
+
+echo >> "$LOG_TEST_FILENAME"
+
+ERROR_COUNT=0
+
+# Ensure all the files contain a copyright
+
+"$CI_ROOT"/script/static-checks/static-checks-check-copyright.sh .
+
+if [ "$?" != 0 ]; then
+ echo "Copyright test: FAILURE"
+ ((ERROR_COUNT++))
+else
+ echo "Copyright test: PASS"
+fi
+echo
+
+# Check line endings
+
+if [ "$IS_CONTINUOUS_INTEGRATION" == 1 ]; then
+ "$CI_ROOT"/script/static-checks/static-checks-coding-style-line-endings.sh . patch
+else
+ "$CI_ROOT"/script/static-checks/static-checks-coding-style-line-endings.sh
+fi
+
+if [ "$?" != 0 ]; then
+ echo "Line ending test: FAILURE"
+ ((ERROR_COUNT++))
+else
+ echo "Line ending test: PASS"
+fi
+echo
+
+# Check coding style with cargo fmt
+
+"$CI_ROOT"/script/next-checks/next-checks-cargo-fmt.sh .
+
+if [ "$?" != 0 ]; then
+ echo "cargo fmt test: FAILURE"
+ ((ERROR_COUNT++))
+else
+ echo "cargo fmt test: PASS"
+fi
+echo
+
+# Check lints with clippy
+
+"$CI_ROOT"/script/next-checks/next-checks-clippy.sh .
+
+if [ "$?" != 0 ]; then
+ echo "Rust clippy: FAILURE"
+ ((ERROR_COUNT++))
+else
+ echo "Rust clippy: PASS"
+fi
+echo
+
+if [ "$ERROR_COUNT" != 0 ]; then
+ echo "Some static checks have failed."
+ exit 1
+fi
+
+exit 0
diff --git a/script/static-checks/check-copyright.py b/script/static-checks/check-copyright.py
index a05b4ca..2bdfa93 100755
--- a/script/static-checks/check-copyright.py
+++ b/script/static-checks/check-copyright.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (c) 2019-2020, Arm Limited. All rights reserved.
+# Copyright (c) 2019-2024, Arm Limited. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -28,7 +28,7 @@
# File extensions to check
VALID_FILE_EXTENSIONS = ('.c', '.conf', '.dts', '.dtsi', '.editorconfig',
'.h', '.i', '.ld', 'Makefile', '.mk', '.msvc',
- '.py', '.S', '.scat', '.sh')
+ '.py', '.S', '.scat', '.sh', '.rs')
# Paths inside the tree to ignore. Hidden folders and files are always ignored.
# They mustn't end in '/'.
diff --git a/script/static-checks/static-checks-coding-style-line-endings.sh b/script/static-checks/static-checks-coding-style-line-endings.sh
index 9c0cda7..66763bc 100755
--- a/script/static-checks/static-checks-coding-style-line-endings.sh
+++ b/script/static-checks/static-checks-coding-style-line-endings.sh
@@ -22,7 +22,7 @@
shopt -s globstar
parent=$(get_merge_base)
git diff $parent..HEAD --no-ext-diff --unified=0 --exit-code -a \
- --no-prefix **/*.{S,c,h,i,dts,dtsi,rst,mk} Makefile | \
+ --no-prefix **/*.{S,c,h,i,dts,dtsi,rst,mk,rs} Makefile | \
awk '/^\+/ && /\r$/' &> "$LOG_FILE"
else
# For all the source and doc files
@@ -37,6 +37,7 @@
-name '*.rst' -or \
-name 'Makefile' -or \
-name '*.mk' \
+ -name '*.rs' \
-\) -exec grep --files-with-matches $'\r$' {} \; &> "$LOG_FILE"
fi