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
use {
anyhow::Result,
slog::warn,
std::{io::Write, path::Path},
tar,
};
pub fn write_tarball_from_directory<W: Write, P: AsRef<Path>>(
logger: &slog::Logger,
fh: &mut W,
source_path: P,
archive_prefix: Option<P>,
) -> Result<()> {
let source_path = source_path.as_ref();
let mut builder = tar::Builder::new(fh);
builder.mode(tar::HeaderMode::Deterministic);
let walk = walkdir::WalkDir::new(source_path).sort_by(|a, b| a.file_name().cmp(b.file_name()));
for entry in walk {
let entry = entry?;
let path = entry.path();
if path == source_path {
continue;
}
let rel_path = path.strip_prefix(source_path)?;
let archive_path = if let Some(prefix) = &archive_prefix {
prefix.as_ref().join(rel_path)
} else {
rel_path.to_path_buf()
};
warn!(
logger,
"adding {} as {}",
path.display(),
archive_path.display()
);
builder.append_path_with_name(path, &archive_path)?;
}
builder.finish()?;
Ok(())
}