mirror of
https://github.com/robbert-vdh/yabridge.git
synced 2026-05-09 20:29:10 +02:00
Move all subcommand handlers to a module
To unclutter in main.rs a bit.
This commit is contained in:
@@ -0,0 +1,280 @@
|
|||||||
|
// yabridge: a Wine VST bridge
|
||||||
|
// Copyright (C) 2020 Robbert van der Helm
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
//! Handlers for the subcommands, just to keep `main.rs` clean.
|
||||||
|
|
||||||
|
use clap::ArgMatches;
|
||||||
|
use colored::Colorize;
|
||||||
|
use std::fs;
|
||||||
|
use std::os::unix::fs::symlink;
|
||||||
|
use std::path::{Path, PathBuf};
|
||||||
|
use std::process::exit;
|
||||||
|
|
||||||
|
use crate::config::{Config, InstallationMethod};
|
||||||
|
use crate::files;
|
||||||
|
use crate::files::FoundFile;
|
||||||
|
|
||||||
|
/// Add a direcotry to the plugin locations. Duplicates get ignord because we're using ordered sets.
|
||||||
|
pub fn add_directory(config: &mut Config, path: PathBuf) {
|
||||||
|
config.plugin_dirs.insert(path);
|
||||||
|
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
|
||||||
|
/// `config.plugin_dirs`, otherwise this si silently ignored.
|
||||||
|
pub 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);
|
||||||
|
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.
|
||||||
|
pub fn list_directories(config: &Config) {
|
||||||
|
for directory in &config.plugin_dirs {
|
||||||
|
println!("{}", directory.display());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Print the current configuration and the installation status for all found plugins.
|
||||||
|
pub fn show_status(config: &Config) {
|
||||||
|
let results = match config.index_directories() {
|
||||||
|
Ok(results) => results,
|
||||||
|
Err(err) => {
|
||||||
|
eprintln!("Error while searching for plugins: {}", err);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
println!(
|
||||||
|
"yabridge path: {}",
|
||||||
|
config
|
||||||
|
.yabridge_home
|
||||||
|
.as_ref()
|
||||||
|
.map(|path| format!("'{}'", path.display()))
|
||||||
|
.unwrap_or_else(|| String::from("<auto>"))
|
||||||
|
);
|
||||||
|
println!(
|
||||||
|
"libyabridge.so: {}",
|
||||||
|
config
|
||||||
|
.libyabridge()
|
||||||
|
.map(|path| format!("'{}'", path.display()))
|
||||||
|
.unwrap_or_else(|_| format!("{}", "<not found>".red()))
|
||||||
|
);
|
||||||
|
println!("installation method: {}", config.method);
|
||||||
|
|
||||||
|
for (path, search_results) in results {
|
||||||
|
println!("\n{}:", path.display());
|
||||||
|
|
||||||
|
for (plugin, status) in search_results.installation_status() {
|
||||||
|
let status_str = match status {
|
||||||
|
Some(FoundFile::Regular(_)) => "copy".green(),
|
||||||
|
Some(FoundFile::Symlink(_)) => "symlink".green(),
|
||||||
|
None => "not installed".red(),
|
||||||
|
};
|
||||||
|
|
||||||
|
println!(" {} :: {}", plugin.display(), status_str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Change configuration settings. The actual options are defined in the clap [app](clap::App).
|
||||||
|
pub fn set_settings(config: &mut Config, options: &ArgMatches) {
|
||||||
|
match options.value_of("method") {
|
||||||
|
Some("copy") => config.method = InstallationMethod::Copy,
|
||||||
|
Some("symlink") => config.method = InstallationMethod::Symlink,
|
||||||
|
Some(s) => unimplemented!("Unexpected installation method '{}'", s),
|
||||||
|
None => (),
|
||||||
|
}
|
||||||
|
|
||||||
|
match options.value_of_t("path") {
|
||||||
|
Ok(path) => config.yabridge_home = Some(path),
|
||||||
|
Err(clap::Error {
|
||||||
|
kind: clap::ErrorKind::ArgumentNotFound,
|
||||||
|
..
|
||||||
|
}) => (),
|
||||||
|
// I don't think we can get any parsing errors here since we already validated that the
|
||||||
|
// argument has to be a valid path, but you never know
|
||||||
|
Err(err) => err.exit(),
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
/// `.so` files if the prune option is set.
|
||||||
|
pub fn do_sync(config: &Config, prune: bool, verbose: bool) {
|
||||||
|
let libyabridge_path = match config.libyabridge() {
|
||||||
|
Ok(path) => {
|
||||||
|
println!("Using '{}'\n", path.display());
|
||||||
|
path
|
||||||
|
}
|
||||||
|
Err(err) => {
|
||||||
|
// The error messages here are already formatted
|
||||||
|
eprintln!("{}", err);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let results = match config.index_directories() {
|
||||||
|
Ok(results) => results,
|
||||||
|
Err(err) => {
|
||||||
|
eprintln!("Error while searching for plugins: {}", err);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Keep track of some global statistics
|
||||||
|
let mut num_installed = 0;
|
||||||
|
let mut skipped_dll_files: Vec<PathBuf> = Vec::new();
|
||||||
|
let mut orphan_so_files: Vec<FoundFile> = Vec::new();
|
||||||
|
for (path, search_results) in results {
|
||||||
|
num_installed += search_results.vst2_files.len();
|
||||||
|
orphan_so_files.extend(search_results.orphans().into_iter().cloned());
|
||||||
|
skipped_dll_files.extend(search_results.skipped_files);
|
||||||
|
|
||||||
|
if verbose {
|
||||||
|
println!("{}:", path.display());
|
||||||
|
}
|
||||||
|
for plugin in search_results.vst2_files {
|
||||||
|
// If the target file already exists, we'll remove it first to prevent issues with
|
||||||
|
// mixing symlinks and regular files
|
||||||
|
let target_path = plugin.with_extension("so");
|
||||||
|
if target_path.exists() {
|
||||||
|
fs::remove_file(&target_path).unwrap_or_else(|err| {
|
||||||
|
eprintln!("Could not remove '{}': {}", target_path.display(), err);
|
||||||
|
exit(1);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
match config.method {
|
||||||
|
InstallationMethod::Copy => {
|
||||||
|
fs::copy(&libyabridge_path, &target_path).unwrap_or_else(|err| {
|
||||||
|
eprintln!(
|
||||||
|
"Error copying '{}' to '{}': {}",
|
||||||
|
libyabridge_path.display(),
|
||||||
|
target_path.display(),
|
||||||
|
err
|
||||||
|
);
|
||||||
|
exit(1);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
InstallationMethod::Symlink => {
|
||||||
|
symlink(&libyabridge_path, &target_path).unwrap_or_else(|err| {
|
||||||
|
eprintln!(
|
||||||
|
"Error symlinking '{}' to '{}': {}",
|
||||||
|
libyabridge_path.display(),
|
||||||
|
target_path.display(),
|
||||||
|
err
|
||||||
|
);
|
||||||
|
exit(1);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if verbose {
|
||||||
|
println!(" {}", plugin.display());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if verbose {
|
||||||
|
println!();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// We'll print the skipped files all at once to prevetn clutter
|
||||||
|
let num_skipped_files = skipped_dll_files.len();
|
||||||
|
if verbose && !skipped_dll_files.is_empty() {
|
||||||
|
println!("Skipped files:");
|
||||||
|
for path in skipped_dll_files {
|
||||||
|
println!("- {}", path.display());
|
||||||
|
}
|
||||||
|
println!();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Always warn about leftover files sicne those might cause warnings or errors when a VST host
|
||||||
|
// tries to load them
|
||||||
|
if !orphan_so_files.is_empty() {
|
||||||
|
if prune {
|
||||||
|
println!("Removing {} leftover '.so' files:", orphan_so_files.len());
|
||||||
|
} else {
|
||||||
|
println!(
|
||||||
|
"Found {} leftover '.so' files, rerun with the '--prune' option to remove them:",
|
||||||
|
orphan_so_files.len()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
for file in orphan_so_files {
|
||||||
|
let path = file.path();
|
||||||
|
|
||||||
|
println!("- {}", path.display());
|
||||||
|
if prune {
|
||||||
|
fs::remove_file(path).unwrap_or_else(|err| {
|
||||||
|
eprintln!("Error while trying to remove '{}': {}", path.display(), err);
|
||||||
|
exit(1);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
println!();
|
||||||
|
}
|
||||||
|
|
||||||
|
println!(
|
||||||
|
"Finished setting up {} plugins using {}, skipped {} non-plugin '.dll' files.",
|
||||||
|
num_installed,
|
||||||
|
config.method.plural(),
|
||||||
|
num_skipped_files
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -14,6 +14,8 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
//! Utilities for managing yabrigectl's configuration.
|
||||||
|
|
||||||
use rayon::prelude::*;
|
use rayon::prelude::*;
|
||||||
use serde_derive::{Deserialize, Serialize};
|
use serde_derive::{Deserialize, Serialize};
|
||||||
use std::collections::{BTreeMap, BTreeSet};
|
use std::collections::{BTreeMap, BTreeSet};
|
||||||
|
|||||||
+12
-265
@@ -14,16 +14,13 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
use clap::{app_from_crate, App, AppSettings, Arg, ArgMatches};
|
use clap::{app_from_crate, App, AppSettings, Arg};
|
||||||
use colored::Colorize;
|
use colored::Colorize;
|
||||||
use std::fs;
|
|
||||||
use std::os::unix::fs::symlink;
|
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::process::exit;
|
|
||||||
|
|
||||||
use crate::config::{Config, InstallationMethod};
|
use crate::config::Config;
|
||||||
use crate::files::FoundFile;
|
|
||||||
|
|
||||||
|
mod actions;
|
||||||
mod config;
|
mod config;
|
||||||
mod files;
|
mod files;
|
||||||
|
|
||||||
@@ -122,14 +119,16 @@ fn main() {
|
|||||||
.get_matches();
|
.get_matches();
|
||||||
|
|
||||||
match matches.subcommand() {
|
match matches.subcommand() {
|
||||||
("add", Some(options)) => add_directory(&mut config, options.value_of_t_or_exit("path")),
|
("add", Some(options)) => {
|
||||||
("rm", Some(options)) => {
|
actions::add_directory(&mut config, options.value_of_t_or_exit("path"))
|
||||||
remove_directory(&mut config, &options.value_of_t_or_exit::<PathBuf>("path"))
|
|
||||||
}
|
}
|
||||||
("list", _) => list_directories(&config),
|
("rm", Some(options)) => {
|
||||||
("status", _) => show_status(&config),
|
actions::remove_directory(&mut config, &options.value_of_t_or_exit::<PathBuf>("path"))
|
||||||
("set", Some(options)) => set_settings(&mut config, options),
|
}
|
||||||
("sync", Some(options)) => do_sync(
|
("list", _) => actions::list_directories(&config),
|
||||||
|
("status", _) => actions::show_status(&config),
|
||||||
|
("set", Some(options)) => actions::set_settings(&mut config, options),
|
||||||
|
("sync", Some(options)) => actions::do_sync(
|
||||||
&config,
|
&config,
|
||||||
options.is_present("prune"),
|
options.is_present("prune"),
|
||||||
options.is_present("verbose"),
|
options.is_present("verbose"),
|
||||||
@@ -138,258 +137,6 @@ 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);
|
|
||||||
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
|
|
||||||
/// `config.plugin_dirs`, otherwise this si silently ignored.
|
|
||||||
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);
|
|
||||||
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.
|
|
||||||
fn list_directories(config: &Config) {
|
|
||||||
for directory in &config.plugin_dirs {
|
|
||||||
println!("{}", directory.display());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Print the current configuration and the installation status for all found plugins.
|
|
||||||
fn show_status(config: &Config) {
|
|
||||||
let results = match config.index_directories() {
|
|
||||||
Ok(results) => results,
|
|
||||||
Err(err) => {
|
|
||||||
eprintln!("Error while searching for plugins: {}", err);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
println!(
|
|
||||||
"yabridge path: {}",
|
|
||||||
config
|
|
||||||
.yabridge_home
|
|
||||||
.as_ref()
|
|
||||||
.map(|path| format!("'{}'", path.display()))
|
|
||||||
.unwrap_or_else(|| String::from("<auto>"))
|
|
||||||
);
|
|
||||||
println!(
|
|
||||||
"libyabridge.so: {}",
|
|
||||||
config
|
|
||||||
.libyabridge()
|
|
||||||
.map(|path| format!("'{}'", path.display()))
|
|
||||||
.unwrap_or_else(|_| format!("{}", "<not found>".red()))
|
|
||||||
);
|
|
||||||
println!("installation method: {}", config.method);
|
|
||||||
|
|
||||||
for (path, search_results) in results {
|
|
||||||
println!("\n{}:", path.display());
|
|
||||||
|
|
||||||
for (plugin, status) in search_results.installation_status() {
|
|
||||||
let status_str = match status {
|
|
||||||
Some(FoundFile::Regular(_)) => "copy".green(),
|
|
||||||
Some(FoundFile::Symlink(_)) => "symlink".green(),
|
|
||||||
None => "not installed".red(),
|
|
||||||
};
|
|
||||||
|
|
||||||
println!(" {} :: {}", plugin.display(), status_str);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Change configuration settings. The actual options are defined in the clap [app](clap::App).
|
|
||||||
fn set_settings(config: &mut Config, options: &ArgMatches) {
|
|
||||||
match options.value_of("method") {
|
|
||||||
Some("copy") => config.method = InstallationMethod::Copy,
|
|
||||||
Some("symlink") => config.method = InstallationMethod::Symlink,
|
|
||||||
Some(s) => unimplemented!("Unexpected installation method '{}'", s),
|
|
||||||
None => (),
|
|
||||||
}
|
|
||||||
|
|
||||||
match options.value_of_t("path") {
|
|
||||||
Ok(path) => config.yabridge_home = Some(path),
|
|
||||||
Err(clap::Error {
|
|
||||||
kind: clap::ErrorKind::ArgumentNotFound,
|
|
||||||
..
|
|
||||||
}) => (),
|
|
||||||
// I don't think we can get any parsing errors here since we already validated that the
|
|
||||||
// argument has to be a valid path, but you never know
|
|
||||||
Err(err) => err.exit(),
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
|
||||||
/// `.so` files if the prune option is set.
|
|
||||||
fn do_sync(config: &Config, prune: bool, verbose: bool) {
|
|
||||||
let libyabridge_path = match config.libyabridge() {
|
|
||||||
Ok(path) => {
|
|
||||||
println!("Using '{}'\n", path.display());
|
|
||||||
path
|
|
||||||
}
|
|
||||||
Err(err) => {
|
|
||||||
// The error messages here are already formatted
|
|
||||||
eprintln!("{}", err);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let results = match config.index_directories() {
|
|
||||||
Ok(results) => results,
|
|
||||||
Err(err) => {
|
|
||||||
eprintln!("Error while searching for plugins: {}", err);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Keep track of some global statistics
|
|
||||||
let mut num_installed = 0;
|
|
||||||
let mut skipped_dll_files: Vec<PathBuf> = Vec::new();
|
|
||||||
let mut orphan_so_files: Vec<FoundFile> = Vec::new();
|
|
||||||
for (path, search_results) in results {
|
|
||||||
num_installed += search_results.vst2_files.len();
|
|
||||||
orphan_so_files.extend(search_results.orphans().into_iter().cloned());
|
|
||||||
skipped_dll_files.extend(search_results.skipped_files);
|
|
||||||
|
|
||||||
if verbose {
|
|
||||||
println!("{}:", path.display());
|
|
||||||
}
|
|
||||||
for plugin in search_results.vst2_files {
|
|
||||||
// If the target file already exists, we'll remove it first to prevent issues with
|
|
||||||
// mixing symlinks and regular files
|
|
||||||
let target_path = plugin.with_extension("so");
|
|
||||||
if target_path.exists() {
|
|
||||||
fs::remove_file(&target_path).unwrap_or_else(|err| {
|
|
||||||
eprintln!("Could not remove '{}': {}", target_path.display(), err);
|
|
||||||
exit(1);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
match config.method {
|
|
||||||
InstallationMethod::Copy => {
|
|
||||||
fs::copy(&libyabridge_path, &target_path).unwrap_or_else(|err| {
|
|
||||||
eprintln!(
|
|
||||||
"Error copying '{}' to '{}': {}",
|
|
||||||
libyabridge_path.display(),
|
|
||||||
target_path.display(),
|
|
||||||
err
|
|
||||||
);
|
|
||||||
exit(1);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
InstallationMethod::Symlink => {
|
|
||||||
symlink(&libyabridge_path, &target_path).unwrap_or_else(|err| {
|
|
||||||
eprintln!(
|
|
||||||
"Error symlinking '{}' to '{}': {}",
|
|
||||||
libyabridge_path.display(),
|
|
||||||
target_path.display(),
|
|
||||||
err
|
|
||||||
);
|
|
||||||
exit(1);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if verbose {
|
|
||||||
println!(" {}", plugin.display());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if verbose {
|
|
||||||
println!();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// We'll print the skipped files all at once to prevetn clutter
|
|
||||||
let num_skipped_files = skipped_dll_files.len();
|
|
||||||
if verbose && !skipped_dll_files.is_empty() {
|
|
||||||
println!("Skipped files:");
|
|
||||||
for path in skipped_dll_files {
|
|
||||||
println!("- {}", path.display());
|
|
||||||
}
|
|
||||||
println!();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Always warn about leftover files sicne those might cause warnings or errors when a VST host
|
|
||||||
// tries to load them
|
|
||||||
if !orphan_so_files.is_empty() {
|
|
||||||
if prune {
|
|
||||||
println!("Removing {} leftover '.so' files:", orphan_so_files.len());
|
|
||||||
} else {
|
|
||||||
println!(
|
|
||||||
"Found {} leftover '.so' files, rerun with the '--prune' option to remove them:",
|
|
||||||
orphan_so_files.len()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
for file in orphan_so_files {
|
|
||||||
let path = file.path();
|
|
||||||
|
|
||||||
println!("- {}", path.display());
|
|
||||||
if prune {
|
|
||||||
fs::remove_file(path).unwrap_or_else(|err| {
|
|
||||||
eprintln!("Error while trying to remove '{}': {}", path.display(), err);
|
|
||||||
exit(1);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
println!();
|
|
||||||
}
|
|
||||||
|
|
||||||
println!(
|
|
||||||
"Finished setting up {} plugins using {}, skipped {} non-plugin '.dll' files.",
|
|
||||||
num_installed,
|
|
||||||
config.method.plural(),
|
|
||||||
num_skipped_files
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Verify that a path exists, used for validating arguments.
|
/// Verify that a path exists, used for validating arguments.
|
||||||
fn validate_path(path: &str) -> Result<(), String> {
|
fn validate_path(path: &str) -> Result<(), String> {
|
||||||
let path = Path::new(path);
|
let path = Path::new(path);
|
||||||
|
|||||||
Reference in New Issue
Block a user