server-mode: Add --experimental flag

Allow for experimental cmProtocolVersions, which will only ever get
listed if the server was started with the (undocumented)
"--experimental" flag.

Mark current protocol version 1.0 as experimental.
This commit is contained in:
Tobias Hunger 2016-09-09 10:01:44 +02:00 committed by Brad King
parent 5c87b92b1b
commit 7df8a8f276
7 changed files with 49 additions and 12 deletions

View File

@ -85,7 +85,8 @@ void read_stdin(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf)
free(buf->base); free(buf->base);
} }
cmServer::cmServer() cmServer::cmServer(bool supportExperimental)
: SupportExperimental(supportExperimental)
{ {
// Register supported protocols: // Register supported protocols:
this->RegisterProtocol(new cmServerProtocol1_0); this->RegisterProtocol(new cmServerProtocol1_0);
@ -93,8 +94,9 @@ cmServer::cmServer()
cmServer::~cmServer() cmServer::~cmServer()
{ {
if (!this->Protocol) // Daemon was never fully started! if (!this->Protocol) { // Server was never fully started!
return; return;
}
uv_close(reinterpret_cast<uv_handle_t*>(this->InputStream), NULL); uv_close(reinterpret_cast<uv_handle_t*>(this->InputStream), NULL);
uv_close(reinterpret_cast<uv_handle_t*>(this->OutputStream), NULL); uv_close(reinterpret_cast<uv_handle_t*>(this->OutputStream), NULL);
@ -171,6 +173,9 @@ void cmServer::handleData(const std::string& data)
void cmServer::RegisterProtocol(cmServerProtocol* protocol) void cmServer::RegisterProtocol(cmServerProtocol* protocol)
{ {
if (protocol->IsExperimental() && !this->SupportExperimental) {
return;
}
auto version = protocol->ProtocolVersion(); auto version = protocol->ProtocolVersion();
assert(version.first >= 0); assert(version.first >= 0);
assert(version.second >= 0); assert(version.second >= 0);
@ -196,6 +201,9 @@ void cmServer::PrintHello() const
Json::Value tmp = Json::objectValue; Json::Value tmp = Json::objectValue;
tmp["major"] = version.first; tmp["major"] = version.first;
tmp["minor"] = version.second; tmp["minor"] = version.second;
if (proto->IsExperimental()) {
tmp["experimental"] = true;
}
protocolVersions.append(tmp); protocolVersions.append(tmp);
} }
@ -245,9 +253,11 @@ cmServerResponse cmServer::SetProtocolVersion(const cmServerRequest& request)
return request.Reply(Json::objectValue); return request.Reply(Json::objectValue);
} }
void cmServer::Serve() bool cmServer::Serve()
{ {
assert(!this->SupportedProtocols.empty()); if (this->SupportedProtocols.empty()) {
return false;
}
assert(!this->Protocol); assert(!this->Protocol);
this->Loop = uv_default_loop(); this->Loop = uv_default_loop();
@ -279,6 +289,7 @@ void cmServer::Serve()
uv_read_start(this->InputStream, alloc_buffer, read_stdin); uv_read_start(this->InputStream, alloc_buffer, read_stdin);
uv_run(this->Loop, UV_RUN_DEFAULT); uv_run(this->Loop, UV_RUN_DEFAULT);
return true;
} }
void cmServer::WriteJsonObject(const Json::Value& jsonValue) const void cmServer::WriteJsonObject(const Json::Value& jsonValue) const

View File

@ -31,10 +31,10 @@ class cmServerResponse;
class cmServer class cmServer
{ {
public: public:
cmServer(); cmServer(bool supportExperimental);
~cmServer(); ~cmServer();
void Serve(); bool Serve();
// for callbacks: // for callbacks:
void PopOne(); void PopOne();
@ -59,6 +59,8 @@ private:
static cmServerProtocol* FindMatchingProtocol( static cmServerProtocol* FindMatchingProtocol(
const std::vector<cmServerProtocol*>& protocols, int major, int minor); const std::vector<cmServerProtocol*>& protocols, int major, int minor);
const bool SupportExperimental;
cmServerProtocol* Protocol = nullptr; cmServerProtocol* Protocol = nullptr;
std::vector<cmServerProtocol*> SupportedProtocols; std::vector<cmServerProtocol*> SupportedProtocols;
std::vector<std::string> Queue; std::vector<std::string> Queue;

View File

@ -262,3 +262,8 @@ const cmServerResponse cmServerProtocol1_0::Process(
return request.ReportError("Unknown command!"); return request.ReportError("Unknown command!");
} }
bool cmServerProtocol1_0::IsExperimental() const
{
return true;
}

View File

@ -82,6 +82,7 @@ public:
virtual ~cmServerProtocol() {} virtual ~cmServerProtocol() {}
virtual std::pair<int, int> ProtocolVersion() const = 0; virtual std::pair<int, int> ProtocolVersion() const = 0;
virtual bool IsExperimental() const = 0;
virtual const cmServerResponse Process(const cmServerRequest& request) = 0; virtual const cmServerResponse Process(const cmServerRequest& request) = 0;
bool Activate(const cmServerRequest& request, std::string* errorMessage); bool Activate(const cmServerRequest& request, std::string* errorMessage);
@ -100,6 +101,7 @@ class cmServerProtocol1_0 : public cmServerProtocol
{ {
public: public:
std::pair<int, int> ProtocolVersion() const override; std::pair<int, int> ProtocolVersion() const override;
bool IsExperimental() const override;
const cmServerResponse Process(const cmServerRequest& request) override; const cmServerResponse Process(const cmServerRequest& request) override;
private: private:

View File

@ -913,15 +913,32 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string>& args)
} }
return 0; return 0;
} else if (args[1] == "server") { } else if (args[1] == "server") {
if (args.size() > 2) { if (args.size() > 3) {
cmSystemTools::Error("Too many arguments to start server mode"); cmSystemTools::Error("Too many arguments to start server mode");
return 1; return 1;
} }
bool supportExperimental = false;
if (args.size() == 3) {
if (args[2] == "--experimental") {
supportExperimental = true;
} else {
cmSystemTools::Error("Unknown argument for server mode");
return 1;
}
}
#if defined(HAVE_SERVER_MODE) && HAVE_SERVER_MODE #if defined(HAVE_SERVER_MODE) && HAVE_SERVER_MODE
cmServer server; cmServer server(supportExperimental);
server.Serve(); if (server.Serve()) {
return 0; return 0;
} else {
cmSystemTools::Error(
"CMake server could not find any supported protocol. "
"Try with \"--experimental\" to enable "
"experimental support.");
return 1;
}
#else #else
static_cast<void>(supportExperimental);
cmSystemTools::Error("CMake was not built with server mode enabled"); cmSystemTools::Error("CMake was not built with server mode enabled");
return 1; return 1;
#endif #endif

View File

@ -1 +1 @@
^CMake Error: Too many arguments to start server mode$ ^CMake Error: Unknown argument for server mode$

View File

@ -79,7 +79,7 @@ def writePayload(cmakeCommand, obj):
writeRawData(cmakeCommand, json.dumps(obj)) writeRawData(cmakeCommand, json.dumps(obj))
def initProc(cmakeCommand): def initProc(cmakeCommand):
cmakeCommand = subprocess.Popen([cmakeCommand, "-E", "server"], cmakeCommand = subprocess.Popen([cmakeCommand, "-E", "server", "--experimental"],
stdin=subprocess.PIPE, stdin=subprocess.PIPE,
stdout=subprocess.PIPE) stdout=subprocess.PIPE)