1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
use std::fs;
use std::fs::File;
use std::io::{Read, Write};
use std::path::Path;
use toml::{Parser, Value};
use walkdir::WalkDir;
use errors::*;
pub fn cp_r(src: &Path, dst: &Path) -> Result<()> {
for e in WalkDir::new(src) {
let e = e.chain_err(|| {
format!(
"intermittent IO error while iterating directory `{}`",
src.display()
)
})?;
let src_file = e.path();
let relative_path = src_file.strip_prefix(src).chain_err(|| {
format!(
"Could not retrieve relative path of child directory or \
file `{}` with regards to parent directory `{}`",
src_file.display(),
src.display()
)
})?;
let dst_file = dst.join(relative_path);
let metadata = e.metadata()
.chain_err(|| format!("Could not retrieve metadata of `{}`", e.path().display()))?;
if metadata.is_dir() {
fs::create_dir_all(&dst_file)
.chain_err(|| format!("Could not create directory `{}`", dst_file.display()))?;
} else {
fs::copy(&src_file, &dst_file).chain_err(|| {
format!(
"copying files from `{}` to `{}` failed",
src_file.display(),
dst_file.display()
)
})?;
};
}
Ok(())
}
pub fn mkdir(path: &Path) -> Result<()> {
fs::create_dir(path).chain_err(|| format!("couldn't create directory {}", path.display()))
}
pub fn parse(path: &Path) -> Result<Value> {
Ok(Value::Table(Parser::new(&read(path)?).parse().ok_or_else(
|| format!("{} is not valid TOML", path.display()),
)?))
}
pub fn read(path: &Path) -> Result<String> {
let mut s = String::new();
let p = path.display();
File::open(path)
.chain_err(|| format!("couldn't open {}", p))?
.read_to_string(&mut s)
.chain_err(|| format!("couldn't read {}", p))?;
Ok(s)
}
pub fn search<'p>(mut path: &'p Path, file: &str) -> Option<&'p Path> {
loop {
if path.join(file).exists() {
return Some(path);
}
if let Some(p) = path.parent() {
path = p;
} else {
return None;
}
}
}
pub fn write(path: &Path, contents: &str) -> Result<()> {
let p = path.display();
File::create(path)
.chain_err(|| format!("couldn't open {}", p))?
.write_all(contents.as_bytes())
.chain_err(|| format!("couldn't write to {}", p))
}
pub fn escape_argument_spaces<S: Into<String>>(arg: S) -> String {
#[cfg(target_os = "windows")]
let escaped = arg.into().replace(" ", "%20");
#[cfg(not(target_os = "windows"))]
let escaped = arg.into();
escaped
}