Disable "hard" examples in CI
[qpms.git] / cmake / GetGitRevisionDescription.cmake
blob4fbd90db79429af8053d53d0d7582c8d622d79b3
1 # - Returns a version string from Git
3 # These functions force a re-configure on each git commit so that you can
4 # trust the values of the variables in your build system.
6 #  get_git_head_revision(<refspecvar> <hashvar> [ALLOW_LOOKING_ABOVE_CMAKE_SOURCE_DIR])
8 # Returns the refspec and sha hash of the current head revision
10 #  git_describe(<var> [<additional arguments to git describe> ...])
12 # Returns the results of git describe on the source tree, and adjusting
13 # the output so that it tests false if an error occurs.
15 #  git_describe_working_tree(<var> [<additional arguments to git describe> ...])
17 # Returns the results of git describe on the working tree (--dirty option),
18 # and adjusting the output so that it tests false if an error occurs.
20 #  git_get_exact_tag(<var> [<additional arguments to git describe> ...])
22 # Returns the results of git describe --exact-match on the source tree,
23 # and adjusting the output so that it tests false if there was no exact
24 # matching tag.
26 #  git_local_changes(<var>)
28 # Returns either "CLEAN" or "DIRTY" with respect to uncommitted changes.
29 # Uses the return code of "git diff-index --quiet HEAD --".
30 # Does not regard untracked files.
32 # Requires CMake 2.6 or newer (uses the 'function' command)
34 # Original Author:
35 # 2009-2020 Ryan Pavlik <ryan.pavlik@gmail.com> <abiryan@ryand.net>
36 # http://academic.cleardefinition.com
38 # Copyright 2009-2013, Iowa State University.
39 # Copyright 2013-2020, Ryan Pavlik
40 # Copyright 2013-2020, Contributors
41 # SPDX-License-Identifier: BSL-1.0
42 # Distributed under the Boost Software License, Version 1.0.
43 # (See accompanying file LICENSE_1_0.txt or copy at
44 # http://www.boost.org/LICENSE_1_0.txt)
46 if(__get_git_revision_description)
47     return()
48 endif()
49 set(__get_git_revision_description YES)
51 # We must run the following at "include" time, not at function call time,
52 # to find the path to this module rather than the path to a calling list file
53 get_filename_component(_gitdescmoddir ${CMAKE_CURRENT_LIST_FILE} PATH)
55 # Function _git_find_closest_git_dir finds the next closest .git directory
56 # that is part of any directory in the path defined by _start_dir.
57 # The result is returned in the parent scope variable whose name is passed
58 # as variable _git_dir_var. If no .git directory can be found, the
59 # function returns an empty string via _git_dir_var.
61 # Example: Given a path C:/bla/foo/bar and assuming C:/bla/.git exists and
62 # neither foo nor bar contain a file/directory .git. This wil return
63 # C:/bla/.git
65 function(_git_find_closest_git_dir _start_dir _git_dir_var)
66     set(cur_dir "${_start_dir}")
67     set(git_dir "${_start_dir}/.git")
68     while(NOT EXISTS "${git_dir}")
69         # .git dir not found, search parent directories
70         set(git_previous_parent "${cur_dir}")
71         get_filename_component(cur_dir "${cur_dir}" DIRECTORY)
72         if(cur_dir STREQUAL git_previous_parent)
73             # We have reached the root directory, we are not in git
74             set(${_git_dir_var}
75                 ""
76                 PARENT_SCOPE)
77             return()
78         endif()
79         set(git_dir "${cur_dir}/.git")
80     endwhile()
81     set(${_git_dir_var}
82         "${git_dir}"
83         PARENT_SCOPE)
84 endfunction()
86 function(get_git_head_revision _refspecvar _hashvar)
87     _git_find_closest_git_dir("${CMAKE_CURRENT_SOURCE_DIR}" GIT_DIR)
89     if("${ARGN}" STREQUAL "ALLOW_LOOKING_ABOVE_CMAKE_SOURCE_DIR")
90         set(ALLOW_LOOKING_ABOVE_CMAKE_SOURCE_DIR TRUE)
91     else()
92         set(ALLOW_LOOKING_ABOVE_CMAKE_SOURCE_DIR FALSE)
93     endif()
94     if(NOT "${GIT_DIR}" STREQUAL "")
95         file(RELATIVE_PATH _relative_to_source_dir "${CMAKE_SOURCE_DIR}"
96              "${GIT_DIR}")
97         if("${_relative_to_source_dir}" MATCHES "[.][.]" AND NOT ALLOW_LOOKING_ABOVE_CMAKE_SOURCE_DIR)
98             # We've gone above the CMake root dir.
99             set(GIT_DIR "")
100         endif()
101     endif()
102     if("${GIT_DIR}" STREQUAL "")
103         set(${_refspecvar}
104             "GITDIR-NOTFOUND"
105             PARENT_SCOPE)
106         set(${_hashvar}
107             "GITDIR-NOTFOUND"
108             PARENT_SCOPE)
109         return()
110     endif()
112     # Check if the current source dir is a git submodule or a worktree.
113     # In both cases .git is a file instead of a directory.
114     #
115     if(NOT IS_DIRECTORY ${GIT_DIR})
116         # The following git command will return a non empty string that
117         # points to the super project working tree if the current
118         # source dir is inside a git submodule.
119         # Otherwise the command will return an empty string.
120         #
121         execute_process(
122             COMMAND "${GIT_EXECUTABLE}" rev-parse
123                     --show-superproject-working-tree
124             WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
125             OUTPUT_VARIABLE out
126             ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
127         if(NOT "${out}" STREQUAL "")
128             # If out is empty, GIT_DIR/CMAKE_CURRENT_SOURCE_DIR is in a submodule
129             file(READ ${GIT_DIR} submodule)
130             string(REGEX REPLACE "gitdir: (.*)$" "\\1" GIT_DIR_RELATIVE
131                                  ${submodule})
132             string(STRIP ${GIT_DIR_RELATIVE} GIT_DIR_RELATIVE)
133             get_filename_component(SUBMODULE_DIR ${GIT_DIR} PATH)
134             get_filename_component(GIT_DIR ${SUBMODULE_DIR}/${GIT_DIR_RELATIVE}
135                                    ABSOLUTE)
136             set(HEAD_SOURCE_FILE "${GIT_DIR}/HEAD")
137         else()
138             # GIT_DIR/CMAKE_CURRENT_SOURCE_DIR is in a worktree
139             file(READ ${GIT_DIR} worktree_ref)
140             # The .git directory contains a path to the worktree information directory
141             # inside the parent git repo of the worktree.
142             #
143             string(REGEX REPLACE "gitdir: (.*)$" "\\1" git_worktree_dir
144                                  ${worktree_ref})
145             string(STRIP ${git_worktree_dir} git_worktree_dir)
146             _git_find_closest_git_dir("${git_worktree_dir}" GIT_DIR)
147             set(HEAD_SOURCE_FILE "${git_worktree_dir}/HEAD")
148         endif()
149     else()
150         set(HEAD_SOURCE_FILE "${GIT_DIR}/HEAD")
151     endif()
152     set(GIT_DATA "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/git-data")
153     if(NOT EXISTS "${GIT_DATA}")
154         file(MAKE_DIRECTORY "${GIT_DATA}")
155     endif()
157     if(NOT EXISTS "${HEAD_SOURCE_FILE}")
158         return()
159     endif()
160     set(HEAD_FILE "${GIT_DATA}/HEAD")
161     configure_file("${HEAD_SOURCE_FILE}" "${HEAD_FILE}" COPYONLY)
163     configure_file("${_gitdescmoddir}/GetGitRevisionDescription.cmake.in"
164                    "${GIT_DATA}/grabRef.cmake" @ONLY)
165     include("${GIT_DATA}/grabRef.cmake")
167     set(${_refspecvar}
168         "${HEAD_REF}"
169         PARENT_SCOPE)
170     set(${_hashvar}
171         "${HEAD_HASH}"
172         PARENT_SCOPE)
173 endfunction()
175 function(git_describe _var)
176     if(NOT GIT_FOUND)
177         find_package(Git QUIET)
178     endif()
179     get_git_head_revision(refspec hash)
180     if(NOT GIT_FOUND)
181         set(${_var}
182             "GIT-NOTFOUND"
183             PARENT_SCOPE)
184         return()
185     endif()
186     if(NOT hash)
187         set(${_var}
188             "HEAD-HASH-NOTFOUND"
189             PARENT_SCOPE)
190         return()
191     endif()
193     # TODO sanitize
194     #if((${ARGN}" MATCHES "&&") OR
195     #   (ARGN MATCHES "||") OR
196     #   (ARGN MATCHES "\\;"))
197     #   message("Please report the following error to the project!")
198     #   message(FATAL_ERROR "Looks like someone's doing something nefarious with git_describe! Passed arguments ${ARGN}")
199     #endif()
201     #message(STATUS "Arguments to execute_process: ${ARGN}")
203     execute_process(
204         COMMAND "${GIT_EXECUTABLE}" describe --tags --always ${hash} ${ARGN}
205         WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
206         RESULT_VARIABLE res
207         OUTPUT_VARIABLE out
208         ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
209     if(NOT res EQUAL 0)
210         set(out "${out}-${res}-NOTFOUND")
211     endif()
213     set(${_var}
214         "${out}"
215         PARENT_SCOPE)
216 endfunction()
218 function(git_describe_working_tree _var)
219     if(NOT GIT_FOUND)
220         find_package(Git QUIET)
221     endif()
222     if(NOT GIT_FOUND)
223         set(${_var}
224             "GIT-NOTFOUND"
225             PARENT_SCOPE)
226         return()
227     endif()
229     execute_process(
230         COMMAND "${GIT_EXECUTABLE}" describe --dirty ${ARGN}
231         WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
232         RESULT_VARIABLE res
233         OUTPUT_VARIABLE out
234         ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
235     if(NOT res EQUAL 0)
236         set(out "${out}-${res}-NOTFOUND")
237     endif()
239     set(${_var}
240         "${out}"
241         PARENT_SCOPE)
242 endfunction()
244 function(git_get_exact_tag _var)
245     git_describe(out --exact-match ${ARGN})
246     set(${_var}
247         "${out}"
248         PARENT_SCOPE)
249 endfunction()
251 function(git_local_changes _var)
252     if(NOT GIT_FOUND)
253         find_package(Git QUIET)
254     endif()
255     get_git_head_revision(refspec hash)
256     if(NOT GIT_FOUND)
257         set(${_var}
258             "GIT-NOTFOUND"
259             PARENT_SCOPE)
260         return()
261     endif()
262     if(NOT hash)
263         set(${_var}
264             "HEAD-HASH-NOTFOUND"
265             PARENT_SCOPE)
266         return()
267     endif()
269     execute_process(
270         COMMAND "${GIT_EXECUTABLE}" diff-index --quiet HEAD --
271         WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
272         RESULT_VARIABLE res
273         OUTPUT_VARIABLE out
274         ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
275     if(res EQUAL 0)
276         set(${_var}
277             "CLEAN"
278             PARENT_SCOPE)
279     else()
280         set(${_var}
281             "DIRTY"
282             PARENT_SCOPE)
283     endif()
284 endfunction()