]> git.proxmox.com Git - rustc.git/blob - src/vendor/mdbook/src/utils/fs.rs
New upstream version 1.20.0+dfsg1
[rustc.git] / src / vendor / mdbook / src / utils / fs.rs
1 use std::path::{Path, Component};
2 use std::error::Error;
3 use std::io::{self, Read};
4 use std::fs::{self, File};
5
6 /// Takes a path to a file and try to read the file into a String
7
8 pub fn file_to_string(path: &Path) -> Result<String, Box<Error>> {
9 let mut file = match File::open(path) {
10 Ok(f) => f,
11 Err(e) => {
12 debug!("[*]: Failed to open {:?}", path);
13 return Err(Box::new(e));
14 },
15 };
16
17 let mut content = String::new();
18
19 if let Err(e) = file.read_to_string(&mut content) {
20 debug!("[*]: Failed to read {:?}", path);
21 return Err(Box::new(e));
22 }
23
24 Ok(content)
25 }
26
27 /// Takes a path and returns a path containing just enough `../` to point to
28 /// the root of the given path.
29 ///
30 /// This is mostly interesting for a relative path to point back to the
31 /// directory from where the path starts.
32 ///
33 /// ```ignore
34 /// let mut path = Path::new("some/relative/path");
35 ///
36 /// println!("{}", path_to_root(&path));
37 /// ```
38 ///
39 /// **Outputs**
40 ///
41 /// ```text
42 /// "../../"
43 /// ```
44 ///
45 /// **note:** it's not very fool-proof, if you find a situation where
46 /// it doesn't return the correct path.
47 /// Consider [submitting a new issue](https://github.com/azerupi/mdBook/issues)
48 /// or a [pull-request](https://github.com/azerupi/mdBook/pulls) to improve it.
49
50 pub fn path_to_root(path: &Path) -> String {
51 debug!("[fn]: path_to_root");
52 // Remove filename and add "../" for every directory
53
54 path.to_path_buf()
55 .parent()
56 .expect("")
57 .components()
58 .fold(String::new(), |mut s, c| {
59 match c {
60 Component::Normal(_) => s.push_str("../"),
61 _ => {
62 debug!("[*]: Other path component... {:?}", c);
63 },
64 }
65 s
66 })
67 }
68
69
70
71 /// This function creates a file and returns it. But before creating the file
72 /// it checks every directory in the path to see if it exists,
73 /// and if it does not it will be created.
74
75 pub fn create_file(path: &Path) -> io::Result<File> {
76 debug!("[fn]: create_file");
77
78 // Construct path
79 if let Some(p) = path.parent() {
80 debug!("Parent directory is: {:?}", p);
81
82 fs::create_dir_all(p)?;
83 }
84
85 debug!("[*]: Create file: {:?}", path);
86 File::create(path)
87 }
88
89 /// Removes all the content of a directory but not the directory itself
90
91 pub fn remove_dir_content(dir: &Path) -> Result<(), Box<Error>> {
92 for item in fs::read_dir(dir)? {
93 if let Ok(item) = item {
94 let item = item.path();
95 if item.is_dir() {
96 fs::remove_dir_all(item)?;
97 } else {
98 fs::remove_file(item)?;
99 }
100 }
101 }
102 Ok(())
103 }
104
105 ///
106 ///
107 /// Copies all files of a directory to another one except the files
108 /// with the extensions given in the `ext_blacklist` array
109
110 pub fn copy_files_except_ext(from: &Path, to: &Path, recursive: bool, ext_blacklist: &[&str])
111 -> Result<(), Box<Error>> {
112 debug!("[fn] copy_files_except_ext");
113 // Check that from and to are different
114 if from == to {
115 return Ok(());
116 }
117 debug!("[*] Loop");
118 for entry in fs::read_dir(from)? {
119 let entry = entry?;
120 debug!("[*] {:?}", entry.path());
121 let metadata = entry.metadata()?;
122
123 // If the entry is a dir and the recursive option is enabled, call itself
124 if metadata.is_dir() && recursive {
125 if entry.path() == to.to_path_buf() {
126 continue;
127 }
128 debug!("[*] is dir");
129
130 // check if output dir already exists
131 if !to.join(entry.file_name()).exists() {
132 fs::create_dir(&to.join(entry.file_name()))?;
133 }
134
135 copy_files_except_ext(&from.join(entry.file_name()), &to.join(entry.file_name()), true, ext_blacklist)?;
136 } else if metadata.is_file() {
137
138 // Check if it is in the blacklist
139 if let Some(ext) = entry.path().extension() {
140 if ext_blacklist.contains(&ext.to_str().unwrap()) {
141 continue;
142 }
143 }
144 debug!("[*] creating path for file: {:?}",
145 &to.join(entry
146 .path()
147 .file_name()
148 .expect("a file should have a file name...")));
149
150 info!("[*] Copying file: {:?}\n to {:?}",
151 entry.path(),
152 &to.join(entry
153 .path()
154 .file_name()
155 .expect("a file should have a file name...")));
156 fs::copy(entry.path(),
157 &to.join(entry
158 .path()
159 .file_name()
160 .expect("a file should have a file name...")))?;
161 }
162 }
163 Ok(())
164 }
165
166
167 // ------------------------------------------------------------------------------------------------
168 // ------------------------------------------------------------------------------------------------
169
170 // tests
171
172 #[cfg(test)]
173 mod tests {
174 extern crate tempdir;
175
176 use super::copy_files_except_ext;
177 use std::fs;
178
179 #[test]
180 fn copy_files_except_ext_test() {
181 let tmp = match tempdir::TempDir::new("") {
182 Ok(t) => t,
183 Err(_) => panic!("Could not create a temp dir"),
184 };
185
186 // Create a couple of files
187 if let Err(_) = fs::File::create(&tmp.path().join("file.txt")) {
188 panic!("Could not create file.txt")
189 }
190 if let Err(_) = fs::File::create(&tmp.path().join("file.md")) {
191 panic!("Could not create file.md")
192 }
193 if let Err(_) = fs::File::create(&tmp.path().join("file.png")) {
194 panic!("Could not create file.png")
195 }
196 if let Err(_) = fs::create_dir(&tmp.path().join("sub_dir")) {
197 panic!("Could not create sub_dir")
198 }
199 if let Err(_) = fs::File::create(&tmp.path().join("sub_dir/file.png")) {
200 panic!("Could not create sub_dir/file.png")
201 }
202 if let Err(_) = fs::create_dir(&tmp.path().join("sub_dir_exists")) {
203 panic!("Could not create sub_dir_exists")
204 }
205 if let Err(_) = fs::File::create(&tmp.path().join("sub_dir_exists/file.txt")) {
206 panic!("Could not create sub_dir_exists/file.txt")
207 }
208
209 // Create output dir
210 if let Err(_) = fs::create_dir(&tmp.path().join("output")) {
211 panic!("Could not create output")
212 }
213 if let Err(_) = fs::create_dir(&tmp.path().join("output/sub_dir_exists")) {
214 panic!("Could not create output/sub_dir_exists")
215 }
216
217 match copy_files_except_ext(&tmp.path(), &tmp.path().join("output"), true, &["md"]) {
218 Err(e) => panic!("Error while executing the function:\n{:?}", e),
219 Ok(_) => {},
220 }
221
222 // Check if the correct files where created
223 if !(&tmp.path().join("output/file.txt")).exists() {
224 panic!("output/file.txt should exist")
225 }
226 if (&tmp.path().join("output/file.md")).exists() {
227 panic!("output/file.md should not exist")
228 }
229 if !(&tmp.path().join("output/file.png")).exists() {
230 panic!("output/file.png should exist")
231 }
232 if !(&tmp.path().join("output/sub_dir/file.png")).exists() {
233 panic!("output/sub_dir/file.png should exist")
234 }
235 if !(&tmp.path().join("output/sub_dir_exists/file.txt")).exists() {
236 panic!("output/sub_dir/file.png should exist")
237 }
238
239 }
240 }