summaryrefslogtreecommitdiff
path: root/Source/CTest/cmCTestVC.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'Source/CTest/cmCTestVC.cxx')
-rw-r--r--Source/CTest/cmCTestVC.cxx241
1 files changed, 241 insertions, 0 deletions
diff --git a/Source/CTest/cmCTestVC.cxx b/Source/CTest/cmCTestVC.cxx
new file mode 100644
index 000000000..fbee2272e
--- /dev/null
+++ b/Source/CTest/cmCTestVC.cxx
@@ -0,0 +1,241 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2009 Kitware, Inc.
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#include "cmCTestVC.h"
+
+#include "cmCTest.h"
+#include "cmSystemTools.h"
+#include "cmXMLSafe.h"
+
+#include <cmsys/Process.h>
+
+//----------------------------------------------------------------------------
+cmCTestVC::cmCTestVC(cmCTest* ct, std::ostream& log): CTest(ct), Log(log)
+{
+ this->PathCount[PathUpdated] = 0;
+ this->PathCount[PathModified] = 0;
+ this->PathCount[PathConflicting] = 0;
+ this->Unknown.Date = "Unknown";
+ this->Unknown.Author = "Unknown";
+ this->Unknown.Rev = "Unknown";
+}
+
+//----------------------------------------------------------------------------
+cmCTestVC::~cmCTestVC()
+{
+}
+
+//----------------------------------------------------------------------------
+void cmCTestVC::SetCommandLineTool(std::string const& tool)
+{
+ this->CommandLineTool = tool;
+}
+
+//----------------------------------------------------------------------------
+void cmCTestVC::SetSourceDirectory(std::string const& dir)
+{
+ this->SourceDirectory = dir;
+}
+
+//----------------------------------------------------------------------------
+bool cmCTestVC::InitialCheckout(const char* command)
+{
+ cmCTestLog(this->CTest, HANDLER_OUTPUT,
+ " First perform the initial checkout: " << command << "\n");
+
+ // Make the parent directory in which to perform the checkout.
+ std::string parent = cmSystemTools::GetFilenamePath(this->SourceDirectory);
+ cmCTestLog(this->CTest, HANDLER_OUTPUT,
+ " Perform checkout in directory: " << parent << "\n");
+ if(!cmSystemTools::MakeDirectory(parent.c_str()))
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "Cannot create directory: " << parent << std::endl);
+ return false;
+ }
+
+ // Construct the initial checkout command line.
+ std::vector<cmStdString> args = cmSystemTools::ParseArguments(command);
+ std::vector<char const*> vc_co;
+ for(std::vector<cmStdString>::const_iterator ai = args.begin();
+ ai != args.end(); ++ai)
+ {
+ vc_co.push_back(ai->c_str());
+ }
+ vc_co.push_back(0);
+
+ // Run the initial checkout command and log its output.
+ this->Log << "--- Begin Initial Checkout ---\n";
+ OutputLogger out(this->Log, "co-out> ");
+ OutputLogger err(this->Log, "co-err> ");
+ bool result = this->RunChild(&vc_co[0], &out, &err, parent.c_str());
+ this->Log << "--- End Initial Checkout ---\n";
+ if(!result)
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "Initial checkout failed!" << std::endl);
+ }
+ return result;
+}
+
+//----------------------------------------------------------------------------
+bool cmCTestVC::RunChild(char const* const* cmd, OutputParser* out,
+ OutputParser* err, const char* workDir)
+{
+ this->Log << this->ComputeCommandLine(cmd) << "\n";
+
+ cmsysProcess* cp = cmsysProcess_New();
+ cmsysProcess_SetCommand(cp, cmd);
+ workDir = workDir? workDir : this->SourceDirectory.c_str();
+ cmsysProcess_SetWorkingDirectory(cp, workDir);
+ this->RunProcess(cp, out, err);
+ int result = cmsysProcess_GetExitValue(cp);
+ cmsysProcess_Delete(cp);
+ return result == 0;
+}
+
+//----------------------------------------------------------------------------
+std::string cmCTestVC::ComputeCommandLine(char const* const* cmd)
+{
+ cmOStringStream line;
+ const char* sep = "";
+ for(const char* const* arg = cmd; *arg; ++arg)
+ {
+ line << sep << "\"" << *arg << "\"";
+ sep = " ";
+ }
+ return line.str();
+}
+
+//----------------------------------------------------------------------------
+bool cmCTestVC::RunUpdateCommand(char const* const* cmd,
+ OutputParser* out, OutputParser* err)
+{
+ // Report the command line.
+ this->UpdateCommandLine = this->ComputeCommandLine(cmd);
+ if(this->CTest->GetShowOnly())
+ {
+ this->Log << this->UpdateCommandLine << "\n";
+ return true;
+ }
+
+ // Run the command.
+ return this->RunChild(cmd, out, err);
+}
+
+//----------------------------------------------------------------------------
+std::string cmCTestVC::GetNightlyTime()
+{
+ // Get the nightly start time corresponding to the current dau.
+ struct tm* t = this->CTest->GetNightlyTime(
+ this->CTest->GetCTestConfiguration("NightlyStartTime"),
+ this->CTest->GetTomorrowTag());
+ char current_time[1024];
+ sprintf(current_time, "%04d-%02d-%02d %02d:%02d:%02d",
+ t->tm_year + 1900,
+ t->tm_mon + 1,
+ t->tm_mday,
+ t->tm_hour,
+ t->tm_min,
+ t->tm_sec);
+ return std::string(current_time);
+}
+
+//----------------------------------------------------------------------------
+void cmCTestVC::Cleanup()
+{
+ this->Log << "--- Begin Cleanup ---\n";
+ this->CleanupImpl();
+ this->Log << "--- End Cleanup ---\n";
+}
+
+//----------------------------------------------------------------------------
+void cmCTestVC::CleanupImpl()
+{
+ // We do no cleanup by default.
+}
+
+//----------------------------------------------------------------------------
+bool cmCTestVC::Update()
+{
+ this->NoteOldRevision();
+ this->Log << "--- Begin Update ---\n";
+ bool result = this->UpdateImpl();
+ this->Log << "--- End Update ---\n";
+ this->NoteNewRevision();
+ return result;
+}
+
+//----------------------------------------------------------------------------
+void cmCTestVC::NoteOldRevision()
+{
+ // We do nothing by default.
+}
+
+//----------------------------------------------------------------------------
+void cmCTestVC::NoteNewRevision()
+{
+ // We do nothing by default.
+}
+
+//----------------------------------------------------------------------------
+bool cmCTestVC::UpdateImpl()
+{
+ cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ "* Unknown VCS tool, not updating!" << std::endl);
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmCTestVC::WriteXML(std::ostream& xml)
+{
+ this->Log << "--- Begin Revisions ---\n";
+ bool result = this->WriteXMLUpdates(xml);
+ this->Log << "--- End Revisions ---\n";
+ return result;
+}
+
+//----------------------------------------------------------------------------
+bool cmCTestVC::WriteXMLUpdates(std::ostream&)
+{
+ cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ "* CTest cannot extract updates for this VCS tool.\n");
+ return true;
+}
+
+//----------------------------------------------------------------------------
+void cmCTestVC::WriteXMLEntry(std::ostream& xml,
+ std::string const& path,
+ std::string const& name,
+ std::string const& full,
+ File const& f)
+{
+ static const char* desc[3] = { "Updated", "Modified", "Conflicting"};
+ Revision const& rev = f.Rev? *f.Rev : this->Unknown;
+ std::string prior = f.PriorRev? f.PriorRev->Rev : std::string("Unknown");
+ xml << "\t\t<" << desc[f.Status] << ">\n"
+ << "\t\t\t<File>" << cmXMLSafe(name) << "</File>\n"
+ << "\t\t\t<Directory>" << cmXMLSafe(path) << "</Directory>\n"
+ << "\t\t\t<FullName>" << cmXMLSafe(full) << "</FullName>\n"
+ << "\t\t\t<CheckinDate>" << cmXMLSafe(rev.Date) << "</CheckinDate>\n"
+ << "\t\t\t<Author>" << cmXMLSafe(rev.Author) << "</Author>\n"
+ << "\t\t\t<Email>" << cmXMLSafe(rev.EMail) << "</Email>\n"
+ << "\t\t\t<Committer>" << cmXMLSafe(rev.Committer) << "</Committer>\n"
+ << "\t\t\t<CommitterEmail>" << cmXMLSafe(rev.CommitterEMail)
+ << "</CommitterEmail>\n"
+ << "\t\t\t<CommitDate>" << cmXMLSafe(rev.CommitDate)
+ << "</CommitDate>\n"
+ << "\t\t\t<Log>" << cmXMLSafe(rev.Log) << "</Log>\n"
+ << "\t\t\t<Revision>" << cmXMLSafe(rev.Rev) << "</Revision>\n"
+ << "\t\t\t<PriorRevision>" << cmXMLSafe(prior) << "</PriorRevision>\n"
+ << "\t\t</" << desc[f.Status] << ">\n";
+ ++this->PathCount[f.Status];
+}