[yabridgectl] Don't skip over broken symlinks

This commit is contained in:
Robbert van der Helm
2022-04-18 12:58:42 +02:00
parent 8abb960813
commit 4e2f72d67a
3 changed files with 58 additions and 41 deletions
+2 -2
View File
@@ -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 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 needing to rerun `yabridgectl sync`. This is particularly useful when using a
distro packaged version of yabridge. 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. 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 - The VST3 subdirectory detection is more robust and can now handle arbitrary
directories, not just directories that are called `VST3`. This, of course, directories, not just directories that are called `VST3`. This, of course,
should not be needed. should not be needed.
+37 -28
View File
@@ -509,52 +509,61 @@ pub fn do_sync(config: &mut Config, options: &SyncOptions) -> Result<()> {
.follow_links(true) .follow_links(true)
.same_file_system(true) .same_file_system(true)
.into_iter() .into_iter()
.filter_map(|e| e.ok()) .filter_map(|e| {
.filter(|entry| !entry.file_type().is_dir()) let path = match e {
.filter(|entry| { Ok(entry) => entry.path().to_owned(),
matches!( Err(err) => err.path()?.to_owned(),
entry };
.path()
.extension() if !path.is_dir() && matches!(path.extension()?.to_str()?, "dll" | "so") {
.and_then(|extension| extension.to_str()), Some(path)
Some("dll" | "so") } else {
) None
}
}); });
let installed_vst3_bundles = WalkDir::new(yabridge_vst3_home()) let installed_vst3_bundles = WalkDir::new(yabridge_vst3_home())
.follow_links(true) .follow_links(true)
.same_file_system(true) .same_file_system(true)
.into_iter() .into_iter()
.filter_entry(|entry| entry.file_type().is_dir()) .filter_entry(|entry| entry.file_type().is_dir())
.filter_map(|e| e.ok()) .filter_map(|e| {
.filter(|entry| { let path = match e {
entry Ok(entry) => entry.path().to_owned(),
.path() Err(err) => err.path()?.to_owned(),
.extension() };
.and_then(|extension| extension.to_str())
== Some("vst3") if path.extension()?.to_str()? == "vst3" {
Some(path)
} else {
None
}
}); });
orphan_files.extend(centralized_vst2_files.filter_map(|entry| { orphan_files.extend(centralized_vst2_files.filter_map(|path| {
if known_centralized_vst2_files.contains(entry.path()) { if known_centralized_vst2_files.contains(&path) {
None None
} else { } else {
get_file_type(entry.path().to_owned()) get_file_type(path)
} }
})); }));
for bundle in installed_vst3_bundles { for bundle_path in installed_vst3_bundles {
match known_centralized_vst3_files.get(bundle.path()) { match known_centralized_vst3_files.get(&bundle_path) {
None => orphan_files.push(NativeFile::Directory(bundle.path().to_owned())), None => orphan_files.push(NativeFile::Directory(bundle_path)),
Some(managed_vst3_bundle_files) => { Some(managed_vst3_bundle_files) => {
// Find orphan files and symlinks within this bundle. We need this to be able to // 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 // switch between 32-bit and 64-bit versions of both yabridge and the Windows plugin
orphan_files.extend( orphan_files.extend(
WalkDir::new(bundle.path()) WalkDir::new(bundle_path)
.follow_links(false) .follow_links(false)
.into_iter() .into_iter()
.filter_map(|e| e.ok()) .filter_map(|e| {
.filter_map(|entry| { let path = match e {
let managed_file = managed_vst3_bundle_files.contains(entry.path()); Ok(entry) => entry.path().to_owned(),
match get_file_type(entry.path().to_owned()).unwrap() { 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 // Don't remove directories, since we're not tracking the
// directories within the bundle // directories within the bundle
NativeFile::Directory(_) => None, NativeFile::Directory(_) => None,
+19 -11
View File
@@ -411,9 +411,7 @@ pub fn index(directory: &Path, blacklist: &HashSet<&Path>) -> SearchIndex {
let mut dll_files: Vec<(PathBuf, Option<PathBuf>)> = Vec::new(); let mut dll_files: Vec<(PathBuf, Option<PathBuf>)> = Vec::new();
let mut vst3_files: Vec<(PathBuf, Option<PathBuf>)> = Vec::new(); let mut vst3_files: Vec<(PathBuf, Option<PathBuf>)> = Vec::new();
let mut so_files: Vec<NativeFile> = Vec::new(); let mut so_files: Vec<NativeFile> = Vec::new();
// XXX: We're silently skipping directories and files we don't have permission to read. This for (file_idx, path) in WalkDir::new(directory)
// sounds like the expected behavior, but I"m not entirely sure.
for (file_idx, entry) in WalkDir::new(directory)
.follow_links(true) .follow_links(true)
.into_iter() .into_iter()
.filter_entry(|e| { .filter_entry(|e| {
@@ -424,8 +422,20 @@ pub fn index(directory: &Path, blacklist: &HashSet<&Path>) -> SearchIndex {
.map(|p| !blacklist.contains(p.as_path())) .map(|p| !blacklist.contains(p.as_path()))
.unwrap_or(false) .unwrap_or(false)
}) })
.filter_map(|e| e.ok()) .filter_map(|e| {
.filter(|e| !e.file_type().is_dir()) // 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() .enumerate()
{ {
// This is a bit of an odd warning, but I can see it happening that someone adds their // 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") => { Some("dll") => {
let path = entry.into_path();
let subdirectory = path let subdirectory = path
.parent() .parent()
.and_then(|p| p.strip_prefix(directory).ok()) .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)); dll_files.push((path, subdirectory));
} }
Some("vst3") => { Some("vst3") => {
let path = entry.into_path();
let subdirectory = path let subdirectory = path
.parent() .parent()
.and_then(|p| p.strip_prefix(directory).ok()) .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)); vst3_files.push((path, subdirectory));
} }
Some("so") => { Some("so") => {
if entry.path_is_symlink() { if path.is_symlink() {
so_files.push(NativeFile::Symlink(entry.into_path())); so_files.push(NativeFile::Symlink(path));
} else { } else {
so_files.push(NativeFile::Regular(entry.into_path())); so_files.push(NativeFile::Regular(path));
} }
} }
_ => (), _ => (),