annotate rust/chg/src/main.rs @ 44681:00ac60658654

rust-chg: collect server flags from command arguments This is the reimplementation of testsensitiveflag() and setcmdserverargs() of chg.c. Differential Revision: https://phab.mercurial-scm.org/D8380
author Yuya Nishihara <yuya@tcha.org>
date Sun, 07 Oct 2018 16:46:30 +0900
parents 0a2516efc463
children 065048e66f32
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
39967
aab43d5861bb rust-chg: add project skeleton
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
1 // Copyright 2018 Yuya Nishihara <yuya@tcha.org>
aab43d5861bb rust-chg: add project skeleton
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
2 //
aab43d5861bb rust-chg: add project skeleton
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
3 // This software may be used and distributed according to the terms of the
aab43d5861bb rust-chg: add project skeleton
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
4 // GNU General Public License version 2 or any later version.
aab43d5861bb rust-chg: add project skeleton
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
5
39979
6bdee4bc181a rust-chg: add main program
Yuya Nishihara <yuya@tcha.org>
parents: 39967
diff changeset
6 extern crate chg;
6bdee4bc181a rust-chg: add main program
Yuya Nishihara <yuya@tcha.org>
parents: 39967
diff changeset
7 extern crate futures;
40288
87c76e5f3427 rust-chg: install logger if $CHGDEBUG is set
Yuya Nishihara <yuya@tcha.org>
parents: 40286
diff changeset
8 extern crate log;
39979
6bdee4bc181a rust-chg: add main program
Yuya Nishihara <yuya@tcha.org>
parents: 39967
diff changeset
9 extern crate tokio;
6bdee4bc181a rust-chg: add main program
Yuya Nishihara <yuya@tcha.org>
parents: 39967
diff changeset
10 extern crate tokio_hglib;
6bdee4bc181a rust-chg: add main program
Yuya Nishihara <yuya@tcha.org>
parents: 39967
diff changeset
11
44681
00ac60658654 rust-chg: collect server flags from command arguments
Yuya Nishihara <yuya@tcha.org>
parents: 44673
diff changeset
12 use chg::locator::{self, Locator};
40120
89742f1fa6cb rust-chg: install signal handlers to forward signals to server
Yuya Nishihara <yuya@tcha.org>
parents: 39979
diff changeset
13 use chg::procutil;
43818
ce088b38f92b rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40288
diff changeset
14 use chg::{ChgClientExt, ChgUiHandler};
39979
6bdee4bc181a rust-chg: add main program
Yuya Nishihara <yuya@tcha.org>
parents: 39967
diff changeset
15 use futures::sync::oneshot;
6bdee4bc181a rust-chg: add main program
Yuya Nishihara <yuya@tcha.org>
parents: 39967
diff changeset
16 use std::env;
6bdee4bc181a rust-chg: add main program
Yuya Nishihara <yuya@tcha.org>
parents: 39967
diff changeset
17 use std::io;
6bdee4bc181a rust-chg: add main program
Yuya Nishihara <yuya@tcha.org>
parents: 39967
diff changeset
18 use std::process;
40288
87c76e5f3427 rust-chg: install logger if $CHGDEBUG is set
Yuya Nishihara <yuya@tcha.org>
parents: 40286
diff changeset
19 use std::time::Instant;
39979
6bdee4bc181a rust-chg: add main program
Yuya Nishihara <yuya@tcha.org>
parents: 39967
diff changeset
20 use tokio::prelude::*;
6bdee4bc181a rust-chg: add main program
Yuya Nishihara <yuya@tcha.org>
parents: 39967
diff changeset
21
40288
87c76e5f3427 rust-chg: install logger if $CHGDEBUG is set
Yuya Nishihara <yuya@tcha.org>
parents: 40286
diff changeset
22 struct DebugLogger {
87c76e5f3427 rust-chg: install logger if $CHGDEBUG is set
Yuya Nishihara <yuya@tcha.org>
parents: 40286
diff changeset
23 start: Instant,
87c76e5f3427 rust-chg: install logger if $CHGDEBUG is set
Yuya Nishihara <yuya@tcha.org>
parents: 40286
diff changeset
24 }
87c76e5f3427 rust-chg: install logger if $CHGDEBUG is set
Yuya Nishihara <yuya@tcha.org>
parents: 40286
diff changeset
25
87c76e5f3427 rust-chg: install logger if $CHGDEBUG is set
Yuya Nishihara <yuya@tcha.org>
parents: 40286
diff changeset
26 impl DebugLogger {
87c76e5f3427 rust-chg: install logger if $CHGDEBUG is set
Yuya Nishihara <yuya@tcha.org>
parents: 40286
diff changeset
27 pub fn new() -> DebugLogger {
87c76e5f3427 rust-chg: install logger if $CHGDEBUG is set
Yuya Nishihara <yuya@tcha.org>
parents: 40286
diff changeset
28 DebugLogger {
87c76e5f3427 rust-chg: install logger if $CHGDEBUG is set
Yuya Nishihara <yuya@tcha.org>
parents: 40286
diff changeset
29 start: Instant::now(),
87c76e5f3427 rust-chg: install logger if $CHGDEBUG is set
Yuya Nishihara <yuya@tcha.org>
parents: 40286
diff changeset
30 }
87c76e5f3427 rust-chg: install logger if $CHGDEBUG is set
Yuya Nishihara <yuya@tcha.org>
parents: 40286
diff changeset
31 }
87c76e5f3427 rust-chg: install logger if $CHGDEBUG is set
Yuya Nishihara <yuya@tcha.org>
parents: 40286
diff changeset
32 }
87c76e5f3427 rust-chg: install logger if $CHGDEBUG is set
Yuya Nishihara <yuya@tcha.org>
parents: 40286
diff changeset
33
87c76e5f3427 rust-chg: install logger if $CHGDEBUG is set
Yuya Nishihara <yuya@tcha.org>
parents: 40286
diff changeset
34 impl log::Log for DebugLogger {
87c76e5f3427 rust-chg: install logger if $CHGDEBUG is set
Yuya Nishihara <yuya@tcha.org>
parents: 40286
diff changeset
35 fn enabled(&self, metadata: &log::Metadata) -> bool {
87c76e5f3427 rust-chg: install logger if $CHGDEBUG is set
Yuya Nishihara <yuya@tcha.org>
parents: 40286
diff changeset
36 metadata.target().starts_with("chg::")
87c76e5f3427 rust-chg: install logger if $CHGDEBUG is set
Yuya Nishihara <yuya@tcha.org>
parents: 40286
diff changeset
37 }
87c76e5f3427 rust-chg: install logger if $CHGDEBUG is set
Yuya Nishihara <yuya@tcha.org>
parents: 40286
diff changeset
38
87c76e5f3427 rust-chg: install logger if $CHGDEBUG is set
Yuya Nishihara <yuya@tcha.org>
parents: 40286
diff changeset
39 fn log(&self, record: &log::Record) {
87c76e5f3427 rust-chg: install logger if $CHGDEBUG is set
Yuya Nishihara <yuya@tcha.org>
parents: 40286
diff changeset
40 if self.enabled(record.metadata()) {
87c76e5f3427 rust-chg: install logger if $CHGDEBUG is set
Yuya Nishihara <yuya@tcha.org>
parents: 40286
diff changeset
41 // just make the output looks similar to chg of C
87c76e5f3427 rust-chg: install logger if $CHGDEBUG is set
Yuya Nishihara <yuya@tcha.org>
parents: 40286
diff changeset
42 let l = format!("{}", record.level()).to_lowercase();
87c76e5f3427 rust-chg: install logger if $CHGDEBUG is set
Yuya Nishihara <yuya@tcha.org>
parents: 40286
diff changeset
43 let t = self.start.elapsed();
43818
ce088b38f92b rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40288
diff changeset
44 writeln!(
ce088b38f92b rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40288
diff changeset
45 io::stderr(),
ce088b38f92b rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40288
diff changeset
46 "chg: {}: {}.{:06} {}",
ce088b38f92b rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40288
diff changeset
47 l,
ce088b38f92b rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40288
diff changeset
48 t.as_secs(),
ce088b38f92b rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40288
diff changeset
49 t.subsec_micros(),
ce088b38f92b rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40288
diff changeset
50 record.args()
ce088b38f92b rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40288
diff changeset
51 )
ce088b38f92b rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40288
diff changeset
52 .unwrap_or(());
40288
87c76e5f3427 rust-chg: install logger if $CHGDEBUG is set
Yuya Nishihara <yuya@tcha.org>
parents: 40286
diff changeset
53 }
87c76e5f3427 rust-chg: install logger if $CHGDEBUG is set
Yuya Nishihara <yuya@tcha.org>
parents: 40286
diff changeset
54 }
87c76e5f3427 rust-chg: install logger if $CHGDEBUG is set
Yuya Nishihara <yuya@tcha.org>
parents: 40286
diff changeset
55
43818
ce088b38f92b rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40288
diff changeset
56 fn flush(&self) {}
40288
87c76e5f3427 rust-chg: install logger if $CHGDEBUG is set
Yuya Nishihara <yuya@tcha.org>
parents: 40286
diff changeset
57 }
87c76e5f3427 rust-chg: install logger if $CHGDEBUG is set
Yuya Nishihara <yuya@tcha.org>
parents: 40286
diff changeset
58
39967
aab43d5861bb rust-chg: add project skeleton
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
59 fn main() {
40288
87c76e5f3427 rust-chg: install logger if $CHGDEBUG is set
Yuya Nishihara <yuya@tcha.org>
parents: 40286
diff changeset
60 if env::var_os("CHGDEBUG").is_some() {
87c76e5f3427 rust-chg: install logger if $CHGDEBUG is set
Yuya Nishihara <yuya@tcha.org>
parents: 40286
diff changeset
61 log::set_boxed_logger(Box::new(DebugLogger::new()))
87c76e5f3427 rust-chg: install logger if $CHGDEBUG is set
Yuya Nishihara <yuya@tcha.org>
parents: 40286
diff changeset
62 .expect("any logger should not be installed yet");
87c76e5f3427 rust-chg: install logger if $CHGDEBUG is set
Yuya Nishihara <yuya@tcha.org>
parents: 40286
diff changeset
63 log::set_max_level(log::LevelFilter::Debug);
87c76e5f3427 rust-chg: install logger if $CHGDEBUG is set
Yuya Nishihara <yuya@tcha.org>
parents: 40286
diff changeset
64 }
87c76e5f3427 rust-chg: install logger if $CHGDEBUG is set
Yuya Nishihara <yuya@tcha.org>
parents: 40286
diff changeset
65
44671
bb936e25a84a rust-chg: spawn server process if not running
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
66 // TODO: add loop detection by $CHGINTERNALMARK
bb936e25a84a rust-chg: spawn server process if not running
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
67
39979
6bdee4bc181a rust-chg: add main program
Yuya Nishihara <yuya@tcha.org>
parents: 39967
diff changeset
68 let code = run().unwrap_or_else(|err| {
40286
af52181f71ff rust-chg: suppress panic while writing chg error to stderr
Yuya Nishihara <yuya@tcha.org>
parents: 40120
diff changeset
69 writeln!(io::stderr(), "chg: abort: {}", err).unwrap_or(());
39979
6bdee4bc181a rust-chg: add main program
Yuya Nishihara <yuya@tcha.org>
parents: 39967
diff changeset
70 255
6bdee4bc181a rust-chg: add main program
Yuya Nishihara <yuya@tcha.org>
parents: 39967
diff changeset
71 });
6bdee4bc181a rust-chg: add main program
Yuya Nishihara <yuya@tcha.org>
parents: 39967
diff changeset
72 process::exit(code);
39967
aab43d5861bb rust-chg: add project skeleton
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
73 }
39979
6bdee4bc181a rust-chg: add main program
Yuya Nishihara <yuya@tcha.org>
parents: 39967
diff changeset
74
6bdee4bc181a rust-chg: add main program
Yuya Nishihara <yuya@tcha.org>
parents: 39967
diff changeset
75 fn run() -> io::Result<i32> {
44681
00ac60658654 rust-chg: collect server flags from command arguments
Yuya Nishihara <yuya@tcha.org>
parents: 44673
diff changeset
76 let mut loc = Locator::prepare_from_env()?;
00ac60658654 rust-chg: collect server flags from command arguments
Yuya Nishihara <yuya@tcha.org>
parents: 44673
diff changeset
77 loc.set_early_args(locator::collect_early_args(env::args_os().skip(1)));
39979
6bdee4bc181a rust-chg: add main program
Yuya Nishihara <yuya@tcha.org>
parents: 39967
diff changeset
78 let handler = ChgUiHandler::new();
6bdee4bc181a rust-chg: add main program
Yuya Nishihara <yuya@tcha.org>
parents: 39967
diff changeset
79 let (result_tx, result_rx) = oneshot::channel();
44671
bb936e25a84a rust-chg: spawn server process if not running
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
80 let fut = loc
bb936e25a84a rust-chg: spawn server process if not running
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
81 .connect()
44673
0a2516efc463 rust-chg: move set_current_dir() to Locator
Yuya Nishihara <yuya@tcha.org>
parents: 44671
diff changeset
82 .and_then(|(_, client)| client.attach_io(io::stdin(), io::stdout(), io::stderr()))
39979
6bdee4bc181a rust-chg: add main program
Yuya Nishihara <yuya@tcha.org>
parents: 39967
diff changeset
83 .and_then(|client| {
40120
89742f1fa6cb rust-chg: install signal handlers to forward signals to server
Yuya Nishihara <yuya@tcha.org>
parents: 39979
diff changeset
84 let pid = client.server_spec().process_id.unwrap();
89742f1fa6cb rust-chg: install signal handlers to forward signals to server
Yuya Nishihara <yuya@tcha.org>
parents: 39979
diff changeset
85 let pgid = client.server_spec().process_group_id;
89742f1fa6cb rust-chg: install signal handlers to forward signals to server
Yuya Nishihara <yuya@tcha.org>
parents: 39979
diff changeset
86 procutil::setup_signal_handler_once(pid, pgid)?;
89742f1fa6cb rust-chg: install signal handlers to forward signals to server
Yuya Nishihara <yuya@tcha.org>
parents: 39979
diff changeset
87 Ok(client)
89742f1fa6cb rust-chg: install signal handlers to forward signals to server
Yuya Nishihara <yuya@tcha.org>
parents: 39979
diff changeset
88 })
43818
ce088b38f92b rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40288
diff changeset
89 .and_then(|client| client.run_command_chg(handler, env::args_os().skip(1)))
39979
6bdee4bc181a rust-chg: add main program
Yuya Nishihara <yuya@tcha.org>
parents: 39967
diff changeset
90 .map(|(_client, _handler, code)| {
40120
89742f1fa6cb rust-chg: install signal handlers to forward signals to server
Yuya Nishihara <yuya@tcha.org>
parents: 39979
diff changeset
91 procutil::restore_signal_handler_once()?;
39979
6bdee4bc181a rust-chg: add main program
Yuya Nishihara <yuya@tcha.org>
parents: 39967
diff changeset
92 Ok(code)
6bdee4bc181a rust-chg: add main program
Yuya Nishihara <yuya@tcha.org>
parents: 39967
diff changeset
93 })
43818
ce088b38f92b rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40288
diff changeset
94 .or_else(|err| Ok(Err(err))) // pass back error to caller
39979
6bdee4bc181a rust-chg: add main program
Yuya Nishihara <yuya@tcha.org>
parents: 39967
diff changeset
95 .map(|res| result_tx.send(res).unwrap());
6bdee4bc181a rust-chg: add main program
Yuya Nishihara <yuya@tcha.org>
parents: 39967
diff changeset
96 tokio::run(fut);
43818
ce088b38f92b rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40288
diff changeset
97 result_rx.wait().unwrap_or(Err(io::Error::new(
ce088b38f92b rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40288
diff changeset
98 io::ErrorKind::Other,
ce088b38f92b rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40288
diff changeset
99 "no exit code set",
ce088b38f92b rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40288
diff changeset
100 )))
39979
6bdee4bc181a rust-chg: add main program
Yuya Nishihara <yuya@tcha.org>
parents: 39967
diff changeset
101 }