blob: 2e909bb6e818eec636dc6369bd2b91136db9713a [file] [log] [blame]
Soby Mathewb4c6df42022-11-09 11:13:29 +00001#
2# SPDX-License-Identifier: BSD-3-Clause
3# SPDX-FileCopyrightText: Copyright TF-RMM Contributors.
4#
5
6#
7# Returns:
8# @FileList_Out: All files in the Git repo in list format. Empty list
9# on error
10#
Soby Mathewb5a29752024-11-14 14:26:11 +000011
12find_package(Git)
13
Soby Mathewb4c6df42022-11-09 11:13:29 +000014function(Git_Get_All_Files FileList_Out)
15 if (GIT_NOT_FOUND OR NOT IS_DIRECTORY .git)
16 set(${FileList_Out} "" PARENT_SCOPE)
17 return()
18 endif()
19
20 execute_process(
21 WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
22 COMMAND ${GIT_EXECUTABLE} ls-files
23 OUTPUT_VARIABLE git_ls_files
24 RESULT_VARIABLE git_rc
25 OUTPUT_STRIP_TRAILING_WHITESPACE
26 )
27
28 # convert string to list
29 if(NOT "${git_ls_files}" STREQUAL "")
30 string(REPLACE "\n" ";" all_files ${git_ls_files})
31 else()
32 set(all_files "")
33 endif()
34
35 set(${FileList_Out} ${all_files} PARENT_SCOPE)
36endfunction()
37
38#
39# Returns:
40# @CommitIdList_Out: All commit ids in current branch between HEAD and
41# upstream tracking branch in List format. Empty list
42# on error
43#
44function(Git_Get_Pending_Commits CommitIdList_Out)
45 if (GIT_NOT_FOUND OR NOT IS_DIRECTORY .git)
46 set(${CommitIdList_Out} "" PARENT_SCOPE)
47 return()
48 endif()
49
50 # Get the upstream branch the current (local) branch is tracking
51 execute_process(
52 WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
53 COMMAND ${GIT_EXECUTABLE} rev-parse --abbrev-ref --symbolic-full-name @{u}
54 OUTPUT_VARIABLE git_upstream_branch
55 RESULT_VARIABLE git_rc
56 OUTPUT_STRIP_TRAILING_WHITESPACE
57 )
58
59 if ("${git_upstream_branch}" STREQUAL "")
60 message(STATUS "Warning: Upstream branch not set. Trying \"origin/main\"")
61 set(git_upstream_branch "origin/main")
62 endif()
63
64 # Get the merge base
65 execute_process(
66 WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
67 COMMAND ${GIT_EXECUTABLE} merge-base HEAD ${git_upstream_branch}
68 OUTPUT_VARIABLE git_merge_base
69 RESULT_VARIABLE git_rc
70 OUTPUT_STRIP_TRAILING_WHITESPACE
71 )
72
73 if("${git_merge_base}" STREQUAL "")
74 set(${CommitIdList_Out} "" PARENT_SCOPE)
75 return()
76 endif()
77
78 # Get list of commits between $merge_base and HEAD
79 execute_process(
80 WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
81 COMMAND ${GIT_EXECUTABLE} rev-list --no-merges "${git_merge_base}..HEAD"
82 OUTPUT_VARIABLE git_rev_output
83 RESULT_VARIABLE git_rc
84 OUTPUT_STRIP_TRAILING_WHITESPACE
85 )
86
87 # convert to list
88 if(NOT "${git_rev_output}" STREQUAL "")
89 string(REPLACE "\n" ";" git_rev_list ${git_rev_output})
90 else()
91 set(git_rev_list "")
92 endif()
93
94 set(${CommitIdList_Out} ${git_rev_list} PARENT_SCOPE)
95endfunction()
96
97#
98# Args In:
99# @CommitId_In: Commit's SHA
100#
101# Returns:
102# @FileList_Out: Files Added or Modified or Deleted by the @CommitId_In
103# in list format. Empty list on error
104#
105function(Git_Get_Files_In_Commit CommitId_In FileList_Out)
106 if (GIT_NOT_FOUND OR NOT IS_DIRECTORY .git OR "${CommitId_In}" STREQUAL "")
107 set(${FileList_Out} "" PARENT_SCOPE)
108 return()
109 endif()
110
111 execute_process(
112 WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
113 # Get list of files that are Added or Renamed or Modified by this commit
114 COMMAND ${GIT_EXECUTABLE} show --diff-filter=ARM --pretty=format: --name-only ${CommitId_In}
115 OUTPUT_VARIABLE git_files
116 RESULT_VARIABLE git_rc
117 OUTPUT_STRIP_TRAILING_WHITESPACE
118 )
119
120 # convert string to list
121 if(NOT "${git_files}" STREQUAL "")
122 string(REPLACE "\n" ";" source_files ${git_files})
123 else()
124 set(source_files "")
125 endif()
126
127 set(${FileList_Out} ${source_files} PARENT_SCOPE)
128endfunction()
Arunachalam Ganapathyd9e8e1b2024-04-19 16:27:14 +0100129
130#
131# Apply patches in @Git_Repo
132#
133# Args In:
134# @Git_Repo: Git repository
Soby Mathewb5a29752024-11-14 14:26:11 +0000135#
136# Returns:
Arunachalam Ganapathyd9e8e1b2024-04-19 16:27:14 +0100137# @Patch_Files_List: List of .patch files to apply
138#
139function(Git_Apply_Patches Git_Repo Patch_Files_List)
140 # use EXISTS as inside submodule .git file contains path to Git repository
141 if(GIT_NOT_FOUND OR NOT EXISTS "${Git_Repo}/.git")
142 message(FATAL_ERROR "${Git_Repo} not a git repository")
143 return()
144 endif()
145
146 # todo: Remove 'checkout' and 'clean' commands.
147 # These commands does a force reset and removes untracked files. If an user
148 # has some work in progress changes in 'Git_Repo', then Git_Apply_Patches will
149 # force delete the changes.
150 execute_process(
151 WORKING_DIRECTORY ${Git_Repo}
152 # removes changes that are not staged
153 COMMAND ${GIT_EXECUTABLE} checkout .
154 )
155 execute_process(
156 WORKING_DIRECTORY ${Git_Repo}
157 # removes changes that are not tracked
158 COMMAND ${GIT_EXECUTABLE} clean -f
159 )
160
161 # todo: For applying patches use -am option, this retains commit history.
162 foreach(PATCH_FILE IN LISTS Patch_Files_List)
163 execute_process(
164 WORKING_DIRECTORY ${Git_Repo}
165 COMMAND ${GIT_EXECUTABLE} apply --verbose ${PATCH_FILE}
166 RESULT_VARIABLE PATCH_STATUS
167 COMMAND_ECHO STDOUT
168 )
169
170 if(NOT PATCH_STATUS EQUAL 0)
171 message(FATAL_ERROR "Failed to apply patch ${PATCH_FILE} at ${Git_Repo}")
172 endif()
173 endforeach()
174endfunction()
Soby Mathewb5a29752024-11-14 14:26:11 +0000175
176#
177# Retrieve the Commit Info
178#
179# Returns:
180# @CommitInfo_Out: The commit info
181#
182function(Git_Get_Commit_Info CommitInfo_Out)
183
184 if(GIT_NOT_FOUND OR NOT EXISTS "${CMAKE_SOURCE_DIR}/.git")
185 message(FATAL_ERROR "${CMAKE_SOURCE_DIR} not a git repository")
186 return()
187 endif()
188
189 execute_process(
190 COMMAND ${GIT_EXECUTABLE} describe --always --dirty --tags
191 WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
192 OUTPUT_VARIABLE commit_info
193 OUTPUT_STRIP_TRAILING_WHITESPACE
194 )
195
196 set(${CommitInfo_Out} ${commit_info} PARENT_SCOPE)
197endfunction()
198
199#
200# Check if the git repo is dirty
201#
202# Args In:
203# @Git_Repo: Git repository
204#
205# Returns:
206# @result: result of the check
207#
208function(is_git_repo_dirty Git_Repo result)
209 execute_process(
210 COMMAND git status --porcelain
211 WORKING_DIRECTORY ${Git_Repo}
212 OUTPUT_VARIABLE git_status_output
213 OUTPUT_STRIP_TRAILING_WHITESPACE
214 )
215 if(git_status_output)
216 set(${result} TRUE PARENT_SCOPE)
217 else()
218 set(${result} FALSE PARENT_SCOPE)
219 endif()
220endfunction()
221
222#
223# Fetch the submodules mentioned in .gitmodules
224#
225function(Git_Update_Submodule)
226 if(GIT_NOT_FOUND OR NOT EXISTS "${CMAKE_SOURCE_DIR}/.git")
227 message(FATAL_ERROR "${CMAKE_SOURCE_DIR} not a git repository")
228 endif()
229
230 message(STATUS "Updating submodules")
231 execute_process(COMMAND ${GIT_EXECUTABLE} submodule update --init --depth 1
232 WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
233 RESULT_VARIABLE GIT_SUBMOD_RESULT)
234 if(NOT GIT_SUBMOD_RESULT EQUAL "0")
235 # TODO: can be enhanced to check all submodules which are patched.
236 if(EXISTS "${CMAKE_SOURCE_DIR}/ext/mbedtls/.git")
237 is_git_repo_dirty("${CMAKE_SOURCE_DIR}/ext/mbedtls" repo_dirty)
238 if(repo_dirty)
239 message(WARNING "The submodules are modified and cannot be updated, try deleting them.")
240 endif()
241
242 message(FATAL_ERROR "git submodule update failed with error: ${GIT_SUBMOD_RESULT}")
243 endif()
244 endif()
245endfunction()