# HG changeset patch # User Pulkit Goyal <7895pulkit@gmail.com> # Date 2021-04-10 19:20:10 # Node ID ebdef62837984851d63d9c0e5792053445814c7b # Parent 8a6e6b62b9a38ba4b5e81befd88ff368659d9a12 rhg: read [paths] for `--repository` value hg parses `-R` and `--repository` CLI arguments "early" in order to know which local repository to load config from. (Config can then affect whether or how to fall back.) The value of of those arguments can be not only a filesystem path, but also an alias configured in the `[paths]` section. This part was missing in rhg and this patch implements that. The current patch still lacks functionality to read config of current repository if we are not at root of repo. That will be fixed in upcoming patches. A new crate `home` is added to get path of home directory. Differential Revision: https://phab.mercurial-scm.org/D10296 diff --git a/rust/Cargo.lock b/rust/Cargo.lock --- a/rust/Cargo.lock +++ b/rust/Cargo.lock @@ -831,6 +831,7 @@ dependencies = [ "env_logger", "format-bytes", "hg-core", + "home", "lazy_static", "log", "micro-timer", diff --git a/rust/hg-core/src/config.rs b/rust/hg-core/src/config.rs --- a/rust/hg-core/src/config.rs +++ b/rust/hg-core/src/config.rs @@ -12,5 +12,5 @@ mod config; mod layer; mod values; -pub use config::{Config, ConfigValueParseError}; +pub use config::{Config, ConfigSource, ConfigValueParseError}; pub use layer::{ConfigError, ConfigParseError}; diff --git a/rust/hg-core/src/repo.rs b/rust/hg-core/src/repo.rs --- a/rust/hg-core/src/repo.rs +++ b/rust/hg-core/src/repo.rs @@ -53,7 +53,7 @@ impl Repo { /// Having two methods would just move that `if` to almost all callers. pub fn find( config: &Config, - explicit_path: Option<&Path>, + explicit_path: Option, ) -> Result { if let Some(root) = explicit_path { if root.join(".hg").is_dir() { diff --git a/rust/rhg/Cargo.toml b/rust/rhg/Cargo.toml --- a/rust/rhg/Cargo.toml +++ b/rust/rhg/Cargo.toml @@ -12,6 +12,7 @@ hg-core = { path = "../hg-core"} chrono = "0.4.19" clap = "2.33.1" derive_more = "0.99" +home = "0.5.3" lazy_static = "1.4.0" log = "0.4.11" micro-timer = "0.3.1" diff --git a/rust/rhg/src/main.rs b/rust/rhg/src/main.rs --- a/rust/rhg/src/main.rs +++ b/rust/rhg/src/main.rs @@ -5,7 +5,7 @@ use clap::AppSettings; use clap::Arg; use clap::ArgMatches; use format_bytes::{format_bytes, join}; -use hg::config::Config; +use hg::config::{Config, ConfigSource}; use hg::repo::{Repo, RepoError}; use hg::utils::files::{get_bytes_from_os_str, get_path_from_bytes}; use hg::utils::SliceExt; @@ -167,8 +167,74 @@ fn main() { ) } } - let repo_path = early_args.repo.as_deref().map(get_path_from_bytes); - let repo_result = match Repo::find(&non_repo_config, repo_path) { + let repo_arg = early_args.repo.unwrap_or(Vec::new()); + let repo_path: Option = { + if repo_arg.is_empty() { + None + } else { + let local_config = { + if std::env::var_os("HGRCSKIPREPO").is_none() { + let current_dir = hg::utils::current_dir(); + // TODO: handle errors from current_dir + if let Ok(current_dir_path) = current_dir { + let config_files = vec![ + ConfigSource::AbsPath( + current_dir_path.join(".hg/hgrc"), + ), + ConfigSource::AbsPath( + current_dir_path.join(".hg/hgrc-not-shared"), + ), + ]; + // TODO: handle errors from + // `load_from_explicit_sources` + Config::load_from_explicit_sources(config_files).ok() + } else { + None + } + } else { + None + } + }; + + let non_repo_config_val = { + let non_repo_val = non_repo_config.get(b"paths", &repo_arg); + match &non_repo_val { + Some(val) if val.len() > 0 => home::home_dir() + .unwrap_or_else(|| PathBuf::from("~")) + .join(get_path_from_bytes(val)) + .canonicalize() + // TODO: handle error and make it similar to python + // implementation maybe? + .ok(), + _ => None, + } + }; + + let config_val = match &local_config { + None => non_repo_config_val, + Some(val) => { + let local_config_val = val.get(b"paths", &repo_arg); + match &local_config_val { + Some(val) if val.len() > 0 => { + // presence of a local_config assures that + // current_dir + // wont result in an Error + let canpath = hg::utils::current_dir() + .unwrap() + .join(get_path_from_bytes(val)) + .canonicalize(); + canpath.ok().or(non_repo_config_val) + } + _ => non_repo_config_val, + } + } + }; + config_val.or(Some(get_path_from_bytes(&repo_arg).to_path_buf())) + } + }; + + let repo_result = match Repo::find(&non_repo_config, repo_path.to_owned()) + { Ok(repo) => Ok(repo), Err(RepoError::NotFound { at }) if repo_path.is_none() => { // Not finding a repo is not fatal yet, if `-R` was not given diff --git a/tests/test-globalopts.t b/tests/test-globalopts.t --- a/tests/test-globalopts.t +++ b/tests/test-globalopts.t @@ -65,8 +65,6 @@ Testing -R/--repository: -R with path aliases: -TODO: add rhg support for path aliases -#if no-rhg $ cd c $ hg -R default identify 8580ff50825a tip @@ -81,7 +79,6 @@ TODO: add rhg support for path aliases $ HOME=`pwd`/../ hg -R relativetohome identify 8580ff50825a tip $ cd .. -#endif #if no-outer-repo