Save git diff?
We already save the git-hash, but in case the code has been edited somewhere it would be nice to also compile the git-diff into the code so we can save it into run output, helping reproducibility. I've done this for STORM, but think I need to hand over to a build-system guru to add it to BOUT++.
One way to save the git hash is to have a Python script, e.g.
#!/usr/bin/env python3
from pathlib import Path
from string import ascii_uppercase
from boututils.run_wrapper import shell
scriptdir = Path(__file__).parent
_, diff = shell("git diff", pipe=True)
# Find a string to use for the delimiter
delimiter = "_BOUT_DIFF_"
for letter in ascii_uppercase:
if ")" + delimiter not in diff:
delimiter_success = True
break
delimiter = "_BOUT_DIFF_" + letter + "_"
if ")" + delimiter in diff:
# print a return code to stdout so we can capture and test it in the makefile
print(11)
raise ValueError(
"save_git_version.py failed to find a delimiter that is not in the git diff"
)
with open("bout_git_hash.hxx", "w") as f:
f.write("constexpr auto bout_git_diff = R\"" + delimiter + "(")
f.write(diff)
f.write(")" + delimiter + "\";\n")
# print a return code to stdout so we can capture and test it in the makefile
print(0)
although probably it would be better to append to include/bout/build_defines.hxx or something. This script only has dependencies on Python standard library (I think) plus boututils (I guess the boututils import needs fixing to make sure it's always imported from the local submodule).
Not sure whether it's best to do this at configure-time or compile-time. I'd favour compile-time if possible - I think we always rebuild bout++.cxx (?) so if we have a header that's only imported there, we could re-generate that header each time make is run. What I've got for STORM is some lines in the makefile like
save_git_version_status := $(shell ./save_git_version.py)
ifeq ($(save_git_version_status), 11)
$(error "save_git_version.py failed to find a delimiter that is not in the git diff")
endif
ifneq ($(save_git_version_status), 0)
$(error "save_git_version.py failed with an unrecognised error $(save_git_version_status)")
endif
This is probably quite easy with CMake, as we basically do something like this for the commit already. CMake can probably generate the file too, although possibly without the fancy delimiter logic you're currently using.
I've just done something similar in raw Makefiles for GS2 as well, basically using an intermediate file and checking if its contents have changed.