D8385: hgk: remove a "b" used on a kwargs expansion, the keys are strs

2020-04-06 Thread spectral (Kyle Lippincott)
spectral created this revision.
Herald added a subscriber: mercurial-devel.
Herald added a reviewer: hg-reviewers.

REPOSITORY
  rHG Mercurial

BRANCH
  default

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

AFFECTED FILES
  hgext/hgk.py

CHANGE DETAILS

diff --git a/hgext/hgk.py b/hgext/hgk.py
--- a/hgext/hgk.py
+++ b/hgext/hgk.py
@@ -358,7 +358,7 @@
 )
 def revlist(ui, repo, *revs, **opts):
 """print revisions"""
-if opts[b'header']:
+if opts['header']:
 full = b"commit"
 else:
 full = None



To: spectral, #hg-reviewers
Cc: mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: Moving patches traffic to a another list?

2020-04-06 Thread Augie Fackler

> On Apr 5, 2020, at 19:38, Pierre-Yves David  
> wrote:
> 
> A couple of day ago, you asked on IRC for help on how to create a new list. 
> It looks like the `newlist` utility is meant for that. A small blog post give 
> some more details here:
> 
> http://data.agaric.com/create-mailman-list-through-command-line
> 
> And the utility seems to have a manpage
> 
> http://manpages.ubuntu.com/manpages/bionic/man8/newlist.8.html
> 
> Does this matches what we have installed ? 

That was a huge help! Okay, I think I've done the right thing. Can you go check?

Also, I have an admin password here for list moderation. Do you want that so 
you can mod through the initial phab messages etc?

I'm also happy to temporarily make you a phab admin to set the right 
knobs...I'm assuming we can't ansible-ize that?
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


mercurial@44667: new changeset (1 on stable)

2020-04-06 Thread Mercurial Commits
New changeset (1 on stable) in mercurial:

https://www.mercurial-scm.org/repo/hg/rev/b561f3a68e41
changeset:   44667:b561f3a68e41
branch:  stable
tag: tip
parent:  44650:3f29c5edac8e
user:Pierre-Yves David 
date:Mon Apr 06 00:24:57 2020 +0200
summary: discovery: avoid wrongly saying there are nothing to pull

-- 
Repository URL: https://www.mercurial-scm.org/repo/hg
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D8384: rust-chg: silence warning about dated coding style

2020-04-06 Thread yuja (Yuya Nishihara)
yuja created this revision.
Herald added a subscriber: mercurial-devel.
Herald added a reviewer: hg-reviewers.

REPOSITORY
  rHG Mercurial

BRANCH
  default

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

AFFECTED FILES
  rust/chg/src/message.rs
  rust/chg/src/runcommand.rs

CHANGE DETAILS

diff --git a/rust/chg/src/runcommand.rs b/rust/chg/src/runcommand.rs
--- a/rust/chg/src/runcommand.rs
+++ b/rust/chg/src/runcommand.rs
@@ -37,7 +37,7 @@
 Finished,
 }
 
-type CommandPoll = io::Result<(AsyncS<(Client, H, i32), 
CommandState>)>;
+type CommandPoll = io::Result, H, i32), 
CommandState>>;
 
 /// Future resolves to `(exit_code, client)`.
 #[must_use = "futures do nothing unless polled"]
diff --git a/rust/chg/src/message.rs b/rust/chg/src/message.rs
--- a/rust/chg/src/message.rs
+++ b/rust/chg/src/message.rs
@@ -152,7 +152,7 @@
 
 fn new_parse_error(error: E) -> io::Error
 where
-E: Into>,
+E: Into>,
 {
 io::Error::new(io::ErrorKind::InvalidData, error)
 }



To: yuja, #hg-reviewers
Cc: mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D8382: rust-chg: send client side umask to server

2020-04-06 Thread yuja (Yuya Nishihara)
yuja created this revision.
Herald added a subscriber: mercurial-devel.
Herald added a reviewer: hg-reviewers.

REVISION SUMMARY
  This is equivalent to forwardumask() of hgclient.c.

REPOSITORY
  rHG Mercurial

BRANCH
  default

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

AFFECTED FILES
  rust/chg/src/clientext.rs
  rust/chg/src/locator.rs
  rust/chg/src/main.rs
  rust/chg/src/procutil.rs

CHANGE DETAILS

diff --git a/rust/chg/src/procutil.rs b/rust/chg/src/procutil.rs
--- a/rust/chg/src/procutil.rs
+++ b/rust/chg/src/procutil.rs
@@ -25,6 +25,19 @@
 unsafe { libc::geteuid() }
 }
 
+/// Returns the umask of the current process.
+///
+/// # Safety
+///
+/// This is unsafe because the umask value is temporarily changed, and
+/// the change can be observed from the other threads. Don't call this in
+/// multi-threaded context.
+pub unsafe fn get_umask() -> u32 {
+let mask = libc::umask(0);
+libc::umask(mask);
+mask
+}
+
 /// Changes the given fd to blocking mode.
 pub fn set_blocking_fd(fd: RawFd) -> io::Result<()> {
 let flags = unsafe { libc::fcntl(fd, libc::F_GETFL) };
diff --git a/rust/chg/src/main.rs b/rust/chg/src/main.rs
--- a/rust/chg/src/main.rs
+++ b/rust/chg/src/main.rs
@@ -73,6 +73,7 @@
 }
 
 fn run() -> io::Result {
+let umask = unsafe { procutil::get_umask() }; // not thread safe
 let mut loc = Locator::prepare_from_env()?;
 loc.set_early_args(locator::collect_early_args(env::args_os().skip(1)));
 let handler = ChgUiHandler::new();
@@ -80,6 +81,7 @@
 let fut = loc
 .connect()
 .and_then(|(_, client)| client.attach_io(io::stdin(), io::stdout(), 
io::stderr()))
+.and_then(move |client| client.set_umask(umask))
 .and_then(|client| {
 let pid = client.server_spec().process_id.unwrap();
 let pgid = client.server_spec().process_group_id;
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
@@ -24,8 +24,14 @@
 use super::message::{Instruction, ServerSpec};
 use super::procutil;
 
-const REQUIRED_SERVER_CAPABILITIES: &[&str] =
-&["attachio", "chdir", "runcommand", "setenv", "validate"];
+const REQUIRED_SERVER_CAPABILITIES: &[&str] = &[
+"attachio",
+"chdir",
+"runcommand",
+"setenv",
+"setumask2",
+"validate",
+];
 
 /// Helper to connect to and spawn a server process.
 #[derive(Clone, Debug)]
diff --git a/rust/chg/src/clientext.rs b/rust/chg/src/clientext.rs
--- a/rust/chg/src/clientext.rs
+++ b/rust/chg/src/clientext.rs
@@ -5,9 +5,10 @@
 
 //! cHg extensions to command server client.
 
-use bytes::Bytes;
+use bytes::{BufMut, Bytes, BytesMut};
 use std::ffi::OsStr;
 use std::io;
+use std::mem;
 use std::os::unix::ffi::OsStrExt;
 use std::os::unix::io::AsRawFd;
 use std::path::Path;
@@ -41,6 +42,9 @@
 I: IntoIterator,
 P: AsRef;
 
+/// Changes the umask of the server process.
+fn set_umask(self, mask: u32) -> OneShotRequest;
+
 /// Runs the specified Mercurial command with cHg extension.
 fn run_command_chg(self, handler: H, args: I) -> ChgRunCommand
 where
@@ -90,6 +94,12 @@
 OneShotRequest::start_with_args(self, b"setenv", 
message::pack_env_vars_os(vars))
 }
 
+fn set_umask(self, mask: u32) -> OneShotRequest {
+let mut args = BytesMut::with_capacity(mem::size_of_val(&mask));
+args.put_u32_be(mask);
+OneShotRequest::start_with_args(self, b"setumask2", args)
+}
+
 fn run_command_chg(self, handler: H, args: I) -> ChgRunCommand
 where
 I: IntoIterator,



To: yuja, #hg-reviewers
Cc: mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D8383: rust-chg: update name of the server process

2020-04-06 Thread yuja (Yuya Nishihara)
yuja created this revision.
Herald added a subscriber: mercurial-devel.
Herald added a reviewer: hg-reviewers.

REVISION SUMMARY
  This is a copy of updateprocname() of hgclient.c.
  
  At this point, rust-chg is basically functional. I did dogfooding for
  a couple of weeks in 2018. There are a few remaining tasks:
  
  a. loop detection by CHGINTERNALMARK
   b. forward unsupported commands (notably serve -d) to real hg
   c. better handling of early server exception
   d. modernize codebase (2018 edition, impl trait, async/await)
  
  For (d), we'll probably want to switch to async-std, but I'm thinking of
  upgrading to Tokio 0.2 as an intermediate step since process API isn't
  ported to async-std yet. I'm pretty sure future migration to async-std
  will be painless compared to the mass rewrite from futures-0.1 to 0.3.
  
  https://github.com/async-rs/async-std/issues/22

REPOSITORY
  rHG Mercurial

BRANCH
  default

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

AFFECTED FILES
  rust/chg/src/clientext.rs
  rust/chg/src/locator.rs

CHANGE DETAILS

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
@@ -196,6 +196,17 @@
 Ok((loc, client))
 })
 .and_then(|(loc, client)| {
+// It's purely optional, and the server might not support this 
command.
+if client.server_spec().capabilities.contains("setprocname") {
+let fut = client
+.set_process_name(format!("chg[worker/{}]", 
loc.process_id))
+.map(|client| (loc, client));
+Either::A(fut)
+} else {
+Either::B(future::ok((loc, client)))
+}
+})
+.and_then(|(loc, client)| {
 client
 .set_current_dir(&loc.current_dir)
 .map(|client| (loc, client))
diff --git a/rust/chg/src/clientext.rs b/rust/chg/src/clientext.rs
--- a/rust/chg/src/clientext.rs
+++ b/rust/chg/src/clientext.rs
@@ -42,6 +42,11 @@
 I: IntoIterator,
 P: AsRef;
 
+/// Changes the process title of the server.
+fn set_process_name(self, name: P) -> OneShotRequest
+where
+P: AsRef;
+
 /// Changes the umask of the server process.
 fn set_umask(self, mask: u32) -> OneShotRequest;
 
@@ -94,6 +99,13 @@
 OneShotRequest::start_with_args(self, b"setenv", 
message::pack_env_vars_os(vars))
 }
 
+fn set_process_name(self, name: P) -> OneShotRequest
+where
+P: AsRef,
+{
+OneShotRequest::start_with_args(self, b"setprocname", 
name.as_ref().as_bytes())
+}
+
 fn set_umask(self, mask: u32) -> OneShotRequest {
 let mut args = BytesMut::with_capacity(mem::size_of_val(&mask));
 args.put_u32_be(mask);



To: yuja, #hg-reviewers
Cc: mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D8381: rust-chg: add config validation and process returned instructions

2020-04-06 Thread yuja (Yuya Nishihara)
yuja created this revision.
Herald added a subscriber: mercurial-devel.
Herald added a reviewer: hg-reviewers.

REVISION SUMMARY
  This is the reimplementation of runinstructions() and main() in chg.c.
  
  In Rust version, we only pass in early arguments to the server as the locator
  doesn't know the full arguments. This should be fine since these arguments
  are just passed in to _earlyparseopts() and _parseconfig(), which means the
  server doesn't need full arguments.
  
  Another difference is the handling of the "exit " instruction. In Rust
  version, we can simply reuse the connection instead of "exit(code)" as the
  command error isn't displayed yet. That's because the client-side stdio is not
  attached until the connection is validated. This behavior is cleaner than C,
  but it also means that the early server exception wouldn't be propagated to
  client because stderr isn't attached. So we might have to reconsider when to
  attach/detach the server stdio.

REPOSITORY
  rHG Mercurial

BRANCH
  default

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

AFFECTED FILES
  rust/chg/src/locator.rs

CHANGE DETAILS

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
@@ -21,10 +21,11 @@
 use tokio_timer;
 
 use super::clientext::ChgClientExt;
-use super::message::ServerSpec;
+use super::message::{Instruction, ServerSpec};
 use super::procutil;
 
-const REQUIRED_SERVER_CAPABILITIES: &[&str] = &["attachio", "chdir", 
"runcommand", "setenv"];
+const REQUIRED_SERVER_CAPABILITIES: &[&str] =
+&["attachio", "chdir", "runcommand", "setenv", "validate"];
 
 /// Helper to connect to and spawn a server process.
 #[derive(Clone, Debug)]
@@ -35,6 +36,7 @@
 env_vars: Vec<(OsString, OsString)>,
 process_id: u32,
 base_sock_path: PathBuf,
+redirect_sock_path: Option,
 timeout: Duration,
 }
 
@@ -51,6 +53,7 @@
 env_vars: env::vars_os().collect(),
 process_id: process::id(),
 base_sock_path: prepare_server_socket_path()?,
+redirect_sock_path: None,
 timeout: default_timeout(),
 })
 }
@@ -77,16 +80,110 @@
 ///
 /// The server process will be spawned if not running.
 pub fn connect(self) -> impl Future {
-self.try_connect()
+future::loop_fn((self, 0), |(loc, cnt)| {
+if cnt < 10 {
+let fut = loc
+.try_connect()
+.and_then(|(loc, client)| {
+client
+.validate(&loc.hg_early_args)
+.map(|(client, instructions)| (loc, client, 
instructions))
+})
+.and_then(move |(loc, client, instructions)| {
+loc.run_instructions(client, instructions, cnt)
+});
+Either::A(fut)
+} else {
+let msg = format!(
+concat!(
+"too many redirections.\n",
+"Please make sure {:?} is not a wrapper which ",
+"changes sensitive environment variables ",
+"before executing hg. If you have to use a ",
+"wrapper, wrap chg instead of hg.",
+),
+loc.hg_command
+);
+Either::B(future::err(io::Error::new(io::ErrorKind::Other, 
msg)))
+}
+})
+}
+
+/// Runs instructions received from the server.
+fn run_instructions(
+mut self,
+client: UnixClient,
+instructions: Vec,
+cnt: usize,
+) -> io::Result> {
+let mut reconnect = false;
+for inst in instructions {
+debug!("instruction: {:?}", inst);
+match inst {
+Instruction::Exit(_) => {
+// Just returns the current connection to run the
+// unparsable command and report the error
+return Ok(Loop::Break((self, client)));
+}
+Instruction::Reconnect => {
+reconnect = true;
+}
+Instruction::Redirect(path) => {
+if path.parent() != self.base_sock_path.parent() {
+let msg = format!(
+"insecure redirect instruction from server: {}",
+path.display()
+);
+return Err(io::Error::new(io::ErrorKind::InvalidData, 
msg));
+}
+self.redirect_sock_path = Some(path);
+reconnect = true;
+}
+Instruction::Unlink(path) => {
+if path.parent() != self.base_sock_path.parent() {
+let msg = format!(
+"insec

D8380: rust-chg: collect server flags from command arguments

2020-04-06 Thread yuja (Yuya Nishihara)
yuja created this revision.
Herald added a subscriber: mercurial-devel.
Herald added a reviewer: hg-reviewers.

REVISION SUMMARY
  This is the reimplementation of testsensitiveflag() and setcmdserverargs()
  of chg.c.

REPOSITORY
  rHG Mercurial

BRANCH
  default

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

AFFECTED FILES
  rust/chg/src/locator.rs
  rust/chg/src/main.rs

CHANGE DETAILS

diff --git a/rust/chg/src/main.rs b/rust/chg/src/main.rs
--- a/rust/chg/src/main.rs
+++ b/rust/chg/src/main.rs
@@ -9,7 +9,7 @@
 extern crate tokio;
 extern crate tokio_hglib;
 
-use chg::locator::Locator;
+use chg::locator::{self, Locator};
 use chg::procutil;
 use chg::{ChgClientExt, ChgUiHandler};
 use futures::sync::oneshot;
@@ -73,7 +73,8 @@
 }
 
 fn run() -> io::Result {
-let loc = Locator::prepare_from_env()?;
+let mut loc = Locator::prepare_from_env()?;
+loc.set_early_args(locator::collect_early_args(env::args_os().skip(1)));
 let handler = ChgUiHandler::new();
 let (result_tx, result_rx) = oneshot::channel();
 let fut = loc
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
@@ -30,6 +30,7 @@
 #[derive(Clone, Debug)]
 pub struct Locator {
 hg_command: OsString,
+hg_early_args: Vec,
 current_dir: PathBuf,
 env_vars: Vec<(OsString, OsString)>,
 process_id: u32,
@@ -45,6 +46,7 @@
 pub fn prepare_from_env() -> io::Result {
 Ok(Locator {
 hg_command: default_hg_command(),
+hg_early_args: Vec::new(),
 current_dir: env::current_dir()?,
 env_vars: env::vars_os().collect(),
 process_id: process::id(),
@@ -62,6 +64,15 @@
 OsString::from_vec(buf).into()
 }
 
+/// Specifies the arguments to be passed to the server at start.
+pub fn set_early_args(&mut self, args: I)
+where
+I: IntoIterator,
+P: AsRef,
+{
+self.hg_early_args = args.into_iter().map(|a| 
a.as_ref().to_owned()).collect();
+}
+
 /// Connects to the server.
 ///
 /// The server process will be spawned if not running.
@@ -109,6 +120,7 @@
 .arg(&sock_path)
 .arg("--daemon-postexec")
 .arg("chdir:/")
+.args(&self.hg_early_args)
 .current_dir(&self.current_dir)
 .env_clear()
 .envs(self.env_vars.iter().cloned())
@@ -275,3 +287,100 @@
 Err(io::Error::new(io::ErrorKind::Other, msg))
 }
 }
+
+/// Collects arguments which need to be passed to the server at start.
+pub fn collect_early_args(args: I) -> Vec
+where
+I: IntoIterator,
+P: AsRef,
+{
+let mut args_iter = args.into_iter();
+let mut early_args = Vec::new();
+while let Some(arg) = args_iter.next() {
+let argb = arg.as_ref().as_bytes();
+if argb == b"--" {
+break;
+} else if argb.starts_with(b"--") {
+let mut split = argb[2..].splitn(2, |&c| c == b'=');
+match split.next().unwrap() {
+b"traceback" => {
+if split.next().is_none() {
+early_args.push(arg.as_ref().to_owned());
+}
+}
+b"config" | b"cwd" | b"repo" | b"repository" => {
+if split.next().is_some() {
+// --=
+early_args.push(arg.as_ref().to_owned());
+} else {
+// -- 
+args_iter.next().map(|val| {
+early_args.push(arg.as_ref().to_owned());
+early_args.push(val.as_ref().to_owned());
+});
+}
+}
+_ => {}
+}
+} else if argb.starts_with(b"-R") {
+if argb.len() > 2 {
+// -R
+early_args.push(arg.as_ref().to_owned());
+} else {
+// -R 
+args_iter.next().map(|val| {
+early_args.push(arg.as_ref().to_owned());
+early_args.push(val.as_ref().to_owned());
+});
+}
+}
+}
+
+early_args
+}
+
+#[cfg(test)]
+mod tests {
+use super::*;
+
+#[test]
+fn collect_early_args_some() {
+assert!(collect_early_args(&[] as &[&OsStr]).is_empty());
+assert!(collect_early_args(&["log"]).is_empty());
+assert_eq!(
+collect_early_args(&["log", "-Ra", "foo"]),
+os_string_vec_from(&[b"-Ra"])
+);
+assert_eq!(
+collect_early_args(&["log", "-R", "repo", "", "--traceback", "a"]),
+os_string_vec_from(&[b"-R", b"repo", b"--traceback"])
+);
+assert_eq!(
+collect_early_args(&["log", "--config", "diff.git=1", "-q"]),
+os_string_vec_from(&[b"--config", b"diff.git=1"])
+)

D8379: rust-chg: add interface to run "validate" request

2020-04-06 Thread yuja (Yuya Nishihara)
yuja created this revision.
Herald added a subscriber: mercurial-devel.
Herald added a reviewer: hg-reviewers.

REPOSITORY
  rHG Mercurial

BRANCH
  default

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

AFFECTED FILES
  rust/chg/src/clientext.rs

CHANGE DETAILS

diff --git a/rust/chg/src/clientext.rs b/rust/chg/src/clientext.rs
--- a/rust/chg/src/clientext.rs
+++ b/rust/chg/src/clientext.rs
@@ -5,15 +5,17 @@
 
 //! cHg extensions to command server client.
 
+use bytes::Bytes;
 use std::ffi::OsStr;
+use std::io;
 use std::os::unix::ffi::OsStrExt;
 use std::os::unix::io::AsRawFd;
 use std::path::Path;
-use tokio_hglib::protocol::OneShotRequest;
+use tokio_hglib::protocol::{OneShotQuery, OneShotRequest};
 use tokio_hglib::{Client, Connection};
 
 use super::attachio::AttachIo;
-use super::message;
+use super::message::{self, Instruction};
 use super::runcommand::ChgRunCommand;
 use super::uihandler::SystemHandler;
 
@@ -45,6 +47,19 @@
 I: IntoIterator,
 P: AsRef,
 H: SystemHandler;
+
+/// Validates if the server can run Mercurial commands with the expected
+/// configuration.
+///
+/// The `args` should contain early command arguments such as `--config`
+/// and `-R`.
+///
+/// Client-side environment must be sent prior to this request, by
+/// `set_current_dir()` and `set_env_vars_os()`.
+fn validate(self, args: I) -> OneShotQuery 
io::Result>>
+where
+I: IntoIterator,
+P: AsRef;
 }
 
 impl ChgClientExt for Client
@@ -83,4 +98,17 @@
 {
 ChgRunCommand::with_client(self, handler, message::pack_args_os(args))
 }
+
+fn validate(self, args: I) -> OneShotQuery 
io::Result>>
+where
+I: IntoIterator,
+P: AsRef,
+{
+OneShotQuery::start_with_args(
+self,
+b"validate",
+message::pack_args_os(args),
+message::parse_instructions,
+)
+}
 }



To: yuja, #hg-reviewers
Cc: mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D8378: rust-chg: add helper to parse instructions sent from server

2020-04-06 Thread yuja (Yuya Nishihara)
yuja created this revision.
Herald added a subscriber: mercurial-devel.
Herald added a reviewer: hg-reviewers.

REVISION SUMMARY
  This is well structured version of runinstructions() of chg.c.

REPOSITORY
  rHG Mercurial

BRANCH
  default

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

AFFECTED FILES
  rust/chg/src/message.rs

CHANGE DETAILS

diff --git a/rust/chg/src/message.rs b/rust/chg/src/message.rs
--- a/rust/chg/src/message.rs
+++ b/rust/chg/src/message.rs
@@ -10,6 +10,7 @@
 use std::ffi::{OsStr, OsString};
 use std::io;
 use std::os::unix::ffi::OsStrExt;
+use std::path::PathBuf;
 
 pub use tokio_hglib::message::*; // re-exports
 
@@ -67,6 +68,42 @@
 }
 }
 
+/// Client-side instruction requested by the server.
+#[derive(Clone, Debug, Eq, PartialEq)]
+pub enum Instruction {
+Exit(i32),
+Reconnect,
+Redirect(PathBuf),
+Unlink(PathBuf),
+}
+
+/// Parses validation result into instructions.
+pub fn parse_instructions(data: Bytes) -> io::Result> {
+let mut instructions = Vec::new();
+for l in data.split(|&c| c == b'\0') {
+if l.is_empty() {
+continue;
+}
+let mut s = l.splitn(2, |&c| c == b' ');
+let inst = match (s.next().unwrap(), s.next()) {
+(b"exit", Some(arg)) => decode_latin1(arg)
+.parse()
+.map(Instruction::Exit)
+.map_err(|_| new_parse_error(format!("invalid exit code: 
{:?}", arg)))?,
+(b"reconnect", None) => Instruction::Reconnect,
+(b"redirect", Some(arg)) => {
+Instruction::Redirect(OsStr::from_bytes(arg).to_owned().into())
+}
+(b"unlink", Some(arg)) => 
Instruction::Unlink(OsStr::from_bytes(arg).to_owned().into()),
+_ => {
+return Err(new_parse_error(format!("unknown command: {:?}", 
l)));
+}
+};
+instructions.push(inst);
+}
+Ok(instructions)
+}
+
 // allocate large buffer as environment variables can be quite long
 const INITIAL_PACKED_ENV_VARS_CAPACITY: usize = 4096;
 
@@ -168,6 +205,50 @@
 }
 
 #[test]
+fn parse_instructions_good() {
+let src = [
+b"exit 123".as_ref(),
+b"reconnect".as_ref(),
+b"redirect /whatever".as_ref(),
+b"unlink /someother".as_ref(),
+]
+.join(&0);
+let insts = vec![
+Instruction::Exit(123),
+Instruction::Reconnect,
+Instruction::Redirect(path_buf_from(b"/whatever")),
+Instruction::Unlink(path_buf_from(b"/someother")),
+];
+assert_eq!(parse_instructions(Bytes::from(src)).unwrap(), insts);
+}
+
+#[test]
+fn parse_instructions_empty() {
+assert_eq!(parse_instructions(Bytes::new()).unwrap(), vec![]);
+assert_eq!(
+parse_instructions(Bytes::from_static(b"\0")).unwrap(),
+vec![]
+);
+}
+
+#[test]
+fn parse_instructions_malformed_exit_code() {
+assert!(parse_instructions(Bytes::from_static(b"exit foo")).is_err());
+}
+
+#[test]
+fn parse_instructions_missing_argument() {
+assert!(parse_instructions(Bytes::from_static(b"exit")).is_err());
+assert!(parse_instructions(Bytes::from_static(b"redirect")).is_err());
+assert!(parse_instructions(Bytes::from_static(b"unlink")).is_err());
+}
+
+#[test]
+fn parse_instructions_unknown_command() {
+assert!(parse_instructions(Bytes::from_static(b"quit 0")).is_err());
+}
+
+#[test]
 fn pack_env_vars_os_good() {
 assert_eq!(
 pack_env_vars_os(vec![] as Vec<(OsString, OsString)>),
@@ -229,4 +310,8 @@
 fn os_string_pair_from(k: &[u8], v: &[u8]) -> (OsString, OsString) {
 (os_string_from(k), os_string_from(v))
 }
+
+fn path_buf_from(s: &[u8]) -> PathBuf {
+os_string_from(s).into()
+}
 }



To: yuja, #hg-reviewers
Cc: mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH STABLE V2] discovery: avoid wrongly saying there are nothing to pull

2020-04-06 Thread Yuya Nishihara
On Mon, 06 Apr 2020 01:33:28 +0200, Pierre-Yves David wrote:
> # HG changeset patch
> # User Pierre-Yves David 
> # Date 1586125497 -7200
> #  Mon Apr 06 00:24:57 2020 +0200
> # Branch stable
> # Node ID 2d761788a0f24e85d6d7e2784a72fa13ccf5217b
> # Parent  3f29c5edac8e4a663f062960f65bba7bc8a26536
> # EXP-Topic pull-shadow
> # Available At https://foss.heptapod.net/octobus/mercurial-devel/
> #  hg pull https://foss.heptapod.net/octobus/mercurial-devel/ -r 
> 2d761788a0f2
> discovery: avoid wrongly saying there are nothing to pull

Sounds good, queued, thanks.
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH STABLE] discovery: avoid wrongly saying there are nothing to pull

2020-04-06 Thread Pierre-Yves David

This one left with unwanted change, disregard it in favor on v2

On 4/6/20 1:32 AM, Pierre-Yves David wrote:

# HG changeset patch
# User Pierre-Yves David 
# Date 1586125497 -7200
#  Mon Apr 06 00:24:57 2020 +0200
# Branch stable
# Node ID e58f537d4c33b4d203b867eca11a1e19ae65e4b9
# Parent  3f29c5edac8e4a663f062960f65bba7bc8a26536
# EXP-Topic pull-shadow
# Available At https://foss.heptapod.net/octobus/mercurial-devel/
#  hg pull https://foss.heptapod.net/octobus/mercurial-devel/ -r 
e58f537d4c33
discovery: avoid wrongly saying there are nothing to pull

We can be in a situation where a revision passed through `hg pull --rev REV`.
For example the server could be during heads advertisement, to hide some pull
request. Or obsolete/hidden content could be explicitly pulled.

So in this case the lookup associated to `REV` returned successfully, but the
normal discovery will find all advertised heads already known locally. This flip
a special boolean `anyinc` that will prevent any fetch attempt, preventing `REV`
to be pulled over.

We add three line of code to detect this case and make sure a pull actually
happens.

My main target is to make some third party extensions happy (I expect the
associated test to move upstream with the extension). However this fix already
make some of the `infinitepush` test happier.

diff --git a/mercurial/discovery.py b/mercurial/discovery.py
--- a/mercurial/discovery.py
+++ b/mercurial/discovery.py
@@ -67,6 +67,10 @@ def findcommonincoming(repo, remote, hea
  ancestorsof=ancestorsof,
  )
  common, anyinc, srvheads = res
+if heads and not anyinc:
+# server could be lying on the advertised heads
+has_node = repo.changelog.hasnode
+anyinc = any(not has_node(n) for n in heads)
  return (list(common), anyinc, heads or list(srvheads))
  
  
diff --git a/tests/test-infinitepush-ci.t b/tests/test-infinitepush-ci.t

--- a/tests/test-infinitepush-ci.t
+++ b/tests/test-infinitepush-ci.t
@@ -249,12 +249,12 @@ XXX: we should show better message when
$ hg pull -r b4e4bce660512ad3e71189e14588a70ac8e31fef
pulling from ssh://user@dummy/repo
searching for changes
-  no changes found
adding changesets
adding manifests
adding file changes
added 4 changesets with 4 changes to 4 files
new changesets eaba929e866c:b4e4bce66051
+  (run 'hg update' to get a working copy)
$ hg glog
o  5:b4e4bce66051 added e
|  public
diff --git a/tests/test-infinitepush.t b/tests/test-infinitepush.t
--- a/tests/test-infinitepush.t
+++ b/tests/test-infinitepush.t
@@ -165,3 +165,36 @@ Make sure phase on the client is public.
(run 'hg heads .' to see heads, 'hg merge' to merge)
$ hg log -r scratch/scratchontopofpublic -T '{phase}'
draft (no-eol)
+
+
+  $ cd ..
+
+Try pulling explicite rev from a vanillia fresh clone
+
+(similar to something done with client3, but without the extension this time)
+
+  $ hg clone ssh://user@dummy/repo client4
+  requesting all changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 2 changesets with 2 changes to 2 files
+  new changesets 67145f466344:a79b6597f322
+  updating to branch default
+  2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+
+  $ cd client4
+  $ cat << EOF >> .hg/hgrc
+  > [extensions]
+  > infinitepush=!
+  > EOF
+  $ hg pull -r `cat ../testpullbycommithash1`
+  pulling from ssh://user@dummy/repo
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to 1 files (+1 heads)
+  new changesets 33910bfe6ffe (1 drafts)
+  (run 'hg heads' to see heads, 'hg merge' to merge)
+  $ cd ..



--
Pierre-Yves David
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel