rust/chg/src/uihandler.rs
author Martin von Zweigbergk <martinvonz@google.com>
Thu, 01 Oct 2020 09:09:35 -0700
changeset 45620 426294d06ddc
parent 44756 27fe8cc1338f
permissions -rw-r--r--
rust: move rustfmt.toml to repo root so it can be used by `hg fix` `hg fix` runs the formatters from the repo root so it doesn't pick up the `rustfmt.toml` configs we had in each the `hg-core`, `hg-cpython`, and `rhg` packages, which resulted in warnings about `async fn` not existing in Rust 2015. This patch moves the `rustfmt.toml` file to the root so `hg fix` will use it. By putting the `rustfmt.toml` file in a higher-level directory, it also applies to the `chg` and `hgcli` packages. That makes `test-check-rust-format.t` fail, so this patch also applies the new formatting rules to those packages. Differential Revision: https://phab.mercurial-scm.org/D9142
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
39974
a9c5fc436fd5 rust-chg: add callback to handle pager and shell command requests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
     1
// Copyright 2018 Yuya Nishihara <yuya@tcha.org>
a9c5fc436fd5 rust-chg: add callback to handle pager and shell command requests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
     2
//
a9c5fc436fd5 rust-chg: add callback to handle pager and shell command requests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
     3
// This software may be used and distributed according to the terms of the
a9c5fc436fd5 rust-chg: add callback to handle pager and shell command requests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
     4
// GNU General Public License version 2 or any later version.
a9c5fc436fd5 rust-chg: add callback to handle pager and shell command requests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
     5
44750
c794d0da5fb2 rust-chg: reimplement uihandler by using async-trait and tokio-0.2
Yuya Nishihara <yuya@tcha.org>
parents: 44737
diff changeset
     6
use async_trait::async_trait;
39974
a9c5fc436fd5 rust-chg: add callback to handle pager and shell command requests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
     7
use std::io;
a9c5fc436fd5 rust-chg: add callback to handle pager and shell command requests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
     8
use std::os::unix::io::AsRawFd;
a9c5fc436fd5 rust-chg: add callback to handle pager and shell command requests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
     9
use std::os::unix::process::ExitStatusExt;
44737
e9e44e61042b rust-chg: upgrade to futures-0.3 based libraries
Yuya Nishihara <yuya@tcha.org>
parents: 44689
diff changeset
    10
use std::process::Stdio;
39974
a9c5fc436fd5 rust-chg: add callback to handle pager and shell command requests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    11
use tokio;
44755
4b0185841058 rust-chg: do not terminate tokio runtime until pager exits
Yuya Nishihara <yuya@tcha.org>
parents: 44750
diff changeset
    12
use tokio::process::{Child, ChildStdin, Command};
39974
a9c5fc436fd5 rust-chg: add callback to handle pager and shell command requests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    13
44689
6bef9d43cc55 rust-chg: use "crate::" to import local modules
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
    14
use crate::message::CommandSpec;
6bef9d43cc55 rust-chg: use "crate::" to import local modules
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
    15
use crate::procutil;
39974
a9c5fc436fd5 rust-chg: add callback to handle pager and shell command requests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    16
a9c5fc436fd5 rust-chg: add callback to handle pager and shell command requests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    17
/// Callback to process shell command requests received from server.
44750
c794d0da5fb2 rust-chg: reimplement uihandler by using async-trait and tokio-0.2
Yuya Nishihara <yuya@tcha.org>
parents: 44737
diff changeset
    18
#[async_trait]
c794d0da5fb2 rust-chg: reimplement uihandler by using async-trait and tokio-0.2
Yuya Nishihara <yuya@tcha.org>
parents: 44737
diff changeset
    19
pub trait SystemHandler {
39974
a9c5fc436fd5 rust-chg: add callback to handle pager and shell command requests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    20
    type PagerStdin: AsRawFd;
a9c5fc436fd5 rust-chg: add callback to handle pager and shell command requests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    21
a9c5fc436fd5 rust-chg: add callback to handle pager and shell command requests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    22
    /// Handles pager command request.
a9c5fc436fd5 rust-chg: add callback to handle pager and shell command requests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    23
    ///
a9c5fc436fd5 rust-chg: add callback to handle pager and shell command requests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    24
    /// Returns the pipe to be attached to the server if the pager is spawned.
45620
426294d06ddc rust: move rustfmt.toml to repo root so it can be used by `hg fix`
Martin von Zweigbergk <martinvonz@google.com>
parents: 44756
diff changeset
    25
    async fn spawn_pager(
426294d06ddc rust: move rustfmt.toml to repo root so it can be used by `hg fix`
Martin von Zweigbergk <martinvonz@google.com>
parents: 44756
diff changeset
    26
        &mut self,
426294d06ddc rust: move rustfmt.toml to repo root so it can be used by `hg fix`
Martin von Zweigbergk <martinvonz@google.com>
parents: 44756
diff changeset
    27
        spec: &CommandSpec,
426294d06ddc rust: move rustfmt.toml to repo root so it can be used by `hg fix`
Martin von Zweigbergk <martinvonz@google.com>
parents: 44756
diff changeset
    28
    ) -> io::Result<Self::PagerStdin>;
39974
a9c5fc436fd5 rust-chg: add callback to handle pager and shell command requests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    29
a9c5fc436fd5 rust-chg: add callback to handle pager and shell command requests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    30
    /// Handles system command request.
a9c5fc436fd5 rust-chg: add callback to handle pager and shell command requests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    31
    ///
a9c5fc436fd5 rust-chg: add callback to handle pager and shell command requests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    32
    /// Returns command exit code (positive) or signal number (negative).
44750
c794d0da5fb2 rust-chg: reimplement uihandler by using async-trait and tokio-0.2
Yuya Nishihara <yuya@tcha.org>
parents: 44737
diff changeset
    33
    async fn run_system(&mut self, spec: &CommandSpec) -> io::Result<i32>;
39974
a9c5fc436fd5 rust-chg: add callback to handle pager and shell command requests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    34
}
a9c5fc436fd5 rust-chg: add callback to handle pager and shell command requests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    35
a9c5fc436fd5 rust-chg: add callback to handle pager and shell command requests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    36
/// Default cHg implementation to process requests received from server.
44755
4b0185841058 rust-chg: do not terminate tokio runtime until pager exits
Yuya Nishihara <yuya@tcha.org>
parents: 44750
diff changeset
    37
pub struct ChgUiHandler {
4b0185841058 rust-chg: do not terminate tokio runtime until pager exits
Yuya Nishihara <yuya@tcha.org>
parents: 44750
diff changeset
    38
    pager: Option<Child>,
4b0185841058 rust-chg: do not terminate tokio runtime until pager exits
Yuya Nishihara <yuya@tcha.org>
parents: 44750
diff changeset
    39
}
39974
a9c5fc436fd5 rust-chg: add callback to handle pager and shell command requests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    40
a9c5fc436fd5 rust-chg: add callback to handle pager and shell command requests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    41
impl ChgUiHandler {
a9c5fc436fd5 rust-chg: add callback to handle pager and shell command requests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    42
    pub fn new() -> ChgUiHandler {
44755
4b0185841058 rust-chg: do not terminate tokio runtime until pager exits
Yuya Nishihara <yuya@tcha.org>
parents: 44750
diff changeset
    43
        ChgUiHandler { pager: None }
4b0185841058 rust-chg: do not terminate tokio runtime until pager exits
Yuya Nishihara <yuya@tcha.org>
parents: 44750
diff changeset
    44
    }
4b0185841058 rust-chg: do not terminate tokio runtime until pager exits
Yuya Nishihara <yuya@tcha.org>
parents: 44750
diff changeset
    45
4b0185841058 rust-chg: do not terminate tokio runtime until pager exits
Yuya Nishihara <yuya@tcha.org>
parents: 44750
diff changeset
    46
    /// Waits until the pager process exits.
4b0185841058 rust-chg: do not terminate tokio runtime until pager exits
Yuya Nishihara <yuya@tcha.org>
parents: 44750
diff changeset
    47
    pub async fn wait_pager(&mut self) -> io::Result<()> {
4b0185841058 rust-chg: do not terminate tokio runtime until pager exits
Yuya Nishihara <yuya@tcha.org>
parents: 44750
diff changeset
    48
        if let Some(p) = self.pager.take() {
4b0185841058 rust-chg: do not terminate tokio runtime until pager exits
Yuya Nishihara <yuya@tcha.org>
parents: 44750
diff changeset
    49
            p.await?;
4b0185841058 rust-chg: do not terminate tokio runtime until pager exits
Yuya Nishihara <yuya@tcha.org>
parents: 44750
diff changeset
    50
        }
4b0185841058 rust-chg: do not terminate tokio runtime until pager exits
Yuya Nishihara <yuya@tcha.org>
parents: 44750
diff changeset
    51
        Ok(())
39974
a9c5fc436fd5 rust-chg: add callback to handle pager and shell command requests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    52
    }
a9c5fc436fd5 rust-chg: add callback to handle pager and shell command requests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    53
}
a9c5fc436fd5 rust-chg: add callback to handle pager and shell command requests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    54
44750
c794d0da5fb2 rust-chg: reimplement uihandler by using async-trait and tokio-0.2
Yuya Nishihara <yuya@tcha.org>
parents: 44737
diff changeset
    55
#[async_trait]
39974
a9c5fc436fd5 rust-chg: add callback to handle pager and shell command requests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    56
impl SystemHandler for ChgUiHandler {
a9c5fc436fd5 rust-chg: add callback to handle pager and shell command requests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    57
    type PagerStdin = ChildStdin;
a9c5fc436fd5 rust-chg: add callback to handle pager and shell command requests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    58
45620
426294d06ddc rust: move rustfmt.toml to repo root so it can be used by `hg fix`
Martin von Zweigbergk <martinvonz@google.com>
parents: 44756
diff changeset
    59
    async fn spawn_pager(
426294d06ddc rust: move rustfmt.toml to repo root so it can be used by `hg fix`
Martin von Zweigbergk <martinvonz@google.com>
parents: 44756
diff changeset
    60
        &mut self,
426294d06ddc rust: move rustfmt.toml to repo root so it can be used by `hg fix`
Martin von Zweigbergk <martinvonz@google.com>
parents: 44756
diff changeset
    61
        spec: &CommandSpec,
426294d06ddc rust: move rustfmt.toml to repo root so it can be used by `hg fix`
Martin von Zweigbergk <martinvonz@google.com>
parents: 44756
diff changeset
    62
    ) -> io::Result<Self::PagerStdin> {
426294d06ddc rust: move rustfmt.toml to repo root so it can be used by `hg fix`
Martin von Zweigbergk <martinvonz@google.com>
parents: 44756
diff changeset
    63
        let mut pager =
426294d06ddc rust: move rustfmt.toml to repo root so it can be used by `hg fix`
Martin von Zweigbergk <martinvonz@google.com>
parents: 44756
diff changeset
    64
            new_shell_command(&spec).stdin(Stdio::piped()).spawn()?;
44737
e9e44e61042b rust-chg: upgrade to futures-0.3 based libraries
Yuya Nishihara <yuya@tcha.org>
parents: 44689
diff changeset
    65
        let pin = pager.stdin.take().unwrap();
39974
a9c5fc436fd5 rust-chg: add callback to handle pager and shell command requests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    66
        procutil::set_blocking_fd(pin.as_raw_fd())?;
40119
e70b616a077b rust-chg: remove SIGCHLD handler which won't work in oxidized chg
Yuya Nishihara <yuya@tcha.org>
parents: 39974
diff changeset
    67
        // TODO: if pager exits, notify the server with SIGPIPE immediately.
e70b616a077b rust-chg: remove SIGCHLD handler which won't work in oxidized chg
Yuya Nishihara <yuya@tcha.org>
parents: 39974
diff changeset
    68
        // otherwise the server won't get SIGPIPE if it does not write
e70b616a077b rust-chg: remove SIGCHLD handler which won't work in oxidized chg
Yuya Nishihara <yuya@tcha.org>
parents: 39974
diff changeset
    69
        // anything. (issue5278)
e70b616a077b rust-chg: remove SIGCHLD handler which won't work in oxidized chg
Yuya Nishihara <yuya@tcha.org>
parents: 39974
diff changeset
    70
        // kill(peerpid, SIGPIPE);
44755
4b0185841058 rust-chg: do not terminate tokio runtime until pager exits
Yuya Nishihara <yuya@tcha.org>
parents: 44750
diff changeset
    71
        self.pager = Some(pager);
44750
c794d0da5fb2 rust-chg: reimplement uihandler by using async-trait and tokio-0.2
Yuya Nishihara <yuya@tcha.org>
parents: 44737
diff changeset
    72
        Ok(pin)
39974
a9c5fc436fd5 rust-chg: add callback to handle pager and shell command requests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    73
    }
a9c5fc436fd5 rust-chg: add callback to handle pager and shell command requests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    74
44750
c794d0da5fb2 rust-chg: reimplement uihandler by using async-trait and tokio-0.2
Yuya Nishihara <yuya@tcha.org>
parents: 44737
diff changeset
    75
    async fn run_system(&mut self, spec: &CommandSpec) -> io::Result<i32> {
c794d0da5fb2 rust-chg: reimplement uihandler by using async-trait and tokio-0.2
Yuya Nishihara <yuya@tcha.org>
parents: 44737
diff changeset
    76
        let status = new_shell_command(&spec).spawn()?.await?;
44756
27fe8cc1338f rust-chg: clean up excessive indents
Yuya Nishihara <yuya@tcha.org>
parents: 44755
diff changeset
    77
        let code = status
27fe8cc1338f rust-chg: clean up excessive indents
Yuya Nishihara <yuya@tcha.org>
parents: 44755
diff changeset
    78
            .code()
27fe8cc1338f rust-chg: clean up excessive indents
Yuya Nishihara <yuya@tcha.org>
parents: 44755
diff changeset
    79
            .or_else(|| status.signal().map(|n| -n))
27fe8cc1338f rust-chg: clean up excessive indents
Yuya Nishihara <yuya@tcha.org>
parents: 44755
diff changeset
    80
            .expect("either exit code or signal should be set");
27fe8cc1338f rust-chg: clean up excessive indents
Yuya Nishihara <yuya@tcha.org>
parents: 44755
diff changeset
    81
        Ok(code)
39974
a9c5fc436fd5 rust-chg: add callback to handle pager and shell command requests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    82
    }
a9c5fc436fd5 rust-chg: add callback to handle pager and shell command requests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    83
}
a9c5fc436fd5 rust-chg: add callback to handle pager and shell command requests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    84
a9c5fc436fd5 rust-chg: add callback to handle pager and shell command requests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    85
fn new_shell_command(spec: &CommandSpec) -> Command {
a9c5fc436fd5 rust-chg: add callback to handle pager and shell command requests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    86
    let mut builder = Command::new("/bin/sh");
a9c5fc436fd5 rust-chg: add callback to handle pager and shell command requests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    87
    builder
a9c5fc436fd5 rust-chg: add callback to handle pager and shell command requests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    88
        .arg("-c")
a9c5fc436fd5 rust-chg: add callback to handle pager and shell command requests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    89
        .arg(&spec.command)
a9c5fc436fd5 rust-chg: add callback to handle pager and shell command requests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    90
        .current_dir(&spec.current_dir)
a9c5fc436fd5 rust-chg: add callback to handle pager and shell command requests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    91
        .env_clear()
a9c5fc436fd5 rust-chg: add callback to handle pager and shell command requests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    92
        .envs(spec.envs.iter().cloned());
a9c5fc436fd5 rust-chg: add callback to handle pager and shell command requests
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    93
    builder
43818
ce088b38f92b rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40119
diff changeset
    94
}