diff --git a/CHANGELOG.md b/CHANGELOG.md index 03c25654..8769b638 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -93,9 +93,9 @@ Versioning](https://semver.org/spec/v2.0.0.html). once after updating to yabridge 4.0, yabridge can now be updated without needing to rerun `yabridgectl sync`. This is particularly useful when using a distro packaged version of yabridge. -- `yabridgectl status` now lists the locations where bridged VST2 and VST3 +- `yabridgectl status` now shows the locations where bridged VST2 and VST3 plugins will be set up. - +- `yabridgectl sync --prune` now also considers broken symlinks. - The VST3 subdirectory detection is more robust and can now handle arbitrary directories, not just directories that are called `VST3`. This, of course, should not be needed. diff --git a/tools/yabridgectl/src/actions.rs b/tools/yabridgectl/src/actions.rs index 103cc4f0..60b78e9a 100644 --- a/tools/yabridgectl/src/actions.rs +++ b/tools/yabridgectl/src/actions.rs @@ -509,52 +509,61 @@ pub fn do_sync(config: &mut Config, options: &SyncOptions) -> Result<()> { .follow_links(true) .same_file_system(true) .into_iter() - .filter_map(|e| e.ok()) - .filter(|entry| !entry.file_type().is_dir()) - .filter(|entry| { - matches!( - entry - .path() - .extension() - .and_then(|extension| extension.to_str()), - Some("dll" | "so") - ) + .filter_map(|e| { + let path = match e { + Ok(entry) => entry.path().to_owned(), + Err(err) => err.path()?.to_owned(), + }; + + if !path.is_dir() && matches!(path.extension()?.to_str()?, "dll" | "so") { + Some(path) + } else { + None + } }); let installed_vst3_bundles = WalkDir::new(yabridge_vst3_home()) .follow_links(true) .same_file_system(true) .into_iter() .filter_entry(|entry| entry.file_type().is_dir()) - .filter_map(|e| e.ok()) - .filter(|entry| { - entry - .path() - .extension() - .and_then(|extension| extension.to_str()) - == Some("vst3") + .filter_map(|e| { + let path = match e { + Ok(entry) => entry.path().to_owned(), + Err(err) => err.path()?.to_owned(), + }; + + if path.extension()?.to_str()? == "vst3" { + Some(path) + } else { + None + } }); - orphan_files.extend(centralized_vst2_files.filter_map(|entry| { - if known_centralized_vst2_files.contains(entry.path()) { + orphan_files.extend(centralized_vst2_files.filter_map(|path| { + if known_centralized_vst2_files.contains(&path) { None } else { - get_file_type(entry.path().to_owned()) + get_file_type(path) } })); - for bundle in installed_vst3_bundles { - match known_centralized_vst3_files.get(bundle.path()) { - None => orphan_files.push(NativeFile::Directory(bundle.path().to_owned())), + for bundle_path in installed_vst3_bundles { + match known_centralized_vst3_files.get(&bundle_path) { + None => orphan_files.push(NativeFile::Directory(bundle_path)), Some(managed_vst3_bundle_files) => { // Find orphan files and symlinks within this bundle. We need this to be able to // switch between 32-bit and 64-bit versions of both yabridge and the Windows plugin orphan_files.extend( - WalkDir::new(bundle.path()) + WalkDir::new(bundle_path) .follow_links(false) .into_iter() - .filter_map(|e| e.ok()) - .filter_map(|entry| { - let managed_file = managed_vst3_bundle_files.contains(entry.path()); - match get_file_type(entry.path().to_owned()).unwrap() { + .filter_map(|e| { + let path = match e { + Ok(entry) => entry.path().to_owned(), + Err(err) => err.path()?.to_owned(), + }; + + let managed_file = managed_vst3_bundle_files.contains(&path); + match get_file_type(path).unwrap() { // Don't remove directories, since we're not tracking the // directories within the bundle NativeFile::Directory(_) => None, diff --git a/tools/yabridgectl/src/files.rs b/tools/yabridgectl/src/files.rs index 976884e7..49257ec1 100644 --- a/tools/yabridgectl/src/files.rs +++ b/tools/yabridgectl/src/files.rs @@ -411,9 +411,7 @@ pub fn index(directory: &Path, blacklist: &HashSet<&Path>) -> SearchIndex { let mut dll_files: Vec<(PathBuf, Option)> = Vec::new(); let mut vst3_files: Vec<(PathBuf, Option)> = Vec::new(); let mut so_files: Vec = Vec::new(); - // XXX: We're silently skipping directories and files we don't have permission to read. This - // sounds like the expected behavior, but I"m not entirely sure. - for (file_idx, entry) in WalkDir::new(directory) + for (file_idx, path) in WalkDir::new(directory) .follow_links(true) .into_iter() .filter_entry(|e| { @@ -424,8 +422,20 @@ pub fn index(directory: &Path, blacklist: &HashSet<&Path>) -> SearchIndex { .map(|p| !blacklist.contains(p.as_path())) .unwrap_or(false) }) - .filter_map(|e| e.ok()) - .filter(|e| !e.file_type().is_dir()) + .filter_map(|e| { + // NOTE: Broken symlinks will also get an `Err` entry, so we'll use `err.path()` to + // still include them in the index + let path = match e { + Ok(entry) => entry.path().to_owned(), + Err(err) => err.path()?.to_owned(), + }; + + if !path.is_dir() { + Some(path) + } else { + None + } + }) .enumerate() { // This is a bit of an odd warning, but I can see it happening that someone adds their @@ -439,9 +449,8 @@ pub fn index(directory: &Path, blacklist: &HashSet<&Path>) -> SearchIndex { ) } - match entry.path().extension().and_then(|os| os.to_str()) { + match path.extension().and_then(|os| os.to_str()) { Some("dll") => { - let path = entry.into_path(); let subdirectory = path .parent() .and_then(|p| p.strip_prefix(directory).ok()) @@ -449,7 +458,6 @@ pub fn index(directory: &Path, blacklist: &HashSet<&Path>) -> SearchIndex { dll_files.push((path, subdirectory)); } Some("vst3") => { - let path = entry.into_path(); let subdirectory = path .parent() .and_then(|p| p.strip_prefix(directory).ok()) @@ -457,10 +465,10 @@ pub fn index(directory: &Path, blacklist: &HashSet<&Path>) -> SearchIndex { vst3_files.push((path, subdirectory)); } Some("so") => { - if entry.path_is_symlink() { - so_files.push(NativeFile::Symlink(entry.into_path())); + if path.is_symlink() { + so_files.push(NativeFile::Symlink(path)); } else { - so_files.push(NativeFile::Regular(entry.into_path())); + so_files.push(NativeFile::Regular(path)); } } _ => (),