##// END OF EJS Templates
rhg-files: make signature of `display_files` more flexible...
Raphaël Gomès -
r50878:795b5b01 default
parent child Browse files
Show More
@@ -1,110 +1,112 b''
1 use crate::error::CommandError;
1 use crate::error::CommandError;
2 use crate::ui::Ui;
2 use crate::ui::Ui;
3 use crate::utils::path_utils::RelativizePaths;
3 use crate::utils::path_utils::RelativizePaths;
4 use clap::Arg;
4 use clap::Arg;
5 use hg::errors::HgError;
6 use hg::operations::list_rev_tracked_files;
5 use hg::operations::list_rev_tracked_files;
7 use hg::repo::Repo;
6 use hg::repo::Repo;
8 use hg::utils::filter_map_results;
7 use hg::utils::filter_map_results;
9 use hg::utils::hg_path::HgPath;
8 use hg::utils::hg_path::HgPath;
10 use rayon::prelude::*;
9 use rayon::prelude::*;
11
10
12 pub const HELP_TEXT: &str = "
11 pub const HELP_TEXT: &str = "
13 List tracked files.
12 List tracked files.
14
13
15 Returns 0 on success.
14 Returns 0 on success.
16 ";
15 ";
17
16
18 pub fn args() -> clap::Command {
17 pub fn args() -> clap::Command {
19 clap::command!("files")
18 clap::command!("files")
20 .arg(
19 .arg(
21 Arg::new("rev")
20 Arg::new("rev")
22 .help("search the repository as it is in REV")
21 .help("search the repository as it is in REV")
23 .short('r')
22 .short('r')
24 .long("revision")
23 .long("revision")
25 .value_name("REV"),
24 .value_name("REV"),
26 )
25 )
27 .about(HELP_TEXT)
26 .about(HELP_TEXT)
28 }
27 }
29
28
30 pub fn run(invocation: &crate::CliInvocation) -> Result<(), CommandError> {
29 pub fn run(invocation: &crate::CliInvocation) -> Result<(), CommandError> {
31 let relative = invocation.config.get(b"ui", b"relative-paths");
30 let relative = invocation.config.get(b"ui", b"relative-paths");
32 if relative.is_some() {
31 if relative.is_some() {
33 return Err(CommandError::unsupported(
32 return Err(CommandError::unsupported(
34 "non-default ui.relative-paths",
33 "non-default ui.relative-paths",
35 ));
34 ));
36 }
35 }
37
36
38 let rev = invocation.subcommand_args.get_one::<String>("rev");
37 let rev = invocation.subcommand_args.get_one::<String>("rev");
39
38
40 let repo = invocation.repo?;
39 let repo = invocation.repo?;
41
40
42 // It seems better if this check is removed: this would correspond to
41 // It seems better if this check is removed: this would correspond to
43 // automatically enabling the extension if the repo requires it.
42 // automatically enabling the extension if the repo requires it.
44 // However we need this check to be in sync with vanilla hg so hg tests
43 // However we need this check to be in sync with vanilla hg so hg tests
45 // pass.
44 // pass.
46 if repo.has_sparse()
45 if repo.has_sparse()
47 && invocation.config.get(b"extensions", b"sparse").is_none()
46 && invocation.config.get(b"extensions", b"sparse").is_none()
48 {
47 {
49 return Err(CommandError::unsupported(
48 return Err(CommandError::unsupported(
50 "repo is using sparse, but sparse extension is not enabled",
49 "repo is using sparse, but sparse extension is not enabled",
51 ));
50 ));
52 }
51 }
53
52
54 if let Some(rev) = rev {
53 if let Some(rev) = rev {
55 if repo.has_narrow() {
54 if repo.has_narrow() {
56 return Err(CommandError::unsupported(
55 return Err(CommandError::unsupported(
57 "rhg files -r <rev> is not supported in narrow clones",
56 "rhg files -r <rev> is not supported in narrow clones",
58 ));
57 ));
59 }
58 }
60 let files = list_rev_tracked_files(repo, rev)
59 let files = list_rev_tracked_files(repo, rev)
61 .map_err(|e| (e, rev.as_ref()))?;
60 .map_err(|e| (e, rev.as_ref()))?;
62 display_files(invocation.ui, repo, files.iter())
61 display_files(invocation.ui, repo, files.iter())
63 } else {
62 } else {
64 // The dirstate always reflects the sparse narrowspec, so if
63 // The dirstate always reflects the sparse narrowspec, so if
65 // we only have sparse without narrow all is fine.
64 // we only have sparse without narrow all is fine.
66 // If we have narrow, then [hg files] needs to check if
65 // If we have narrow, then [hg files] needs to check if
67 // the store narrowspec is in sync with the one of the dirstate,
66 // the store narrowspec is in sync with the one of the dirstate,
68 // so we can't support that without explicit code.
67 // so we can't support that without explicit code.
69 if repo.has_narrow() {
68 if repo.has_narrow() {
70 return Err(CommandError::unsupported(
69 return Err(CommandError::unsupported(
71 "rhg files is not supported in narrow clones",
70 "rhg files is not supported in narrow clones",
72 ));
71 ));
73 }
72 }
74 let dirstate = repo.dirstate_map()?;
73 let dirstate = repo.dirstate_map()?;
75 let files_res: Result<Vec<_>, _> =
74 let files_res: Result<Vec<_>, _> =
76 filter_map_results(dirstate.iter(), |(path, entry)| {
75 filter_map_results(dirstate.iter(), |(path, entry)| {
77 Ok(if entry.tracked() { Some(path) } else { None })
76 Ok(if entry.tracked() { Some(path) } else { None })
78 })
77 })
79 .collect();
78 .collect();
80
79
81 let mut files = files_res?;
80 let mut files = files_res?;
82 files.par_sort_unstable();
81 files.par_sort_unstable();
83
82
84 display_files(invocation.ui, repo, files.into_iter().map(Ok))
83 display_files(invocation.ui, repo, files.into_iter().map(Ok))
85 }
84 }
86 }
85 }
87
86
88 fn display_files<'a>(
87 fn display_files<'a, E>(
89 ui: &Ui,
88 ui: &Ui,
90 repo: &Repo,
89 repo: &Repo,
91 files: impl IntoIterator<Item = Result<&'a HgPath, HgError>>,
90 files: impl IntoIterator<Item = Result<&'a HgPath, E>>,
92 ) -> Result<(), CommandError> {
91 ) -> Result<(), CommandError>
92 where
93 CommandError: From<E>,
94 {
93 let mut stdout = ui.stdout_buffer();
95 let mut stdout = ui.stdout_buffer();
94 let mut any = false;
96 let mut any = false;
95
97
96 let relativize = RelativizePaths::new(repo)?;
98 let relativize = RelativizePaths::new(repo)?;
97 for result in files {
99 for result in files {
98 let path = result?;
100 let path = result?;
99 stdout.write_all(&relativize.relativize(path))?;
101 stdout.write_all(&relativize.relativize(path))?;
100 stdout.write_all(b"\n")?;
102 stdout.write_all(b"\n")?;
101 any = true;
103 any = true;
102 }
104 }
103
105
104 stdout.flush()?;
106 stdout.flush()?;
105 if any {
107 if any {
106 Ok(())
108 Ok(())
107 } else {
109 } else {
108 Err(CommandError::Unsuccessful)
110 Err(CommandError::Unsuccessful)
109 }
111 }
110 }
112 }
General Comments 0
You need to be logged in to leave comments. Login now