RevisionTools.cmake
Go to the documentation of this file.
1 # ============================================================================
2 # Copyright (c) 2011-2012 University of Pennsylvania
3 # Copyright (c) 2013-2016 Andreas Schuh
4 # All rights reserved.
5 #
6 # See COPYING file for license information or visit
7 # https://cmake-basis.github.io/download.html#license
8 # ============================================================================
9 
10 ##############################################################################
11 # @file RevisionTools.cmake
12 # @brief CMake functions and macros related to revision control systems.
13 #
14 # @ingroup CMakeTools
15 ##############################################################################
16 
18  return ()
19 else ()
21 endif ()
22 
23 
24 # ============================================================================
25 # required commands
26 # ============================================================================
27 
28 find_package (Subversion QUIET)
29 find_package (Git QUIET)
30 
31 
32 ## @addtogroup CMakeUtilities
33 # @{
34 
35 
36 # ============================================================================
37 # Subversion
38 # ============================================================================
39 
40 # ----------------------------------------------------------------------------
41 ## @brief Get current revision of file or directory.
42 #
43 # @param [in] URL Absolute path to directory or file. May also be a URL to the
44 # directory or file in the repository. A leading "file://" is
45 # automatically removed such that the svn command treats it as a
46 # local path.
47 # @param [out] REV The revision number of URL. If URL is not under revision
48 # control or Subversion_SVN_EXECUTABLE is invalid, "0" is returned.
49 #
50 # @returns Sets @p REV to the revision of the working copy/repository
51 # at URL @p URL.
52 function (basis_svn_get_revision URL REV)
53  set (OUT 0)
54  if (Subversion_SVN_EXECUTABLE)
55  # remove "file://" from URL
56  string (REGEX REPLACE "file://" "" TMP "${URL}")
57  # retrieve SVN info
58  execute_process (
59  COMMAND "${Subversion_SVN_EXECUTABLE}" info "${TMP}"
60  OUTPUT_VARIABLE OUT
61  ERROR_QUIET
62  OUTPUT_STRIP_TRAILING_WHITESPACE
63  )
64  if (BASIS_DEBUG)
65  message ("** basis_svn_get_revision()")
66  message ("** svn info: ${OUT}")
67  endif ()
68  # extract revision
69  if (OUT MATCHES "^(.*\n)?Revision: ([^\n]+).*" AND NOT CMAKE_MATCH_2 STREQUAL "")
70  set (OUT "${CMAKE_MATCH_2}")
71  else ()
72  set (OUT 0)
73  endif ()
74  endif ()
75  # return
76  set ("${REV}" "${OUT}" PARENT_SCOPE)
77 endfunction ()
78 
79 # ----------------------------------------------------------------------------
80 ## @brief Get revision number when directory or file was last changed.
81 #
82 # @param [in] URL Absolute path to directory or file. May also be a URL to the
83 # directory or file in the repository. A leading "file://" is
84 # automatically removed such that the svn command treats it as a
85 # local path.
86 # @param [out] REV Revision number when URL was last modified. If URL is not
87 # under Subversion control or Subversion_SVN_EXECUTABLE is invalid,
88 # "0" is returned.
89 #
90 # @returns Sets @p REV to revision number at which the working copy/repository
91 # specified by the URL @p URL was last modified.
92 function (basis_svn_get_last_changed_revision URL REV)
93  set (OUT 0)
94  if (Subversion_SVN_EXECUTABLE)
95  # remove "file://" from URL
96  string (REGEX REPLACE "file://" "" TMP "${URL}")
97  # retrieve SVN info
98  execute_process (
99  COMMAND "${Subversion_SVN_EXECUTABLE}" info "${TMP}"
100  OUTPUT_VARIABLE OUT
101  ERROR_QUIET
102  OUTPUT_STRIP_TRAILING_WHITESPACE
103  )
104  if (BASIS_DEBUG)
105  message ("** basis_svn_get_revision()")
106  message ("** svn info: ${OUT}")
107  endif ()
108  # extract last changed revision
109  if (OUT MATCHES "^(.*\n)?Last Changed Rev: ([^\n]+).*" AND NOT CMAKE_MATCH_2 STREQUAL "")
110  set (OUT "${CMAKE_MATCH_2}")
111  else ()
112  set (OUT 0)
113  endif ()
114  endif ()
115  # return
116  set ("${REV}" "${OUT}" PARENT_SCOPE)
117 endfunction ()
118 
119 # ----------------------------------------------------------------------------
120 ## @brief Get status of revision controlled file.
121 #
122 # @param [in] URL Absolute path to directory or file. May also be a URL to
123 # the directory or file in the repository.
124 # A leading "file://" will be removed such that the svn
125 # command treats it as a local path.
126 # @param [out] STATUS The status of URL as returned by 'svn status'.
127 # If the local directory or file is unmodified, an
128 # empty string is returned. An empty string is also
129 # returned when Subversion_SVN_EXECUTABLE is invalid.
130 #
131 # @returns Sets @p STATUS to the output of the <tt>svn info</tt> command.
132 function (basis_svn_status URL STATUS)
133  if (Subversion_SVN_EXECUTABLE)
134  # remove "file://" from URL
135  string (REGEX REPLACE "file://" "" TMP "${URL}")
136 
137  # retrieve SVN status of URL
138  execute_process (
139  COMMAND "${Subversion_SVN_EXECUTABLE}" status "${TMP}"
140  OUTPUT_VARIABLE OUT
141  ERROR_QUIET
142  )
143 
144  # return
145  set ("${STATUS}" "${OUT}" PARENT_SCOPE)
146  else ()
147  set ("${STATUS}" "" PARENT_SCOPE)
148  endif ()
149 endfunction ()
150 
151 # ============================================================================
152 # Git
153 # ============================================================================
154 
155 # ----------------------------------------------------------------------------
156 # @brief Determine whether or not a given directory is a Git repository
157 function (basis_is_git_repository FLAG DIR)
158  if (GITCOMMAND AND NOT GIT_EXECUTABLE)
159  set (GIT_EXECUTABLE GITCOMMAND)
160  endif ()
161  if (GIT_EXECUTABLE)
162  execute_process (
163  COMMAND "${GIT_EXECUTABLE}" rev-parse
164  WORKING_DIRECTORY "${DIR}"
165  RESULT_VARIABLE RETVAL
166  OUTPUT_QUIET
167  ERROR_QUIET
168  )
169  else ()
170  set (RETVAL 1)
171  endif ()
172  if (RETVAL EQUAL 0)
173  set (${FLAG} "TRUE" PARENT_SCOPE)
174  else ()
175  set (${FLAG} "FALSE" PARENT_SCOPE)
176  endif ()
177 endfunction ()
178 
179 # ----------------------------------------------------------------------------
180 ## @brief Get HEAD commit SHA of file or directory.
181 #
182 # @param [in] URL Absolute path to repository directory or single file.
183 # @param [out] REV The short commit SHA when URL was last modified. If URL
184 # is not under Git control or GIT_EXECUTABLE is invalid,
185 # "0" is returned.
186 # @param [in] ARGN Length of commit SHA to return.
187 #
188 # @returns Sets @p REV either to the HEAD commit SHA of the repository at
189 # directory @p URL or the last commit which modified the file.
190 function (basis_git_get_revision URL REV)
191  if (ARGC GREATER 3)
192  message (FATAL_ERROR "basis_git_get_revision: Too many arguments")
193  endif ()
194  set (OUT 0)
195  if (GITCOMMAND AND NOT GIT_EXECUTABLE)
196  set (GIT_EXECUTABLE GITCOMMAND)
197  endif ()
198  if (GIT_EXECUTABLE)
199  # remove "file://" from URL
200  string (REGEX REPLACE "file://" "" DIR "${URL}")
201  # retrieve Git commit SHA of HEAD
202  if (IS_DIRECTORY "${DIR}")
203  execute_process (
204  COMMAND "${GIT_EXECUTABLE}" rev-parse HEAD
205  WORKING_DIRECTORY "${DIR}"
206  OUTPUT_VARIABLE OUT
207  ERROR_QUIET
208  OUTPUT_STRIP_TRAILING_WHITESPACE
209  )
210  if (BASIS_DEBUG)
211  message ("** basis_git_get_revision()")
212  message ("** DIR: ${DIR}")
213  message ("** OUT: ${OUT}")
214  endif ()
215  # retrieve Git commit SHA when file was last modified
216  else ()
217  basis_get_filename_component(OBJ "${DIR}" NAME)
218  basis_get_filename_component(DIR "${DIR}" PATH)
219  execute_process (
220  COMMAND "${GIT_EXECUTABLE}" log -n 1 -- "${OBJ}"
221  WORKING_DIRECTORY "${DIR}"
222  OUTPUT_VARIABLE OUT
223  ERROR_QUIET
224  OUTPUT_STRIP_TRAILING_WHITESPACE
225  )
226  if (BASIS_DEBUG)
227  message ("** basis_git_get_revision()")
228  message ("** DIR: ${DIR}")
229  message ("** OBJ: ${OBJ}")
230  message ("** OUT: ${OUT}")
231  endif ()
232  # extract commit SHA
233  if (OUT MATCHES "commit ([0-9a-f]+).*" AND NOT CMAKE_MATCH_1 STREQUAL "")
234  set (OUT "${CMAKE_MATCH_1}")
235  else ()
236  set (OUT 0)
237  endif ()
238  endif ()
239  endif ()
240  if (ARGC EQUAL 3)
241  string (SUBSTRING "${OUT}" 0 "${ARGV2}" OUT)
242  endif ()
243  # return
244  set ("${REV}" "${OUT}" PARENT_SCOPE)
245 endfunction ()
246 
247 
248 # ============================================================================
249 # Meta
250 # ============================================================================
251 
252 # ----------------------------------------------------------------------------
253 ## @brief Get revision of file or directory.
254 #
255 # @param [in] URL Absolute path to directory or single file.
256 # @param [out] REV Revision number when directory / repository or file was
257 # last modified, "0" is returned when no known revision
258 # control system is used or revision command not found.
259 #
260 # @returns Revision when directory of file was last modified.
261 function (basis_get_revision URL REV)
262  # remove "file://" from URL
263  string (REGEX REPLACE "file://" "" DIR "${URL}")
264  # get directory path
265  if (NOT IS_DIRECTORY "${URL}")
266  basis_get_filename_component (DIR "${URL}" PATH)
267  else ()
268  set (DIR "${URL}")
269  endif ()
270  # check if directory is part of a Git repository
271  basis_is_git_repository (IS_GIT_REPOSITORY "${DIR}")
272  if (IS_GIT_REPOSITORY)
273  basis_git_get_revision ("${URL}" OUT 7)
274  else ()
276  endif ()
277  # return revision
278  set ("${REV}" "${OUT}" PARENT_SCOPE)
279 endfunction ()
280 
281 
282 ## @}
283 # end of Doxygen group
function basis_svn_get_last_changed_revision(in URL, out REV)
Get revision number when directory or file was last changed.
function basis_get_revision(in URL, out REV)
Get revision of file or directory.
function basis_is_git_repository(in FLAG, in DIR)
cmake NAME
macro basis_get_filename_component()
Alias for the overwritten get_filename_component() function.
cmake RETVAL
cmake __BASIS_REVISIONTOOLS_INCLUDED
function basis_svn_get_revision(in URL, out REV)
Get current revision of file or directory.
cmake COMMAND
cmake DIR
option BASIS_DEBUG
Request debugging messages from BASIS functions.
function basis_svn_status(in URL, out STATUS)
Get status of revision controlled file.
function basis_git_get_revision(in URL, out REV, in ARGN)
Get HEAD commit SHA of file or directory.
macro find_package()
Overloaded find_package() command.
cmake TMP