Mercurial > public > mercurial-scm > hg-stable
diff rust/rhg/src/commands/cat.rs @ 52567:f33f37accb43
rhg: add resolve_file_args to path_utils.rs
Extracted logic for resolving `FILE ...` arguments from cat.rs into a new
function in path_utils.rs. I plan to use this for rhg annotate.
I tried to reuse hg::utils::files::canonical_path instead, but that didn't work.
For example it reports a InsideDotHg error for any path containing "..".
author | Mitchell Kember <mkember@janestreet.com> |
---|---|
date | Mon, 16 Dec 2024 10:52:01 -0500 |
parents | 393ad2685fb4 |
children |
line wrap: on
line diff
--- a/rust/rhg/src/commands/cat.rs Thu Dec 19 00:18:33 2024 +0100 +++ b/rust/rhg/src/commands/cat.rs Mon Dec 16 10:52:01 2024 -0500 @@ -1,10 +1,9 @@ use crate::error::CommandError; +use crate::utils::path_utils::resolve_file_args; use clap::Arg; use format_bytes::format_bytes; use hg::operations::cat; -use hg::utils::hg_path::HgPathBuf; use std::ffi::OsString; -use std::os::unix::prelude::OsStrExt; pub const HELP_TEXT: &str = " Output the current or given revision of files @@ -40,52 +39,15 @@ )); } - let rev = invocation.subcommand_args.get_one::<String>("rev"); - let file_args = - match invocation.subcommand_args.get_many::<OsString>("files") { - Some(files) => files - .filter(|s| !s.is_empty()) - .map(|s| s.as_os_str()) - .collect(), - None => vec![], - }; - let repo = invocation.repo?; - let cwd = hg::utils::current_dir()?; - let working_directory = repo.working_directory_path(); - let working_directory = cwd.join(working_directory); // Make it absolute - - let mut files = vec![]; - for file in file_args { - if file.as_bytes().starts_with(b"set:") { - let message = "fileset"; - return Err(CommandError::unsupported(message)); - } - let normalized = cwd.join(file); - // TODO: actually normalize `..` path segments etc? - let dotted = normalized.components().any(|c| c.as_os_str() == ".."); - if file.as_bytes() == b"." || dotted { - let message = "`..` or `.` path segment"; - return Err(CommandError::unsupported(message)); - } - let relative_path = working_directory - .strip_prefix(&cwd) - .unwrap_or(&working_directory); - let stripped = normalized - .strip_prefix(&working_directory) - .map_err(|_| { - CommandError::abort(format!( - "abort: {} not under root '{}'\n(consider using '--cwd {}')", - String::from_utf8_lossy(file.as_bytes()), - working_directory.display(), - relative_path.display(), - )) - })?; - let hg_file = HgPathBuf::try_from(stripped.to_path_buf()) - .map_err(|e| CommandError::abort(e.to_string()))?; - files.push(hg_file); - } + let rev = invocation.subcommand_args.get_one::<String>("rev"); + let files = match invocation.subcommand_args.get_many::<OsString>("files") + { + None => vec![], + Some(files) => resolve_file_args(repo, files)?, + }; + let files = files.iter().map(|file| file.as_ref()).collect(); // TODO probably move this to a util function like `repo.default_rev` or // something when it's used somewhere else