Prompt to remove leftover files when removing dir

This commit is contained in:
Robbert van der Helm
2020-07-15 22:49:34 +02:00
parent ae0f4aa64e
commit 7e3086c354
4 changed files with 259 additions and 29 deletions
+171
View File
@@ -9,6 +9,18 @@ dependencies = [
"memchr",
]
[[package]]
name = "arrayref"
version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544"
[[package]]
name = "arrayvec"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cff77d8686867eceff3105329d4698d96c2391c176d5d03adc90c7389162b5b8"
[[package]]
name = "atty"
version = "0.2.14"
@@ -26,12 +38,35 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d"
[[package]]
name = "base64"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b41b7ea54a0c9d92199de89e20e58d49f02f8e699814ef3fdf266f6f748d15c7"
[[package]]
name = "bitflags"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
[[package]]
name = "blake2b_simd"
version = "0.5.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d8fb2d74254a3a0b5cac33ac9f8ed0e44aa50378d9dbb2e5d83bd21ed1dc2c8a"
dependencies = [
"arrayref",
"arrayvec",
"constant_time_eq",
]
[[package]]
name = "cc"
version = "1.0.58"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f9a06fb2e53271d7c279ec1efea6ab691c35a2ae67ec0d91d7acec0caf13b518"
[[package]]
name = "cfg-if"
version = "0.1.10"
@@ -82,6 +117,12 @@ dependencies = [
"winapi 0.3.9",
]
[[package]]
name = "constant_time_eq"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc"
[[package]]
name = "crossbeam-deque"
version = "0.7.3"
@@ -130,12 +171,44 @@ dependencies = [
"lazy_static",
]
[[package]]
name = "dirs-next"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1cbcf9241d9e8d106295bd496bbe2e9cffd5fa098f2a8c9e2bbcbf09773c11a8"
dependencies = [
"cfg-if",
"dirs-sys-next",
]
[[package]]
name = "dirs-sys-next"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c60f7b8a8953926148223260454befb50c751d3c50e1c178c4fd1ace4083c9a"
dependencies = [
"libc",
"redox_users",
"winapi 0.3.9",
]
[[package]]
name = "either"
version = "1.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bb1f6b1ce1c140482ea30ddd3335fc0024ac7ee112895426e0a629a6c20adfe3"
[[package]]
name = "getrandom"
version = "0.1.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb"
dependencies = [
"cfg-if",
"libc",
"wasi",
]
[[package]]
name = "heck"
version = "0.3.1"
@@ -185,6 +258,15 @@ version = "0.2.72"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a9f8082297d534141b30c8d39e9b1773713ab50fdbe4ff30f750d063b3bfd701"
[[package]]
name = "log"
version = "0.4.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7"
dependencies = [
"cfg-if",
]
[[package]]
name = "maybe-uninit"
version = "2.0.0"
@@ -206,6 +288,19 @@ dependencies = [
"autocfg",
]
[[package]]
name = "nix"
version = "0.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "50e4785f2c3b7589a0d0c1dd60285e1188adac4006e8abd6dd578e1567027363"
dependencies = [
"bitflags",
"cc",
"cfg-if",
"libc",
"void",
]
[[package]]
name = "num_cpus"
version = "1.13.0"
@@ -257,6 +352,15 @@ dependencies = [
"unicode-xid",
]
[[package]]
name = "promptly"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b99cfb0289110d969dd21637cfbc922584329bc9e5037c5e576325c615658509"
dependencies = [
"rustyline",
]
[[package]]
name = "quote"
version = "1.0.7"
@@ -291,6 +395,54 @@ dependencies = [
"num_cpus",
]
[[package]]
name = "redox_syscall"
version = "0.1.57"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce"
[[package]]
name = "redox_users"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09b23093265f8d200fa7b4c2c76297f47e681c655f6f1285a8780d6a022f7431"
dependencies = [
"getrandom",
"redox_syscall",
"rust-argon2",
]
[[package]]
name = "rust-argon2"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2bc8af4bda8e1ff4932523b94d3dd20ee30a87232323eda55903ffd71d2fb017"
dependencies = [
"base64",
"blake2b_simd",
"constant_time_eq",
"crossbeam-utils",
]
[[package]]
name = "rustyline"
version = "6.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3358c21cbbc1a751892528db4e1de4b7a2b6a73f001e215aaba97d712cfa9777"
dependencies = [
"cfg-if",
"dirs-next",
"libc",
"log",
"memchr",
"nix",
"scopeguard",
"unicode-segmentation",
"unicode-width",
"utf8parse",
"winapi 0.3.9",
]
[[package]]
name = "same-file"
version = "1.0.6"
@@ -418,6 +570,12 @@ version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
[[package]]
name = "utf8parse"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "936e4b492acfd135421d8dca4b1aa80a7bfc26e702ef3af710e0752684df5372"
[[package]]
name = "vec_map"
version = "0.8.2"
@@ -430,6 +588,12 @@ version = "0.9.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed"
[[package]]
name = "void"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
[[package]]
name = "walkdir"
version = "2.3.1"
@@ -441,6 +605,12 @@ dependencies = [
"winapi-util",
]
[[package]]
name = "wasi"
version = "0.9.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
[[package]]
name = "winapi"
version = "0.2.8"
@@ -498,6 +668,7 @@ dependencies = [
"clap",
"colored",
"lazy_static",
"promptly",
"rayon",
"serde",
"serde_derive",
+1
View File
@@ -14,6 +14,7 @@ aho-corasick = "0.7.13"
colored = "2.0.0"
clap = { version = "3.0.0-beta.1", features = ["wrap_help"] }
lazy_static = "1.4.0"
promptly = "0.3.0"
rayon = "1.3.1"
serde = "1.0.114"
serde_derive = "1.0.114"
+50 -22
View File
@@ -99,28 +99,7 @@ impl FoundFile {
/// the directory does not exist, or if `winedump` could not be found.
pub fn index(directory: &Path) -> Result<SearchResults, std::io::Error> {
// First we'll find all .dll and .so files in the directory
let mut dll_files: Vec<PathBuf> = Vec::new();
let mut so_files: Vec<FoundFile> = 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 entry in WalkDir::new(directory)
.follow_links(true)
.into_iter()
.filter_map(|e| e.ok())
.filter(|x| !x.file_type().is_dir())
{
match entry.path().extension().and_then(|os| os.to_str()) {
Some("dll") => dll_files.push(entry.into_path()),
Some("so") => {
if entry.path_is_symlink() {
so_files.push(FoundFile::Symlink(entry.into_path()));
} else {
so_files.push(FoundFile::Regular(entry.into_path()));
}
}
_ => (),
}
}
let (dll_files, so_files) = find_files(directory);
lazy_static! {
static ref VST2_AUTOMATON: AhoCorasick =
@@ -160,3 +139,52 @@ pub fn index(directory: &Path) -> Result<SearchResults, std::io::Error> {
so_files,
})
}
/// THe same as [index()](index), but only report found `.so` files. This avoids unnecesarily
/// filtering the found `.dll` files.
pub fn index_so_files(directory: &Path) -> Vec<FoundFile> {
let (_, so_files) = find_files(directory);
so_files
}
/// Find all `.dll` and `.so` files under a directory. The results are a pair of `(dll_files,
/// so_files)`.
fn find_files(directory: &Path) -> (Vec<PathBuf>, Vec<FoundFile>) {
let mut dll_files: Vec<PathBuf> = Vec::new();
let mut so_files: Vec<FoundFile> = 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)
.follow_links(true)
.into_iter()
.filter_map(|e| e.ok())
.filter(|x| !x.file_type().is_dir())
.enumerate()
{
// This is a bit of an odd warning, but I can see it happening that someone adds their
// entire home directory by accident. Removing the home directory would cause yabridgectl to
// scan for leftover `.so` files, which would of course take an enternity. This warning will
// at least tell the user what's happening and that they can safely cancel the scan.
if file_idx == 100_000 {
eprintln!(
"Indexed over 100.000 files, press Ctrl+C to cancel this operation if this was not \
intentional."
)
}
match entry.path().extension().and_then(|os| os.to_str()) {
Some("dll") => dll_files.push(entry.into_path()),
Some("so") => {
if entry.path_is_symlink() {
so_files.push(FoundFile::Symlink(entry.into_path()));
} else {
so_files.push(FoundFile::Regular(entry.into_path()));
}
}
_ => (),
}
}
(dll_files, so_files)
}
+37 -7
View File
@@ -29,7 +29,6 @@ mod files;
// TODO: Naming and descriptions could be made clearer
// TODO: When creating copies, check whether `yabridge-host.exe` is in the PATH for the login shell
// TODO: Check for left over files when removing directory
// TODO: Reward parts of the readme
fn main() {
@@ -142,10 +141,10 @@ fn main() {
/// Add a direcotry to the plugin locations. Duplicates get ignord because we're using ordered sets.
fn add_directory(config: &mut Config, path: PathBuf) {
config.plugin_dirs.insert(path);
if let Err(err) = config.write() {
config.write().unwrap_or_else(|err| {
eprintln!("Error while writing config file: {}", err);
exit(1);
};
});
}
/// Remove a direcotry to the plugin locations. The path is assumed to be part of
@@ -154,10 +153,41 @@ fn remove_directory(config: &mut Config, path: &Path) {
// We've already verified that this path is in `config.plugin_dirs`
// XXS: Would it be a good idea to warn about leftover .so files?
config.plugin_dirs.remove(path);
if let Err(err) = config.write() {
config.write().unwrap_or_else(|err| {
eprintln!("Error while writing config file: {}", err);
exit(1);
};
});
// Ask the user to remove any leftover files to prevent possible future problems and out of date
// copies
let orphan_files = files::index_so_files(path);
if !orphan_files.is_empty() {
println!(
"WARNING: Found {} leftover '.so' files still in this directory:",
orphan_files.len()
);
for file in &orphan_files {
println!("- {}", file.path().display());
}
match promptly::prompt_opt::<String, &str>(
"\nWould you like to remove these files? Entering anything other than YES will leave \
these files intact",
) {
Ok(Some(answer)) if answer == "YES" => {
for file in &orphan_files {
fs::remove_file(file.path()).unwrap_or_else(|err| {
eprintln!("Could not remove '{}': {}", file.path().display(), err);
exit(1);
});
}
println!("\nRemoved {} files.", orphan_files.len());
}
_ => {}
}
}
}
/// List the plugin locations.
@@ -229,10 +259,10 @@ fn set_settings(config: &mut Config, options: &ArgMatches) {
Err(err) => err.exit(),
}
if let Err(err) = config.write() {
config.write().unwrap_or_else(|err| {
eprintln!("Error while writing config file: {}", err);
exit(1);
};
});
}
/// Set up yabridge for all Windows VST2 plugins in the plugin directories. Will also remove orphan