ok/jj
1
0
Fork 0
forked from mirrors/jj

cli: add builder type that handles CLI initialization and teardown

parse_args() will probably become more involved to deal with --config-toml,
-R, and repository configs. This builder will hopefully allow us to move
things around without changing the high-level interface.
This commit is contained in:
Yuya Nishihara 2023-01-03 17:03:33 +09:00
parent 406be5e043
commit 9296ae6eb4
4 changed files with 54 additions and 24 deletions

View file

@ -17,7 +17,7 @@ use std::path::Path;
use clap::{FromArgMatches, Subcommand}; use clap::{FromArgMatches, Subcommand};
use git2::Repository; use git2::Repository;
use jujutsu::cli_util::{handle_command_result, parse_args, CommandError, TracingSubscription}; use jujutsu::cli_util::{parse_args, CliRunner, CommandError, TracingSubscription};
use jujutsu::commands::{default_app, run_command}; use jujutsu::commands::{default_app, run_command};
use jujutsu::config::read_config; use jujutsu::config::read_config;
use jujutsu::ui::Ui; use jujutsu::ui::Ui;
@ -64,13 +64,7 @@ fn run(ui: &mut Ui, tracing_subscription: &TracingSubscription) -> Result<(), Co
} }
fn main() { fn main() {
let tracing_subscription = TracingSubscription::init(); CliRunner::init().set_dispatch_fn(run).run_and_exit();
jujutsu::cleanup_guard::init();
let mut ui = Ui::new();
let result = run(&mut ui, &tracing_subscription);
let exit_code = handle_command_result(&mut ui, result);
ui.finalize_writes();
std::process::exit(exit_code);
} }
/// A commit backend that's extremely similar to the Git backend /// A commit backend that's extremely similar to the Git backend

View file

@ -14,7 +14,7 @@
use clap::{FromArgMatches, Subcommand}; use clap::{FromArgMatches, Subcommand};
use jujutsu::cli_util::{ use jujutsu::cli_util::{
handle_command_result, parse_args, short_commit_description, CommandError, TracingSubscription, parse_args, short_commit_description, CliRunner, CommandError, TracingSubscription,
}; };
use jujutsu::commands::{default_app, run_command}; use jujutsu::commands::{default_app, run_command};
use jujutsu::config::read_config; use jujutsu::config::read_config;
@ -62,11 +62,5 @@ fn run(ui: &mut Ui, tracing_subscription: &TracingSubscription) -> Result<(), Co
} }
fn main() { fn main() {
let tracing_subscription = TracingSubscription::init(); CliRunner::init().set_dispatch_fn(run).run_and_exit();
jujutsu::cleanup_guard::init();
let mut ui = Ui::new();
let result = run(&mut ui, &tracing_subscription);
let exit_code = handle_command_result(&mut ui, result);
ui.finalize_writes();
std::process::exit(exit_code);
} }

View file

@ -1682,3 +1682,51 @@ pub fn handle_command_result(ui: &mut Ui, result: Result<(), CommandError>) -> i
} }
} }
} }
/// CLI command builder and runner.
#[must_use]
pub struct CliRunner<F> {
tracing_subscription: TracingSubscription,
dispatch_fn: F,
}
impl CliRunner<()> {
/// Initializes CLI environment and returns a builder. This should be called
/// as early as possible.
pub fn init() -> Self {
let tracing_subscription = TracingSubscription::init();
crate::cleanup_guard::init();
CliRunner {
tracing_subscription,
dispatch_fn: (),
}
}
// TODO: use crate::commands::run_command() by default
pub fn set_dispatch_fn<F>(self, dispatch_fn: F) -> CliRunner<F>
where
F: FnOnce(&mut Ui, &TracingSubscription) -> Result<(), CommandError>,
{
CliRunner {
tracing_subscription: self.tracing_subscription,
dispatch_fn,
}
}
}
impl<F> CliRunner<F>
where
F: FnOnce(&mut Ui, &TracingSubscription) -> Result<(), CommandError>,
{
pub fn run(self, ui: &mut Ui) -> Result<(), CommandError> {
(self.dispatch_fn)(ui, &self.tracing_subscription)
}
pub fn run_and_exit(self) -> ! {
let mut ui = Ui::new();
let result = self.run(&mut ui);
let exit_code = handle_command_result(&mut ui, result);
ui.finalize_writes();
std::process::exit(exit_code);
}
}

View file

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
use jujutsu::cli_util::{handle_command_result, parse_args, CommandError, TracingSubscription}; use jujutsu::cli_util::{parse_args, CliRunner, CommandError, TracingSubscription};
use jujutsu::commands::{default_app, run_command}; use jujutsu::commands::{default_app, run_command};
use jujutsu::config::read_config; use jujutsu::config::read_config;
use jujutsu::ui::Ui; use jujutsu::ui::Ui;
@ -25,11 +25,5 @@ fn run(ui: &mut Ui, tracing_subscription: &TracingSubscription) -> Result<(), Co
} }
fn main() { fn main() {
let tracing_subscription = TracingSubscription::init(); CliRunner::init().set_dispatch_fn(run).run_and_exit();
jujutsu::cleanup_guard::init();
let mut ui = Ui::new();
let result = run(&mut ui, &tracing_subscription);
let exit_code = handle_command_result(&mut ui, result);
ui.finalize_writes();
std::process::exit(exit_code);
} }