1# This script drives creation of a git repository and checks
2# that CTest can update from it.
3
4#-----------------------------------------------------------------------------
5# Test in a directory next to this script.
6get_filename_component(TOP "${CMAKE_CURRENT_LIST_FILE}" PATH)
7string(APPEND TOP "/@CTestUpdateGIT_DIR@")
8set(UPDATE_EXTRA Updated{module})
9
10# Include code common to all update tests.
11include("@CMAKE_CURRENT_SOURCE_DIR@/CTestUpdateCommon.cmake")
12
13#-----------------------------------------------------------------------------
14# Report git tools in use.
15message("Using GIT tools:")
16set(GIT "@GIT_EXECUTABLE@")
17message(" git = ${GIT}")
18
19set(AUTHOR_CONFIG "[user]
20\tname = Test Author
21\temail = testauthor@cmake.org
22")
23
24#-----------------------------------------------------------------------------
25# Initialize the testing directory.
26message("Creating test directory...")
27init_testing()
28
29if(UNIX)
30  set(src "@CMAKE_CURRENT_SOURCE_DIR@")
31  configure_file(${src}/CTestUpdateGIT.sh.in ${TOP}/git.sh @ONLY)
32  set(GIT ${TOP}/git.sh)
33endif()
34
35# Adapt to the system default branch name.
36execute_process(
37  COMMAND ${GIT} config --get init.defaultBranch
38  RESULT_VARIABLE defaultBranchFailed
39  OUTPUT_VARIABLE defaultBranch
40  ERROR_VARIABLE defaultBranchError
41  OUTPUT_STRIP_TRAILING_WHITESPACE
42  ERROR_STRIP_TRAILING_WHITESPACE
43  )
44if(defaultBranch STREQUAL "")
45  set(defaultBranch master)
46endif()
47message("Detected default branch name '${defaultBranch}'")
48
49#-----------------------------------------------------------------------------
50# Create the repository.
51message("Creating repository...")
52file(MAKE_DIRECTORY ${TOP}/repo.git)
53run_child(
54  WORKING_DIRECTORY ${TOP}/repo.git
55  COMMAND ${GIT} --bare init
56  )
57file(REMOVE_RECURSE ${TOP}/repo.git/hooks)
58
59# Create submodule repository.
60message("Creating submodule...")
61file(MAKE_DIRECTORY ${TOP}/module.git)
62run_child(
63  WORKING_DIRECTORY ${TOP}/module.git
64  COMMAND ${GIT} --bare init
65  )
66file(REMOVE_RECURSE ${TOP}/module.git/hooks)
67run_child(WORKING_DIRECTORY ${TOP}
68  COMMAND ${GIT} clone module.git module
69  )
70file(REMOVE_RECURSE ${TOP}/module/.git/hooks)
71file(APPEND ${TOP}/module/.git/config "
72${AUTHOR_CONFIG}")
73create_content(module)
74run_child(WORKING_DIRECTORY ${TOP}/module
75  COMMAND ${GIT} add .
76  )
77run_child(WORKING_DIRECTORY ${TOP}/module
78  COMMAND ${GIT} commit -m "Initial content"
79  )
80run_child(WORKING_DIRECTORY ${TOP}/module
81  COMMAND ${GIT} push origin ${defaultBranch}:refs/heads/${defaultBranch}
82  )
83
84#-----------------------------------------------------------------------------
85# Import initial content into the repository.
86message("Importing content...")
87
88# Import the content into the repository.
89run_child(WORKING_DIRECTORY ${TOP}
90  COMMAND ${GIT} clone repo.git import
91  )
92file(REMOVE_RECURSE ${TOP}/import/.git/hooks)
93file(APPEND ${TOP}/import/.git/config "
94${AUTHOR_CONFIG}")
95create_content(import)
96file(WRITE ${TOP}/import/HEAD "HEAD\n")
97file(WRITE ${TOP}/import/${defaultBranch} "${defaultBranch}\n")
98run_child(WORKING_DIRECTORY ${TOP}/import
99  COMMAND ${GIT} add .
100  )
101run_child(WORKING_DIRECTORY ${TOP}/import
102  COMMAND ${GIT} config core.safecrlf false
103  )
104run_child(WORKING_DIRECTORY ${TOP}/import
105  COMMAND ${GIT} submodule add ../module.git module
106  )
107run_child(WORKING_DIRECTORY ${TOP}/import
108  COMMAND ${GIT} commit -m "Initial content"
109  )
110run_child(WORKING_DIRECTORY ${TOP}/import
111  COMMAND ${GIT} push origin ${defaultBranch}:refs/heads/${defaultBranch}
112  )
113
114#-----------------------------------------------------------------------------
115# Modify the submodule.
116change_content(module)
117run_child(WORKING_DIRECTORY ${TOP}/module
118  COMMAND ${GIT} add -u
119  )
120run_child(WORKING_DIRECTORY ${TOP}/module
121  COMMAND ${GIT} commit -m "Changed content"
122  )
123run_child(WORKING_DIRECTORY ${TOP}/module
124  COMMAND ${GIT} push origin ${defaultBranch}:refs/heads/${defaultBranch}
125  )
126
127#-----------------------------------------------------------------------------
128# Create a working tree.
129message("Checking out revision 1...")
130run_child(
131  WORKING_DIRECTORY ${TOP}
132  COMMAND ${GIT} clone repo.git user-source
133  )
134file(REMOVE_RECURSE ${TOP}/user-source/.git/hooks)
135file(APPEND ${TOP}/user-source/.git/config "${AUTHOR_CONFIG}")
136run_child(
137  WORKING_DIRECTORY ${TOP}/user-source
138  COMMAND ${GIT} submodule init
139  )
140run_child(
141  WORKING_DIRECTORY ${TOP}/user-source
142  COMMAND ${GIT} submodule update
143  )
144
145# Save the first revision name.
146execute_process(
147  WORKING_DIRECTORY ${TOP}/user-source
148  COMMAND ${GIT} rev-parse HEAD
149  OUTPUT_VARIABLE revision1
150  OUTPUT_STRIP_TRAILING_WHITESPACE
151  )
152
153#-----------------------------------------------------------------------------
154# Create an empty commit.
155message("Creating empty commit...")
156run_child(
157  WORKING_DIRECTORY ${TOP}/user-source
158  COMMAND ${GIT} commit --allow-empty -m "Empty commit"
159  )
160
161#-----------------------------------------------------------------------------
162# Make changes in the working tree.
163message("Changing content...")
164update_content(user-source files_added files_removed dirs_added)
165if(dirs_added)
166  run_child(
167    WORKING_DIRECTORY ${TOP}/user-source
168    COMMAND ${GIT} add -- ${dirs_added}
169    )
170endif()
171run_child(
172  WORKING_DIRECTORY ${TOP}/user-source
173  COMMAND ${GIT} add -- ${files_added}
174  )
175run_child(
176  WORKING_DIRECTORY ${TOP}/user-source
177  COMMAND ${GIT} rm -- ${files_removed}
178  )
179run_child(WORKING_DIRECTORY ${TOP}/user-source/module
180  COMMAND ${GIT} checkout ${defaultBranch} --
181  )
182run_child(
183  WORKING_DIRECTORY ${TOP}/user-source
184  COMMAND ${GIT} add -u
185  )
186
187#-----------------------------------------------------------------------------
188# Commit the changes to the repository.
189message("Committing revision 2...")
190run_child(
191  WORKING_DIRECTORY ${TOP}/user-source
192  COMMAND ${GIT} commit -m "Changed content"
193  )
194run_child(
195  WORKING_DIRECTORY ${TOP}/user-source
196  COMMAND ${GIT} push origin
197  )
198
199#-----------------------------------------------------------------------------
200# Make changes in the working tree.
201message("Changing content again...")
202change_content(user-source)
203run_child(
204  WORKING_DIRECTORY ${TOP}/user-source
205  COMMAND ${GIT} add -u
206  )
207
208#-----------------------------------------------------------------------------
209# Commit the changes to the repository.
210message("Committing revision 3...")
211run_child(
212  WORKING_DIRECTORY ${TOP}/user-source
213  COMMAND ${GIT} commit -m "Changed content again"
214  )
215run_child(
216  WORKING_DIRECTORY ${TOP}/user-source
217  COMMAND ${GIT} push origin
218  )
219
220#-----------------------------------------------------------------------------
221# Go back to before the changes so we can test updating.
222macro(rewind_source src_dir)
223  message("Backing up to revision 1...")
224  run_child(
225    WORKING_DIRECTORY ${TOP}/${src_dir}
226    COMMAND ${GIT} reset --hard ${revision1}
227    )
228  run_child(
229    WORKING_DIRECTORY ${TOP}/${src_dir}
230    COMMAND ${GIT} submodule update
231    )
232endmacro()
233rewind_source(user-source)
234
235# Make sure pull does not try to rebase (which does not work with
236# modified files) even if ~/.gitconfig sets "branch.master.rebase".
237run_child(
238  WORKING_DIRECTORY ${TOP}/user-source
239  COMMAND ${GIT} config branch.${defaultBranch}.rebase false
240  )
241
242# Create a modified file.
243modify_content(user-source)
244
245#-----------------------------------------------------------------------------
246# Test updating the user work directory with the command-line interface.
247message("Running CTest Dashboard Command Line...")
248
249# Create the user build tree.
250create_build_tree(user-source user-binary)
251file(APPEND ${TOP}/user-binary/CTestConfiguration.ini
252  "# GIT command configuration
253UpdateCommand: ${GIT}
254")
255
256# Run the dashboard command line interface.
257set(UPDATE_NO_MODIFIED 1)
258run_dashboard_command_line(user-binary)
259set(UPDATE_NO_MODIFIED 0)
260
261rewind_source(user-source)
262modify_content(user-source)
263
264message("Running CTest Dashboard Command Line (custom update)...")
265
266# Create the user build tree.
267create_build_tree(user-source user-binary-custom)
268file(APPEND ${TOP}/user-binary-custom/CTestConfiguration.ini
269  "# GIT command configuration
270UpdateCommand: ${GIT}
271GITUpdateCustom: ${GIT};pull;origin;${defaultBranch}
272")
273
274# Run the dashboard command line interface.
275run_dashboard_command_line(user-binary-custom)
276
277#-----------------------------------------------------------------------------
278# Test initial checkout and update with a dashboard script.
279message("Running CTest Dashboard Script...")
280
281create_dashboard_script(dash-binary
282  "# git command configuration
283set(CTEST_GIT_COMMAND \"${GIT}\")
284set(CTEST_GIT_UPDATE_OPTIONS)
285execute_process(
286  WORKING_DIRECTORY \"${TOP}\"
287  COMMAND \"${GIT}\" clone repo.git dash-source
288  )
289
290# Test .git file.
291file(RENAME \"${TOP}/dash-source/.git\" \"${TOP}/dash-source/repo.git\")
292file(WRITE \"${TOP}/dash-source/.git\" \"gitdir: repo.git\n\")
293
294execute_process(
295  WORKING_DIRECTORY \"${TOP}/dash-source\"
296  COMMAND \"${GIT}\" reset --hard ${revision1}
297  )
298execute_process(
299  WORKING_DIRECTORY \"${TOP}/dash-source\"
300  COMMAND \"${GIT}\" submodule init
301  )
302execute_process(
303  WORKING_DIRECTORY \"${TOP}/dash-source\"
304  COMMAND \"${GIT}\" submodule update
305  )
306")
307
308# Run the dashboard script with CTest.
309run_dashboard_script(dash-binary)
310
311rewind_source(dash-source)
312
313#-----------------------------------------------------------------------------
314# Test custom update with a dashboard script.
315message("Running CTest Dashboard Script (custom update)...")
316
317create_dashboard_script(dash-binary-custom
318  "# git command configuration
319set(CTEST_GIT_COMMAND \"${GIT}\")
320set(CTEST_GIT_UPDATE_OPTIONS)
321set(CTEST_GIT_UPDATE_CUSTOM \${CTEST_GIT_COMMAND} pull origin ${defaultBranch})
322")
323
324# Run the dashboard script with CTest.
325run_dashboard_script(dash-binary-custom)
326
327
328rewind_source(dash-source)
329
330#-----------------------------------------------------------------------------
331# Test no update with a dashboard script.
332message("Running CTest Dashboard Script (No update)...")
333
334create_dashboard_script(dash-binary-no-update
335  "# git command configuration
336set(CTEST_GIT_COMMAND \"${GIT}\")
337set(CTEST_UPDATE_VERSION_ONLY TRUE)
338")
339
340# Run the dashboard script with CTest.
341set(NO_UPDATE 1)
342run_dashboard_script(dash-binary-no-update)
343unset(NO_UPDATE)
344
345rewind_source(dash-source)
346
347#-----------------------------------------------------------------------------
348# Test ctest_update(QUIET)
349message("Running CTest Dashboard Script (update quietly)...")
350
351set(ctest_update_args QUIET)
352create_dashboard_script(dash-binary-quiet
353  "# git command configuration
354set(CTEST_GIT_COMMAND \"${GIT}\")
355set(CTEST_GIT_UPDATE_OPTIONS)
356set(CTEST_GIT_UPDATE_CUSTOM \${CTEST_GIT_COMMAND} pull origin ${defaultBranch})
357")
358unset(ctest_update_args)
359
360# Run the dashboard script with CTest.
361run_dashboard_script(dash-binary-quiet)
362
363# Make sure the output seems quiet.
364if("${OUTPUT}" MATCHES "Updating the repository")
365  message(FATAL_ERROR "Found 'Updating the repository' in quiet output")
366endif()
367
368#-----------------------------------------------------------------------------
369# Test ctest_update(RETURN_VALUE) on failure
370message("Running CTest Dashboard Script (fail to update)...")
371
372set(ctest_update_check [[
373
374if(NOT ret LESS 0)
375  message(FATAL_ERROR "ctest_update incorrectly succeeded with ${ret}")
376endif()
377]])
378create_dashboard_script(dash-binary-fail
379  "set(CTEST_GIT_COMMAND \"update-command-does-not-exist\")
380")
381unset(ctest_update_check)
382
383# Run the dashboard script with CTest.
384set(FAIL_UPDATE 1)
385run_dashboard_script(dash-binary-fail)
386unset(FAIL_UPDATE)
387