11# git_watcher.cmake
2- # https://github. com/andrew-hardin/cmake-git-version-tracking/blob/20c58d5d08bad70550d969b478943c962faa6264 /git_watcher.cmake
2+ # https://raw.githubusercontent. com/andrew-hardin/cmake-git-version-tracking/master /git_watcher.cmake
33#
44# Released under the MIT License.
55# https://raw.githubusercontent.com/andrew-hardin/cmake-git-version-tracking/master/LICENSE
2727# -- The path to the git executable. It'll automatically be set if the
2828# user doesn't supply a path.
2929#
30+ # GIT_FAIL_IF_NONZERO_EXIT (OPTIONAL)
31+ # -- Raise a FATAL_ERROR if any of the git commands return a non-zero
32+ # exit code. This is set to TRUE by default. You can set this to FALSE
33+ # if you'd like the build to continue even if a git command fails.
34+ #
35+ # GIT_IGNORE_UNTRACKED (OPTIONAL)
36+ # -- Ignore the presence of untracked files when detecting if the
37+ # working tree is dirty. This is set to FALSE by default.
38+ #
3039# DESIGN
3140# - This script was designed similar to a Python application
3241# with a Main() function. I wanted to keep it compact to
@@ -57,17 +66,25 @@ macro(CHECK_REQUIRED_VARIABLE var_name)
5766endmacro ()
5867
5968# Check that an optional variable is set, or, set it to a default value.
60- macro (CHECK_OPTIONAL_VARIABLE var_name default_value)
69+ macro (CHECK_OPTIONAL_VARIABLE_NOPATH var_name default_value)
6170 if (NOT DEFINED ${var_name} )
6271 set (${var_name} ${default_value} )
6372 endif ()
73+ endmacro ()
74+
75+ # Check that an optional variable is set, or, set it to a default value.
76+ # Also converts that path to an abspath.
77+ macro (CHECK_OPTIONAL_VARIABLE var_name default_value)
78+ CHECK_OPTIONAL_VARIABLE_NOPATH(${var_name} ${default_value} )
6479 PATH_TO_ABSOLUTE(${var_name} )
6580endmacro ()
6681
6782CHECK_REQUIRED_VARIABLE(PRE_CONFIGURE_FILE)
6883CHECK_REQUIRED_VARIABLE(POST_CONFIGURE_FILE)
69- CHECK_OPTIONAL_VARIABLE(GIT_STATE_FILE "${CMAKE_BINARY_DIR } /git-state-hash" )
84+ CHECK_OPTIONAL_VARIABLE(GIT_STATE_FILE "${CMAKE_CURRENT_BINARY_DIR } /git-state-hash" )
7085CHECK_OPTIONAL_VARIABLE(GIT_WORKING_DIR "${CMAKE_SOURCE_DIR} " )
86+ CHECK_OPTIONAL_VARIABLE_NOPATH(GIT_FAIL_IF_NONZERO_EXIT TRUE )
87+ CHECK_OPTIONAL_VARIABLE_NOPATH(GIT_IGNORE_UNTRACKED FALSE )
7188
7289# Check the optional git variable.
7390# If it's not set, we'll try to find it using the CMake packaging system.
@@ -86,7 +103,8 @@ set(_state_variable_names
86103 GIT_COMMIT_DATE_ISO8601
87104 GIT_COMMIT_SUBJECT
88105 GIT_COMMIT_BODY
89- VERSION_STRING
106+ GIT_DESCRIBE
107+ GIT_BRANCH
90108 # >>>
91109 # 1. Add the name of the additional git variable you're interested in monitoring
92110 # to this list.
@@ -96,17 +114,30 @@ set(_state_variable_names
96114
97115# Macro: RunGitCommand
98116# Description: short-hand macro for calling a git function. Outputs are the
99- # "exit_code" and "output" variables.
117+ # "exit_code" and "output" variables. The "_permit_git_failure"
118+ # variable can locally override the exit code checking- use it
119+ # with caution.
100120macro (RunGitCommand)
101121 execute_process (COMMAND
102122 "${GIT_EXECUTABLE} " ${ARGV}
103123 WORKING_DIRECTORY "${_working_dir} "
104124 RESULT_VARIABLE exit_code
105125 OUTPUT_VARIABLE output
106- ERROR_QUIET
126+ ERROR_VARIABLE stderr
107127 OUTPUT_STRIP_TRAILING_WHITESPACE)
108- if (NOT exit_code EQUAL 0)
128+ if (NOT exit_code EQUAL 0 AND NOT _permit_git_failure )
109129 set (ENV{GIT_RETRIEVED_STATE} "false" )
130+
131+ # Issue 26: git info not properly set
132+ #
133+ # Check if we should fail if any of the exit codes are non-zero.
134+ # Most methods have a fall-back default value that's used in case of non-zero
135+ # exit codes. If you're feeling risky, disable this safety check and use
136+ # those default values.
137+ if (GIT_FAIL_IF_NONZERO_EXIT )
138+ string (REPLACE ";" " " args_with_spaces "${ARGV} " )
139+ message (FATAL_ERROR "${stderr} (${GIT_EXECUTABLE} ${args_with_spaces} )" )
140+ endif ()
110141 endif ()
111142endmacro ()
112143
@@ -123,7 +154,12 @@ function(GetGitState _working_dir)
123154 set (ENV{GIT_RETRIEVED_STATE} "true" )
124155
125156 # Get whether or not the working tree is dirty.
126- RunGitCommand(status --porcelain)
157+ if (GIT_IGNORE_UNTRACKED)
158+ set (untracked_flag "-uno" )
159+ else ()
160+ set (untracked_flag "-unormal" )
161+ endif ()
162+ RunGitCommand(status --porcelain ${untracked_flag} )
127163 if (NOT exit_code EQUAL 0)
128164 set (ENV{GIT_IS_DIRTY} "false" )
129165 else ()
@@ -158,6 +194,8 @@ function(GetGitState _working_dir)
158194
159195 RunGitCommand(show -s "--format=%s" ${object} )
160196 if (exit_code EQUAL 0)
197+ # Escape \
198+ string (REPLACE "\\ " "\\\\ " output "${output} " )
161199 # Escape quotes
162200 string (REPLACE "\" " "\\\" " output "${output} " )
163201 set (ENV{GIT_COMMIT_SUBJECT} "${output} " )
@@ -166,6 +204,8 @@ function(GetGitState _working_dir)
166204 RunGitCommand(show -s "--format=%b" ${object} )
167205 if (exit_code EQUAL 0)
168206 if (output )
207+ # Escape \
208+ string (REPLACE "\\ " "\\\\ " output "${output} " )
169209 # Escape quotes
170210 string (REPLACE "\" " "\\\" " output "${output} " )
171211 # Escape line breaks in the commit message.
@@ -178,9 +218,9 @@ function(GetGitState _working_dir)
178218 # There was no commit body - set the safe string to empty.
179219 set (safe "" )
180220 endif ()
181- set (ENV{GIT_COMMIT_BODY} "\" ${safe} \" " )
221+ set (ENV{GIT_COMMIT_BODY} "${safe} " )
182222 else ()
183- set (ENV{GIT_COMMIT_BODY} "\"\" " ) # empty string.
223+ set (ENV{GIT_COMMIT_BODY} "" ) # empty string.
184224 endif ()
185225
186226 # Get output of git describe
@@ -191,20 +231,23 @@ function(GetGitState _working_dir)
191231 set (ENV{GIT_DESCRIBE} "${output} " )
192232 endif ()
193233
234+ # Convert HEAD to a symbolic ref. This can fail, in which case we just
235+ # set that variable to HEAD.
236+ set (_permit_git_failure ON )
237+ RunGitCommand(symbolic -ref --short -q ${object} )
238+ unset (_permit_git_failure)
239+ if (NOT exit_code EQUAL 0)
240+ set (ENV{GIT_BRANCH} "${object} " )
241+ else ()
242+ set (ENV{GIT_BRANCH} "${output} " )
243+ endif ()
244+
194245 # >>>
195246 # 2. Additional git properties can be added here via the
196247 # "execute_process()" command. Be sure to set them in
197248 # the environment using the same variable name you added
198249 # to the "_state_variable_names" list.
199250
200- if (EXISTS "${GIT_WORKING_DIR} /VERSION" )
201- file (READ "${GIT_WORKING_DIR} /VERSION" version_output_raw)
202- string (STRIP "${version_output_raw} " version_output)
203- set (ENV{VERSION_STRING} "${version_output} " )
204- else ()
205- set (ENV{VERSION_STRING} "" )
206- endif ()
207-
208251endfunction ()
209252
210253
@@ -296,6 +339,8 @@ function(SetupGitMonitoring)
296339 -DGIT_STATE_FILE=${GIT_STATE_FILE}
297340 -DPRE_CONFIGURE_FILE=${PRE_CONFIGURE_FILE}
298341 -DPOST_CONFIGURE_FILE=${POST_CONFIGURE_FILE}
342+ -DGIT_FAIL_IF_NONZERO_EXIT=${GIT_FAIL_IF_NONZERO_EXIT}
343+ -DGIT_IGNORE_UNTRACKED=${GIT_IGNORE_UNTRACKED}
299344 -P "${CMAKE_CURRENT_LIST_FILE} " )
300345endfunction ()
301346
0 commit comments