Capture git diff when building#3415
Conversation
- Generates a git diff on build, so the diff used when compiling is stored, not the diff when configuring. Handles out-of-source builds and cases where the source is not under git e.g. release tarballs. - Stores the diff as a string in a compilation unit git_metadata.cxx - Saves to output, along with flags indicating whether the diff was available, and whether the build had uncommitted changes.
dschwoerer
left a comment
There was a problem hiding this comment.
If we want to test this in CI, it would not be that hard. We already have some post ctest tests: https://github.com/boutproject/BOUT-dev/blob/next/.ci_with_cmake.sh#L18
We could it there. Modify a source file, adding some white space to a file, and then build a test executable, and check the output. Certainly not a nice implementation, and I am not sure it is worth to have the extra time spent in CI.
| ERROR_QUIET | ||
| ) | ||
| if(NOT git_cached_diff_result EQUAL 0) | ||
| set(git_cached_diff "") |
There was a problem hiding this comment.
| set(git_cached_diff "") | |
| set(git_cached_diff "git diff unavailable") |
We could store also that the git diff is not available in the string.
If it is used programmatically, it would fail to apply the diff, which would be fine, I think. If it is used by humans, it is easy enough to see that this is not actually a diff.
| set(output_tmp "${OUTPUT_FILE}.tmp") | ||
| file(WRITE "${output_tmp}" "#include \"bout/git_metadata.hxx\"\n\n") | ||
| file(APPEND "${output_tmp}" "namespace bout {\n") | ||
| file(APPEND "${output_tmp}" "namespace version {\n") | ||
| file(APPEND "${output_tmp}" "namespace {\n") | ||
| file( | ||
| APPEND "${output_tmp}" | ||
| "constexpr bool git_metadata_available_value = ${git_metadata_available};\n" | ||
| ) | ||
| file(APPEND "${output_tmp}" "constexpr bool git_dirty_value = ${git_dirty};\n") | ||
| file(APPEND "${output_tmp}" "constexpr char git_diff_value[] =\n") | ||
| file(APPEND "${output_tmp}" "\"${git_diff_escaped}\";\n") | ||
| file(APPEND "${output_tmp}" "} // namespace\n\n") | ||
| file( | ||
| APPEND "${output_tmp}" | ||
| "auto git_metadata_available() -> bool { return git_metadata_available_value; }\n" | ||
| ) | ||
| file(APPEND "${output_tmp}" | ||
| "auto git_dirty() -> bool { return git_dirty_value; }\n" | ||
| ) | ||
| file(APPEND "${output_tmp}" | ||
| "auto git_diff() -> std::string_view { return git_diff_value; }\n" | ||
| ) | ||
| file(APPEND "${output_tmp}" "} // namespace version\n") | ||
| file(APPEND "${output_tmp}" "} // namespace bout\n") |
There was a problem hiding this comment.
For other cases we have a file, that we configure. I think that is easier to read and maintain.
| COMMAND "${CMAKE_COMMAND}" -E copy_if_different "${output_tmp}" | ||
| "${OUTPUT_FILE}" | ||
| ) | ||
| execute_process(COMMAND "${CMAKE_COMMAND}" -E rm -f "${output_tmp}") |
There was a problem hiding this comment.
I think cmake should be able to move?
| set_source_files_properties( | ||
| ${BOUT_GIT_METADATA_SOURCE} PROPERTIES GENERATED TRUE | ||
| ) | ||
| add_custom_target( |
There was a problem hiding this comment.
I would prefer add_custom_command - like we use for the timestamp above.
Although, it makes me wonder - could / should they be in the same file? Having to compile just one file should be faster, and both contain dynamic, generated content. They both get modified at the same time.
|
|
||
| add_library( | ||
| bout++ ${BOUT_SOURCES} ${CMAKE_CURRENT_BINARY_DIR}/bout++-time.cxx | ||
| ${BOUT_GIT_METADATA_SOURCE} |
There was a problem hiding this comment.
I think we can just write the name here (and above), that makes it easier to read.
Stores code changes from the current commit into the output dump files. This is to help in reproducing results when code was not committed before building.
Generates a git diff on build, so the diff used when compiling is stored, not the diff when configuring. Handles out-of-source builds and cases where the source is not under git e.g. release tarballs.
Stores the diff as a string in a compilation unit git_metadata.cxx
Saves to output, along with flags indicating whether the diff was available, and whether the build had uncommitted changes.
Not sure how to test this in CI, so I just verified manually that changes in source get stored in the output files (
conductionexample). GPT-5.4 wrote most of the code; I reviewed and modified slightly.Fixes #2217