Patchwork D8361: rust-chg: abort if server doesn't have required capabilities

login
register
mail settings
Submitter phabricator
Date April 3, 2020, 7:17 p.m.
Message ID <5d6a1654c791f52de8b39d9fdb9ccca0@localhost.localdomain>
Download mbox | patch
Permalink /patch/46019/
State Not Applicable
Headers show

Comments

phabricator - April 3, 2020, 7:17 p.m.
Closed by commit rHG7bf45ed9e25e: rust-chg: abort if server doesn&#039;t have required capabilities (authored by yuja).
This revision was automatically updated to reflect the committed changes.
This revision was not accepted when it landed; it landed in state "Needs Review".

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D8361?vs=20963&id=20990

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8361/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D8361

AFFECTED FILES
  rust/chg/src/locator.rs

CHANGE DETAILS




To: yuja, #hg-reviewers, Alphare
Cc: mercurial-devel

Patch

diff --git a/rust/chg/src/locator.rs b/rust/chg/src/locator.rs
--- a/rust/chg/src/locator.rs
+++ b/rust/chg/src/locator.rs
@@ -20,8 +20,11 @@ 
 use tokio_process::{Child, CommandExt};
 use tokio_timer;
 
+use super::message::ServerSpec;
 use super::procutil;
 
+const REQUIRED_SERVER_CAPABILITIES: &[&str] = &["attachio", "chdir", "runcommand"];
+
 /// Helper to connect to and spawn a server process.
 #[derive(Clone, Debug)]
 pub struct Locator {
@@ -68,10 +71,15 @@ 
     /// Tries to connect to the existing server, or spawns new if not running.
     fn try_connect(self) -> impl Future<Item = (Self, UnixClient), Error = io::Error> {
         debug!("try connect to {}", self.base_sock_path.display());
-        UnixClient::connect(self.base_sock_path.clone()).then(|res| match res {
-            Ok(client) => Either::A(future::ok((self, client))),
-            Err(_) => Either::B(self.spawn_connect()),
-        })
+        UnixClient::connect(self.base_sock_path.clone())
+            .then(|res| match res {
+                Ok(client) => Either::A(future::ok((self, client))),
+                Err(_) => Either::B(self.spawn_connect()),
+            })
+            .and_then(|(loc, client)| {
+                check_server_capabilities(client.server_spec())?;
+                Ok((loc, client))
+            })
     }
 
     /// Spawns new server process and connects to it.
@@ -239,3 +247,20 @@ 
         Err(io::Error::new(io::ErrorKind::Other, "insecure directory"))
     }
 }
+
+fn check_server_capabilities(spec: &ServerSpec) -> io::Result<()> {
+    let unsupported: Vec<_> = REQUIRED_SERVER_CAPABILITIES
+        .iter()
+        .cloned()
+        .filter(|&s| !spec.capabilities.contains(s))
+        .collect();
+    if unsupported.is_empty() {
+        Ok(())
+    } else {
+        let msg = format!(
+            "insufficient server capabilities: {}",
+            unsupported.join(", ")
+        );
+        Err(io::Error::new(io::ErrorKind::Other, msg))
+    }
+}