MCPcopy Create free account
hub / github.com/dtormoen/tsk-tsk / copy_dir

Function copy_dir

src/file_system.rs:11–63  ·  view source on GitHub ↗

Recursively copies a directory from source to destination.

(
    from: &'a Path,
    to: &'a Path,
)

Source from the content-addressed store, hash-verified

9
10/// Recursively copies a directory from source to destination.
11pub fn copy_dir<'a>(
12 from: &'a Path,
13 to: &'a Path,
14) -> std::pin::Pin<Box<dyn std::future::Future<Output = Result<()>> + Send + 'a>> {
15 Box::pin(async move {
16 create_dir(to).await?;
17
18 let mut entries = tokio::fs::read_dir(from).await?;
19 while let Some(entry) = entries.next_entry().await? {
20 let path = entry.path();
21 let relative_path = path.strip_prefix(from)?;
22 let dst_path = to.join(relative_path);
23
24 // Get metadata without following symlinks to check if it's a symlink
25 let metadata = tokio::fs::symlink_metadata(&path).await?;
26
27 if metadata.is_symlink() {
28 // Preserve symlinks by reading the target and creating a new symlink
29 let target = tokio::fs::read_link(&path).await?;
30 if let Some(parent) = dst_path.parent() {
31 create_dir(parent).await?;
32 }
33 // Create symlink at destination pointing to the same target
34 #[cfg(unix)]
35 tokio::fs::symlink(&target, &dst_path).await?;
36 #[cfg(windows)]
37 {
38 // On Windows, we need to determine if it's a file or directory symlink
39 // Try to get the target metadata to determine the type
40 if let Ok(target_metadata) = tokio::fs::metadata(&path).await {
41 if target_metadata.is_dir() {
42 tokio::fs::symlink_dir(&target, &dst_path).await?;
43 } else {
44 tokio::fs::symlink_file(&target, &dst_path).await?;
45 }
46 } else {
47 // If we can't determine the type, try as a file symlink
48 tokio::fs::symlink_file(&target, &dst_path).await?;
49 }
50 }
51 } else if metadata.is_dir() {
52 copy_dir(&path, &dst_path).await?;
53 } else {
54 if let Some(parent) = dst_path.parent() {
55 create_dir(parent).await?;
56 }
57 copy_file(&path, &dst_path).await?;
58 }
59 }
60
61 Ok(())
62 })
63}
64
65/// Writes content to a file, creating parent directories if needed.
66pub async fn write_file(path: &Path, content: &str) -> Result<()> {

Callers 5

copy_repoMethod · 0.85
test_copy_dirFunction · 0.85

Calls 3

create_dirFunction · 0.85
copy_fileFunction · 0.85
pathMethod · 0.80

Tested by 4

test_copy_dirFunction · 0.68