Skip to content

Commit 0664ac5

Browse files
committed
Allow saving a single file instead of a filesystem tree
1 parent d88b7e2 commit 0664ac5

File tree

1 file changed

+43
-15
lines changed

1 file changed

+43
-15
lines changed

src/chunks/tree.rs

Lines changed: 43 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
use anyhow::{Context, Result};
2-
use std::{fs, os::unix::fs::PermissionsExt, path::Path};
2+
use std::{
3+
fs,
4+
os::unix::fs::PermissionsExt,
5+
path::{Path, PathBuf},
6+
};
37
use walkdir::WalkDir;
48

59
use crate::chunks::{Chunk, HashKind, hash::hash};
@@ -9,32 +13,30 @@ use crate::chunks::{Chunk, HashKind, hash::hash};
913
/// # Errors
1014
///
1115
/// - Filesystem out of space (Very likely)
16+
///
17+
/// # Panics
18+
///
19+
/// - If `tree_path` points to a file, but the file somehow has no parent (eg: is root), then this will panic because there is no way that can be handled.
1220
pub fn save_tree(
1321
tree_path: &Path,
1422
chunk_store_path: &Path,
1523
hash_kind: HashKind,
1624
) -> Result<Vec<Chunk>> {
1725
let mut chunks = Vec::new();
1826

19-
for entry in WalkDir::new(tree_path) {
20-
let file = entry?;
21-
22-
if !file.file_type().is_file() {
23-
continue;
24-
}
27+
if !chunk_store_path.exists() {
28+
fs::create_dir_all(chunk_store_path)?;
29+
}
2530

26-
let path = file.path().strip_prefix(tree_path)?.to_path_buf();
27-
let contents = fs::read(file.path())?;
31+
if tree_path.is_file() {
32+
let path: PathBuf = tree_path.file_name().unwrap().into();
33+
let contents = fs::read(tree_path)?;
2834
let size = (contents.len() as u64) / 1024;
2935
let hash = hash(hash_kind, &contents);
30-
let mode = file.metadata()?.permissions().mode() & 0o777;
31-
32-
if !chunk_store_path.exists() {
33-
fs::create_dir_all(chunk_store_path)?;
34-
}
36+
let mode = fs::metadata(tree_path)?.permissions().mode() & 0o777;
3537

3638
let chunk_path = &chunk_store_path.join(get_chunk_filename(&hash, mode));
37-
if fs::hard_link(file.path(), chunk_path).is_err() {
39+
if fs::hard_link(tree_path, chunk_path).is_err() {
3840
fs::write(chunk_path, contents)?;
3941
}
4042

@@ -44,6 +46,32 @@ pub fn save_tree(
4446
size,
4547
permissions: mode,
4648
});
49+
} else {
50+
for entry in WalkDir::new(tree_path) {
51+
let file = entry?;
52+
53+
if !file.file_type().is_file() {
54+
continue;
55+
}
56+
57+
let path = file.path().strip_prefix(tree_path)?.to_path_buf();
58+
let contents = fs::read(file.path())?;
59+
let size = (contents.len() as u64) / 1024;
60+
let hash = hash(hash_kind, &contents);
61+
let mode = file.metadata()?.permissions().mode() & 0o777;
62+
63+
let chunk_path = &chunk_store_path.join(get_chunk_filename(&hash, mode));
64+
if fs::hard_link(file.path(), chunk_path).is_err() {
65+
fs::write(chunk_path, contents)?;
66+
}
67+
68+
chunks.push(Chunk {
69+
hash,
70+
path,
71+
size,
72+
permissions: mode,
73+
});
74+
}
4775
}
4876

4977
Ok(chunks)

0 commit comments

Comments
 (0)