##// END OF EJS Templates
rhg: make output of `files` relative to the current directory and the root...
Raphaël Gomès -
r46007:1b319704 default
parent child Browse files
Show More
@@ -14,7 +14,7 b' use std::convert::From;'
14 14 use std::fmt;
15 15 use std::fs;
16 16 use std::io;
17 use std::path::PathBuf;
17 use std::path::{Path, PathBuf};
18 18
19 19 /// Kind of error encoutered by ListTrackedFiles
20 20 #[derive(Debug)]
@@ -60,6 +60,15 b' impl ListTrackedFiles {'
60 60 let content = fs::read(&dirstate)?;
61 61 Ok(ListDirstateTrackedFiles { content })
62 62 }
63
64 /// Returns the repository root directory
65 /// TODO I think this is a crutch that creates a dependency that should not
66 /// be there. Operations that need the root of the repository should get
67 /// it themselves, probably in a lazy fashion. But this would make the
68 /// current series even larger, so this is simplified for now.
69 pub fn get_root(&self) -> &Path {
70 &self.root
71 }
63 72 }
64 73
65 74 /// List files under Mercurial control in the working directory
@@ -16,7 +16,7 b' use crate::utils::{'
16 16 };
17 17 use lazy_static::lazy_static;
18 18 use same_file::is_same_file;
19 use std::borrow::ToOwned;
19 use std::borrow::{Cow, ToOwned};
20 20 use std::fs::Metadata;
21 21 use std::iter::FusedIterator;
22 22 use std::ops::Deref;
@@ -248,6 +248,66 b' pub fn canonical_path('
248 248 }
249 249 }
250 250
251 /// Returns the representation of the path relative to the current working
252 /// directory for display purposes.
253 ///
254 /// `cwd` is a `HgPath`, so it is considered relative to the root directory
255 /// of the repository.
256 ///
257 /// # Examples
258 ///
259 /// ```
260 /// use hg::utils::hg_path::HgPath;
261 /// use hg::utils::files::relativize_path;
262 /// use std::borrow::Cow;
263 ///
264 /// let file = HgPath::new(b"nested/file");
265 /// let cwd = HgPath::new(b"");
266 /// assert_eq!(relativize_path(file, cwd), Cow::Borrowed(b"nested/file"));
267 ///
268 /// let cwd = HgPath::new(b"nested");
269 /// assert_eq!(relativize_path(file, cwd), Cow::Borrowed(b"file"));
270 ///
271 /// let cwd = HgPath::new(b"other");
272 /// assert_eq!(relativize_path(file, cwd), Cow::Borrowed(b"../nested/file"));
273 /// ```
274 pub fn relativize_path(path: &HgPath, cwd: impl AsRef<HgPath>) -> Cow<[u8]> {
275 if cwd.as_ref().is_empty() {
276 Cow::Borrowed(path.as_bytes())
277 } else {
278 let mut res: Vec<u8> = Vec::new();
279 let mut path_iter = path.as_bytes().split(|b| *b == b'/').peekable();
280 let mut cwd_iter =
281 cwd.as_ref().as_bytes().split(|b| *b == b'/').peekable();
282 loop {
283 match (path_iter.peek(), cwd_iter.peek()) {
284 (Some(a), Some(b)) if a == b => (),
285 _ => break,
286 }
287 path_iter.next();
288 cwd_iter.next();
289 }
290 let mut need_sep = false;
291 for _ in cwd_iter {
292 if need_sep {
293 res.extend(b"/")
294 } else {
295 need_sep = true
296 };
297 res.extend(b"..");
298 }
299 for c in path_iter {
300 if need_sep {
301 res.extend(b"/")
302 } else {
303 need_sep = true
304 };
305 res.extend(c);
306 }
307 Cow::Owned(res)
308 }
309 }
310
251 311 #[cfg(test)]
252 312 mod tests {
253 313 use super::*;
@@ -2,6 +2,8 b' use crate::commands::Command;'
2 2 use crate::error::{CommandError, CommandErrorKind};
3 3 use crate::ui::Ui;
4 4 use hg::operations::{ListTrackedFiles, ListTrackedFilesErrorKind};
5 use hg::utils::files::{get_bytes_from_path, relativize_path};
6 use hg::utils::hg_path::HgPathBuf;
5 7
6 8 pub const HELP_TEXT: &str = "
7 9 List tracked files.
@@ -38,9 +40,17 b" impl<'a> Command<'a> for FilesCommand<'a"
38 40 }
39 41 })?;
40 42
43 let cwd = std::env::current_dir()
44 .or_else(|e| Err(CommandErrorKind::CurrentDirNotFound(e)))?;
45 let rooted_cwd = cwd
46 .strip_prefix(operation_builder.get_root())
47 .expect("cwd was already checked within the repository");
48 let rooted_cwd = HgPathBuf::from(get_bytes_from_path(rooted_cwd));
49
41 50 let mut stdout = self.ui.stdout_buffer();
51
42 52 for file in files {
43 stdout.write_all(file.as_bytes())?;
53 stdout.write_all(relativize_path(file, &rooted_cwd).as_ref())?;
44 54 stdout.write_all(b"\n")?;
45 55 }
46 56 stdout.flush()?;
General Comments 0
You need to be logged in to leave comments. Login now