diff --git a/Source/CTest/cmCTestSubmitCommand.cxx b/Source/CTest/cmCTestSubmitCommand.cxx index a321c3f3c..2e435a7c3 100644 --- a/Source/CTest/cmCTestSubmitCommand.cxx +++ b/Source/CTest/cmCTestSubmitCommand.cxx @@ -18,6 +18,7 @@ #include "cmCTest.h" #include "cmCTestGenericHandler.h" +#include "cmCTestSubmitHandler.h" cmCTestGenericHandler* cmCTestSubmitCommand::InitializeHandler() { @@ -106,7 +107,52 @@ cmCTestGenericHandler* cmCTestSubmitCommand::InitializeHandler() this->SetError("internal CTest error. Cannot instantiate submit handler"); return 0; } + + // If a PARTS option was given, select only the named parts for submission. + if(!this->Parts.empty()) + { + static_cast(handler)->SelectParts(this->Parts); + } return handler; } + +//---------------------------------------------------------------------------- +bool cmCTestSubmitCommand::CheckArgumentKeyword(std::string const& arg) +{ + // Look for arguments specific to this command. + if(arg == "PARTS") + { + this->ArgumentDoing = ArgumentDoingParts; + return true; + } + + // Look for other arguments. + return this->Superclass::CheckArgumentKeyword(arg); +} + +//---------------------------------------------------------------------------- +bool cmCTestSubmitCommand::CheckArgumentValue(std::string const& arg) +{ + // Handle states specific to this command. + if(this->ArgumentDoing == ArgumentDoingParts) + { + cmCTest::Part p = this->CTest->GetPartFromName(arg.c_str()); + if(p != cmCTest::PartCount) + { + this->Parts.insert(p); + } + else + { + cmOStringStream e; + e << "Part name \"" << arg << "\" is invalid."; + this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str()); + this->ArgumentDoing = ArgumentDoingError; + } + return true; + } + + // Look for other arguments. + return this->Superclass::CheckArgumentValue(arg); +} diff --git a/Source/CTest/cmCTestSubmitCommand.h b/Source/CTest/cmCTestSubmitCommand.h index 2faebba27..dd99461be 100644 --- a/Source/CTest/cmCTestSubmitCommand.h +++ b/Source/CTest/cmCTestSubmitCommand.h @@ -18,6 +18,7 @@ #define cmCTestSubmitCommand_h #include "cmCTestHandlerCommand.h" +#include "cmCTest.h" /** \class cmCTestSubmit * \brief Run a ctest script @@ -61,14 +62,25 @@ public: virtual const char* GetFullDocumentation() { return - " ctest_submit([RETURN_VALUE res])\n" - "Submits the test results for the project."; + " ctest_submit([RETURN_VALUE res] [PARTS ...])\n" + "Submits the test results for the project. " + "By default all available parts are submitted. " + "The PARTS option lists a subset of parts to be submitted."; } cmTypeMacro(cmCTestSubmitCommand, cmCTestHandlerCommand); protected: cmCTestGenericHandler* InitializeHandler(); + + virtual bool CheckArgumentKeyword(std::string const& arg); + virtual bool CheckArgumentValue(std::string const& arg); + enum + { + ArgumentDoingParts = Superclass::ArgumentDoingLast1, + ArgumentDoingLast2 + }; + std::set Parts; }; diff --git a/Source/CTest/cmCTestSubmitHandler.cxx b/Source/CTest/cmCTestSubmitHandler.cxx index 3e811d5ae..3a801b6f6 100644 --- a/Source/CTest/cmCTestSubmitHandler.cxx +++ b/Source/CTest/cmCTestSubmitHandler.cxx @@ -69,6 +69,13 @@ cmCTestSubmitHandler::cmCTestSubmitHandler() : HTTPProxy(), FTPProxy() this->FTPProxy = ""; this->FTPProxyType = 0; this->CDash = false; + + // We submit all available parts by default. + for(cmCTest::Part p = cmCTest::PartStart; + p != cmCTest::PartCount; p = cmCTest::Part(p+1)) + { + this->SubmitPart[p] = true; + } } //---------------------------------------------------------------------------- @@ -893,6 +900,13 @@ int cmCTestSubmitHandler::ProcessHandler() for(cmCTest::Part p = cmCTest::PartStart; p != cmCTest::PartCount; p = cmCTest::Part(p+1)) { + // Skip parts we are not submitting. + if(!this->SubmitPart[p]) + { + continue; + } + + // Submit files from this part. std::vector const& pfiles = this->CTest->GetSubmitFiles(p); for(std::vector::const_iterator pi = pfiles.begin(); pi != pfiles.end(); ++pi) @@ -1107,4 +1121,13 @@ std::string cmCTestSubmitHandler::GetSubmitResultsPrefix() return name; } - +//---------------------------------------------------------------------------- +void cmCTestSubmitHandler::SelectParts(std::set const& parts) +{ + // Check whether each part is selected. + for(cmCTest::Part p = cmCTest::PartStart; + p != cmCTest::PartCount; p = cmCTest::Part(p+1)) + { + this->SubmitPart[p] = (parts.find(p) != parts.end()); + } +} diff --git a/Source/CTest/cmCTestSubmitHandler.h b/Source/CTest/cmCTestSubmitHandler.h index 6aa11cabc..eb84d2d6a 100644 --- a/Source/CTest/cmCTestSubmitHandler.h +++ b/Source/CTest/cmCTestSubmitHandler.h @@ -39,7 +39,9 @@ public: int ProcessHandler(); void Initialize(); - + + /** Specify a set of parts (by name) to submit. */ + void SelectParts(std::set const& parts); private: void SetLogFile(std::ostream* ost) { this->LogFile = ost; } @@ -77,6 +79,7 @@ private: cmStdString FTPProxy; int FTPProxyType; std::ostream* LogFile; + bool SubmitPart[cmCTest::PartCount]; bool CDash; }; diff --git a/Tests/CTestTest2/test.cmake.in b/Tests/CTestTest2/test.cmake.in index c9e263619..643e767e5 100644 --- a/Tests/CTestTest2/test.cmake.in +++ b/Tests/CTestTest2/test.cmake.in @@ -42,3 +42,8 @@ CTEST_TEST(BUILD "${CTEST_BINARY_DIRECTORY}" RETURN_VALUE res START 6 STRIDE 2 S CTEST_MEMCHECK(BUILD "${CTEST_BINARY_DIRECTORY}" RETURN_VALUE res STRIDE 1.5) CTEST_COVERAGE(BUILD "${CTEST_BINARY_DIRECTORY}" RETURN_VALUE res) CTEST_SUBMIT(RETURN_VALUE res) + +# Test submission of a subset of parts. +SET(CTEST_EXTRA_SUBMIT_FILES ${CTEST_NOTES_FILES}) +CTEST_SUBMIT(RETURN_VALUE res PARTS ExtraFiles) +SET(CTEST_EXTRA_SUBMIT_FILES)