##// END OF EJS Templates
rhg: add a test for --rev with a hex changeset ID...
Simon Sapin -
r46611:904647f7 default
parent child Browse files
Show More
@@ -1,101 +1,101
1 1 use crate::commands::Command;
2 2 use crate::error::{CommandError, CommandErrorKind};
3 3 use crate::ui::utf8_to_local;
4 4 use crate::ui::Ui;
5 5 use hg::operations::FindRoot;
6 6 use hg::operations::{CatRev, CatRevError, CatRevErrorKind};
7 7 use hg::requirements;
8 8 use hg::utils::hg_path::HgPathBuf;
9 9 use micro_timer::timed;
10 10 use std::convert::TryFrom;
11 11
12 12 pub const HELP_TEXT: &str = "
13 13 Output the current or given revision of files
14 14 ";
15 15
16 16 pub struct CatCommand<'a> {
17 17 rev: Option<&'a str>,
18 18 files: Vec<&'a str>,
19 19 }
20 20
21 21 impl<'a> CatCommand<'a> {
22 22 pub fn new(rev: Option<&'a str>, files: Vec<&'a str>) -> Self {
23 23 Self { rev, files }
24 24 }
25 25
26 26 fn display(&self, ui: &Ui, data: &[u8]) -> Result<(), CommandError> {
27 27 ui.write_stdout(data)?;
28 28 Ok(())
29 29 }
30 30 }
31 31
32 32 impl<'a> Command for CatCommand<'a> {
33 33 #[timed]
34 34 fn run(&self, ui: &Ui) -> Result<(), CommandError> {
35 35 let root = FindRoot::new().run()?;
36 36 requirements::check(&root)?;
37 37 let cwd = std::env::current_dir()
38 38 .or_else(|e| Err(CommandErrorKind::CurrentDirNotFound(e)))?;
39 39
40 40 let mut files = vec![];
41 41 for file in self.files.iter() {
42 42 let normalized = cwd.join(&file);
43 43 let stripped = normalized
44 44 .strip_prefix(&root)
45 45 .or(Err(CommandErrorKind::Abort(None)))?;
46 46 let hg_file = HgPathBuf::try_from(stripped.to_path_buf())
47 47 .or(Err(CommandErrorKind::Abort(None)))?;
48 48 files.push(hg_file);
49 49 }
50 50
51 51 match self.rev {
52 52 Some(rev) => {
53 53 let mut operation = CatRev::new(&root, rev, &files)
54 54 .map_err(|e| map_rev_error(rev, e))?;
55 55 let data =
56 56 operation.run().map_err(|e| map_rev_error(rev, e))?;
57 57 self.display(ui, &data)
58 58 }
59 59 None => Err(CommandErrorKind::Unimplemented.into()),
60 60 }
61 61 }
62 62 }
63 63
64 64 /// Convert `CatRevErrorKind` to `CommandError`
65 65 fn map_rev_error(rev: &str, err: CatRevError) -> CommandError {
66 66 CommandError {
67 67 kind: match err.kind {
68 68 CatRevErrorKind::IoError(err) => CommandErrorKind::Abort(Some(
69 69 utf8_to_local(&format!("abort: {}\n", err)).into(),
70 70 )),
71 71 CatRevErrorKind::InvalidRevision => CommandErrorKind::Abort(Some(
72 72 utf8_to_local(&format!(
73 "abort: invalid revision identifier{}\n",
73 "abort: invalid revision identifier {}\n",
74 74 rev
75 75 ))
76 76 .into(),
77 77 )),
78 78 CatRevErrorKind::UnsuportedRevlogVersion(version) => {
79 79 CommandErrorKind::Abort(Some(
80 80 utf8_to_local(&format!(
81 81 "abort: unsupported revlog version {}\n",
82 82 version
83 83 ))
84 84 .into(),
85 85 ))
86 86 }
87 87 CatRevErrorKind::CorruptedRevlog => CommandErrorKind::Abort(Some(
88 88 "abort: corrupted revlog\n".into(),
89 89 )),
90 90 CatRevErrorKind::UnknowRevlogDataFormat(format) => {
91 91 CommandErrorKind::Abort(Some(
92 92 utf8_to_local(&format!(
93 93 "abort: unknow revlog dataformat {:?}\n",
94 94 format
95 95 ))
96 96 .into(),
97 97 ))
98 98 }
99 99 },
100 100 }
101 101 }
@@ -1,138 +1,138
1 1 use crate::commands::Command;
2 2 use crate::error::{CommandError, CommandErrorKind};
3 3 use crate::ui::utf8_to_local;
4 4 use crate::ui::Ui;
5 5 use hg::operations::FindRoot;
6 6 use hg::operations::{
7 7 ListDirstateTrackedFiles, ListDirstateTrackedFilesError,
8 8 ListDirstateTrackedFilesErrorKind,
9 9 };
10 10 use hg::operations::{
11 11 ListRevTrackedFiles, ListRevTrackedFilesError,
12 12 ListRevTrackedFilesErrorKind,
13 13 };
14 14 use hg::requirements;
15 15 use hg::utils::files::{get_bytes_from_path, relativize_path};
16 16 use hg::utils::hg_path::{HgPath, HgPathBuf};
17 17 use std::path::PathBuf;
18 18
19 19 pub const HELP_TEXT: &str = "
20 20 List tracked files.
21 21
22 22 Returns 0 on success.
23 23 ";
24 24
25 25 pub struct FilesCommand<'a> {
26 26 rev: Option<&'a str>,
27 27 }
28 28
29 29 impl<'a> FilesCommand<'a> {
30 30 pub fn new(rev: Option<&'a str>) -> Self {
31 31 FilesCommand { rev }
32 32 }
33 33
34 34 fn display_files(
35 35 &self,
36 36 ui: &Ui,
37 37 root: &PathBuf,
38 38 files: impl IntoIterator<Item = &'a HgPath>,
39 39 ) -> Result<(), CommandError> {
40 40 let cwd = std::env::current_dir()
41 41 .or_else(|e| Err(CommandErrorKind::CurrentDirNotFound(e)))?;
42 42 let rooted_cwd = cwd
43 43 .strip_prefix(&root)
44 44 .expect("cwd was already checked within the repository");
45 45 let rooted_cwd = HgPathBuf::from(get_bytes_from_path(rooted_cwd));
46 46
47 47 let mut stdout = ui.stdout_buffer();
48 48
49 49 for file in files {
50 50 stdout.write_all(relativize_path(file, &rooted_cwd).as_ref())?;
51 51 stdout.write_all(b"\n")?;
52 52 }
53 53 stdout.flush()?;
54 54 Ok(())
55 55 }
56 56 }
57 57
58 58 impl<'a> Command for FilesCommand<'a> {
59 59 fn run(&self, ui: &Ui) -> Result<(), CommandError> {
60 60 let root = FindRoot::new().run()?;
61 61 requirements::check(&root)?;
62 62 if let Some(rev) = self.rev {
63 63 let mut operation = ListRevTrackedFiles::new(&root, rev)
64 64 .map_err(|e| map_rev_error(rev, e))?;
65 65 let files = operation.run().map_err(|e| map_rev_error(rev, e))?;
66 66 self.display_files(ui, &root, files)
67 67 } else {
68 68 let mut operation = ListDirstateTrackedFiles::new(&root)
69 69 .map_err(map_dirstate_error)?;
70 70 let files = operation.run().map_err(map_dirstate_error)?;
71 71 self.display_files(ui, &root, files)
72 72 }
73 73 }
74 74 }
75 75
76 76 /// Convert `ListRevTrackedFilesErrorKind` to `CommandError`
77 77 fn map_rev_error(rev: &str, err: ListRevTrackedFilesError) -> CommandError {
78 78 CommandError {
79 79 kind: match err.kind {
80 80 ListRevTrackedFilesErrorKind::IoError(err) => {
81 81 CommandErrorKind::Abort(Some(
82 82 utf8_to_local(&format!("abort: {}\n", err)).into(),
83 83 ))
84 84 }
85 85 ListRevTrackedFilesErrorKind::InvalidRevision => {
86 86 CommandErrorKind::Abort(Some(
87 87 utf8_to_local(&format!(
88 "abort: invalid revision identifier{}\n",
88 "abort: invalid revision identifier {}\n",
89 89 rev
90 90 ))
91 91 .into(),
92 92 ))
93 93 }
94 94 ListRevTrackedFilesErrorKind::UnsuportedRevlogVersion(version) => {
95 95 CommandErrorKind::Abort(Some(
96 96 utf8_to_local(&format!(
97 97 "abort: unsupported revlog version {}\n",
98 98 version
99 99 ))
100 100 .into(),
101 101 ))
102 102 }
103 103 ListRevTrackedFilesErrorKind::CorruptedRevlog => {
104 104 CommandErrorKind::Abort(Some(
105 105 "abort: corrupted revlog\n".into(),
106 106 ))
107 107 }
108 108 ListRevTrackedFilesErrorKind::UnknowRevlogDataFormat(format) => {
109 109 CommandErrorKind::Abort(Some(
110 110 utf8_to_local(&format!(
111 111 "abort: unknow revlog dataformat {:?}\n",
112 112 format
113 113 ))
114 114 .into(),
115 115 ))
116 116 }
117 117 },
118 118 }
119 119 }
120 120
121 121 /// Convert `ListDirstateTrackedFilesError` to `CommandError`
122 122 fn map_dirstate_error(err: ListDirstateTrackedFilesError) -> CommandError {
123 123 CommandError {
124 124 kind: match err.kind {
125 125 ListDirstateTrackedFilesErrorKind::IoError(err) => {
126 126 CommandErrorKind::Abort(Some(
127 127 utf8_to_local(&format!("abort: {}\n", err)).into(),
128 128 ))
129 129 }
130 130 ListDirstateTrackedFilesErrorKind::ParseError(_) => {
131 131 CommandErrorKind::Abort(Some(
132 132 // TODO find a better error message
133 133 b"abort: parse error\n".to_vec(),
134 134 ))
135 135 }
136 136 },
137 137 }
138 138 }
@@ -1,147 +1,167
1 1 #require rust
2 2
3 3 Define an rhg function that will only run if rhg exists
4 4 $ rhg() {
5 5 > if [ -f "$RUNTESTDIR/../rust/target/debug/rhg" ]; then
6 6 > "$RUNTESTDIR/../rust/target/debug/rhg" "$@"
7 7 > else
8 8 > echo "skipped: Cannot find rhg. Try to run cargo build in rust/rhg."
9 9 > exit 80
10 10 > fi
11 11 > }
12 12
13 13 Unimplemented command
14 14 $ rhg unimplemented-command
15 15 error: Found argument 'unimplemented-command' which wasn't expected, or isn't valid in this context
16 16
17 17 USAGE:
18 18 rhg <SUBCOMMAND>
19 19
20 20 For more information try --help
21 21 [252]
22 22
23 23 Finding root
24 24 $ rhg root
25 25 abort: no repository found in '$TESTTMP' (.hg not found)!
26 26 [255]
27 27
28 28 $ hg init repository
29 29 $ cd repository
30 30 $ rhg root
31 31 $TESTTMP/repository
32 32
33 33 Unwritable file descriptor
34 34 $ rhg root > /dev/full
35 35 abort: No space left on device (os error 28)
36 36 [255]
37 37
38 38 Deleted repository
39 39 $ rm -rf `pwd`
40 40 $ rhg root
41 41 abort: error getting current working directory: $ENOENT$
42 42 [255]
43 43
44 44 Listing tracked files
45 45 $ cd $TESTTMP
46 46 $ hg init repository
47 47 $ cd repository
48 48 $ for i in 1 2 3; do
49 49 > echo $i >> file$i
50 50 > hg add file$i
51 51 > done
52 52 > hg commit -m "commit $i" -q
53 53
54 54 Listing tracked files from root
55 55 $ rhg files
56 56 file1
57 57 file2
58 58 file3
59 59
60 60 Listing tracked files from subdirectory
61 61 $ mkdir -p path/to/directory
62 62 $ cd path/to/directory
63 63 $ rhg files
64 64 ../../../file1
65 65 ../../../file2
66 66 ../../../file3
67 67
68 68 Listing tracked files through broken pipe
69 69 $ rhg files | head -n 1
70 70 ../../../file1
71 71
72 72 Debuging data in inline index
73 73 $ cd $TESTTMP
74 74 $ rm -rf repository
75 75 $ hg init repository
76 76 $ cd repository
77 77 $ for i in 1 2 3; do
78 78 > echo $i >> file$i
79 79 > hg add file$i
80 80 > hg commit -m "commit $i" -q
81 81 > done
82 82 $ rhg debugdata -c 2
83 83 e36fa63d37a576b27a69057598351db6ee5746bd
84 84 test
85 85 0 0
86 86 file3
87 87
88 88 commit 3 (no-eol)
89 89 $ rhg debugdata -m 2
90 90 file1\x00b8e02f6433738021a065f94175c7cd23db5f05be (esc)
91 91 file2\x005d9299349fc01ddd25d0070d149b124d8f10411e (esc)
92 92 file3\x002661d26c649684b482d10f91960cc3db683c38b4 (esc)
93 93
94 94 Debuging with full node id
95 95 $ rhg debugdata -c `hg log -r 0 -T '{node}'`
96 96 c8e64718e1ca0312eeee0f59d37f8dc612793856
97 97 test
98 98 0 0
99 99 file1
100 100
101 101 commit 1 (no-eol)
102 102
103 103 Cat files
104 104 $ cd $TESTTMP
105 105 $ rm -rf repository
106 106 $ hg init repository
107 107 $ cd repository
108 108 $ echo "original content" > original
109 109 $ hg add original
110 110 $ hg commit -m "add original" original
111 111 $ rhg cat -r 0 original
112 112 original content
113 113 Cat copied file should not display copy metadata
114 114 $ hg copy original copy_of_original
115 115 $ hg commit -m "add copy of original"
116 116 $ rhg cat -r 1 copy_of_original
117 117 original content
118 118
119 Specifying revisions by changeset ID
120 $ hg log
121 changeset: 1:41263439dc17
122 tag: tip
123 user: test
124 date: Thu Jan 01 00:00:00 1970 +0000
125 summary: add copy of original
126
127 changeset: 0:1c9e69808da7
128 user: test
129 date: Thu Jan 01 00:00:00 1970 +0000
130 summary: add original
131
132 $ rhg files -r 41263439dc17
133 abort: invalid revision identifier 41263439dc17
134 [255]
135 $ rhg cat -r 41263439dc17 original
136 abort: invalid revision identifier 41263439dc17
137 [255]
138
119 139 Requirements
120 140 $ rhg debugrequirements
121 141 dotencode
122 142 fncache
123 143 generaldelta
124 144 revlogv1
125 145 sparserevlog
126 146 store
127 147
128 148 $ echo indoor-pool >> .hg/requires
129 149 $ rhg files
130 150 [252]
131 151
132 152 $ rhg cat -r 1 copy_of_original
133 153 [252]
134 154
135 155 $ rhg debugrequirements
136 156 dotencode
137 157 fncache
138 158 generaldelta
139 159 revlogv1
140 160 sparserevlog
141 161 store
142 162 indoor-pool
143 163
144 164 $ echo -e '\xFF' >> .hg/requires
145 165 $ rhg debugrequirements
146 166 abort: .hg/requires is corrupted
147 167 [255]
General Comments 0
You need to be logged in to leave comments. Login now