From 178f177dac9ec3c8d5b40e4d020b865cf4136bcc Mon Sep 17 00:00:00 2001 From: David Hewson Date: Fri, 3 Jan 2020 22:51:45 +0000 Subject: [PATCH] perf(hg_branch): Replace direct calls to `hg` (#803) perf: don't use hg process to get branch / bookmark information, each call was taking 250ms and it was making on average 2 calls. the branch and bookmark information is available in files in the root of the repo, use that instead. now takes 300 micro seconds fix: do not use .hgignore to decide if it is an hg repo. was providing false positives. #721 fix: after changing branch the new branch was not show (the old branch was shown), the new branch is now correctly shown. #722 fix: if no branch override was set it would say (no branch) however if you commited in that state you would commit to the branch default so say that instead --- src/modules/hg_branch.rs | 37 +++++++++++++----------------------- tests/testsuite/hg_branch.rs | 4 ++-- 2 files changed, 15 insertions(+), 26 deletions(-) diff --git a/src/modules/hg_branch.rs b/src/modules/hg_branch.rs index 34b666c49..23d924822 100644 --- a/src/modules/hg_branch.rs +++ b/src/modules/hg_branch.rs @@ -1,4 +1,3 @@ -use std::process::Command; use unicode_segmentation::UnicodeSegmentation; use super::{Context, Module, RootModuleConfig}; @@ -9,11 +8,7 @@ use crate::configs::hg_branch::HgBranchConfig; /// /// Will display the bookmark or branch name if the current directory is an hg repo pub fn module<'a>(context: &'a Context) -> Option> { - let is_hg_repo = context - .try_begin_scan()? - .set_files(&[".hgignore"]) - .set_folders(&[".hg"]) - .is_match(); + let is_hg_repo = context.try_begin_scan()?.set_folders(&[".hg"]).is_match(); if !is_hg_repo { return None; @@ -25,7 +20,6 @@ pub fn module<'a>(context: &'a Context) -> Option> { module.get_prefix().set_value("on "); - let truncation_symbol = get_graphemes(config.truncation_symbol, 1); module.create_segment("symbol", &config.symbol); // TODO: Once error handling is implemented, warn the user if their config @@ -40,15 +34,13 @@ pub fn module<'a>(context: &'a Context) -> Option> { config.truncation_length as usize }; - let get_branch_name = |tmpl| get_hg_log_template(tmpl, context); - - let branch_name = get_branch_name("{activebookmark}") - .or_else(|| get_branch_name("{branch}")) - .unwrap_or_else(|| "(no branch)".to_string()); + let branch_name = + get_hg_current_bookmark(context).unwrap_or_else(|| get_hg_branch_name(context)); let truncated_graphemes = get_graphemes(&branch_name, len); // The truncation symbol should only be added if we truncated let truncated_and_symbol = if len < graphemes_len(&branch_name) { + let truncation_symbol = get_graphemes(config.truncation_symbol, 1); truncated_graphemes + &truncation_symbol } else { truncated_graphemes @@ -62,19 +54,16 @@ pub fn module<'a>(context: &'a Context) -> Option> { Some(module) } -fn get_hg_log_template(hgtmpl: &str, ctx: &Context) -> Option { - let output = Command::new("hg") - .args(&["log", "-r", ".", "--template", hgtmpl]) - .current_dir(&ctx.current_dir) - .output() - .ok() - .and_then(|output| String::from_utf8(output.stdout).ok())?; +fn get_hg_branch_name(ctx: &Context) -> String { + std::fs::read_to_string(ctx.current_dir.join(".hg").join("branch")) + .map(|s| s.trim().into()) + .unwrap_or_else(|_| "default".to_string()) +} - if output.is_empty() { - None - } else { - Some(output) - } +fn get_hg_current_bookmark(ctx: &Context) -> Option { + std::fs::read_to_string(ctx.current_dir.join(".hg").join("bookmarks.current")) + .map(|s| s.trim().into()) + .ok() } fn get_graphemes(text: &str, length: usize) -> String { diff --git a/tests/testsuite/hg_branch.rs b/tests/testsuite/hg_branch.rs index 12d2dc9bd..dc54b620d 100644 --- a/tests/testsuite/hg_branch.rs +++ b/tests/testsuite/hg_branch.rs @@ -29,7 +29,7 @@ fn test_hg_get_branch_fails() -> io::Result<()> { expect_hg_branch_with_config( tempdir.path(), "", - &[Expect::BranchName(&"(no branch)"), Expect::NoTruncation], + &[Expect::BranchName(&"default"), Expect::NoTruncation], ) } @@ -156,7 +156,7 @@ fn expect_hg_branch_with_config( let actual = String::from_utf8(output.stdout).unwrap(); - let mut expect_branch_name = "(no branch)"; + let mut expect_branch_name = "default"; let mut expect_style = Color::Purple.bold(); let mut expect_symbol = "\u{e0a0}"; let mut expect_truncation_symbol = "…";