From 7df8a8f2769de784c24dc6baeb55ad2038aa059f Mon Sep 17 00:00:00 2001 From: Tobias Hunger Date: Fri, 9 Sep 2016 10:01:44 +0200 Subject: [PATCH] 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. --- Source/cmServer.cxx | 19 +++++++++++--- Source/cmServer.h | 6 +++-- Source/cmServerProtocol.cxx | 5 ++++ Source/cmServerProtocol.h | 2 ++ Source/cmcmd.cxx | 25 ++++++++++++++++--- .../CommandLine/E_server-arg-stderr.txt | 2 +- Tests/Server/cmakelib.py | 2 +- 7 files changed, 49 insertions(+), 12 deletions(-) diff --git a/Source/cmServer.cxx b/Source/cmServer.cxx index 123b6a48e..208fac6ac 100644 --- a/Source/cmServer.cxx +++ b/Source/cmServer.cxx @@ -85,7 +85,8 @@ void read_stdin(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf) free(buf->base); } -cmServer::cmServer() +cmServer::cmServer(bool supportExperimental) + : SupportExperimental(supportExperimental) { // Register supported protocols: this->RegisterProtocol(new cmServerProtocol1_0); @@ -93,8 +94,9 @@ cmServer::cmServer() cmServer::~cmServer() { - if (!this->Protocol) // Daemon was never fully started! + if (!this->Protocol) { // Server was never fully started! return; + } uv_close(reinterpret_cast(this->InputStream), NULL); uv_close(reinterpret_cast(this->OutputStream), NULL); @@ -171,6 +173,9 @@ void cmServer::handleData(const std::string& data) void cmServer::RegisterProtocol(cmServerProtocol* protocol) { + if (protocol->IsExperimental() && !this->SupportExperimental) { + return; + } auto version = protocol->ProtocolVersion(); assert(version.first >= 0); assert(version.second >= 0); @@ -196,6 +201,9 @@ void cmServer::PrintHello() const Json::Value tmp = Json::objectValue; tmp["major"] = version.first; tmp["minor"] = version.second; + if (proto->IsExperimental()) { + tmp["experimental"] = true; + } protocolVersions.append(tmp); } @@ -245,9 +253,11 @@ cmServerResponse cmServer::SetProtocolVersion(const cmServerRequest& request) return request.Reply(Json::objectValue); } -void cmServer::Serve() +bool cmServer::Serve() { - assert(!this->SupportedProtocols.empty()); + if (this->SupportedProtocols.empty()) { + return false; + } assert(!this->Protocol); this->Loop = uv_default_loop(); @@ -279,6 +289,7 @@ void cmServer::Serve() uv_read_start(this->InputStream, alloc_buffer, read_stdin); uv_run(this->Loop, UV_RUN_DEFAULT); + return true; } void cmServer::WriteJsonObject(const Json::Value& jsonValue) const diff --git a/Source/cmServer.h b/Source/cmServer.h index 0ef1e17e5..4a9c3f53c 100644 --- a/Source/cmServer.h +++ b/Source/cmServer.h @@ -31,10 +31,10 @@ class cmServerResponse; class cmServer { public: - cmServer(); + cmServer(bool supportExperimental); ~cmServer(); - void Serve(); + bool Serve(); // for callbacks: void PopOne(); @@ -59,6 +59,8 @@ private: static cmServerProtocol* FindMatchingProtocol( const std::vector& protocols, int major, int minor); + const bool SupportExperimental; + cmServerProtocol* Protocol = nullptr; std::vector SupportedProtocols; std::vector Queue; diff --git a/Source/cmServerProtocol.cxx b/Source/cmServerProtocol.cxx index c3a4d8e55..d53ac28a1 100644 --- a/Source/cmServerProtocol.cxx +++ b/Source/cmServerProtocol.cxx @@ -262,3 +262,8 @@ const cmServerResponse cmServerProtocol1_0::Process( return request.ReportError("Unknown command!"); } + +bool cmServerProtocol1_0::IsExperimental() const +{ + return true; +} diff --git a/Source/cmServerProtocol.h b/Source/cmServerProtocol.h index 33183e973..e95c2f19c 100644 --- a/Source/cmServerProtocol.h +++ b/Source/cmServerProtocol.h @@ -82,6 +82,7 @@ public: virtual ~cmServerProtocol() {} virtual std::pair ProtocolVersion() const = 0; + virtual bool IsExperimental() const = 0; virtual const cmServerResponse Process(const cmServerRequest& request) = 0; bool Activate(const cmServerRequest& request, std::string* errorMessage); @@ -100,6 +101,7 @@ class cmServerProtocol1_0 : public cmServerProtocol { public: std::pair ProtocolVersion() const override; + bool IsExperimental() const override; const cmServerResponse Process(const cmServerRequest& request) override; private: diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx index c09ea8bb9..38f00e61f 100644 --- a/Source/cmcmd.cxx +++ b/Source/cmcmd.cxx @@ -913,15 +913,32 @@ int cmcmd::ExecuteCMakeCommand(std::vector& args) } return 0; } else if (args[1] == "server") { - if (args.size() > 2) { + if (args.size() > 3) { cmSystemTools::Error("Too many arguments to start server mode"); 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 - cmServer server; - server.Serve(); - return 0; + cmServer server(supportExperimental); + if (server.Serve()) { + return 0; + } else { + cmSystemTools::Error( + "CMake server could not find any supported protocol. " + "Try with \"--experimental\" to enable " + "experimental support."); + return 1; + } #else + static_cast(supportExperimental); cmSystemTools::Error("CMake was not built with server mode enabled"); return 1; #endif diff --git a/Tests/RunCMake/CommandLine/E_server-arg-stderr.txt b/Tests/RunCMake/CommandLine/E_server-arg-stderr.txt index 7877c01c3..4dcbab93d 100644 --- a/Tests/RunCMake/CommandLine/E_server-arg-stderr.txt +++ b/Tests/RunCMake/CommandLine/E_server-arg-stderr.txt @@ -1 +1 @@ -^CMake Error: Too many arguments to start server mode$ +^CMake Error: Unknown argument for server mode$ diff --git a/Tests/Server/cmakelib.py b/Tests/Server/cmakelib.py index 48ebc89ae..e89b1f06e 100644 --- a/Tests/Server/cmakelib.py +++ b/Tests/Server/cmakelib.py @@ -79,7 +79,7 @@ def writePayload(cmakeCommand, obj): writeRawData(cmakeCommand, json.dumps(obj)) def initProc(cmakeCommand): - cmakeCommand = subprocess.Popen([cmakeCommand, "-E", "server"], + cmakeCommand = subprocess.Popen([cmakeCommand, "-E", "server", "--experimental"], stdin=subprocess.PIPE, stdout=subprocess.PIPE)