summaryrefslogtreecommitdiffstats
path: root/Source/CTest/cmCTestUpdateHandler.cxx
diff options
context:
space:
mode:
authorKen Martin <ken.martin@kitware.com>2004-09-07 13:17:15 (GMT)
committerKen Martin <ken.martin@kitware.com>2004-09-07 13:17:15 (GMT)
commit05d985c08277350c3a1ca5ea6023ac397cf9bf1b (patch)
tree3de2553519af7ff8543538831f2f7017cd44efe7 /Source/CTest/cmCTestUpdateHandler.cxx
parent9d6ea59a69542b008d296bc4ce42d975f4020d53 (diff)
downloadCMake-05d985c08277350c3a1ca5ea6023ac397cf9bf1b.zip
CMake-05d985c08277350c3a1ca5ea6023ac397cf9bf1b.tar.gz
CMake-05d985c08277350c3a1ca5ea6023ac397cf9bf1b.tar.bz2
some bug fixes for my recent checkins and some more cleanup
Diffstat (limited to 'Source/CTest/cmCTestUpdateHandler.cxx')
-rw-r--r--Source/CTest/cmCTestUpdateHandler.cxx407
1 files changed, 407 insertions, 0 deletions
diff --git a/Source/CTest/cmCTestUpdateHandler.cxx b/Source/CTest/cmCTestUpdateHandler.cxx
new file mode 100644
index 0000000..139f7d2
--- /dev/null
+++ b/Source/CTest/cmCTestUpdateHandler.cxx
@@ -0,0 +1,407 @@
+/*=========================================================================
+
+ Program: CMake - Cross-Platform Makefile Generator
+ Module: $RCSfile$
+ Language: C++
+ Date: $Date$
+ Version: $Revision$
+
+ Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
+ See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even
+ the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE. See the above copyright notices for more information.
+
+=========================================================================*/
+
+#include "cmCTestUpdateHandler.h"
+
+#include "cmCTest.h"
+#include "cmake.h"
+#include "cmMakefile.h"
+#include "cmLocalGenerator.h"
+#include "cmGlobalGenerator.h"
+
+//#include <cmsys/RegularExpression.hxx>
+#include <cmsys/Process.h>
+
+// used for sleep
+#ifdef _WIN32
+#include "windows.h"
+#endif
+
+#include <stdlib.h>
+#include <time.h>
+#include <math.h>
+#include <float.h>
+
+
+//----------------------------------------------------------------------
+cmCTestUpdateHandler::cmCTestUpdateHandler()
+{
+ m_Verbose = false;
+ m_CTest = 0;
+}
+
+
+//----------------------------------------------------------------------
+//clearly it would be nice if this were broken up into a few smaller
+//functions and commented...
+int cmCTestUpdateHandler::UpdateDirectory(cmCTest *ctest_inst)
+{
+ m_CTest = ctest_inst;
+
+ int count = 0;
+ std::string::size_type cc, kk;
+ std::string cvsCommand = m_CTest->GetDartConfiguration("CVSCommand");
+ if ( cvsCommand.size() == 0 )
+ {
+ std::cerr << "Cannot find CVSCommand key in the DartConfiguration.tcl" << std::endl;
+ return -1;
+ }
+ std::string cvsOptions = m_CTest->GetDartConfiguration("CVSUpdateOptions");
+ if ( cvsOptions.size() == 0 )
+ {
+ std::cerr << "Cannot find CVSUpdateOptions key in the DartConfiguration.tcl" << std::endl;
+ return -1;
+ }
+
+ std::string sourceDirectory = m_CTest->GetDartConfiguration("SourceDirectory");
+ if ( sourceDirectory.size() == 0 )
+ {
+ std::cerr << "Cannot find SourceDirectory key in the DartConfiguration.tcl" << std::endl;
+ return -1;
+ }
+
+ std::string extra_update_opts;
+ if ( m_CTest->GetTestModel() == cmCTest::NIGHTLY )
+ {
+ struct tm* t = cmCTest::GetNightlyTime(m_CTest->GetDartConfiguration("NightlyStartTime"),
+ m_Verbose, m_CTest->GetTomorrowTag());
+ char current_time[1024];
+ sprintf(current_time, "%04d-%02d-%02d %02d:%02d:%02d UTC",
+ t->tm_year + 1900,
+ t->tm_mon + 1,
+ t->tm_mday,
+ t->tm_hour,
+ t->tm_min,
+ t->tm_sec);
+ std::string today_update_date = current_time;
+
+ extra_update_opts += "-D \"" + today_update_date +"\"";
+ //std::cout << "Update: " << extra_update_opts << std::endl;
+ }
+
+ std::string command = cvsCommand + " -z3 update " + cvsOptions +
+ " " + extra_update_opts;
+ std::ofstream os;
+ if ( !m_CTest->OpenOutputFile(m_CTest->GetCurrentTag(), "Update.xml", os) )
+ {
+ std::cerr << "Cannot open log file" << std::endl;
+ }
+ std::string start_time = m_CTest->CurrentTime();
+ double elapsed_time_start = cmSystemTools::GetTime();
+
+ std::string goutput;
+ int retVal = 0;
+ bool res = true;
+ std::ofstream ofs;
+ if ( !m_CTest->GetShowOnly() )
+ {
+ res = cmSystemTools::RunSingleCommand(command.c_str(), &goutput,
+ &retVal, sourceDirectory.c_str(),
+ m_Verbose, 0 /*m_TimeOut*/);
+ if ( m_CTest->OpenOutputFile("Temporary", "LastUpdate.log", ofs) )
+ {
+ ofs << goutput << std::endl;;
+ }
+ }
+ else
+ {
+ std::cout << "Update with command: " << command << std::endl;
+ }
+
+ os << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+ << "<Update mode=\"Client\" Generator=\"ctest-" << CMake_VERSION_FULL << "\">\n"
+ << "\t<Site>" << m_CTest->GetDartConfiguration("Site") << "</Site>\n"
+ << "\t<BuildName>" << m_CTest->GetDartConfiguration("BuildName")
+ << "</BuildName>\n"
+ << "\t<BuildStamp>" << m_CTest->GetCurrentTag() << "-"
+ << m_CTest->GetTestModelString() << "</BuildStamp>" << std::endl;
+ os << "\t<StartDateTime>" << start_time << "</StartDateTime>\n"
+ << "\t<UpdateCommand>" << m_CTest->MakeXMLSafe(command)
+ << "</UpdateCommand>\n"
+ << "\t<UpdateReturnStatus>";
+ int failed = 0;
+ if ( !res || retVal )
+ {
+ os << "Update error: ";
+ os << m_CTest->MakeXMLSafe(goutput);
+ std::cerr << "Update with command: " << command << " failed" << std::endl;
+ failed = 1;
+ }
+ os << "</UpdateReturnStatus>" << std::endl;
+ if ( !failed )
+ {
+
+ std::vector<cmStdString> lines;
+ cmSystemTools::Split(goutput.c_str(), lines);
+ std::cout << "Updated; gathering version information" << std::endl;
+ cmsys::RegularExpression date_author("^date: +([^;]+); +author: +([^;]+); +state: +[^;]+;");
+ cmsys::RegularExpression revision("^revision +([^ ]*) *$");
+ cmsys::RegularExpression end_of_file("^=============================================================================$");
+ cmsys::RegularExpression end_of_comment("^----------------------------$");
+ std::string current_path = "<no-path>";
+ bool first_file = true;
+
+ cmCTestUpdateHandler::AuthorsToUpdatesMap authors_files_map;
+ int num_updated = 0;
+ int num_modified = 0;
+ int num_conflicting = 0;
+ for ( cc= 0 ; cc < lines.size(); cc ++ )
+ {
+ const char* line = lines[cc].c_str();
+ char mod = line[0];
+ if ( line[1] == ' ' && mod != '?' )
+ {
+ if ( mod != 'M' && mod != 'C' )
+ {
+ count ++;
+ }
+ const char* file = line + 2;
+ //std::cout << "Line" << cc << ": " << mod << " - " << file << std::endl;
+ std::string logcommand = cvsCommand + " -z3 log -N " + file;
+ //std::cout << "Do log: " << logcommand << std::endl;
+ std::string output;
+ res = cmSystemTools::RunSingleCommand(logcommand.c_str(), &output,
+ &retVal, sourceDirectory.c_str(),
+ m_Verbose, 0 /*m_TimeOut*/);
+ if ( ofs )
+ {
+ ofs << output << std::endl;
+ }
+ if ( res && retVal == 0)
+ {
+ //std::cout << output << std::endl;
+ std::vector<cmStdString> ulines;
+ cmSystemTools::Split(output.c_str(), ulines);
+ std::string::size_type sline = 0;
+ std::string srevision1 = "Unknown";
+ std::string sdate1 = "Unknown";
+ std::string sauthor1 = "Unknown";
+ std::string semail1 = "Unknown";
+ std::string comment1 = "";
+ std::string srevision2 = "Unknown";
+ std::string sdate2 = "Unknown";
+ std::string sauthor2 = "Unknown";
+ std::string comment2 = "";
+ std::string semail2 = "Unknown";
+ bool have_first = false;
+ bool have_second = false;
+ for ( kk = 0; kk < ulines.size(); kk ++ )
+ {
+ const char* clp = ulines[kk].c_str();
+ if ( !have_second && !sline && revision.find(clp) )
+ {
+ if ( !have_first )
+ {
+ srevision1 = revision.match(1);
+ }
+ else
+ {
+ srevision2 = revision.match(1);
+ }
+ }
+ else if ( !have_second && !sline && date_author.find(clp) )
+ {
+ sline = kk + 1;
+ if ( !have_first )
+ {
+ sdate1 = date_author.match(1);
+ sauthor1 = date_author.match(2);
+ }
+ else
+ {
+ sdate2 = date_author.match(1);
+ sauthor2 = date_author.match(2);
+ }
+ }
+ else if ( sline && end_of_comment.find(clp) || end_of_file.find(clp))
+ {
+ if ( !have_first )
+ {
+ have_first = true;
+ }
+ else if ( !have_second )
+ {
+ have_second = true;
+ }
+ sline = 0;
+ }
+ else if ( sline )
+ {
+ if ( !have_first )
+ {
+ comment1 += clp;
+ comment1 += "\n";
+ }
+ else
+ {
+ comment2 += clp;
+ comment2 += "\n";
+ }
+ }
+ }
+ if ( mod == 'M' )
+ {
+ comment1 = "Locally modified file\n";
+ }
+ if ( mod == 'C' )
+ {
+ comment1 = "Conflict while updating\n";
+ }
+ std::string path = cmSystemTools::GetFilenamePath(file);
+ std::string fname = cmSystemTools::GetFilenameName(file);
+ if ( path != current_path )
+ {
+ if ( !first_file )
+ {
+ os << "\t</Directory>" << std::endl;
+ }
+ else
+ {
+ first_file = false;
+ }
+ os << "\t<Directory>\n"
+ << "\t\t<Name>" << path << "</Name>" << std::endl;
+ }
+ if ( mod == 'C' )
+ {
+ num_conflicting ++;
+ os << "\t<Conflicting>" << std::endl;
+ }
+ else if ( mod == 'M' )
+ {
+ num_modified ++;
+ os << "\t<Modified>" << std::endl;
+ }
+ else
+ {
+ num_updated ++;
+ os << "\t<Updated>" << std::endl;
+ }
+ if ( srevision2 == "Unknown" )
+ {
+ srevision2 = srevision1;
+ }
+ os << "\t\t<File Directory=\"" << path << "\">" << fname
+ << "</File>\n"
+ << "\t\t<Directory>" << path << "</Directory>\n"
+ << "\t\t<FullName>" << file << "</FullName>\n"
+ << "\t\t<CheckinDate>" << sdate1 << "</CheckinDate>\n"
+ << "\t\t<Author>" << sauthor1 << "</Author>\n"
+ << "\t\t<Email>" << semail1 << "</Email>\n"
+ << "\t\t<Log>" << cmCTest::MakeXMLSafe(comment1) << "</Log>\n"
+ << "\t\t<Revision>" << srevision1 << "</Revision>\n"
+ << "\t\t<PriorRevision>" << srevision2 << "</PriorRevision>"
+ << std::endl;
+ if ( srevision2 != srevision1 )
+ {
+ os
+ << "\t\t<Revisions>\n"
+ << "\t\t\t<Revision>" << srevision1 << "</Revision>\n"
+ << "\t\t\t<PreviousRevision>" << srevision2 << "</PreviousRevision>\n"
+ << "\t\t\t<Author>" << sauthor1<< "</Author>\n"
+ << "\t\t\t<Date>" << sdate1 << "</Date>\n"
+ << "\t\t\t<Comment>" << cmCTest::MakeXMLSafe(comment1) << "</Comment>\n"
+ << "\t\t\t<Email>" << semail1 << "</Email>\n"
+ << "\t\t</Revisions>\n"
+ << "\t\t<Revisions>\n"
+ << "\t\t\t<Revision>" << srevision2 << "</Revision>\n"
+ << "\t\t\t<PreviousRevision>" << srevision2 << "</PreviousRevision>\n"
+ << "\t\t\t<Author>" << sauthor2<< "</Author>\n"
+ << "\t\t\t<Date>" << sdate2 << "</Date>\n"
+ << "\t\t\t<Comment>" << cmCTest::MakeXMLSafe(comment2) << "</Comment>\n"
+ << "\t\t\t<Email>" << semail2 << "</Email>\n"
+ << "\t\t</Revisions>" << std::endl;
+ }
+ if ( mod == 'C' )
+ {
+ os << "\t</Conflicting>" << std::endl;
+ }
+ else if ( mod == 'M' )
+ {
+ os << "\t</Modified>" << std::endl;
+ }
+ else
+ {
+ os << "\t</Updated>" << std::endl;
+ }
+ cmCTestUpdateHandler::UpdateFiles *u = &authors_files_map[sauthor1];
+ cmCTestUpdateHandler::StringPair p;
+ p.first = path;
+ p.second = fname;
+ u->push_back(p);
+
+ current_path = path;
+ }
+ }
+ }
+ if ( num_updated )
+ {
+ std::cout << "Found " << num_updated << " updated files" << std::endl;
+ }
+ if ( num_modified )
+ {
+ std::cout << "Found " << num_modified << " locally modified files"
+ << std::endl;
+ }
+ if ( num_conflicting )
+ {
+ std::cout << "Found " << num_conflicting << " conflicting files"
+ << std::endl;
+ }
+ if ( !first_file )
+ {
+ os << "\t</Directory>" << std::endl;
+ }
+
+ cmCTestUpdateHandler::AuthorsToUpdatesMap::iterator it;
+ for ( it = authors_files_map.begin();
+ it != authors_files_map.end();
+ it ++ )
+ {
+ os << "\t<Author>\n"
+ << "\t\t<Name>" << it->first << "</Name>" << std::endl;
+ cmCTestUpdateHandler::UpdateFiles *u = &(it->second);
+ for ( cc = 0; cc < u->size(); cc ++ )
+ {
+ os << "\t\t<File Directory=\"" << (*u)[cc].first << "\">"
+ << (*u)[cc].second << "</File>" << std::endl;
+ }
+ os << "\t</Author>" << std::endl;
+ }
+ }
+
+ //std::cout << "End" << std::endl;
+ std::string end_time = m_CTest->CurrentTime();
+ os << "\t<EndDateTime>" << end_time << "</EndDateTime>\n"
+ << "<ElapsedMinutes>" <<
+ static_cast<int>((cmSystemTools::GetTime() - elapsed_time_start)/6)/10.0
+ << "</ElapsedMinutes>"
+ << "</Update>" << std::endl;
+
+ if ( ofs )
+ {
+ ofs.close();
+ }
+
+ if (! res || retVal )
+ {
+ std::cerr << "Error(s) when updating the project" << std::endl;
+ std::cerr << "Output: " << goutput << std::endl;
+ return -1;
+ }
+ return count;
+}