From 2a34d0ac3613101996b4e751bc2653e4cbeaf5b0 Mon Sep 17 00:00:00 2001
From: Zack Galbreath <zack.galbreath@kitware.com>
Date: Tue, 30 Apr 2019 16:12:02 -0400
Subject: ctest: Add new variable CTEST_UPDATE_VERSION_OVERRIDE

Set this in a CTest script to explicitly define what the current revision
will be reported as in Update.xml.
---
 Help/manual/cmake-variables.7.rst                          |  1 +
 Help/manual/ctest.1.rst                                    | 12 ++++++++++++
 Help/release/dev/ctest_update_version_override.rst         |  7 +++++++
 Help/variable/CTEST_UPDATE_VERSION_OVERRIDE.rst            |  5 +++++
 Source/CTest/cmCTestGlobalVC.cxx                           |  5 +++++
 Source/CTest/cmCTestGlobalVC.h                             |  2 ++
 Source/CTest/cmCTestUpdateCommand.cxx                      |  3 +++
 Source/CTest/cmCTestVC.cxx                                 | 14 ++++++++++++++
 Source/CTest/cmCTestVC.h                                   |  1 +
 Tests/RunCMake/ctest_update/RunCMakeTest.cmake             |  8 ++++++++
 .../RunCMake/ctest_update/UpdateActualVersion-check.cmake  | 12 ++++++++++++
 11 files changed, 70 insertions(+)
 create mode 100644 Help/release/dev/ctest_update_version_override.rst
 create mode 100644 Help/variable/CTEST_UPDATE_VERSION_OVERRIDE.rst
 create mode 100644 Tests/RunCMake/ctest_update/UpdateActualVersion-check.cmake

diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst
index 6d93ae9..86dc186 100644
--- a/Help/manual/cmake-variables.7.rst
+++ b/Help/manual/cmake-variables.7.rst
@@ -583,6 +583,7 @@ Variables for CTest
    /variable/CTEST_UPDATE_COMMAND
    /variable/CTEST_UPDATE_OPTIONS
    /variable/CTEST_UPDATE_VERSION_ONLY
+   /variable/CTEST_UPDATE_VERSION_OVERRIDE
    /variable/CTEST_USE_LAUNCHERS
 
 Variables for CPack
diff --git a/Help/manual/ctest.1.rst b/Help/manual/ctest.1.rst
index fab045b..5773176 100644
--- a/Help/manual/ctest.1.rst
+++ b/Help/manual/ctest.1.rst
@@ -831,6 +831,18 @@ Configuration settings to specify the version control tool include:
 
   * `CTest Script`_ variable: :variable:`CTEST_UPDATE_VERSION_ONLY`
 
+.. _`UpdateVersionOverride`:
+
+``UpdateVersionOverride``
+  Specify the current version of your source tree.
+
+  When this variable is set to a non-empty string, CTest will report the value
+  you specified rather than using the update command to discover the current
+  version that is checked out. Use of this variable supersedes
+  ``UpdateVersionOnly``. Like ``UpdateVersionOnly``, using this variable tells
+  CTest not to update the source tree to a different version.
+
+  * `CTest Script`_ variable: :variable:`CTEST_UPDATE_VERSION_OVERRIDE`
 
 Additional configuration settings include:
 
diff --git a/Help/release/dev/ctest_update_version_override.rst b/Help/release/dev/ctest_update_version_override.rst
new file mode 100644
index 0000000..03b47db
--- /dev/null
+++ b/Help/release/dev/ctest_update_version_override.rst
@@ -0,0 +1,7 @@
+CTEST_UPDATE_VERSION_OVERRIDE
+-----------------------------
+
+* The :command:`ctest_update` command learned to honor a new variable:
+  :variable:`CTEST_UPDATE_VERSION_OVERRIDE`. This can be used to specify
+  the current version of your source tree rather than using the update
+  command to discover the current version that is checked out.
diff --git a/Help/variable/CTEST_UPDATE_VERSION_OVERRIDE.rst b/Help/variable/CTEST_UPDATE_VERSION_OVERRIDE.rst
new file mode 100644
index 0000000..39fbaba
--- /dev/null
+++ b/Help/variable/CTEST_UPDATE_VERSION_OVERRIDE.rst
@@ -0,0 +1,5 @@
+CTEST_UPDATE_VERSION_OVERRIDE
+-----------------------------
+
+Specify the CTest :ref:`UpdateVersionOverride <UpdateVersionOverride>` setting
+in a :manual:`ctest(1)` dashboard client script.
diff --git a/Source/CTest/cmCTestGlobalVC.cxx b/Source/CTest/cmCTestGlobalVC.cxx
index a2d4d2c..54ebd4f 100644
--- a/Source/CTest/cmCTestGlobalVC.cxx
+++ b/Source/CTest/cmCTestGlobalVC.cxx
@@ -117,3 +117,8 @@ bool cmCTestGlobalVC::WriteXMLUpdates(cmXMLWriter& xml)
 
   return result;
 }
+
+void cmCTestGlobalVC::SetNewRevision(std::string const& revision)
+{
+  this->NewRevision = revision;
+}
diff --git a/Source/CTest/cmCTestGlobalVC.h b/Source/CTest/cmCTestGlobalVC.h
index 76377ed..9c57215 100644
--- a/Source/CTest/cmCTestGlobalVC.h
+++ b/Source/CTest/cmCTestGlobalVC.h
@@ -32,6 +32,8 @@ protected:
   // Implement cmCTestVC internal API.
   bool WriteXMLUpdates(cmXMLWriter& xml) override;
 
+  void SetNewRevision(std::string const& revision) override;
+
   /** Represent a vcs-reported action for one path in a revision.  */
   struct Change
   {
diff --git a/Source/CTest/cmCTestUpdateCommand.cxx b/Source/CTest/cmCTestUpdateCommand.cxx
index a2f1462..65dc921 100644
--- a/Source/CTest/cmCTestUpdateCommand.cxx
+++ b/Source/CTest/cmCTestUpdateCommand.cxx
@@ -62,6 +62,9 @@ cmCTestGenericHandler* cmCTestUpdateCommand::InitializeHandler()
     this->Makefile, "UpdateVersionOnly", "CTEST_UPDATE_VERSION_ONLY",
     this->Quiet);
   this->CTest->SetCTestConfigurationFromCMakeVariable(
+    this->Makefile, "UpdateVersionOverride", "CTEST_UPDATE_VERSION_OVERRIDE",
+    this->Quiet);
+  this->CTest->SetCTestConfigurationFromCMakeVariable(
     this->Makefile, "HGCommand", "CTEST_HG_COMMAND", this->Quiet);
   this->CTest->SetCTestConfigurationFromCMakeVariable(
     this->Makefile, "HGUpdateOptions", "CTEST_HG_UPDATE_OPTIONS", this->Quiet);
diff --git a/Source/CTest/cmCTestVC.cxx b/Source/CTest/cmCTestVC.cxx
index 374e73f..eea41cf 100644
--- a/Source/CTest/cmCTestVC.cxx
+++ b/Source/CTest/cmCTestVC.cxx
@@ -141,6 +141,15 @@ void cmCTestVC::CleanupImpl()
 bool cmCTestVC::Update()
 {
   bool result = true;
+
+  // Use the explicitly specified version.
+  std::string versionOverride =
+    this->CTest->GetCTestConfiguration("UpdateVersionOverride");
+  if (!versionOverride.empty()) {
+    this->SetNewRevision(versionOverride);
+    return true;
+  }
+
   // if update version only is on then do not actually update,
   // just note the current version and finish
   if (!cmSystemTools::IsOn(
@@ -166,6 +175,11 @@ bool cmCTestVC::NoteNewRevision()
   return true;
 }
 
+void cmCTestVC::SetNewRevision(std::string const& /*unused*/)
+{
+  // We do nothing by default.
+}
+
 bool cmCTestVC::UpdateImpl()
 {
   cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
diff --git a/Source/CTest/cmCTestVC.h b/Source/CTest/cmCTestVC.h
index 69a3bf0..2a4765d 100644
--- a/Source/CTest/cmCTestVC.h
+++ b/Source/CTest/cmCTestVC.h
@@ -70,6 +70,7 @@ protected:
   virtual bool NoteOldRevision();
   virtual bool UpdateImpl();
   virtual bool NoteNewRevision();
+  virtual void SetNewRevision(std::string const& revision);
   virtual bool WriteXMLUpdates(cmXMLWriter& xml);
 
 #if defined(__SUNPRO_CC) && __SUNPRO_CC <= 0x510
diff --git a/Tests/RunCMake/ctest_update/RunCMakeTest.cmake b/Tests/RunCMake/ctest_update/RunCMakeTest.cmake
index f7a31e5..f8d7665 100644
--- a/Tests/RunCMake/ctest_update/RunCMakeTest.cmake
+++ b/Tests/RunCMake/ctest_update/RunCMakeTest.cmake
@@ -15,3 +15,11 @@ function(run_UpdateChangeId)
   run_ctest(UpdateChangeId)
 endfunction()
 run_UpdateChangeId()
+
+function(run_UpdateVersionOverride)
+  set(CASE_TEST_PREFIX_CODE [[
+    set(CTEST_UPDATE_VERSION_OVERRIDE "qwertyuiop")
+  ]])
+  run_ctest(UpdateVersionOverride)
+endfunction()
+run_UpdateVersionOverride()
diff --git a/Tests/RunCMake/ctest_update/UpdateActualVersion-check.cmake b/Tests/RunCMake/ctest_update/UpdateActualVersion-check.cmake
new file mode 100644
index 0000000..12bd5a0
--- /dev/null
+++ b/Tests/RunCMake/ctest_update/UpdateActualVersion-check.cmake
@@ -0,0 +1,12 @@
+file(GLOB update_xml_file "${RunCMake_TEST_BINARY_DIR}/Testing/*/Update.xml")
+if(update_xml_file)
+  file(READ "${update_xml_file}" update_xml LIMIT 4096)
+  if(NOT update_xml MATCHES "qwertyuiop")
+    string(REPLACE "\n" "\n  " update_xml "  ${update_xml}")
+    set(RunCMake_TEST_FAILED
+      "Did not find 'qwertyuiop' in Update.xml:\n${update_xml}"
+      )
+  endif()
+else()
+  set(RunCMake_TEST_FAILED "Update.xml not found")
+endif()
-- 
cgit v0.12