# # SPDX-License-Identifier: BSD-3-Clause # SPDX-FileCopyrightText: Copyright TF-RMM Contributors. # # # This script is called from main CMakeLists.txt to determine if code complies # to coding standards as mentioned in docs/getting_started/coding-standard.rst # # Runs checkpatch.pl on entire codebase if variable CHECKCODEBASE_RUN is defined. # # Runs checkpatch.pl on new commits if variable CHECKCODEBASE_RUN is defined. # find_package(Git REQUIRED) find_package(Perl REQUIRED) find_program(CHECKPATCH_EXECUTABLE "checkpatch.pl" PATHS ${CMAKE_SOURCE_DIR} PATH_SUFFIXES tools/checkpatch DOC "Path to checkpatch.pl" ) list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/tools/common") include(GitUtils) # # List of directories and files to exclude from checking for target checkcodebase # list(APPEND glob_excludes "^.git") list(APPEND glob_excludes "^out") list(APPEND glob_excludes "^build") list(APPEND glob_excludes "^ext") list(APPEND glob_excludes "^tools") list(APPEND glob_excludes ".patch$") list(APPEND glob_excludes ".md$") list(APPEND glob_excludes "~$") list(APPEND glob_excludes ".swp$") list(APPEND glob_excludes "^cscope.") set(total_errors "0") set(total_warnings "0") # Check if pre-reqs met if(PERL_NOT_FOUND OR NOT EXISTS ${CHECKPATCH_EXECUTABLE}) message(FATAL_ERROR "required dependencies not found") endif() # # checkpatch_get_stats: Parse and returns number of errors and warnings # function(checkpatch_get_stats stats_arg errors_ret warnings_ret) string(FIND "${stats_arg}" "total:" idx REVERSE) string(LENGTH "${stats_arg}" len) string(SUBSTRING "${stats_arg}" ${idx} ${len} last_line) string(REPLACE " " ";" last_line_list ${last_line}) list(GET last_line_list 1 errors) list(GET last_line_list 3 warnings) set(${errors_ret} ${errors} PARENT_SCOPE) set(${warnings_ret} ${warnings} PARENT_SCOPE) endfunction() # # print_stats_and_exit: Print summary of all errors and warnings. # If there are errors call message(FATAL_ERROR) # function(print_stats_and_exit check_type total_errors total_warnings) message(STATUS "${check_type}: total errors: ${total_errors} " "warnings: ${total_warnings}") if(${total_errors} GREATER 0) message(FATAL_ERROR "${check_type}: FAILED") endif() message(STATUS "${check_type}: PASSED") endfunction() # # Run checkpatch on entire codebase. This verifies all files in this repository # except the files listed in "glob_excludes". # # Exits with FATAL_ERROR upon errors. Warnings are ignored (temporary) # if(CHECKCODEBASE_RUN) set(source_files "") if (GIT_FOUND AND IS_DIRECTORY .git) Git_Get_All_Files(source_files) else() file(GLOB_RECURSE source_files RELATIVE ${CMAKE_SOURCE_DIR} "*") endif() # Filter out 'glob_excludes' foreach(exclude IN LISTS glob_excludes) list(FILTER source_files EXCLUDE REGEX "${exclude}") endforeach() if(NOT source_files) message(STATUS "checkcodebase: No files to check") return() endif() foreach(source_file ${source_files}) execute_process( COMMAND ${CMAKE_COMMAND} -E echo "Checking file ${source_file}" ) execute_process( WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} COMMAND ${CHECKPATCH_EXECUTABLE} -f ${source_file} OUTPUT_VARIABLE checkpatch_output RESULT_VARIABLE checkpatch_rc ECHO_OUTPUT_VARIABLE OUTPUT_STRIP_TRAILING_WHITESPACE ) # checkpatch.pl failed for this file. Collect no.of errors and warnings if(${checkpatch_rc}) checkpatch_get_stats("${checkpatch_output}" errors warnings) MATH(EXPR total_errors "${total_errors}+${errors}") MATH(EXPR total_warnings "${total_warnings}+${warnings}") endif() endforeach() print_stats_and_exit("checkcodebase" ${total_errors}, ${total_warnings}) endif() # # Run checkpatch on pending commits. # # Exits with FATAL_ERROR upon errors. # if(CHECKPATCH_RUN) if(GIT_NOT_FOUND OR NOT IS_DIRECTORY .git) message(FATAL_ERROR "Required dependencies Git not found") endif() # Get list of commits to check Git_Get_Pending_Commits(pending_commits) foreach(commit IN LISTS pending_commits) message(STATUS "Checking commit: ${commit}") execute_process( WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} COMMAND ${GIT_EXECUTABLE} diff --format=email "${commit}~..${commit}" COMMAND ${CHECKPATCH_EXECUTABLE} - OUTPUT_VARIABLE checkpatch_output RESULT_VARIABLE checkpatch_rc ECHO_OUTPUT_VARIABLE ) # checkpatch.pl failed for this commit. Collect no.of errors and warnings if(${checkpatch_rc}) checkpatch_get_stats("${checkpatch_output}" errors warnings) MATH(EXPR total_errors "${total_errors}+${errors}") MATH(EXPR total_warnings "${total_warnings}+${warnings}") endif() endforeach() print_stats_and_exit("checkpatch" ${total_errors}, ${total_warnings}) endif()