##// END OF EJS Templates
rhg: refactor relativize_path into a struct + method...
Simon Sapin -
r49284:9b0e1f64 default
parent child Browse files
Show More
@@ -1,14 +1,12 b''
1 use crate::error::CommandError;
1 use crate::error::CommandError;
2 use crate::ui::Ui;
2 use crate::ui::Ui;
3 use crate::ui::UiError;
3 use crate::utils::path_utils::RelativizePaths;
4 use crate::utils::path_utils::relativize_paths;
5 use clap::Arg;
4 use clap::Arg;
6 use hg::errors::HgError;
5 use hg::errors::HgError;
7 use hg::operations::list_rev_tracked_files;
6 use hg::operations::list_rev_tracked_files;
8 use hg::operations::Dirstate;
7 use hg::operations::Dirstate;
9 use hg::repo::Repo;
8 use hg::repo::Repo;
10 use hg::utils::hg_path::HgPath;
9 use hg::utils::hg_path::HgPath;
11 use std::borrow::Cow;
12
10
13 pub const HELP_TEXT: &str = "
11 pub const HELP_TEXT: &str = "
14 List tracked files.
12 List tracked files.
@@ -86,11 +84,14 b" fn display_files<'a>("
86 let mut stdout = ui.stdout_buffer();
84 let mut stdout = ui.stdout_buffer();
87 let mut any = false;
85 let mut any = false;
88
86
89 relativize_paths(repo, files, |path: Cow<[u8]>| -> Result<(), UiError> {
87 let relativize = RelativizePaths::new(repo)?;
88 for result in files {
89 let path = result?;
90 stdout.write_all(&relativize.relativize(path))?;
91 stdout.write_all(b"\n")?;
90 any = true;
92 any = true;
91 stdout.write_all(path.as_ref())?;
93 }
92 stdout.write_all(b"\n")
94
93 })?;
94 stdout.flush()?;
95 stdout.flush()?;
95 if any {
96 if any {
96 Ok(())
97 Ok(())
@@ -7,7 +7,7 b''
7
7
8 use crate::error::CommandError;
8 use crate::error::CommandError;
9 use crate::ui::Ui;
9 use crate::ui::Ui;
10 use crate::utils::path_utils::relativize_paths;
10 use crate::utils::path_utils::RelativizePaths;
11 use clap::{Arg, SubCommand};
11 use clap::{Arg, SubCommand};
12 use format_bytes::format_bytes;
12 use format_bytes::format_bytes;
13 use hg;
13 use hg;
@@ -261,9 +261,12 b' pub fn run(invocation: &crate::CliInvoca'
261 .unwrap_or(config.get_bool(b"ui", b"relative-paths")?);
261 .unwrap_or(config.get_bool(b"ui", b"relative-paths")?);
262 let output = DisplayStatusPaths {
262 let output = DisplayStatusPaths {
263 ui,
263 ui,
264 repo,
265 no_status,
264 no_status,
266 relative_paths,
265 relativize: if relative_paths {
266 Some(RelativizePaths::new(repo)?)
267 } else {
268 None
269 },
267 };
270 };
268 if display_states.modified {
271 if display_states.modified {
269 output.display(b"M", ds_status.modified)?;
272 output.display(b"M", ds_status.modified)?;
@@ -379,9 +382,8 b' fn ignore_files(repo: &Repo, config: &Co'
379
382
380 struct DisplayStatusPaths<'a> {
383 struct DisplayStatusPaths<'a> {
381 ui: &'a Ui,
384 ui: &'a Ui,
382 repo: &'a Repo,
383 no_status: bool,
385 no_status: bool,
384 relative_paths: bool,
386 relativize: Option<RelativizePaths>,
385 }
387 }
386
388
387 impl DisplayStatusPaths<'_> {
389 impl DisplayStatusPaths<'_> {
@@ -393,27 +395,24 b" impl DisplayStatusPaths<'_> {"
393 mut paths: Vec<HgPathCow>,
395 mut paths: Vec<HgPathCow>,
394 ) -> Result<(), CommandError> {
396 ) -> Result<(), CommandError> {
395 paths.sort_unstable();
397 paths.sort_unstable();
396 let print_path = |path: &[u8]| {
398 for path in paths {
399 let relative;
400 let path = if let Some(relativize) = &self.relativize {
401 relative = relativize.relativize(&path);
402 &*relative
403 } else {
404 path.as_bytes()
405 };
397 // TODO optim, probably lots of unneeded copies here, especially
406 // TODO optim, probably lots of unneeded copies here, especially
398 // if out stream is buffered
407 // if out stream is buffered
399 if self.no_status {
408 if self.no_status {
400 self.ui.write_stdout(&format_bytes!(b"{}\n", path))
409 self.ui.write_stdout(&format_bytes!(b"{}\n", path))?
401 } else {
410 } else {
402 self.ui.write_stdout(&format_bytes!(
411 self.ui.write_stdout(&format_bytes!(
403 b"{} {}\n",
412 b"{} {}\n",
404 status_prefix,
413 status_prefix,
405 path
414 path
406 ))
415 ))?
407 }
408 };
409
410 if self.relative_paths {
411 relativize_paths(self.repo, paths.iter().map(Ok), |path| {
412 print_path(&path)
413 })?;
414 } else {
415 for path in paths {
416 print_path(path.as_bytes())?
417 }
416 }
418 }
417 }
419 Ok(())
418 Ok(())
@@ -3,8 +3,6 b''
3 // This software may be used and distributed according to the terms of the
3 // This software may be used and distributed according to the terms of the
4 // GNU General Public License version 2 or any later version.
4 // GNU General Public License version 2 or any later version.
5
5
6 use crate::error::CommandError;
7 use crate::ui::UiError;
8 use hg::errors::HgError;
6 use hg::errors::HgError;
9 use hg::repo::Repo;
7 use hg::repo::Repo;
10 use hg::utils::current_dir;
8 use hg::utils::current_dir;
@@ -13,37 +11,45 b' use hg::utils::hg_path::HgPath;'
13 use hg::utils::hg_path::HgPathBuf;
11 use hg::utils::hg_path::HgPathBuf;
14 use std::borrow::Cow;
12 use std::borrow::Cow;
15
13
16 pub fn relativize_paths(
14 pub struct RelativizePaths {
17 repo: &Repo,
15 repo_root: HgPathBuf,
18 paths: impl IntoIterator<Item = Result<impl AsRef<HgPath>, HgError>>,
16 cwd: HgPathBuf,
19 mut callback: impl FnMut(Cow<[u8]>) -> Result<(), UiError>,
17 outside_repo: bool,
20 ) -> Result<(), CommandError> {
18 }
19
20 impl RelativizePaths {
21 pub fn new(repo: &Repo) -> Result<Self, HgError> {
21 let cwd = current_dir()?;
22 let cwd = current_dir()?;
22 let repo_root = repo.working_directory_path();
23 let repo_root = repo.working_directory_path();
23 let repo_root = cwd.join(repo_root); // Make it absolute
24 let repo_root = cwd.join(repo_root); // Make it absolute
24 let repo_root_hgpath =
25 let repo_root_hgpath =
25 HgPathBuf::from(get_bytes_from_path(repo_root.to_owned()));
26 HgPathBuf::from(get_bytes_from_path(repo_root.to_owned()));
26 let outside_repo: bool;
27 let cwd_hgpath: HgPathBuf;
28
27
29 if let Ok(cwd_relative_to_repo) = cwd.strip_prefix(&repo_root) {
28 if let Ok(cwd_relative_to_repo) = cwd.strip_prefix(&repo_root) {
30 // The current directory is inside the repo, so we can work with
29 // The current directory is inside the repo, so we can work with
31 // relative paths
30 // relative paths
32 outside_repo = false;
31 Ok(Self {
33 cwd_hgpath =
32 repo_root: repo_root_hgpath,
34 HgPathBuf::from(get_bytes_from_path(cwd_relative_to_repo));
33 cwd: HgPathBuf::from(get_bytes_from_path(
34 cwd_relative_to_repo,
35 )),
36 outside_repo: false,
37 })
35 } else {
38 } else {
36 outside_repo = true;
39 Ok(Self {
37 cwd_hgpath = HgPathBuf::from(get_bytes_from_path(cwd));
40 repo_root: repo_root_hgpath,
41 cwd: HgPathBuf::from(get_bytes_from_path(cwd)),
42 outside_repo: true,
43 })
44 }
38 }
45 }
39
46
40 for file in paths {
47 pub fn relativize<'a>(&self, path: &'a HgPath) -> Cow<'a, [u8]> {
41 if outside_repo {
48 if self.outside_repo {
42 let file = repo_root_hgpath.join(file?.as_ref());
49 let joined = self.repo_root.join(path);
43 callback(relativize_path(&file, &cwd_hgpath))?;
50 Cow::Owned(relativize_path(&joined, &self.cwd).into_owned())
44 } else {
51 } else {
45 callback(relativize_path(file?.as_ref(), &cwd_hgpath))?;
52 relativize_path(path, &self.cwd)
46 }
53 }
47 }
54 }
48 Ok(())
49 }
55 }
General Comments 0
You need to be logged in to leave comments. Login now