Skip to content

Commit

Permalink
fix(fs): ignore metadata error while reading dir entries
Browse files Browse the repository at this point in the history
closes #2014
  • Loading branch information
amrbashir committed Nov 7, 2024
1 parent 3449dd5 commit 17f8ff8
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 33 deletions.
7 changes: 7 additions & 0 deletions .changes/fs-read-dir-broken-symlink.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"fs": "patch"
"fs-js": "patch"
---

Fix `readDir` function failing to read directories that contain broken symlinks.

5 changes: 3 additions & 2 deletions examples/api/package.json
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
{
"name": "svelte-app",
"name": "api",
"private": true,
"version": "2.0.2",
"type": "module",
"scripts": {
"dev": "vite --clearScreen false",
"build": "vite build",
"serve": "vite preview"
"serve": "vite preview",
"tauri": "tauri"
},
"dependencies": {
"@tauri-apps/api": "2.0.3",
Expand Down
6 changes: 4 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
"build": "pnpm run -r --parallel --filter !plugins-workspace --filter !\"./plugins/*/examples/**\" --filter !\"./examples/*\" build",
"lint": "eslint .",
"format": "prettier --write .",
"format:check": "prettier --check ."
"format:check": "prettier --check .",
"example:api:dev": "pnpm run --filter \"api\" tauri dev"
},
"devDependencies": {
"@eslint/js": "9.14.0",
Expand All @@ -31,5 +32,6 @@
},
"engines": {
"pnpm": "^9.0.0"
}
},
"packageManager": "[email protected]+sha512.0a203ffaed5a3f63242cd064c8fb5892366c103e328079318f78062f24ea8c9d50bc6a47aa3567cabefd824d170e78fa2745ed1f16b132e16436146b7688f19b"
}
61 changes: 32 additions & 29 deletions plugins/fs/src/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use std::{
borrow::Cow,
fs::File,
io::{BufReader, Lines, Read, Write},
path::{Path, PathBuf},
path::PathBuf,
str::FromStr,
sync::Mutex,
time::{SystemTime, UNIX_EPOCH},
Expand Down Expand Up @@ -245,32 +245,12 @@ pub fn mkdir<R: Runtime>(
#[serde(rename_all = "camelCase")]
#[non_exhaustive]
pub struct DirEntry {
pub name: Option<String>,
pub name: String,
pub is_directory: bool,
pub is_file: bool,
pub is_symlink: bool,
}

fn read_dir_inner<P: AsRef<Path>>(path: P) -> crate::Result<Vec<DirEntry>> {
let mut files_and_dirs: Vec<DirEntry> = vec![];
for entry in std::fs::read_dir(path)? {
let path = entry?.path();
let file_type = path.metadata()?.file_type();
files_and_dirs.push(DirEntry {
is_directory: file_type.is_dir(),
is_file: file_type.is_file(),
is_symlink: std::fs::symlink_metadata(&path)
.map(|md| md.file_type().is_symlink())
.unwrap_or(false),
name: path
.file_name()
.map(|name| name.to_string_lossy())
.map(|name| name.to_string()),
});
}
Result::Ok(files_and_dirs)
}

#[tauri::command]
pub async fn read_dir<R: Runtime>(
webview: Webview<R>,
Expand All @@ -287,14 +267,37 @@ pub async fn read_dir<R: Runtime>(
options.as_ref().and_then(|o| o.base_dir),
)?;

read_dir_inner(&resolved_path)
.map_err(|e| {
format!(
"failed to read directory at path: {} with error: {e}",
resolved_path.display()
)
let entries = std::fs::read_dir(&resolved_path).map_err(|e| {
format!(
"failed to read directory at path: {} with error: {e}",
resolved_path.display()
)
})?;

let entries = entries
.filter_map(|entry| {
let entry = entry.ok()?;
let name = entry.file_name().into_string().ok()?;
let metadata = entry.file_type();
macro_rules! method_or_false {
($method:ident) => {
if let Ok(metadata) = &metadata {
metadata.$method()
} else {
false
}
};
}
Some(DirEntry {
name,
is_file: method_or_false!(is_file),
is_directory: method_or_false!(is_dir),
is_symlink: method_or_false!(is_symlink),
})
})
.map_err(Into::into)
.collect();

Ok(entries)
}

#[tauri::command]
Expand Down

0 comments on commit 17f8ff8

Please sign in to comment.