From 1b4bf29e00df1657c7ae24be597334aab361411e Mon Sep 17 00:00:00 2001 From: Zhaolong Zhu Date: Thu, 6 Feb 2025 14:12:21 -0800 Subject: [PATCH] pathmatcher: provide a hint when users use -R with a cwd-relative path Summary: A common mistake is to use -R, but specify a file relative to the repo instead of cwd. Detect that case, and provide a hint to the user. Reviewed By: muirdm Differential Revision: D69250238 fbshipit-source-id: 84195a55a4e5986d809d3c3055aca64e1d18ab0c --- eden/scm/lib/pathmatcher/src/error.rs | 31 ++++++++++++++++++------- eden/scm/lib/pathmatcher/src/pattern.rs | 2 ++ eden/scm/tests/test-alias.t | 3 ++- eden/scm/tests/test-parents.t | 3 ++- eden/scm/tests/test-walk.t | 9 ++++--- 5 files changed, 35 insertions(+), 13 deletions(-) diff --git a/eden/scm/lib/pathmatcher/src/error.rs b/eden/scm/lib/pathmatcher/src/error.rs index 74a167a2f57b7..e7c9e16dd42e3 100644 --- a/eden/scm/lib/pathmatcher/src/error.rs +++ b/eden/scm/lib/pathmatcher/src/error.rs @@ -7,15 +7,30 @@ #[derive(Debug, thiserror::Error)] pub enum Error { - #[error("unsuppported pattern kind {0}")] UnsupportedPatternKind(String), - - #[error("{0} not under root '{1}'")] - PathOutsideRoot(String, String), - - #[error("non-utf8 path '{0}' when building pattern")] + PathOutsideRoot(String, String, bool), NonUtf8(String), - - #[error("listfile:- may only be used once as a direct CLI argument")] StdinUnavailable, } + +impl std::fmt::Display for Error { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Error::UnsupportedPatternKind(s) => write!(f, "unsupported pattern kind {}", s), + Error::PathOutsideRoot(path, root, show_hint) => { + let message = format!("cwd relative path '{}' is not under root '{}'", path, root); + if *show_hint { + let hint_message = "consider using --cwd to change working directory"; + write!(f, "{}\n(hint: {})", message, hint_message) + } else { + write!(f, "{}", message) + } + } + Error::NonUtf8(s) => write!(f, "non-utf8 path '{}' when building pattern", s), + Error::StdinUnavailable => write!( + f, + "listfile:- may only be used once as a direct CLI argument" + ), + } + } +} diff --git a/eden/scm/lib/pathmatcher/src/pattern.rs b/eden/scm/lib/pathmatcher/src/pattern.rs index d92edb54705ac..ba146d75b02de 100644 --- a/eden/scm/lib/pathmatcher/src/pattern.rs +++ b/eden/scm/lib/pathmatcher/src/pattern.rs @@ -226,9 +226,11 @@ where .into_string() .map_err(|s| Error::NonUtf8(s.to_string_lossy().to_string()))?, None => { + let show_hint = !cwd.starts_with(root); return Err(Error::PathOutsideRoot( pat.to_string(), root.to_string_lossy().to_string(), + show_hint, ) .into()); } diff --git a/eden/scm/tests/test-alias.t b/eden/scm/tests/test-alias.t index e3f773a7a03ed..47d96d43e142b 100644 --- a/eden/scm/tests/test-alias.t +++ b/eden/scm/tests/test-alias.t @@ -148,7 +148,8 @@ no closing quotation "--" in alias definition should be preserved $ hg --config alias.dash='cat --' -R alias dash -r0 - abort: -r0 not under root '$TESTTMP/alias' + abort: cwd relative path '-r0' is not under root '$TESTTMP/alias' + (hint: consider using --cwd to change working directory) [255] invalid options diff --git a/eden/scm/tests/test-parents.t b/eden/scm/tests/test-parents.t index 01ad82a9c15c9..22c7f511b7ee9 100644 --- a/eden/scm/tests/test-parents.t +++ b/eden/scm/tests/test-parents.t @@ -75,7 +75,8 @@ hg parents c, single revision $ hg parents -r 'max(desc(b))' ../a - abort: ../a not under root '$TESTTMP/repo' + abort: cwd relative path '../a' is not under root '$TESTTMP/repo' + (hint: consider using --cwd to change working directory) [255] diff --git a/eden/scm/tests/test-walk.t b/eden/scm/tests/test-walk.t index f394a736f95bd..9c87a70f7cf26 100644 --- a/eden/scm/tests/test-walk.t +++ b/eden/scm/tests/test-walk.t @@ -275,10 +275,12 @@ f mammals/Procyonidae/raccoon mammals/Procyonidae/raccoon f mammals/skunk mammals/skunk $ hg debugwalk .. - abort: .. not under root '$TESTTMP/t' + abort: cwd relative path '..' is not under root '$TESTTMP/t' + (hint: consider using --cwd to change working directory) [255] $ hg debugwalk beans/../.. - abort: beans/../.. not under root '$TESTTMP/t' + abort: cwd relative path 'beans/../..' is not under root '$TESTTMP/t' + (hint: consider using --cwd to change working directory) [255] $ hg debugwalk .hg abort: path contains illegal component: .hg @@ -306,7 +308,8 @@ Test absolute paths: f beans/pinto beans/pinto f beans/turtle beans/turtle $ hg debugwalk `pwd`/.. - abort: $TESTTMP/t/.. not under root '$TESTTMP/t' + abort: cwd relative path '$TESTTMP/t/..' is not under root '$TESTTMP/t' + (hint: consider using --cwd to change working directory) [255] Test patterns: