##// END OF EJS Templates
rhg: simplify the subcommands macro...
rhg: simplify the subcommands macro Reduce the scope of the macro to only generate individual `SubCommand` values. This way, it will be easy to tweak the behavior of `add_subcommand_args` and `subcommand_run_fn` without having to understand the details of the macro. It also lets us easy add commands that don't fit the idiom, for example the "admin::" commands or "script::" commands.

File last commit:

r45239:4b018584 default
r53419:92c6c8ab default
Show More
main.rs
88 lines | 2.4 KiB | application/rls-services+xml | RustLexer
Yuya Nishihara
rust-chg: add project skeleton...
r40003 // Copyright 2018 Yuya Nishihara <yuya@tcha.org>
//
// This software may be used and distributed according to the terms of the
// GNU General Public License version 2 or any later version.
Yuya Nishihara
rust-chg: collect server flags from command arguments...
r45172 use chg::locator::{self, Locator};
Yuya Nishihara
rust-chg: install signal handlers to forward signals to server...
r40156 use chg::procutil;
Yuya Nishihara
rust-chg: modernize entry function...
r45238 use chg::ChgUiHandler;
Yuya Nishihara
rust-chg: add main program...
r40015 use std::env;
use std::io;
Yuya Nishihara
rust-chg: modernize entry function...
r45238 use std::io::Write;
Yuya Nishihara
rust-chg: add main program...
r40015 use std::process;
Yuya Nishihara
rust-chg: install logger if $CHGDEBUG is set...
r40324 use std::time::Instant;
Yuya Nishihara
rust-chg: add main program...
r40015
Yuya Nishihara
rust-chg: install logger if $CHGDEBUG is set...
r40324 struct DebugLogger {
start: Instant,
}
impl DebugLogger {
pub fn new() -> DebugLogger {
DebugLogger {
start: Instant::now(),
}
}
}
impl log::Log for DebugLogger {
fn enabled(&self, metadata: &log::Metadata) -> bool {
metadata.target().starts_with("chg::")
}
fn log(&self, record: &log::Record) {
if self.enabled(record.metadata()) {
// just make the output looks similar to chg of C
let l = format!("{}", record.level()).to_lowercase();
let t = self.start.elapsed();
Gregory Szorc
rust: run rustfmt...
r44270 writeln!(
io::stderr(),
"chg: {}: {}.{:06} {}",
l,
t.as_secs(),
t.subsec_micros(),
record.args()
)
.unwrap_or(());
Yuya Nishihara
rust-chg: install logger if $CHGDEBUG is set...
r40324 }
}
Gregory Szorc
rust: run rustfmt...
r44270 fn flush(&self) {}
Yuya Nishihara
rust-chg: install logger if $CHGDEBUG is set...
r40324 }
Yuya Nishihara
rust-chg: add project skeleton...
r40003 fn main() {
Yuya Nishihara
rust-chg: install logger if $CHGDEBUG is set...
r40324 if env::var_os("CHGDEBUG").is_some() {
log::set_boxed_logger(Box::new(DebugLogger::new()))
.expect("any logger should not be installed yet");
log::set_max_level(log::LevelFilter::Debug);
}
Yuya Nishihara
rust-chg: spawn server process if not running...
r45161 // TODO: add loop detection by $CHGINTERNALMARK
Yuya Nishihara
rust-chg: move get_umask() call out of run() function...
r45184 let umask = unsafe { procutil::get_umask() }; // not thread safe
let code = run(umask).unwrap_or_else(|err| {
Yuya Nishihara
rust-chg: suppress panic while writing chg error to stderr...
r40322 writeln!(io::stderr(), "chg: abort: {}", err).unwrap_or(());
Yuya Nishihara
rust-chg: add main program...
r40015 255
});
process::exit(code);
Yuya Nishihara
rust-chg: add project skeleton...
r40003 }
Yuya Nishihara
rust-chg: add main program...
r40015
Yuya Nishihara
rust-chg: modernize entry function...
r45238 #[tokio::main]
async fn run(umask: u32) -> io::Result<i32> {
Yuya Nishihara
rust-chg: collect server flags from command arguments...
r45172 let mut loc = Locator::prepare_from_env()?;
loc.set_early_args(locator::collect_early_args(env::args_os().skip(1)));
Yuya Nishihara
rust-chg: modernize entry function...
r45238 let mut handler = ChgUiHandler::new();
let mut client = loc.connect().await?;
client
.attach_io(&io::stdin(), &io::stdout(), &io::stderr())
.await?;
client.set_umask(umask).await?;
let pid = client.server_spec().process_id.unwrap();
let pgid = client.server_spec().process_group_id;
procutil::setup_signal_handler_once(pid, pgid)?;
let code = client
.run_command_chg(&mut handler, env::args_os().skip(1))
.await?;
procutil::restore_signal_handler_once()?;
Yuya Nishihara
rust-chg: do not terminate tokio runtime until pager exits...
r45239 handler.wait_pager().await?;
Yuya Nishihara
rust-chg: modernize entry function...
r45238 Ok(code)
Yuya Nishihara
rust-chg: add main program...
r40015 }