##// END OF EJS Templates
rhg: use default configitem in `cat`...
Raphaël Gomès -
r51661:067edf50 default
parent child Browse files
Show More
@@ -1,117 +1,116
1 1 use crate::error::CommandError;
2 2 use clap::Arg;
3 3 use format_bytes::format_bytes;
4 4 use hg::operations::cat;
5 5 use hg::utils::hg_path::HgPathBuf;
6 6 use std::ffi::OsString;
7 7 use std::os::unix::prelude::OsStrExt;
8 8
9 9 pub const HELP_TEXT: &str = "
10 10 Output the current or given revision of files
11 11 ";
12 12
13 13 pub fn args() -> clap::Command {
14 14 clap::command!("cat")
15 15 .arg(
16 16 Arg::new("rev")
17 17 .help("search the repository as it is in REV")
18 18 .short('r')
19 19 .long("rev")
20 20 .value_name("REV"),
21 21 )
22 22 .arg(
23 23 clap::Arg::new("files")
24 24 .required(true)
25 25 .num_args(1..)
26 26 .value_name("FILE")
27 27 .value_parser(clap::value_parser!(std::ffi::OsString))
28 28 .help("Files to output"),
29 29 )
30 30 .about(HELP_TEXT)
31 31 }
32 32
33 33 #[logging_timer::time("trace")]
34 34 pub fn run(invocation: &crate::CliInvocation) -> Result<(), CommandError> {
35 let cat_enabled_default = true;
36 let cat_enabled = invocation.config.get_option(b"rhg", b"cat")?;
37 if !cat_enabled.unwrap_or(cat_enabled_default) {
35 let cat_enabled = invocation.config.get_bool(b"rhg", b"cat")?;
36 if !cat_enabled {
38 37 return Err(CommandError::unsupported(
39 38 "cat is disabled in rhg (enable it with 'rhg.cat = true' \
40 39 or enable fallback with 'rhg.on-unsupported = fallback')",
41 40 ));
42 41 }
43 42
44 43 let rev = invocation.subcommand_args.get_one::<String>("rev");
45 44 let file_args =
46 45 match invocation.subcommand_args.get_many::<OsString>("files") {
47 46 Some(files) => files
48 47 .filter(|s| !s.is_empty())
49 48 .map(|s| s.as_os_str())
50 49 .collect(),
51 50 None => vec![],
52 51 };
53 52
54 53 let repo = invocation.repo?;
55 54 let cwd = hg::utils::current_dir()?;
56 55 let working_directory = repo.working_directory_path();
57 56 let working_directory = cwd.join(working_directory); // Make it absolute
58 57
59 58 let mut files = vec![];
60 59 for file in file_args {
61 60 if file.as_bytes().starts_with(b"set:") {
62 61 let message = "fileset";
63 62 return Err(CommandError::unsupported(message));
64 63 }
65 64
66 65 let normalized = cwd.join(&file);
67 66 // TODO: actually normalize `..` path segments etc?
68 67 let dotted = normalized.components().any(|c| c.as_os_str() == "..");
69 68 if file.as_bytes() == b"." || dotted {
70 69 let message = "`..` or `.` path segment";
71 70 return Err(CommandError::unsupported(message));
72 71 }
73 72 let relative_path = working_directory
74 73 .strip_prefix(&cwd)
75 74 .unwrap_or(&working_directory);
76 75 let stripped = normalized
77 76 .strip_prefix(&working_directory)
78 77 .map_err(|_| {
79 78 CommandError::abort(format!(
80 79 "abort: {} not under root '{}'\n(consider using '--cwd {}')",
81 80 String::from_utf8_lossy(file.as_bytes()),
82 81 working_directory.display(),
83 82 relative_path.display(),
84 83 ))
85 84 })?;
86 85 let hg_file = HgPathBuf::try_from(stripped.to_path_buf())
87 86 .map_err(|e| CommandError::abort(e.to_string()))?;
88 87 files.push(hg_file);
89 88 }
90 89 let files = files.iter().map(|file| file.as_ref()).collect();
91 90 // TODO probably move this to a util function like `repo.default_rev` or
92 91 // something when it's used somewhere else
93 92 let rev = match rev {
94 93 Some(r) => r.to_string(),
95 94 None => format!("{:x}", repo.dirstate_parents()?.p1),
96 95 };
97 96
98 97 let output = cat(repo, &rev, files).map_err(|e| (e, rev.as_str()))?;
99 98 for (_file, contents) in output.results {
100 99 invocation.ui.write_stdout(&contents)?;
101 100 }
102 101 if !output.missing.is_empty() {
103 102 let short = format!("{:x}", output.node.short()).into_bytes();
104 103 for path in &output.missing {
105 104 invocation.ui.write_stderr(&format_bytes!(
106 105 b"{}: no such file in rev {}\n",
107 106 path.as_bytes(),
108 107 short
109 108 ))?;
110 109 }
111 110 }
112 111 if output.found_any {
113 112 Ok(())
114 113 } else {
115 114 Err(CommandError::Unsuccessful)
116 115 }
117 116 }
General Comments 0
You need to be logged in to leave comments. Login now