##// END OF EJS Templates
rust: replace most "operation" structs with functions...
Simon Sapin -
r46751:dca9cb99 default
parent child Browse files
Show More
@@ -9,7 +9,7 b' use std::convert::From;'
9 use std::path::{Path, PathBuf};
9 use std::path::{Path, PathBuf};
10
10
11 use crate::revlog::changelog::Changelog;
11 use crate::revlog::changelog::Changelog;
12 use crate::revlog::manifest::{Manifest, ManifestEntry};
12 use crate::revlog::manifest::Manifest;
13 use crate::revlog::path_encode::path_encode;
13 use crate::revlog::path_encode::path_encode;
14 use crate::revlog::revlog::Revlog;
14 use crate::revlog::revlog::Revlog;
15 use crate::revlog::revlog::RevlogError;
15 use crate::revlog::revlog::RevlogError;
@@ -70,97 +70,60 b' impl From<RevlogError> for CatRevError {'
70 }
70 }
71
71
72 /// List files under Mercurial control at a given revision.
72 /// List files under Mercurial control at a given revision.
73 pub struct CatRev<'a> {
73 ///
74 root: &'a Path,
74 /// * `root`: Repository root
75 /// The revision to cat the files from.
75 /// * `rev`: The revision to cat the files from.
76 rev: &'a str,
76 /// * `files`: The files to output.
77 /// The files to output.
77 pub fn cat(
78 files: &'a [HgPathBuf],
78 root: &Path,
79 /// The changelog file
79 rev: &str,
80 changelog: Changelog,
80 files: &[HgPathBuf],
81 /// The manifest file
81 ) -> Result<Vec<u8>, CatRevError> {
82 manifest: Manifest,
82 let changelog = Changelog::open(&root)?;
83 /// The manifest entry corresponding to the revision.
83 let manifest = Manifest::open(&root)?;
84 ///
84
85 /// Used to hold the owner of the returned references.
85 let changelog_entry = match rev.parse::<Revision>() {
86 manifest_entry: Option<ManifestEntry>,
86 Ok(rev) => changelog.get_rev(rev)?,
87 }
87 _ => {
88 let changelog_node = NodePrefix::from_hex(&rev)
89 .map_err(|_| CatRevErrorKind::InvalidRevision)?;
90 changelog.get_node(changelog_node.borrow())?
91 }
92 };
93 let manifest_node = Node::from_hex(&changelog_entry.manifest_node()?)
94 .map_err(|_| CatRevErrorKind::CorruptedRevlog)?;
95
96 let manifest_entry = manifest.get_node((&manifest_node).into())?;
97 let mut bytes = vec![];
88
98
89 impl<'a> CatRev<'a> {
99 for (manifest_file, node_bytes) in manifest_entry.files_with_nodes() {
90 pub fn new(
100 for cat_file in files.iter() {
91 root: &'a Path,
101 if cat_file.as_bytes() == manifest_file.as_bytes() {
92 rev: &'a str,
102 let index_path = store_path(root, manifest_file, b".i");
93 files: &'a [HgPathBuf],
103 let data_path = store_path(root, manifest_file, b".d");
94 ) -> Result<Self, CatRevError> {
95 let changelog = Changelog::open(&root)?;
96 let manifest = Manifest::open(&root)?;
97 let manifest_entry = None;
98
104
99 Ok(Self {
105 let file_log = Revlog::open(&index_path, Some(&data_path))?;
100 root,
106 let file_node = Node::from_hex(node_bytes)
101 rev,
107 .map_err(|_| CatRevErrorKind::CorruptedRevlog)?;
102 files,
108 let file_rev = file_log.get_node_rev((&file_node).into())?;
103 changelog,
109 let data = file_log.get_rev_data(file_rev)?;
104 manifest,
110 if data.starts_with(&METADATA_DELIMITER) {
105 manifest_entry,
111 let end_delimiter_position = data
106 })
112 [METADATA_DELIMITER.len()..]
113 .windows(METADATA_DELIMITER.len())
114 .position(|bytes| bytes == METADATA_DELIMITER);
115 if let Some(position) = end_delimiter_position {
116 let offset = METADATA_DELIMITER.len() * 2;
117 bytes.extend(data[position + offset..].iter());
118 }
119 } else {
120 bytes.extend(data);
121 }
122 }
123 }
107 }
124 }
108
125
109 pub fn run(&mut self) -> Result<Vec<u8>, CatRevError> {
126 Ok(bytes)
110 let changelog_entry = match self.rev.parse::<Revision>() {
111 Ok(rev) => self.changelog.get_rev(rev)?,
112 _ => {
113 let changelog_node = NodePrefix::from_hex(&self.rev)
114 .map_err(|_| CatRevErrorKind::InvalidRevision)?;
115 self.changelog.get_node(changelog_node.borrow())?
116 }
117 };
118 let manifest_node = Node::from_hex(&changelog_entry.manifest_node()?)
119 .map_err(|_| CatRevErrorKind::CorruptedRevlog)?;
120
121 self.manifest_entry =
122 Some(self.manifest.get_node((&manifest_node).into())?);
123 if let Some(ref manifest_entry) = self.manifest_entry {
124 let mut bytes = vec![];
125
126 for (manifest_file, node_bytes) in
127 manifest_entry.files_with_nodes()
128 {
129 for cat_file in self.files.iter() {
130 if cat_file.as_bytes() == manifest_file.as_bytes() {
131 let index_path =
132 store_path(self.root, manifest_file, b".i");
133 let data_path =
134 store_path(self.root, manifest_file, b".d");
135
136 let file_log =
137 Revlog::open(&index_path, Some(&data_path))?;
138 let file_node = Node::from_hex(node_bytes)
139 .map_err(|_| CatRevErrorKind::CorruptedRevlog)?;
140 let file_rev =
141 file_log.get_node_rev((&file_node).into())?;
142 let data = file_log.get_rev_data(file_rev)?;
143 if data.starts_with(&METADATA_DELIMITER) {
144 let end_delimiter_position = data
145 [METADATA_DELIMITER.len()..]
146 .windows(METADATA_DELIMITER.len())
147 .position(|bytes| bytes == METADATA_DELIMITER);
148 if let Some(position) = end_delimiter_position {
149 let offset = METADATA_DELIMITER.len() * 2;
150 bytes.extend(data[position + offset..].iter());
151 }
152 } else {
153 bytes.extend(data);
154 }
155 }
156 }
157 }
158
159 Ok(bytes)
160 } else {
161 unreachable!("manifest_entry should have been stored");
162 }
163 }
164 }
127 }
165
128
166 fn store_path(root: &Path, hg_path: &HgPath, suffix: &[u8]) -> PathBuf {
129 fn store_path(root: &Path, hg_path: &HgPath, suffix: &[u8]) -> PathBuf {
@@ -5,7 +5,8 b''
5 // This software may be used and distributed according to the terms of the
5 // This software may be used and distributed according to the terms of the
6 // GNU General Public License version 2 or any later version.
6 // GNU General Public License version 2 or any later version.
7
7
8 use super::find_root;
8 use std::path::Path;
9
9 use crate::revlog::revlog::{Revlog, RevlogError};
10 use crate::revlog::revlog::{Revlog, RevlogError};
10 use crate::revlog::NodePrefix;
11 use crate::revlog::NodePrefix;
11 use crate::revlog::Revision;
12 use crate::revlog::Revision;
@@ -20,7 +21,6 b' pub enum DebugDataKind {'
20 /// Kind of error encountered by DebugData
21 /// Kind of error encountered by DebugData
21 #[derive(Debug)]
22 #[derive(Debug)]
22 pub enum DebugDataErrorKind {
23 pub enum DebugDataErrorKind {
23 FindRootError(find_root::FindRootError),
24 /// Error when reading a `revlog` file.
24 /// Error when reading a `revlog` file.
25 IoError(std::io::Error),
25 IoError(std::io::Error),
26 /// The revision has not been found.
26 /// The revision has not been found.
@@ -48,13 +48,6 b' impl From<DebugDataErrorKind> for DebugD'
48 }
48 }
49 }
49 }
50
50
51 impl From<find_root::FindRootError> for DebugDataError {
52 fn from(err: find_root::FindRootError) -> Self {
53 let kind = DebugDataErrorKind::FindRootError(err);
54 DebugDataError { kind }
55 }
56 }
57
58 impl From<std::io::Error> for DebugDataError {
51 impl From<std::io::Error> for DebugDataError {
59 fn from(err: std::io::Error) -> Self {
52 fn from(err: std::io::Error) -> Self {
60 let kind = DebugDataErrorKind::IoError(err);
53 let kind = DebugDataErrorKind::IoError(err);
@@ -85,36 +78,26 b' impl From<RevlogError> for DebugDataErro'
85 }
78 }
86
79
87 /// Dump the contents data of a revision.
80 /// Dump the contents data of a revision.
88 pub struct DebugData<'a> {
81 pub fn debug_data(
89 /// Revision or hash of the revision.
82 root: &Path,
90 rev: &'a str,
83 rev: &str,
91 /// Kind of data to debug.
92 kind: DebugDataKind,
84 kind: DebugDataKind,
93 }
85 ) -> Result<Vec<u8>, DebugDataError> {
94
86 let index_file = match kind {
95 impl<'a> DebugData<'a> {
87 DebugDataKind::Changelog => root.join(".hg/store/00changelog.i"),
96 pub fn new(rev: &'a str, kind: DebugDataKind) -> Self {
88 DebugDataKind::Manifest => root.join(".hg/store/00manifest.i"),
97 DebugData { rev, kind }
89 };
98 }
90 let revlog = Revlog::open(&index_file, None)?;
99
91
100 pub fn run(&mut self) -> Result<Vec<u8>, DebugDataError> {
92 let data = match rev.parse::<Revision>() {
101 let root = find_root::FindRoot::new().run()?;
93 Ok(rev) => revlog.get_rev_data(rev)?,
102 let index_file = match self.kind {
94 _ => {
103 DebugDataKind::Changelog => root.join(".hg/store/00changelog.i"),
95 let node = NodePrefix::from_hex(&rev)
104 DebugDataKind::Manifest => root.join(".hg/store/00manifest.i"),
96 .map_err(|_| DebugDataErrorKind::InvalidRevision)?;
105 };
97 let rev = revlog.get_node_rev(node.borrow())?;
106 let revlog = Revlog::open(&index_file, None)?;
98 revlog.get_rev_data(rev)?
99 }
100 };
107
101
108 let data = match self.rev.parse::<Revision>() {
102 Ok(data)
109 Ok(rev) => revlog.get_rev_data(rev)?,
110 _ => {
111 let node = NodePrefix::from_hex(&self.rev)
112 .map_err(|_| DebugDataErrorKind::InvalidRevision)?;
113 let rev = revlog.get_node_rev(node.borrow())?;
114 revlog.get_rev_data(rev)?
115 }
116 };
117
118 Ok(data)
119 }
120 }
103 }
@@ -28,46 +28,29 b' impl fmt::Display for FindRootError {'
28 }
28 }
29
29
30 /// Find the root of the repository
30 /// Find the root of the repository
31 /// by searching for a .hg directory in the current directory and its
31 /// by searching for a .hg directory in the process’ current directory and its
32 /// ancestors
32 /// ancestors
33 pub struct FindRoot<'a> {
33 pub fn find_root() -> Result<PathBuf, FindRootError> {
34 current_dir: Option<&'a Path>,
34 let current_dir = std::env::current_dir().map_err(|e| FindRootError {
35 kind: FindRootErrorKind::GetCurrentDirError(e),
36 })?;
37 Ok(find_root_from_path(&current_dir)?.into())
35 }
38 }
36
39
37 impl<'a> FindRoot<'a> {
40 /// Find the root of the repository
38 pub fn new() -> Self {
41 /// by searching for a .hg directory in the given directory and its ancestors
39 Self { current_dir: None }
42 pub fn find_root_from_path(start: &Path) -> Result<&Path, FindRootError> {
43 if start.join(".hg").exists() {
44 return Ok(start);
40 }
45 }
41
46 for ancestor in start.ancestors() {
42 pub fn new_from_path(current_dir: &'a Path) -> Self {
47 if ancestor.join(".hg").exists() {
43 Self {
48 return Ok(ancestor);
44 current_dir: Some(current_dir),
45 }
49 }
46 }
50 }
47
51 Err(FindRootError {
48 pub fn run(&self) -> Result<PathBuf, FindRootError> {
52 kind: FindRootErrorKind::RootNotFound(start.into()),
49 let current_dir = match self.current_dir {
53 })
50 None => std::env::current_dir().or_else(|e| {
51 Err(FindRootError {
52 kind: FindRootErrorKind::GetCurrentDirError(e),
53 })
54 })?,
55 Some(path) => path.into(),
56 };
57
58 if current_dir.join(".hg").exists() {
59 return Ok(current_dir);
60 }
61 let ancestors = current_dir.ancestors();
62 for parent in ancestors {
63 if parent.join(".hg").exists() {
64 return Ok(parent.into());
65 }
66 }
67 Err(FindRootError {
68 kind: FindRootErrorKind::RootNotFound(current_dir.to_path_buf()),
69 })
70 }
71 }
54 }
72
55
73 #[cfg(test)]
56 #[cfg(test)]
@@ -81,7 +64,7 b' mod tests {'
81 let tmp_dir = tempfile::tempdir().unwrap();
64 let tmp_dir = tempfile::tempdir().unwrap();
82 let path = tmp_dir.path();
65 let path = tmp_dir.path();
83
66
84 let err = FindRoot::new_from_path(&path).run().unwrap_err();
67 let err = find_root_from_path(&path).unwrap_err();
85
68
86 // TODO do something better
69 // TODO do something better
87 assert!(match err {
70 assert!(match err {
@@ -98,7 +81,7 b' mod tests {'
98 let root = tmp_dir.path();
81 let root = tmp_dir.path();
99 fs::create_dir_all(root.join(".hg")).unwrap();
82 fs::create_dir_all(root.join(".hg")).unwrap();
100
83
101 let result = FindRoot::new_from_path(&root).run().unwrap();
84 let result = find_root_from_path(&root).unwrap();
102
85
103 assert_eq!(result, root)
86 assert_eq!(result, root)
104 }
87 }
@@ -109,10 +92,8 b' mod tests {'
109 let root = tmp_dir.path();
92 let root = tmp_dir.path();
110 fs::create_dir_all(root.join(".hg")).unwrap();
93 fs::create_dir_all(root.join(".hg")).unwrap();
111
94
112 let result =
95 let directory = root.join("some/nested/directory");
113 FindRoot::new_from_path(&root.join("some/nested/directory"))
96 let result = find_root_from_path(&directory).unwrap();
114 .run()
115 .unwrap();
116
97
117 assert_eq!(result, root)
98 assert_eq!(result, root)
118 }
99 }
@@ -51,20 +51,20 b' impl From<std::io::Error> for ListDirsta'
51
51
52 /// List files under Mercurial control in the working directory
52 /// List files under Mercurial control in the working directory
53 /// by reading the dirstate
53 /// by reading the dirstate
54 pub struct ListDirstateTrackedFiles {
54 pub struct Dirstate {
55 /// The `dirstate` content.
55 /// The `dirstate` content.
56 content: Vec<u8>,
56 content: Vec<u8>,
57 }
57 }
58
58
59 impl ListDirstateTrackedFiles {
59 impl Dirstate {
60 pub fn new(root: &Path) -> Result<Self, ListDirstateTrackedFilesError> {
60 pub fn new(root: &Path) -> Result<Self, ListDirstateTrackedFilesError> {
61 let dirstate = root.join(".hg/dirstate");
61 let dirstate = root.join(".hg/dirstate");
62 let content = fs::read(&dirstate)?;
62 let content = fs::read(&dirstate)?;
63 Ok(Self { content })
63 Ok(Self { content })
64 }
64 }
65
65
66 pub fn run(
66 pub fn tracked_files(
67 &mut self,
67 &self,
68 ) -> Result<Vec<&HgPath>, ListDirstateTrackedFilesError> {
68 ) -> Result<Vec<&HgPath>, ListDirstateTrackedFilesError> {
69 let (_, entries, _) = parse_dirstate(&self.content)
69 let (_, entries, _) = parse_dirstate(&self.content)
70 .map_err(ListDirstateTrackedFilesErrorKind::ParseError)?;
70 .map_err(ListDirstateTrackedFilesErrorKind::ParseError)?;
@@ -137,58 +137,31 b' impl From<RevlogError> for ListRevTracke'
137 }
137 }
138
138
139 /// List files under Mercurial control at a given revision.
139 /// List files under Mercurial control at a given revision.
140 pub struct ListRevTrackedFiles<'a> {
140 pub fn list_rev_tracked_files(
141 /// The revision to list the files from.
141 root: &Path,
142 rev: &'a str,
142 rev: &str,
143 /// The changelog file
143 ) -> Result<FilesForRev, ListRevTrackedFilesError> {
144 changelog: Changelog,
144 let changelog = Changelog::open(root)?;
145 /// The manifest file
145 let manifest = Manifest::open(root)?;
146 manifest: Manifest,
146
147 /// The manifest entry corresponding to the revision.
147 let changelog_entry = match rev.parse::<Revision>() {
148 ///
148 Ok(rev) => changelog.get_rev(rev)?,
149 /// Used to hold the owner of the returned references.
149 _ => {
150 manifest_entry: Option<ManifestEntry>,
150 let changelog_node = NodePrefix::from_hex(&rev)
151 .or(Err(ListRevTrackedFilesErrorKind::InvalidRevision))?;
152 changelog.get_node(changelog_node.borrow())?
153 }
154 };
155 let manifest_node = Node::from_hex(&changelog_entry.manifest_node()?)
156 .or(Err(ListRevTrackedFilesErrorKind::CorruptedRevlog))?;
157 let manifest_entry = manifest.get_node((&manifest_node).into())?;
158 Ok(FilesForRev(manifest_entry))
151 }
159 }
152
160
153 impl<'a> ListRevTrackedFiles<'a> {
161 pub struct FilesForRev(ManifestEntry);
154 pub fn new(
155 root: &Path,
156 rev: &'a str,
157 ) -> Result<Self, ListRevTrackedFilesError> {
158 let changelog = Changelog::open(root)?;
159 let manifest = Manifest::open(root)?;
160
161 Ok(Self {
162 rev,
163 changelog,
164 manifest,
165 manifest_entry: None,
166 })
167 }
168
162
169 pub fn run(
163 impl FilesForRev {
170 &mut self,
164 pub fn iter(&self) -> impl Iterator<Item = &HgPath> {
171 ) -> Result<impl Iterator<Item = &HgPath>, ListRevTrackedFilesError> {
165 self.0.files()
172 let changelog_entry = match self.rev.parse::<Revision>() {
173 Ok(rev) => self.changelog.get_rev(rev)?,
174 _ => {
175 let changelog_node = NodePrefix::from_hex(&self.rev)
176 .or(Err(ListRevTrackedFilesErrorKind::InvalidRevision))?;
177 self.changelog.get_node(changelog_node.borrow())?
178 }
179 };
180 let manifest_node = Node::from_hex(&changelog_entry.manifest_node()?)
181 .or(Err(ListRevTrackedFilesErrorKind::CorruptedRevlog))?;
182
183 self.manifest_entry =
184 Some(self.manifest.get_node((&manifest_node).into())?);
185
186 if let Some(ref manifest_entry) = self.manifest_entry {
187 Ok(manifest_entry.files())
188 } else {
189 panic!(
190 "manifest entry should have been stored in self.manifest_node to ensure its lifetime since references are returned from it"
191 )
192 }
193 }
166 }
194 }
167 }
@@ -7,22 +7,17 b' mod debugdata;'
7 mod dirstate_status;
7 mod dirstate_status;
8 mod find_root;
8 mod find_root;
9 mod list_tracked_files;
9 mod list_tracked_files;
10 pub use cat::{CatRev, CatRevError, CatRevErrorKind};
10 pub use cat::{cat, CatRevError, CatRevErrorKind};
11 pub use debugdata::{
11 pub use debugdata::{
12 DebugData, DebugDataError, DebugDataErrorKind, DebugDataKind,
12 debug_data, DebugDataError, DebugDataErrorKind, DebugDataKind,
13 };
13 };
14 pub use find_root::{FindRoot, FindRootError, FindRootErrorKind};
14 pub use find_root::{
15 pub use list_tracked_files::{
15 find_root, find_root_from_path, FindRootError, FindRootErrorKind,
16 ListDirstateTrackedFiles, ListDirstateTrackedFilesError,
17 ListDirstateTrackedFilesErrorKind,
18 };
16 };
19 pub use list_tracked_files::{
17 pub use list_tracked_files::{
20 ListRevTrackedFiles, ListRevTrackedFilesError,
18 list_rev_tracked_files, FilesForRev, ListRevTrackedFilesError,
21 ListRevTrackedFilesErrorKind,
19 ListRevTrackedFilesErrorKind,
22 };
20 };
23
21 pub use list_tracked_files::{
24 // TODO add an `Operation` trait when GAT have landed (rust #44265):
22 Dirstate, ListDirstateTrackedFilesError, ListDirstateTrackedFilesErrorKind,
25 // there is no way to currently define a trait which can both return
23 };
26 // references to `self` and to passed data, which is what we would need.
27 // Generic Associated Types may fix this and allow us to have a unified
28 // interface.
@@ -2,8 +2,8 b' use crate::commands::Command;'
2 use crate::error::{CommandError, CommandErrorKind};
2 use crate::error::{CommandError, CommandErrorKind};
3 use crate::ui::utf8_to_local;
3 use crate::ui::utf8_to_local;
4 use crate::ui::Ui;
4 use crate::ui::Ui;
5 use hg::operations::FindRoot;
5 use hg::operations::find_root;
6 use hg::operations::{CatRev, CatRevError, CatRevErrorKind};
6 use hg::operations::{cat, CatRevError, CatRevErrorKind};
7 use hg::requirements;
7 use hg::requirements;
8 use hg::utils::hg_path::HgPathBuf;
8 use hg::utils::hg_path::HgPathBuf;
9 use micro_timer::timed;
9 use micro_timer::timed;
@@ -32,7 +32,7 b" impl<'a> CatCommand<'a> {"
32 impl<'a> Command for CatCommand<'a> {
32 impl<'a> Command for CatCommand<'a> {
33 #[timed]
33 #[timed]
34 fn run(&self, ui: &Ui) -> Result<(), CommandError> {
34 fn run(&self, ui: &Ui) -> Result<(), CommandError> {
35 let root = FindRoot::new().run()?;
35 let root = find_root()?;
36 requirements::check(&root)?;
36 requirements::check(&root)?;
37 let cwd = std::env::current_dir()
37 let cwd = std::env::current_dir()
38 .or_else(|e| Err(CommandErrorKind::CurrentDirNotFound(e)))?;
38 .or_else(|e| Err(CommandErrorKind::CurrentDirNotFound(e)))?;
@@ -50,10 +50,8 b" impl<'a> Command for CatCommand<'a> {"
50
50
51 match self.rev {
51 match self.rev {
52 Some(rev) => {
52 Some(rev) => {
53 let mut operation = CatRev::new(&root, rev, &files)
53 let data = cat(&root, rev, &files)
54 .map_err(|e| map_rev_error(rev, e))?;
54 .map_err(|e| map_rev_error(rev, e))?;
55 let data =
56 operation.run().map_err(|e| map_rev_error(rev, e))?;
57 self.display(ui, &data)
55 self.display(ui, &data)
58 }
56 }
59 None => Err(CommandErrorKind::Unimplemented.into()),
57 None => Err(CommandErrorKind::Unimplemented.into()),
@@ -2,8 +2,9 b' use crate::commands::Command;'
2 use crate::error::{CommandError, CommandErrorKind};
2 use crate::error::{CommandError, CommandErrorKind};
3 use crate::ui::utf8_to_local;
3 use crate::ui::utf8_to_local;
4 use crate::ui::Ui;
4 use crate::ui::Ui;
5 use hg::operations::find_root;
5 use hg::operations::{
6 use hg::operations::{
6 DebugData, DebugDataError, DebugDataErrorKind, DebugDataKind,
7 debug_data, DebugDataError, DebugDataErrorKind, DebugDataKind,
7 };
8 };
8 use micro_timer::timed;
9 use micro_timer::timed;
9
10
@@ -25,9 +26,9 b" impl<'a> DebugDataCommand<'a> {"
25 impl<'a> Command for DebugDataCommand<'a> {
26 impl<'a> Command for DebugDataCommand<'a> {
26 #[timed]
27 #[timed]
27 fn run(&self, ui: &Ui) -> Result<(), CommandError> {
28 fn run(&self, ui: &Ui) -> Result<(), CommandError> {
28 let mut operation = DebugData::new(self.rev, self.kind);
29 let root = find_root()?;
29 let data =
30 let data = debug_data(&root, self.rev, self.kind)
30 operation.run().map_err(|e| to_command_error(self.rev, e))?;
31 .map_err(|e| to_command_error(self.rev, e))?;
31
32
32 let mut stdout = ui.stdout_buffer();
33 let mut stdout = ui.stdout_buffer();
33 stdout.write_all(&data)?;
34 stdout.write_all(&data)?;
@@ -40,7 +41,6 b" impl<'a> Command for DebugDataCommand<'a"
40 /// Convert operation errors to command errors
41 /// Convert operation errors to command errors
41 fn to_command_error(rev: &str, err: DebugDataError) -> CommandError {
42 fn to_command_error(rev: &str, err: DebugDataError) -> CommandError {
42 match err.kind {
43 match err.kind {
43 DebugDataErrorKind::FindRootError(err) => CommandError::from(err),
44 DebugDataErrorKind::IoError(err) => CommandError {
44 DebugDataErrorKind::IoError(err) => CommandError {
45 kind: CommandErrorKind::Abort(Some(
45 kind: CommandErrorKind::Abort(Some(
46 utf8_to_local(&format!("abort: {}\n", err)).into(),
46 utf8_to_local(&format!("abort: {}\n", err)).into(),
@@ -1,7 +1,7 b''
1 use crate::commands::Command;
1 use crate::commands::Command;
2 use crate::error::CommandError;
2 use crate::error::CommandError;
3 use crate::ui::Ui;
3 use crate::ui::Ui;
4 use hg::operations::FindRoot;
4 use hg::operations::find_root;
5 use hg::requirements;
5 use hg::requirements;
6
6
7 pub const HELP_TEXT: &str = "
7 pub const HELP_TEXT: &str = "
@@ -18,7 +18,7 b' impl DebugRequirementsCommand {'
18
18
19 impl Command for DebugRequirementsCommand {
19 impl Command for DebugRequirementsCommand {
20 fn run(&self, ui: &Ui) -> Result<(), CommandError> {
20 fn run(&self, ui: &Ui) -> Result<(), CommandError> {
21 let root = FindRoot::new().run()?;
21 let root = find_root()?;
22 let mut output = String::new();
22 let mut output = String::new();
23 for req in requirements::load(&root)? {
23 for req in requirements::load(&root)? {
24 output.push_str(&req);
24 output.push_str(&req);
@@ -2,14 +2,13 b' use crate::commands::Command;'
2 use crate::error::{CommandError, CommandErrorKind};
2 use crate::error::{CommandError, CommandErrorKind};
3 use crate::ui::utf8_to_local;
3 use crate::ui::utf8_to_local;
4 use crate::ui::Ui;
4 use crate::ui::Ui;
5 use hg::operations::FindRoot;
5 use hg::operations::find_root;
6 use hg::operations::{
6 use hg::operations::{
7 ListDirstateTrackedFiles, ListDirstateTrackedFilesError,
7 list_rev_tracked_files, ListRevTrackedFilesError,
8 ListDirstateTrackedFilesErrorKind,
8 ListRevTrackedFilesErrorKind,
9 };
9 };
10 use hg::operations::{
10 use hg::operations::{
11 ListRevTrackedFiles, ListRevTrackedFilesError,
11 Dirstate, ListDirstateTrackedFilesError, ListDirstateTrackedFilesErrorKind,
12 ListRevTrackedFilesErrorKind,
13 };
12 };
14 use hg::requirements;
13 use hg::requirements;
15 use hg::utils::files::{get_bytes_from_path, relativize_path};
14 use hg::utils::files::{get_bytes_from_path, relativize_path};
@@ -57,17 +56,15 b" impl<'a> FilesCommand<'a> {"
57
56
58 impl<'a> Command for FilesCommand<'a> {
57 impl<'a> Command for FilesCommand<'a> {
59 fn run(&self, ui: &Ui) -> Result<(), CommandError> {
58 fn run(&self, ui: &Ui) -> Result<(), CommandError> {
60 let root = FindRoot::new().run()?;
59 let root = find_root()?;
61 requirements::check(&root)?;
60 requirements::check(&root)?;
62 if let Some(rev) = self.rev {
61 if let Some(rev) = self.rev {
63 let mut operation = ListRevTrackedFiles::new(&root, rev)
62 let files = list_rev_tracked_files(&root, rev)
64 .map_err(|e| map_rev_error(rev, e))?;
63 .map_err(|e| map_rev_error(rev, e))?;
65 let files = operation.run().map_err(|e| map_rev_error(rev, e))?;
64 self.display_files(ui, &root, files.iter())
66 self.display_files(ui, &root, files)
67 } else {
65 } else {
68 let mut operation = ListDirstateTrackedFiles::new(&root)
66 let distate = Dirstate::new(&root).map_err(map_dirstate_error)?;
69 .map_err(map_dirstate_error)?;
67 let files = distate.tracked_files().map_err(map_dirstate_error)?;
70 let files = operation.run().map_err(map_dirstate_error)?;
71 self.display_files(ui, &root, files)
68 self.display_files(ui, &root, files)
72 }
69 }
73 }
70 }
@@ -2,7 +2,7 b' use crate::commands::Command;'
2 use crate::error::CommandError;
2 use crate::error::CommandError;
3 use crate::ui::Ui;
3 use crate::ui::Ui;
4 use format_bytes::format_bytes;
4 use format_bytes::format_bytes;
5 use hg::operations::FindRoot;
5 use hg::operations::find_root;
6 use hg::utils::files::get_bytes_from_path;
6 use hg::utils::files::get_bytes_from_path;
7
7
8 pub const HELP_TEXT: &str = "
8 pub const HELP_TEXT: &str = "
@@ -21,7 +21,7 b' impl RootCommand {'
21
21
22 impl Command for RootCommand {
22 impl Command for RootCommand {
23 fn run(&self, ui: &Ui) -> Result<(), CommandError> {
23 fn run(&self, ui: &Ui) -> Result<(), CommandError> {
24 let path_buf = FindRoot::new().run()?;
24 let path_buf = find_root()?;
25
25
26 let bytes = get_bytes_from_path(path_buf);
26 let bytes = get_bytes_from_path(path_buf);
27
27
General Comments 0
You need to be logged in to leave comments. Login now