Commit 05d985c0 authored by Ken Martin's avatar Ken Martin
Browse files

some bug fixes for my recent checkins and some more cleanup

parent 9d6ea59a
......@@ -111,6 +111,8 @@ ADD_EXECUTABLE(DumpDocumentation cmDumpDocumentation)
SET(CMTEST_SRCS ctest.cxx cmCTest.cxx
CTest/cmCTestScriptHandler.cxx
CTest/cmCTestUpdateHandler.cxx
CTest/cmCTestConfigureHandler.cxx
)
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/Source/CTest)
......
/*=========================================================================
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 "cmCTestConfigureHandler.h"
#include "cmCTest.h"
#include "cmake.h"
#include <cmsys/Process.h>
//----------------------------------------------------------------------
cmCTestConfigureHandler::cmCTestConfigureHandler()
{
m_Verbose = false;
m_CTest = 0;
}
//----------------------------------------------------------------------
//clearly it would be nice if this were broken up into a few smaller
//functions and commented...
int cmCTestConfigureHandler::ConfigureDirectory(cmCTest *ctest_inst)
{
m_CTest = ctest_inst;
std::cout << "Configure project" << std::endl;
std::string cCommand = m_CTest->GetDartConfiguration("ConfigureCommand");
if ( cCommand.size() == 0 )
{
std::cerr << "Cannot find ConfigureCommand key in the DartConfiguration.tcl"
<< std::endl;
return 1;
}
std::string buildDirectory = m_CTest->GetDartConfiguration("BuildDirectory");
if ( buildDirectory.size() == 0 )
{
std::cerr << "Cannot find BuildDirectory key in the DartConfiguration.tcl" << std::endl;
return 1;
}
double elapsed_time_start = cmSystemTools::GetTime();
std::string output;
int retVal = 0;
int res = 0;
if ( !m_CTest->GetShowOnly() )
{
std::ofstream os;
if ( !m_CTest->OpenOutputFile(m_CTest->GetCurrentTag(), "Configure.xml", os) )
{
std::cerr << "Cannot open configure file" << std::endl;
return 1;
}
std::string start_time = m_CTest->CurrentTime();
std::ofstream ofs;
m_CTest->OpenOutputFile("Temporary", "LastConfigure.log", ofs);
res = m_CTest->RunMakeCommand(cCommand.c_str(), &output,
&retVal, buildDirectory.c_str(),
m_Verbose, 0, ofs);
if ( ofs )
{
ofs.close();
}
if ( os )
{
m_CTest->StartXML(os);
os << "<Configure>\n"
<< "\t<StartDateTime>" << start_time << "</StartDateTime>" << std::endl;
if ( res == cmsysProcess_State_Exited && retVal )
{
os << retVal;
}
os << "<ConfigureCommand>" << cCommand.c_str() << "</ConfigureCommand>" << std::endl;
//std::cout << "End" << std::endl;
os << "<Log>" << cmCTest::MakeXMLSafe(output) << "</Log>" << std::endl;
std::string end_time = m_CTest->CurrentTime();
os << "\t<ConfigureStatus>" << retVal << "</ConfigureStatus>\n"
<< "\t<EndDateTime>" << end_time << "</EndDateTime>\n"
<< "<ElapsedMinutes>"
<< static_cast<int>(
(cmSystemTools::GetTime() - elapsed_time_start)/6)/10.0
<< "</ElapsedMinutes>"
<< "</Configure>" << std::endl;
m_CTest->EndXML(os);
}
}
else
{
std::cout << "Configure with command: " << cCommand << std::endl;
}
if (! res || retVal )
{
std::cerr << "Error(s) when updating the project" << std::endl;
return 1;
}
return 0;
}
/*=========================================================================
Program: CMake - Cross-Platform Makefile Generator
Module: $RCSfile$
Language: C++
Date: $Date$
Version: $Revision$
Copyright (c) 2002 Kitware, Inc. 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.
=========================================================================*/
#ifndef cmCTestConfigureHandler_h
#define cmCTestConfigureHandler_h
#include "cmStandardIncludes.h"
#include "cmListFileCache.h"
class cmCTest;
/** \class cmCTestConfigureHandler
* \brief A class that handles ctest -S invocations
*
*/
class cmCTestConfigureHandler
{
public:
/*
* The main entry point for this class
*/
int ConfigureDirectory(cmCTest *);
/*
* If verbose then more informaiton is printed out
*/
void SetVerbose(bool val) { m_Verbose = val; }
cmCTestConfigureHandler();
private:
bool m_Verbose;
cmCTest *m_CTest;
};
#endif
......@@ -48,7 +48,9 @@ cmCTestScriptHandler::cmCTestScriptHandler()
m_Backup = false;
m_Makefile = 0;
m_LocalGenerator = 0;
m_CMake = 0;
m_GlobalGenerator = 0;
// the *60 is becuase the settings are in minutes but GetTime is seconds
m_MinimumInterval = 30*60;
}
......@@ -57,16 +59,23 @@ cmCTestScriptHandler::cmCTestScriptHandler()
//----------------------------------------------------------------------
cmCTestScriptHandler::~cmCTestScriptHandler()
{
if (m_Makefile)
{
delete m_Makefile;
}
// local generator owns the makefile
m_Makefile = 0;
if (m_LocalGenerator)
{
delete m_LocalGenerator;
}
m_LocalGenerator = 0;
if (m_GlobalGenerator)
{
delete m_GlobalGenerator;
}
m_GlobalGenerator = 0;
if (m_CMake)
{
delete m_CMake;
}
m_CMake = 0;
}
......@@ -121,18 +130,20 @@ int cmCTestScriptHandler::ReadInScript(const std::string& total_script_arg)
}
// create a cmake instance to read the configuration script
cmake cm;
cmGlobalGenerator gg;
gg.SetCMakeInstance(&cm);
// read in the list file to fill the cache
if (m_LocalGenerator)
if (m_CMake)
{
delete m_CMake;
delete m_GlobalGenerator;
delete m_LocalGenerator;
}
m_LocalGenerator = gg.CreateLocalGenerator();
m_LocalGenerator->SetGlobalGenerator(&gg);
m_CMake = new cmake;
m_GlobalGenerator = new cmGlobalGenerator;
m_GlobalGenerator->SetCMakeInstance(m_CMake);
m_LocalGenerator = m_GlobalGenerator->CreateLocalGenerator();
m_LocalGenerator->SetGlobalGenerator(m_GlobalGenerator);
// set a variable with the path to the current script
m_LocalGenerator->GetMakefile()->AddDefinition("CTEST_SCRIPT_DIRECTORY",
cmSystemTools::GetFilenamePath(
......@@ -163,14 +174,31 @@ int cmCTestScriptHandler::ExtractVariables()
{
// get some info that should be set
m_Makefile = m_LocalGenerator->GetMakefile();
m_SourceDir.clear();
m_BinaryDir.clear();
m_CTestCmd.clear();
m_SourceDir = m_Makefile->GetDefinition("CTEST_SOURCE_DIRECTORY");
m_BinaryDir = m_Makefile->GetDefinition("CTEST_BINARY_DIRECTORY");
m_CTestCmd = m_Makefile->GetDefinition("CTEST_COMMAND");
if (m_Makefile->GetDefinition("CTEST_SOURCE_DIRECTORY"))
{
m_SourceDir = m_Makefile->GetDefinition("CTEST_SOURCE_DIRECTORY");
}
if (m_Makefile->GetDefinition("CTEST_BINARY_DIRECTORY"))
{
m_BinaryDir = m_Makefile->GetDefinition("CTEST_BINARY_DIRECTORY");
}
if (m_Makefile->GetDefinition("CTEST_COMMAND"))
{
m_CTestCmd = m_Makefile->GetDefinition("CTEST_COMMAND");
}
m_Backup = m_Makefile->IsOn("CTEST_BACKUP_AND_RESTORE");
// in order to backup and restore we also must have the cvs root
m_CVSCheckOut = m_Makefile->GetDefinition("CTEST_CVS_CHECKOUT");
m_CVSCheckOut.clear();
if (m_Makefile->GetDefinition("CTEST_CVS_CHECKOUT"))
{
m_CVSCheckOut = m_Makefile->GetDefinition("CTEST_CVS_CHECKOUT");
}
if (m_Backup && m_CVSCheckOut.empty())
{
cmSystemTools::Error(
......@@ -213,7 +241,11 @@ int cmCTestScriptHandler::ExtractVariables()
atof(m_Makefile->GetDefinition("CTEST_CONTINUOUS_MINIMUM_INTERVAL"));
}
m_CVSCmd = m_Makefile->GetDefinition("CTEST_CVS_COMMAND");
m_CVSCmd.clear();
if (m_Makefile->GetDefinition("CTEST_CVS_COMMAND"))
{
m_CVSCmd = m_Makefile->GetDefinition("CTEST_CVS_COMMAND");
}
return 0;
}
......
......@@ -24,6 +24,8 @@
class cmMakefile;
class cmLocalGenerator;
class cmGlobalGenerator;
class cmake;
/** \class cmCTestScriptHandler
* \brief A class that handles ctest -S invocations
......@@ -91,6 +93,9 @@ private:
cmMakefile *m_Makefile;
cmLocalGenerator *m_LocalGenerator;
cmGlobalGenerator *m_GlobalGenerator;
cmake *m_CMake;
};
#endif
/*=========================================================================
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