Warning, /frameworks/extra-cmake-modules/kde-modules/KDEGitCommitHooks.cmake is written in an unsupported language. File is not indexed.
0001 # SPDX-FileCopyrightText: 2020-2023 Alexander Lohnau <alexander.lohnau@gmx.de> 0002 # SPDX-FileCopyrightText: 2022 Ahmad Samir <a.samirh78@gmail.com> 0003 # SPDX-FileCopyrightText: 2023 Johannes Zarl-Zierl <johannes@zarl-zierl.at> 0004 # 0005 # SPDX-License-Identifier: BSD-3-Clause 0006 0007 #[=======================================================================[.rst: 0008 KDEGitCommitHooks 0009 -------------------- 0010 0011 This module provides a functionality to enforce formatting 0012 or in the future other QS checks. 0013 0014 This module provides the following function: 0015 0016 :: 0017 0018 kde_configure_git_pre_commit_hook( 0019 CHECKS <check1> [<check2> [...] 0020 [CUSTOM_SCRIPTS [<script paths> [<script paths> ...]]] # since 5.109 0021 ) 0022 0023 This function will create a pre-commit hook which contains all the given checks. 0024 In addition to that, you can pass in paths to custom scripts that will be run as the pre-commit hook. 0025 If a custom hooks directory is set via ``core.hooksPath``, a warning is issued. 0026 0027 Checks: 0028 0029 - ``CLANG_FORMAT`` With this check enabled the ``git clang-format`` tool will be used to make sure that 0030 the changed parts are properly formatted. In case the changes are not properly formatted an error 0031 message with the command to preview the formatting changes and to format the files in place 0032 will be displayed. This tool will reuse the exsting ``.clang-format`` file, in case you 0033 want to use the one provided by ECM you can include ``include(KDEClangFormat)`` which will copy 0034 the file to the source dir. It is also recommended to reformat the entire project before enforcing 0035 the formatting using this commit hook. 0036 - ``JSON_SCHEMA`` Since 5.110, uses the check-jsonschema CLI tool to ensure that all files are valid JSON and 0037 match the KPluginMetaData spec. This only applied if the JSON file has a "KPlugin" object in its root. 0038 To ignore invalid files, for example for testing error handling, given files can be exlcuded in the .kde-ci.yml file 0039 Define Options.json-validate-ignore with an array of the files you want to ignore 0040 0041 Example usage: 0042 0043 .. code-block:: cmake 0044 0045 include(KDEGitCommitHooks) 0046 kde_configure_git_pre_commit_hook(CHECKS JSON_SCHEMA CLANG_FORMAT) 0047 0048 Since 5.79 0049 #]=======================================================================] 0050 0051 # try to find clang-format in path 0052 find_program(KDE_CLANG_FORMAT_EXECUTABLE clang-format) 0053 find_program(KDE_CHECK_JSONSCHEMA_EXECUTABLE check-jsonschema) 0054 set(PRE_COMMIT_HOOK_UNIX "${CMAKE_CURRENT_LIST_DIR}/kde-git-commit-hooks/pre-commit.in") 0055 set(CLANG_FORMAT_UNIX "${CMAKE_CURRENT_LIST_DIR}/kde-git-commit-hooks/clang-format.sh") 0056 set(JSON_SCHEMA_SCRIPT "${CMAKE_CURRENT_LIST_DIR}/kde-git-commit-hooks/json-schema.py") 0057 set(JSON_SCHEMA_IN "${CMAKE_CURRENT_LIST_DIR}/kde-git-commit-hooks/combined.schema.json.in") 0058 set(GIT_DIR "${CMAKE_SOURCE_DIR}/.git") 0059 set(GIT_HOOKS_DIR "${GIT_DIR}/hooks") 0060 set(JSON_SCHEMA_OUT "${GIT_HOOKS_DIR}/scripts/combined.schema.json") 0061 0062 function(KDE_CONFIGURE_GIT_PRE_COMMIT_HOOK) 0063 set(_oneValueArgs "") 0064 set(_multiValueArgs CHECKS CUSTOM_SCRIPTS) 0065 cmake_parse_arguments(ARG "" "${_oneValueArgs}" "${_multiValueArgs}" ${ARGN}) 0066 0067 if(NOT CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME) 0068 message(STATUS "Project is not top level project - pre-commit hook not installed") 0069 return() 0070 endif() 0071 0072 if(NOT ARG_CHECKS) 0073 message(FATAL_ERROR "No checks were specified") 0074 endif() 0075 0076 find_package(Git QUIET) 0077 0078 if (NOT IS_DIRECTORY ${GIT_DIR} # In case of tarballs there is no .git directory 0079 OR NOT (UNIX OR WIN32) 0080 OR NOT GIT_FOUND 0081 ) 0082 return() 0083 endif() 0084 0085 execute_process(COMMAND "${GIT_EXECUTABLE}" config --get core.hooksPath 0086 WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}" 0087 RESULT_VARIABLE _gitresult 0088 OUTPUT_VARIABLE _gitoutput 0089 ERROR_QUIET 0090 OUTPUT_STRIP_TRAILING_WHITESPACE) 0091 0092 if(_gitresult EQUAL 0 AND NOT ${GIT_HOOKS_DIR} EQUAL "${_gitoutput}") 0093 message(WARNING "Git is configured to use '${_gitoutput}' for hooks. The generated commit hooks will likely not be executed.") 0094 endif() 0095 0096 string(REPLACE ";" "\n" PRE_COMMIT_SCRIPTS "${ARG_CUSTOM_SCRIPTS}") 0097 set(_write_hook FALSE) 0098 if(KDE_CLANG_FORMAT_EXECUTABLE) 0099 list(FIND ARG_CHECKS "CLANG_FORMAT" _index) 0100 # Used to configure clang-format.sh script 0101 if (COMMAND KDE_CLANG_FORMAT) 0102 set(HAS_CLANG_FORMAT_COMMAND_INCLUDED TRUE) 0103 else() 0104 set(HAS_CLANG_FORMAT_COMMAND_INCLUDED FALSE) 0105 endif() 0106 if (${_index} GREATER -1) 0107 # get version of clang-format 0108 execute_process( 0109 COMMAND "${KDE_CLANG_FORMAT_EXECUTABLE}" --version 0110 OUTPUT_VARIABLE _clang_format_version_raw 0111 ERROR_VARIABLE _clang_format_version_raw 0112 ) 0113 if (_clang_format_version_raw MATCHES "clang-format version ([0-9]+)(\\.[0-9]+)*") 0114 set(KDE_CLANG_FORMAT_MAJOR_VERSION "${CMAKE_MATCH_1}") 0115 endif() 0116 unset(_clang_format_version_raw) 0117 message(STATUS "Found clang-format version ${KDE_CLANG_FORMAT_MAJOR_VERSION}") 0118 0119 set(CLANG_FORMAT_SCRIPT "\"$(git rev-parse --git-common-dir)\"/hooks/scripts/clang-format.sh") 0120 configure_file(${CLANG_FORMAT_UNIX} "${GIT_HOOKS_DIR}/scripts/clang-format.sh" @ONLY) 0121 set(PRE_COMMIT_SCRIPTS "\"$(git rev-parse --git-common-dir)\"/hooks/scripts/clang-format.sh\n${PRE_COMMIT_SCRIPTS}") 0122 set(_write_hook TRUE) 0123 endif() 0124 endif() 0125 0126 list(FIND ARG_CHECKS "JSON_SCHEMA" _index) 0127 if (${_index} GREATER -1) 0128 set(_write_hook TRUE) 0129 foreach(path ${CMAKE_PREFIX_PATH};${CMAKE_INCLUDE_PATH}) 0130 file(GLOB files "${path}/${KDE_INSTALL_DATADIR}/kf6/jsonschema/*.json") 0131 set(SCHEMA_FILES ${SCHEMA_FILES};${files}) 0132 endforeach() 0133 foreach (SCHEMA ${SCHEMA_FILES}) 0134 if (SCHEMA_INCLUDES) 0135 set(SCHEMA_INCLUDES "${SCHEMA_INCLUDES},") 0136 endif() 0137 set(SCHEMA_INCLUDES "${SCHEMA_INCLUDES}{\"$ref\": \"${SCHEMA}\"}") 0138 endforeach() 0139 configure_file(${JSON_SCHEMA_IN} ${JSON_SCHEMA_OUT} @ONLY) 0140 if (KDE_CHECK_JSONSCHEMA_EXECUTABLE) 0141 set(PRE_COMMIT_SCRIPTS "set -e\npython3 ${JSON_SCHEMA_SCRIPT} \"${JSON_SCHEMA_OUT}\"\n${PRE_COMMIT_SCRIPTS}") 0142 else() 0143 message(WARNING "check-jsonschema executable not found. Please install it using pip or using your package manager") 0144 endif() 0145 endif() 0146 0147 0148 set(_hook_file "${GIT_HOOKS_DIR}/pre-commit") 0149 # Appending to the file is quite ugly and causes edge cases. With the CUSTOM_SCRIPTS arg, this should not be needed though 0150 if (ECM_GLOBAL_FIND_VERSION VERSION_GREATER_EQUAL 5.109.0) 0151 set(PRE_COMMIT_SCRIPTS "# This file is autogenerated by kde_configure_git_pre_commit_hook, any changes will be lost! \n${PRE_COMMIT_SCRIPTS}") 0152 configure_file(${PRE_COMMIT_HOOK_UNIX} "${_hook_file}") 0153 else() 0154 if(NOT _write_hook) 0155 message(WARNING "No clang-format executable was found, skipping the formatting pre-commit hook") 0156 return() 0157 endif() 0158 # Doesn't exist? write away 0159 if(NOT EXISTS ${_hook_file}) 0160 configure_file(${PRE_COMMIT_HOOK_UNIX} "${_hook_file}") 0161 return() 0162 endif() 0163 0164 file(READ ${_hook_file} _contents) 0165 0166 # For when CLANG_FORMAT_SCRIPT didn't have the 'git rev-parse --git-common-dir' part 0167 set(_old_cmd "./.git/hooks/scripts/clang-format.sh") 0168 string(FIND "${_contents}" "${_old_cmd}" _idx) 0169 if (${_idx} GREATER -1) 0170 string(REPLACE "${_old_cmd}" "${CLANG_FORMAT_SCRIPT}" _contents "${_contents}") 0171 file(WRITE ${_hook_file} "${_contents}") 0172 return() 0173 endif() 0174 0175 string(FIND "${_contents}" "${CLANG_FORMAT_SCRIPT}" _idx) 0176 # File exists and doesn't have the clang-format.sh line, append it 0177 # so as to not overwrite users' customisations 0178 if (_idx EQUAL -1) 0179 file(APPEND ${_hook_file} "${CLANG_FORMAT_SCRIPT}") 0180 endif() 0181 endif() 0182 endfunction()