1 /*=========================================================================
3 Program: CMake - Cross-Platform Makefile Generator
4 Module: $RCSfile: cmCTestVC.cxx,v $
6 Date: $Date: 2009-02-26 14:22:32 $
7 Version: $Revision: 1.8 $
9 Copyright (c) 2002 Kitware, Inc. All rights reserved.
10 See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
12 This software is distributed WITHOUT ANY WARRANTY; without even
13 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14 PURPOSE. See the above copyright notices for more information.
16 =========================================================================*/
17 #include "cmCTestVC.h"
20 #include "cmSystemTools.h"
21 #include "cmXMLSafe.h"
23 #include <cmsys/Process.h>
25 //----------------------------------------------------------------------------
26 cmCTestVC::cmCTestVC(cmCTest
* ct
, std::ostream
& log
): CTest(ct
), Log(log
)
28 this->PathCount
[PathUpdated
] = 0;
29 this->PathCount
[PathModified
] = 0;
30 this->PathCount
[PathConflicting
] = 0;
31 this->Unknown
.Date
= "Unknown";
32 this->Unknown
.Author
= "Unknown";
33 this->Unknown
.Rev
= "Unknown";
36 //----------------------------------------------------------------------------
37 cmCTestVC::~cmCTestVC()
41 //----------------------------------------------------------------------------
42 void cmCTestVC::SetCommandLineTool(std::string
const& tool
)
44 this->CommandLineTool
= tool
;
47 //----------------------------------------------------------------------------
48 void cmCTestVC::SetSourceDirectory(std::string
const& dir
)
50 this->SourceDirectory
= dir
;
53 //----------------------------------------------------------------------------
54 bool cmCTestVC::InitialCheckout(const char* command
)
56 cmCTestLog(this->CTest
, HANDLER_OUTPUT
,
57 " First perform the initial checkout: " << command
<< "\n");
59 // Make the parent directory in which to perform the checkout.
60 std::string parent
= cmSystemTools::GetFilenamePath(this->SourceDirectory
);
61 cmCTestLog(this->CTest
, HANDLER_OUTPUT
,
62 " Perform checkout in directory: " << parent
<< "\n");
63 if(!cmSystemTools::MakeDirectory(parent
.c_str()))
65 cmCTestLog(this->CTest
, ERROR_MESSAGE
,
66 "Cannot create directory: " << parent
<< std::endl
);
70 // Construct the initial checkout command line.
71 std::vector
<cmStdString
> args
= cmSystemTools::ParseArguments(command
);
72 std::vector
<char const*> vc_co
;
73 for(std::vector
<cmStdString
>::const_iterator ai
= args
.begin();
74 ai
!= args
.end(); ++ai
)
76 vc_co
.push_back(ai
->c_str());
80 // Run the initial checkout command and log its output.
81 this->Log
<< "--- Begin Initial Checkout ---\n";
82 OutputLogger
out(this->Log
, "co-out> ");
83 OutputLogger
err(this->Log
, "co-err> ");
84 bool result
= this->RunChild(&vc_co
[0], &out
, &err
, parent
.c_str());
85 this->Log
<< "--- End Initial Checkout ---\n";
88 cmCTestLog(this->CTest
, ERROR_MESSAGE
,
89 "Initial checkout failed!" << std::endl
);
94 //----------------------------------------------------------------------------
95 bool cmCTestVC::RunChild(char const* const* cmd
, OutputParser
* out
,
96 OutputParser
* err
, const char* workDir
)
98 this->Log
<< this->ComputeCommandLine(cmd
) << "\n";
100 cmsysProcess
* cp
= cmsysProcess_New();
101 cmsysProcess_SetCommand(cp
, cmd
);
102 workDir
= workDir
? workDir
: this->SourceDirectory
.c_str();
103 cmsysProcess_SetWorkingDirectory(cp
, workDir
);
104 this->RunProcess(cp
, out
, err
);
105 int result
= cmsysProcess_GetExitValue(cp
);
106 cmsysProcess_Delete(cp
);
110 //----------------------------------------------------------------------------
111 std::string
cmCTestVC::ComputeCommandLine(char const* const* cmd
)
113 cmOStringStream line
;
114 const char* sep
= "";
115 for(const char* const* arg
= cmd
; *arg
; ++arg
)
117 line
<< sep
<< "\"" << *arg
<< "\"";
123 //----------------------------------------------------------------------------
124 bool cmCTestVC::RunUpdateCommand(char const* const* cmd
,
125 OutputParser
* out
, OutputParser
* err
)
127 // Report the command line.
128 this->UpdateCommandLine
= this->ComputeCommandLine(cmd
);
129 if(this->CTest
->GetShowOnly())
131 this->Log
<< this->UpdateCommandLine
<< "\n";
136 return this->RunChild(cmd
, out
, err
);
139 //----------------------------------------------------------------------------
140 std::string
cmCTestVC::GetNightlyTime()
142 // Get the nightly start time corresponding to the current dau.
143 struct tm
* t
= this->CTest
->GetNightlyTime(
144 this->CTest
->GetCTestConfiguration("NightlyStartTime"),
145 this->CTest
->GetTomorrowTag());
146 char current_time
[1024];
147 sprintf(current_time
, "%04d-%02d-%02d %02d:%02d:%02d",
154 return std::string(current_time
);
157 //----------------------------------------------------------------------------
158 void cmCTestVC::Cleanup()
160 this->Log
<< "--- Begin Cleanup ---\n";
162 this->Log
<< "--- End Cleanup ---\n";
165 //----------------------------------------------------------------------------
166 void cmCTestVC::CleanupImpl()
168 // We do no cleanup by default.
171 //----------------------------------------------------------------------------
172 bool cmCTestVC::Update()
174 this->NoteOldRevision();
175 this->Log
<< "--- Begin Update ---\n";
176 bool result
= this->UpdateImpl();
177 this->Log
<< "--- End Update ---\n";
178 this->NoteNewRevision();
182 //----------------------------------------------------------------------------
183 void cmCTestVC::NoteOldRevision()
185 // We do nothing by default.
188 //----------------------------------------------------------------------------
189 void cmCTestVC::NoteNewRevision()
191 // We do nothing by default.
194 //----------------------------------------------------------------------------
195 bool cmCTestVC::UpdateImpl()
197 cmCTestLog(this->CTest
, HANDLER_VERBOSE_OUTPUT
,
198 "* Unknown VCS tool, not updating!" << std::endl
);
202 //----------------------------------------------------------------------------
203 bool cmCTestVC::WriteXML(std::ostream
& xml
)
205 this->Log
<< "--- Begin Revisions ---\n";
206 bool result
= this->WriteXMLUpdates(xml
);
207 this->Log
<< "--- End Revisions ---\n";
211 //----------------------------------------------------------------------------
212 bool cmCTestVC::WriteXMLUpdates(std::ostream
&)
214 cmCTestLog(this->CTest
, HANDLER_VERBOSE_OUTPUT
,
215 "* CTest cannot extract updates for this VCS tool.\n");
219 //----------------------------------------------------------------------------
220 void cmCTestVC::WriteXMLEntry(std::ostream
& xml
,
221 std::string
const& path
,
222 std::string
const& name
,
223 std::string
const& full
,
226 static const char* desc
[3] = { "Updated", "Modified", "Conflicting"};
227 Revision
const& rev
= f
.Rev
? *f
.Rev
: this->Unknown
;
228 std::string prior
= f
.PriorRev
? f
.PriorRev
->Rev
: std::string("Unknown");
229 xml
<< "\t\t<" << desc
[f
.Status
] << ">\n"
230 << "\t\t\t<File>" << cmXMLSafe(name
) << "</File>\n"
231 << "\t\t\t<Directory>" << cmXMLSafe(path
) << "</Directory>\n"
232 << "\t\t\t<FullName>" << cmXMLSafe(full
) << "</FullName>\n"
233 << "\t\t\t<CheckinDate>" << cmXMLSafe(rev
.Date
) << "</CheckinDate>\n"
234 << "\t\t\t<Author>" << cmXMLSafe(rev
.Author
) << "</Author>\n"
235 << "\t\t\t<Log>" << cmXMLSafe(rev
.Log
) << "</Log>\n"
236 << "\t\t\t<Revision>" << cmXMLSafe(rev
.Rev
) << "</Revision>\n"
237 << "\t\t\t<PriorRevision>" << cmXMLSafe(prior
) << "</PriorRevision>\n"
238 << "\t\t</" << desc
[f
.Status
] << ">\n";
239 ++this->PathCount
[f
.Status
];