Warning, /frameworks/extra-cmake-modules/kde-modules/KDEGitCommitHooks.cmake is written in an unsupported language. File is not indexed.

0001 # SPDX-FileCopyrightText: 2020 Alexander Lohnau <alexander.lohnau@gmx.de>
0002 # SPDX-FileCopyrightText: 2022 Ahmad Samir <a.samirh78@gmail.com>
0003 #
0004 # SPDX-License-Identifier: BSD-3-Clause
0005 
0006 #[=======================================================================[.rst:
0007 KDEGitCommitHooks
0008 --------------------
0009 
0010 This module provides a functionality to enforce formatting
0011 or in the future other QS checks.
0012 
0013 This module provides the following function:
0014 
0015 ::
0016 
0017   kde_configure_pre_commit_hook(
0018      CHECKS <check1> [<check2> [...]
0019      [CUSTOM_SCRIPTS [<script paths> [<script paths> ...]]] # since 5.109
0020   )
0021 
0022 This function will create a pre-commit hook which contains all the given checks.
0023 In addition to that, you can pass in paths to custom scripts that will be run as the pre-commit hook.
0024 
0025 Checks:
0026 
0027 - ``CLANG_FORMAT`` With this check enabled the ``git clang-format`` tool will be used to make sure that
0028   the changed parts are properly formatted. In case the changes are not properly formatted an error
0029   message with the command to preview the formatting changes and to format the files in place
0030   will be displayed. This tool will reuse the exsting ``.clang-format`` file, in case you
0031   want to use the one provided by ECM you can include ``include(KDEClangFormat)`` which will copy
0032   the file to the source dir. It is also recommended to reformat the entire project before enforcing
0033   the formatting using this commit hook.
0034 
0035 Example usage:
0036 
0037 .. code-block:: cmake
0038 
0039   include(KDEGitCommitHooks)
0040   kde_configure_git_pre_commit_hook(CHECKS CLANG_FORMAT)
0041 
0042 Since 5.79
0043 #]=======================================================================]
0044 
0045 # try to find clang-format in path
0046 find_program(KDE_CLANG_FORMAT_EXECUTABLE clang-format)
0047 set(PRE_COMMIT_HOOK_UNIX "${CMAKE_CURRENT_LIST_DIR}/kde-git-commit-hooks/pre-commit.in")
0048 set(CLANG_FORMAT_UNIX "${CMAKE_CURRENT_LIST_DIR}/kde-git-commit-hooks/clang-format.sh")
0049 
0050 function(KDE_CONFIGURE_GIT_PRE_COMMIT_HOOK)
0051     set(_oneValueArgs "")
0052     set(_multiValueArgs CHECKS CUSTOM_SCRIPTS)
0053     cmake_parse_arguments(ARG "" "${_oneValueArgs}" "${_multiValueArgs}" ${ARGN} )
0054 
0055     if(NOT CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME)
0056         message(STATUS "Project is not top level project - pre-commit hook not installed")
0057         return()
0058     endif()
0059 
0060     if(NOT ARG_CHECKS)
0061         message(FATAL_ERROR "No checks were specified")
0062     endif()
0063     set(GIT_DIR "${CMAKE_SOURCE_DIR}/.git")
0064 
0065     if (NOT IS_DIRECTORY ${GIT_DIR} # In case of tarballs there is no .git directory
0066         OR NOT (UNIX OR WIN32)
0067     )
0068         return()
0069     endif()
0070     if (COMMAND KDE_CLANG_FORMAT)
0071         set(HAS_CLANG_FORMAT_COMMAND_INCLUDED TRUE)
0072     else()
0073         set(HAS_CLANG_FORMAT_COMMAND_INCLUDED FALSE)
0074     endif()
0075 
0076     string(REPLACE ";" "\n" PRE_COMMIT_SCRIPTS "${ARG_CUSTOM_SCRIPTS}")
0077 
0078     set(_write_hook FALSE)
0079     if(KDE_CLANG_FORMAT_EXECUTABLE)
0080         list(FIND ARG_CHECKS "CLANG_FORMAT" _index)
0081         if (${_index} GREATER -1)
0082             set(CLANG_FORMAT_SCRIPT "\"$(git rev-parse --git-common-dir)\"/hooks/scripts/clang-format.sh")
0083             configure_file(${CLANG_FORMAT_UNIX} "${GIT_DIR}/hooks/scripts/clang-format.sh" @ONLY)
0084             set(PRE_COMMIT_SCRIPTS "\"$(git rev-parse --git-common-dir)\"/hooks/scripts/clang-format.sh\n${PRE_COMMIT_SCRIPTS}")
0085             set(_write_hook TRUE)
0086         endif()
0087     endif()
0088 
0089 
0090     set(_hook_file "${GIT_DIR}/hooks/pre-commit")
0091     # Appending to the file is quite ugly and causes edge cases. With the CUSTOM_SCRIPTS arg, this should not be needed though
0092     if (ECM_GLOBAL_FIND_VERSION VERSION_GREATER_EQUAL 5.109.0)
0093       set(PRE_COMMIT_SCRIPTS "# This file is autogenerated by kde_configure_pre_commit_hook, any changes will be lost! \n${PRE_COMMIT_SCRIPTS}")
0094       configure_file(${PRE_COMMIT_HOOK_UNIX} "${_hook_file}")
0095     else()
0096       if(NOT _write_hook)
0097           return()
0098           message(WARNING "No clang-format executable was found, skipping the formatting pre-commit hook")
0099       endif()
0100       # Doesn't exist? write away
0101       if(NOT EXISTS ${_hook_file})
0102           configure_file(${PRE_COMMIT_HOOK_UNIX} "${_hook_file}")
0103           return()
0104       endif()
0105 
0106       file(READ ${_hook_file} _contents)
0107 
0108       # For when CLANG_FORMAT_SCRIPT didn't have the 'git rev-parse --git-common-dir' part
0109       set(_old_cmd "./.git/hooks/scripts/clang-format.sh")
0110       string(FIND "${_contents}" "${_old_cmd}" _idx)
0111       if (${_idx} GREATER -1)
0112           string(REPLACE "${_old_cmd}" "${CLANG_FORMAT_SCRIPT}" _contents "${_contents}")
0113           file(WRITE ${_hook_file} "${_contents}")
0114           return()
0115       endif()
0116 
0117       string(FIND "${_contents}" "${CLANG_FORMAT_SCRIPT}" _idx)
0118       # File exists and doesn't have the clang-format.sh line, append it
0119       # so as to not overwrite users' customisations
0120       if (_idx EQUAL -1)
0121           file(APPEND ${_hook_file} "${CLANG_FORMAT_SCRIPT}")
0122       endif()
0123     endif()
0124 endfunction()