| 
					
				 | 
			
			
				@@ -2,16 +2,250 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				    file Copyright.txt or https://cmake.org/licensing for details.  */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include "cmCTestUpdateCommand.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#include <chrono> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#include <sstream> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#include <string> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include <utility> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#include <vector> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include <cm/memory> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#include "cmCLocaleEnvironmentScope.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include "cmCTest.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#include "cmCTestBZR.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#include "cmCTestCVS.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#include "cmCTestGIT.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include "cmCTestGenericHandler.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-#include "cmCTestUpdateHandler.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#include "cmCTestHG.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#include "cmCTestP4.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#include "cmCTestSVN.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#include "cmCTestVC.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include "cmExecutionStatus.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#include "cmGeneratedFileStream.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include "cmMakefile.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#include "cmStringAlgorithms.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include "cmSystemTools.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#include "cmVersion.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#include "cmXMLWriter.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/** \class cmCTestUpdateHandler 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * \brief A class that handles ctest -S invocations 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+class cmCTestUpdateHandler : public cmCTestGenericHandler 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+public: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  using Superclass = cmCTestGenericHandler; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /* 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   * The main entry point for this class 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  int ProcessHandler() override; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  cmCTestUpdateHandler(cmCTest* ctest); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  enum 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    e_UNKNOWN = 0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    e_CVS, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    e_SVN, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    e_BZR, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    e_GIT, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    e_HG, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    e_P4, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    e_LAST 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+private: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  // Some structures needed for update 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  struct StringPair : public std::pair<std::string, std::string> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  struct UpdateFiles : public std::vector<StringPair> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  // Determine the type of version control 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  int DetermineType(const char* cmd, const char* type); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  // The VCS command to update the working tree. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  std::string UpdateCommand; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  std::string SourceDirectory; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  int UpdateType = e_CVS; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  int DetectVCS(const std::string& dir); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  bool SelectVCS(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  friend class cmCTestUpdateCommand; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static const char* cmCTestUpdateHandlerUpdateStrings[] = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  "Unknown", "CVS", "SVN", "BZR", "GIT", "HG", "P4" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static const char* cmCTestUpdateHandlerUpdateToString(int type) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (type < cmCTestUpdateHandler::e_UNKNOWN || 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      type >= cmCTestUpdateHandler::e_LAST) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return cmCTestUpdateHandlerUpdateStrings[cmCTestUpdateHandler::e_UNKNOWN]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  return cmCTestUpdateHandlerUpdateStrings[type]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+cmCTestUpdateHandler::cmCTestUpdateHandler(cmCTest* ctest) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  : Superclass(ctest) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+int cmCTestUpdateHandler::DetermineType(const char* cmd, const char* type) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  cmCTestOptionalLog(this->CTest, DEBUG, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                     "Determine update type from command: " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                       << cmd << " and type: " << type << std::endl, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                     this->Quiet); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (type && *type) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    cmCTestOptionalLog(this->CTest, DEBUG, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                       "Type specified: " << type << std::endl, this->Quiet); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    std::string stype = cmSystemTools::LowerCase(type); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (stype.find("cvs") != std::string::npos) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return cmCTestUpdateHandler::e_CVS; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (stype.find("svn") != std::string::npos) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return cmCTestUpdateHandler::e_SVN; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (stype.find("bzr") != std::string::npos) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return cmCTestUpdateHandler::e_BZR; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (stype.find("git") != std::string::npos) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return cmCTestUpdateHandler::e_GIT; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (stype.find("hg") != std::string::npos) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return cmCTestUpdateHandler::e_HG; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (stype.find("p4") != std::string::npos) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return cmCTestUpdateHandler::e_P4; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    cmCTestOptionalLog( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this->CTest, DEBUG, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      "Type not specified, check command: " << cmd << std::endl, this->Quiet); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    std::string stype = cmSystemTools::LowerCase(cmd); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (stype.find("cvs") != std::string::npos) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return cmCTestUpdateHandler::e_CVS; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (stype.find("svn") != std::string::npos) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return cmCTestUpdateHandler::e_SVN; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (stype.find("bzr") != std::string::npos) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return cmCTestUpdateHandler::e_BZR; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (stype.find("git") != std::string::npos) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return cmCTestUpdateHandler::e_GIT; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (stype.find("hg") != std::string::npos) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return cmCTestUpdateHandler::e_HG; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (stype.find("p4") != std::string::npos) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return cmCTestUpdateHandler::e_P4; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  return cmCTestUpdateHandler::e_UNKNOWN; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+int cmCTestUpdateHandler::DetectVCS(const std::string& dir) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  std::string sourceDirectory = dir; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  cmCTestOptionalLog(this->CTest, DEBUG, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                     "Check directory: " << sourceDirectory << std::endl, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                     this->Quiet); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  sourceDirectory += "/.svn"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (cmSystemTools::FileExists(sourceDirectory)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return cmCTestUpdateHandler::e_SVN; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  sourceDirectory = cmStrCat(dir, "/CVS"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (cmSystemTools::FileExists(sourceDirectory)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return cmCTestUpdateHandler::e_CVS; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  sourceDirectory = cmStrCat(dir, "/.bzr"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (cmSystemTools::FileExists(sourceDirectory)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return cmCTestUpdateHandler::e_BZR; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  sourceDirectory = cmStrCat(dir, "/.git"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (cmSystemTools::FileExists(sourceDirectory)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return cmCTestUpdateHandler::e_GIT; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  sourceDirectory = cmStrCat(dir, "/.hg"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (cmSystemTools::FileExists(sourceDirectory)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return cmCTestUpdateHandler::e_HG; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  sourceDirectory = cmStrCat(dir, "/.p4"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (cmSystemTools::FileExists(sourceDirectory)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return cmCTestUpdateHandler::e_P4; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  sourceDirectory = cmStrCat(dir, "/.p4config"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (cmSystemTools::FileExists(sourceDirectory)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return cmCTestUpdateHandler::e_P4; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  return cmCTestUpdateHandler::e_UNKNOWN; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+bool cmCTestUpdateHandler::SelectVCS() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  // Get update command 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  this->UpdateCommand = this->CTest->GetCTestConfiguration("UpdateCommand"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  // Detect the VCS managing the source tree. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  this->UpdateType = this->DetectVCS(this->SourceDirectory); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (this->UpdateType == e_UNKNOWN) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // The source tree does not have a recognized VCS.  Check the 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // configuration value or command name. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this->UpdateType = this->DetermineType( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this->UpdateCommand.c_str(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this->CTest->GetCTestConfiguration("UpdateType").c_str()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  // If no update command was specified, lookup one for this VCS tool. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (this->UpdateCommand.empty()) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const char* key = nullptr; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    switch (this->UpdateType) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      case e_CVS: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        key = "CVSCommand"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      case e_SVN: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        key = "SVNCommand"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      case e_BZR: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        key = "BZRCommand"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      case e_GIT: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        key = "GITCommand"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      case e_HG: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        key = "HGCommand"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      case e_P4: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        key = "P4Command"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      default: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (key) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this->UpdateCommand = this->CTest->GetCTestConfiguration(key); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (this->UpdateCommand.empty()) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      std::ostringstream e; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      e << "Cannot find UpdateCommand "; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (key) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        e << "or " << key; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      e << " configuration key."; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      cmCTestLog(this->CTest, ERROR_MESSAGE, e.str() << std::endl); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  return true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 std::unique_ptr<cmCTestGenericHandler> cmCTestUpdateCommand::InitializeHandler( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   HandlerArguments& args, cmExecutionStatus& status) const 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -84,6 +318,163 @@ std::unique_ptr<cmCTestGenericHandler> cmCTestUpdateCommand::InitializeHandler( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   return std::unique_ptr<cmCTestGenericHandler>(std::move(handler)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// clearly it would be nice if this were broken up into a few smaller 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// functions and commented... 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+int cmCTestUpdateHandler::ProcessHandler() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  // Make sure VCS tool messages are in English so we can parse them. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  cmCLocaleEnvironmentScope fixLocale; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  static_cast<void>(fixLocale); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  // Get source dir 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (this->SourceDirectory.empty()) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    cmCTestLog(this->CTest, ERROR_MESSAGE, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+               "Cannot find SourceDirectory  key in the DartConfiguration.tcl" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                 << std::endl); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  cmGeneratedFileStream ofs; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (!this->CTest->GetShowOnly()) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this->StartLogFile("Update", ofs); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                     "   Updating the repository: " << this->SourceDirectory 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                                    << std::endl, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                     this->Quiet); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (!this->SelectVCS()) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                     "   Use " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                       << cmCTestUpdateHandlerUpdateToString(this->UpdateType) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                       << " repository type" << std::endl; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                     , this->Quiet); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  // Create an object to interact with the VCS tool. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  std::unique_ptr<cmCTestVC> vc; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  switch (this->UpdateType) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    case e_CVS: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      vc = cm::make_unique<cmCTestCVS>(this->CTest, ofs); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    case e_SVN: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      vc = cm::make_unique<cmCTestSVN>(this->CTest, ofs); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    case e_BZR: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      vc = cm::make_unique<cmCTestBZR>(this->CTest, ofs); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    case e_GIT: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      vc = cm::make_unique<cmCTestGIT>(this->CTest, ofs); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    case e_HG: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      vc = cm::make_unique<cmCTestHG>(this->CTest, ofs); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    case e_P4: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      vc = cm::make_unique<cmCTestP4>(this->CTest, ofs); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    default: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      vc = cm::make_unique<cmCTestVC>(this->CTest, ofs); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  vc->SetCommandLineTool(this->UpdateCommand); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  vc->SetSourceDirectory(this->SourceDirectory); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  // Cleanup the working tree. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  vc->Cleanup(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  // 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  // Now update repository and remember what files were updated 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  // 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  cmGeneratedFileStream os; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (!this->StartResultingXML(cmCTest::PartUpdate, "Update", os)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    cmCTestLog(this->CTest, ERROR_MESSAGE, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+               "Cannot open log file" << std::endl); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  std::string start_time = this->CTest->CurrentTime(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  auto start_time_time = std::chrono::system_clock::now(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  auto elapsed_time_start = std::chrono::steady_clock::now(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  bool updated = vc->Update(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  std::string buildname = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    cmCTest::SafeBuildIdField(this->CTest->GetCTestConfiguration("BuildName")); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  cmXMLWriter xml(os); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  xml.StartDocument(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  xml.StartElement("Update"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  xml.Attribute("mode", "Client"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  xml.Attribute("Generator", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                std::string("ctest-") + cmVersion::GetCMakeVersion()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  xml.Element("Site", this->CTest->GetCTestConfiguration("Site")); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  xml.Element("BuildName", buildname); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  xml.Element("BuildStamp", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              this->CTest->GetCurrentTag() + "-" + 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                this->CTest->GetTestGroupString()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  xml.Element("StartDateTime", start_time); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  xml.Element("StartTime", start_time_time); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  xml.Element("UpdateCommand", vc->GetUpdateCommandLine()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  xml.Element("UpdateType", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              cmCTestUpdateHandlerUpdateToString(this->UpdateType)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  std::string changeId = this->CTest->GetCTestConfiguration("ChangeId"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (!changeId.empty()) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    xml.Element("ChangeId", changeId); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  bool loadedMods = vc->WriteXML(xml); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  int localModifications = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  int numUpdated = vc->GetPathCount(cmCTestVC::PathUpdated); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (numUpdated) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                       "   Found " << numUpdated << " updated files\n", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                       this->Quiet); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (int numModified = vc->GetPathCount(cmCTestVC::PathModified)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    cmCTestOptionalLog( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this->CTest, HANDLER_OUTPUT, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      "   Found " << numModified << " locally modified files\n", this->Quiet); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    localModifications += numModified; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (int numConflicting = vc->GetPathCount(cmCTestVC::PathConflicting)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                       "   Found " << numConflicting << " conflicting files\n", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                       this->Quiet); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    localModifications += numConflicting; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  cmCTestOptionalLog(this->CTest, DEBUG, "End" << std::endl, this->Quiet); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  std::string end_time = this->CTest->CurrentTime(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  xml.Element("EndDateTime", end_time); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  xml.Element("EndTime", std::chrono::system_clock::now()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  xml.Element("ElapsedMinutes", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              std::chrono::duration_cast<std::chrono::minutes>( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                std::chrono::steady_clock::now() - elapsed_time_start) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                .count()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  xml.StartElement("UpdateReturnStatus"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (localModifications) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    xml.Content("Update error: " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                "There are modified or conflicting files in the repository"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    cmCTestLog(this->CTest, WARNING, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+               "   There are modified or conflicting files in the repository" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                 << std::endl); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (!updated) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    xml.Content("Update command failed:\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    xml.Content(vc->GetUpdateCommandLine()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    cmCTestLog(this->CTest, HANDLER_OUTPUT, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+               "   Update command failed: " << vc->GetUpdateCommandLine() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                            << "\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  xml.EndElement(); // UpdateReturnStatus 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  xml.EndElement(); // Update 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  xml.EndDocument(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  return updated && loadedMods ? numUpdated : -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 bool cmCTestUpdateCommand::InitialPass(std::vector<std::string> const& args, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                        cmExecutionStatus& status) const 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 |