ENH: Teach ctest_coverage to filter with LABELS
This teaches ctest_coverage() to report only coverage of files labeled with at least one label given by a new LABELS option.
This commit is contained in:
parent
3078fef81c
commit
91a8569648
|
@ -17,22 +17,55 @@
|
|||
#include "cmCTestCoverageCommand.h"
|
||||
|
||||
#include "cmCTest.h"
|
||||
#include "cmCTestGenericHandler.h"
|
||||
#include "cmCTestCoverageHandler.h"
|
||||
|
||||
cmCTestGenericHandler* cmCTestCoverageCommand::InitializeHandler()
|
||||
{
|
||||
this->CTest->SetCTestConfigurationFromCMakeVariable(this->Makefile,
|
||||
"CoverageCommand", "CTEST_COVERAGE_COMMAND");
|
||||
|
||||
cmCTestGenericHandler* handler
|
||||
= this->CTest->GetInitializedHandler("coverage");
|
||||
cmCTestCoverageHandler* handler = static_cast<cmCTestCoverageHandler*>(
|
||||
this->CTest->GetInitializedHandler("coverage"));
|
||||
if ( !handler )
|
||||
{
|
||||
this->SetError("internal CTest error. Cannot instantiate test handler");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// If a LABELS option was given, select only files with the labels.
|
||||
if(this->LabelsMentioned)
|
||||
{
|
||||
handler->SetLabelFilter(this->Labels);
|
||||
}
|
||||
|
||||
return handler;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool cmCTestCoverageCommand::CheckArgumentKeyword(std::string const& arg)
|
||||
{
|
||||
// Look for arguments specific to this command.
|
||||
if(arg == "LABELS")
|
||||
{
|
||||
this->ArgumentDoing = ArgumentDoingLabels;
|
||||
this->LabelsMentioned = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Look for other arguments.
|
||||
return this->Superclass::CheckArgumentKeyword(arg);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool cmCTestCoverageCommand::CheckArgumentValue(std::string const& arg)
|
||||
{
|
||||
// Handle states specific to this command.
|
||||
if(this->ArgumentDoing == ArgumentDoingLabels)
|
||||
{
|
||||
this->Labels.insert(arg);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Look for other arguments.
|
||||
return this->Superclass::CheckArgumentValue(arg);
|
||||
}
|
||||
|
|
|
@ -60,11 +60,15 @@ public:
|
|||
virtual const char* GetFullDocumentation()
|
||||
{
|
||||
return
|
||||
" ctest_coverage([BUILD build_dir] [RETURN_VALUE res] [APPEND])\n"
|
||||
" ctest_coverage([BUILD build_dir] [RETURN_VALUE res] [APPEND]\n"
|
||||
" [LABELS label1 [label2 [...]]])\n"
|
||||
"Perform the coverage of the given build directory and stores results "
|
||||
"in Coverage.xml. The second argument is a variable that will hold "
|
||||
"value."
|
||||
"\n"
|
||||
"The LABELS option filters the coverage report to include only "
|
||||
"source files labeled with at least one of the labels specified."
|
||||
"\n"
|
||||
CTEST_COMMAND_APPEND_OPTION_DOCS;
|
||||
}
|
||||
|
||||
|
@ -72,6 +76,18 @@ public:
|
|||
|
||||
protected:
|
||||
cmCTestGenericHandler* InitializeHandler();
|
||||
|
||||
virtual bool CheckArgumentKeyword(std::string const& arg);
|
||||
virtual bool CheckArgumentValue(std::string const& arg);
|
||||
|
||||
enum
|
||||
{
|
||||
ArgumentDoingLabels = Superclass::ArgumentDoingLast1,
|
||||
ArgumentDoingLast2
|
||||
};
|
||||
|
||||
bool LabelsMentioned;
|
||||
std::set<cmStdString> Labels;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include "cmCTestCoverageHandler.h"
|
||||
#include "cmCTest.h"
|
||||
#include "cmake.h"
|
||||
#include "cmMakefile.h"
|
||||
#include "cmSystemTools.h"
|
||||
#include "cmGeneratedFileStream.h"
|
||||
#include "cmXMLSafe.h"
|
||||
|
@ -24,6 +25,8 @@
|
|||
#include <cmsys/Process.h>
|
||||
#include <cmsys/RegularExpression.hxx>
|
||||
#include <cmsys/Glob.hxx>
|
||||
#include <cmsys/stl/iterator>
|
||||
#include <cmsys/stl/algorithm>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
|
@ -156,6 +159,7 @@ void cmCTestCoverageHandler::Initialize()
|
|||
this->SourceLabels.clear();
|
||||
this->LabelIdMap.clear();
|
||||
this->Labels.clear();
|
||||
this->LabelFilter.clear();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
@ -207,6 +211,11 @@ bool cmCTestCoverageHandler::ShouldIDoCoverage(const char* file,
|
|||
const char* srcDir,
|
||||
const char* binDir)
|
||||
{
|
||||
if(this->IsFilteredOut(file))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<cmsys::RegularExpression>::iterator sit;
|
||||
for ( sit = this->CustomCoverageExcludeRegex.begin();
|
||||
sit != this->CustomCoverageExcludeRegex.end(); ++ sit )
|
||||
|
@ -1817,3 +1826,39 @@ void cmCTestCoverageHandler::WriteXMLLabels(std::ofstream& os,
|
|||
os << "\t\t</Labels>\n";
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void
|
||||
cmCTestCoverageHandler::SetLabelFilter(std::set<cmStdString> const& labels)
|
||||
{
|
||||
this->LabelFilter.clear();
|
||||
for(std::set<cmStdString>::const_iterator li = labels.begin();
|
||||
li != labels.end(); ++li)
|
||||
{
|
||||
this->LabelFilter.insert(this->GetLabelId(*li));
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
bool cmCTestCoverageHandler::IsFilteredOut(std::string const& source)
|
||||
{
|
||||
// If there is no label filter then nothing is filtered out.
|
||||
if(this->LabelFilter.empty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// The source is filtered out if it does not have any labels in
|
||||
// common with the filter set.
|
||||
std::vector<int> ids;
|
||||
std::string shortSrc = this->CTest->GetShortPathToFile(source.c_str());
|
||||
LabelMapType::const_iterator li = this->SourceLabels.find(shortSrc);
|
||||
if(li != this->SourceLabels.end() && !li->second.empty())
|
||||
{
|
||||
cmsys_stl::set_intersection
|
||||
(li->second.begin(), li->second.end(),
|
||||
this->LabelFilter.begin(), this->LabelFilter.end(),
|
||||
cmsys_stl::back_inserter(ids));
|
||||
}
|
||||
return ids.empty();
|
||||
}
|
||||
|
|
|
@ -50,6 +50,9 @@ public:
|
|||
*/
|
||||
void PopulateCustomVectors(cmMakefile *mf);
|
||||
|
||||
/** Report coverage only for sources with these labels. */
|
||||
void SetLabelFilter(std::set<cmStdString> const& labels);
|
||||
|
||||
private:
|
||||
bool ShouldIDoCoverage(const char* file, const char* srcDir,
|
||||
const char* binDir);
|
||||
|
@ -153,6 +156,10 @@ private:
|
|||
void LoadLabels();
|
||||
void LoadLabels(const char* fname);
|
||||
void WriteXMLLabels(std::ofstream& os, std::string const& source);
|
||||
|
||||
// Label-based filtering.
|
||||
std::set<int> LabelFilter;
|
||||
bool IsFilteredOut(std::string const& source);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue