commit 243aed525a2fd8e5fe32139fd0f8d0cc0e40cc33 Author: Bernhard M. Wiedemann Date: Wed Jan 25 07:15:40 2017 +0100 cmTimestamp: Support SOURCE_DATE_EPOCH to override current time See https://reproducible-builds.org/ for why this is good and https://reproducible-builds.org/specs/source-date-epoch/ for the definition of this variable. diff --git a/Help/command/string.rst b/Help/command/string.rst index 77538f6..2c7847a 100644 --- a/Help/command/string.rst +++ b/Help/command/string.rst @@ -329,6 +329,12 @@ If no explicit ```` is given it will default to: Write a string which can be used as an identifier in C. +.. note:: + + If the ``SOURCE_DATE_EPOCH`` environment variable is set, + its value will be used instead of the current time. + See https://reproducible-builds.org/specs/source-date-epoch/ for details. + UUID """" diff --git a/Help/release/dev/SOURCE_DATE_EPOCH.rst b/Help/release/dev/SOURCE_DATE_EPOCH.rst new file mode 100644 index 0000000..576e1da --- /dev/null +++ b/Help/release/dev/SOURCE_DATE_EPOCH.rst @@ -0,0 +1,5 @@ +SOURCE_DATE_EPOCH +----------------- + +* The :command:`string(TIMESTAMP)` will now honor the ``SOURCE_DATE_EPOCH`` + environment variable and use its value instead of the current time. diff --git a/Source/cmTimestamp.cxx b/Source/cmTimestamp.cxx index 4a97114..1e5ac5b 100644 --- a/Source/cmTimestamp.cxx +++ b/Source/cmTimestamp.cxx @@ -12,6 +13,16 @@ std::string cmTimestamp::CurrentTime(const std::string& formatString, bool utcFlag) { time_t currentTimeT = time(CM_NULLPTR); + std::string source_date_epoch; + cmSystemTools::GetEnv("SOURCE_DATE_EPOCH", source_date_epoch); + if (!source_date_epoch.empty()) { + std::istringstream iss(source_date_epoch); + iss >> currentTimeT; + if (iss.fail() || !iss.eof()) { + cmSystemTools::Error("Cannot parse SOURCE_DATE_EPOCH as integer"); + exit(27); + } + } if (currentTimeT == time_t(-1)) { return std::string(); } diff --git a/Tests/RunCMake/string/RunCMakeTest.cmake b/Tests/RunCMake/string/RunCMakeTest.cmake index 8067d9d..38a77b0 100644 --- a/Tests/RunCMake/string/RunCMakeTest.cmake +++ b/Tests/RunCMake/string/RunCMakeTest.cmake @@ -6,6 +6,11 @@ run_cmake(AppendNoArgs) run_cmake(Concat) run_cmake(ConcatNoArgs) +run_cmake(Timestamp) +run_cmake(TimestampEmpty) +run_cmake(TimestampInvalid) +run_cmake(TimestampInvalid2) + run_cmake(Uuid) run_cmake(UuidMissingNamespace) run_cmake(UuidMissingNamespaceValue) diff --git a/Tests/RunCMake/string/Timestamp-result.txt b/Tests/RunCMake/string/Timestamp-result.txt new file mode 100644 index 0000000..573541a --- /dev/null +++ b/Tests/RunCMake/string/Timestamp-result.txt @@ -0,0 +1 @@ +0 diff --git a/Tests/RunCMake/string/Timestamp-stderr.txt b/Tests/RunCMake/string/Timestamp-stderr.txt new file mode 100644 index 0000000..c12b070 --- /dev/null +++ b/Tests/RunCMake/string/Timestamp-stderr.txt @@ -0,0 +1 @@ +RESULT=2005-08-07 23:19:49 Sun Aug 05 day=219 wd=0 week=32 %%I=11 diff --git a/Tests/RunCMake/string/Timestamp.cmake b/Tests/RunCMake/string/Timestamp.cmake new file mode 100644 index 0000000..1232300 --- /dev/null +++ b/Tests/RunCMake/string/Timestamp.cmake @@ -0,0 +1,3 @@ +set(ENV{SOURCE_DATE_EPOCH} "1123456789") +string(TIMESTAMP RESULT "%Y-%m-%d %H:%M:%S %a %b %y day=%j wd=%w week=%U %%I=%I" UTC) +message("RESULT=${RESULT}") diff --git a/Tests/RunCMake/string/TimestampEmpty-result.txt b/Tests/RunCMake/string/TimestampEmpty-result.txt new file mode 100644 index 0000000..573541a --- /dev/null +++ b/Tests/RunCMake/string/TimestampEmpty-result.txt @@ -0,0 +1 @@ +0 diff --git a/Tests/RunCMake/string/TimestampEmpty-stderr.txt b/Tests/RunCMake/string/TimestampEmpty-stderr.txt new file mode 100644 index 0000000..35cbd3c --- /dev/null +++ b/Tests/RunCMake/string/TimestampEmpty-stderr.txt @@ -0,0 +1 @@ +RESULT=2 diff --git a/Tests/RunCMake/string/TimestampEmpty.cmake b/Tests/RunCMake/string/TimestampEmpty.cmake new file mode 100644 index 0000000..21b770f --- /dev/null +++ b/Tests/RunCMake/string/TimestampEmpty.cmake @@ -0,0 +1,3 @@ +set(ENV{SOURCE_DATE_EPOCH} "") +string(TIMESTAMP RESULT "%Y-%m-%d %H:%M:%S" UTC) +message("RESULT=${RESULT}") diff --git a/Tests/RunCMake/string/TimestampInvalid-result.txt b/Tests/RunCMake/string/TimestampInvalid-result.txt new file mode 100644 index 0000000..f64f5d8 --- /dev/null +++ b/Tests/RunCMake/string/TimestampInvalid-result.txt @@ -0,0 +1 @@ +27 diff --git a/Tests/RunCMake/string/TimestampInvalid-stderr.txt b/Tests/RunCMake/string/TimestampInvalid-stderr.txt new file mode 100644 index 0000000..75566da --- /dev/null +++ b/Tests/RunCMake/string/TimestampInvalid-stderr.txt @@ -0,0 +1 @@ +CMake Error: Cannot parse SOURCE_DATE_EPOCH as integer diff --git a/Tests/RunCMake/string/TimestampInvalid.cmake b/Tests/RunCMake/string/TimestampInvalid.cmake new file mode 100644 index 0000000..ab36270 --- /dev/null +++ b/Tests/RunCMake/string/TimestampInvalid.cmake @@ -0,0 +1,3 @@ +set(ENV{SOURCE_DATE_EPOCH} "invalid-integer") +string(TIMESTAMP RESULT "%Y-%m-%d %H:%M:%S" UTC) +message("RESULT=${RESULT}") diff --git a/Tests/RunCMake/string/TimestampInvalid2-result.txt b/Tests/RunCMake/string/TimestampInvalid2-result.txt new file mode 100644 index 0000000..f64f5d8 --- /dev/null +++ b/Tests/RunCMake/string/TimestampInvalid2-result.txt @@ -0,0 +1 @@ +27 diff --git a/Tests/RunCMake/string/TimestampInvalid2-stderr.txt b/Tests/RunCMake/string/TimestampInvalid2-stderr.txt new file mode 100644 index 0000000..75566da --- /dev/null +++ b/Tests/RunCMake/string/TimestampInvalid2-stderr.txt @@ -0,0 +1 @@ +CMake Error: Cannot parse SOURCE_DATE_EPOCH as integer diff --git a/Tests/RunCMake/string/TimestampInvalid2.cmake b/Tests/RunCMake/string/TimestampInvalid2.cmake new file mode 100644 index 0000000..5cc61b8 --- /dev/null +++ b/Tests/RunCMake/string/TimestampInvalid2.cmake @@ -0,0 +1,3 @@ +set(ENV{SOURCE_DATE_EPOCH} "123trailing-garbage") +string(TIMESTAMP RESULT "%Y-%m-%d %H:%M:%S" UTC) +message("RESULT=${RESULT}")