diff --git a/tools/yabridgectl/Cargo.lock b/tools/yabridgectl/Cargo.lock index 094db8c0..7fc29473 100644 --- a/tools/yabridgectl/Cargo.lock +++ b/tools/yabridgectl/Cargo.lock @@ -269,6 +269,15 @@ dependencies = [ "num_cpus", ] +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + [[package]] name = "scopeguard" version = "1.1.0" @@ -366,6 +375,17 @@ version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed" +[[package]] +name = "walkdir" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "777182bc735b6424e1a57516d35ed72cb8019d85c8c9bf536dccb3445c1a2f7d" +dependencies = [ + "same-file", + "winapi", + "winapi-util", +] + [[package]] name = "winapi" version = "0.3.9" @@ -397,6 +417,12 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "xdg" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d089681aa106a86fade1b0128fb5daf07d5867a509ab036d99988dec80429a57" + [[package]] name = "yabridgectl" version = "1.2.1" @@ -405,4 +431,6 @@ dependencies = [ "clap", "rayon", "toml", + "walkdir", + "xdg", ] diff --git a/tools/yabridgectl/Cargo.toml b/tools/yabridgectl/Cargo.toml index 5917925e..c9afb3ad 100644 --- a/tools/yabridgectl/Cargo.toml +++ b/tools/yabridgectl/Cargo.toml @@ -9,10 +9,10 @@ description = "Optional command line helper to set up yabridge" repository = "https://github.com/robbert-vdh/yabridge" license = "GPL-3.0-or-later" -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - [dependencies] aho-corasick = "0.7.13" clap = "3.0.0-beta.1" rayon = "1.3.1" toml = "0.5.6" +walkdir = "2.3.1" +xdg = "2.2.0" diff --git a/tools/yabridgectl/src/config.rs b/tools/yabridgectl/src/config.rs new file mode 100644 index 00000000..6909e959 --- /dev/null +++ b/tools/yabridgectl/src/config.rs @@ -0,0 +1,89 @@ +// 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 . + +use std::path::{Path, PathBuf}; +use xdg::BaseDirectories; + +const LIBYABRIDGE_NAME: &str = "libyabridge.so"; + +/// The configuration used for yabridgectl. This will be serialized to and deserialized from +/// `$XDG_CONFIG_HOME/yabridge/config.toml`. +pub struct Config { + /// The installation method to use. We will default to creating copies since that works + /// everywehre. + pub method: InstallationMethod, + /// The path to the directory containing `libyabridge.so`. If not set, then yabridgectl will + /// look in `/usr/lib` and `$XDG_DATA_HOME/yabridge` since those are the expected locations for + /// yabridge to be installed in. + pub yabridge_home: Option, + /// Directories to search for Windows VST plugins. + pub plugin_dirs: Vec, +} + +impl Config { + /// Return the path to `libyabridge.so`, or a descriptive error if it can't be found. If + /// `yabridge_home` is `None`, then we'll search in both `/usr/lib` and + /// `$XDG_DATA_HOME/yabridge`. + pub fn libyabridge(&self) -> Result { + match &self.yabridge_home { + Some(directory) => { + let candidate = directory.join(LIBYABRIDGE_NAME); + if candidate.exists() { + Ok(candidate) + } else { + Err(format!( + "Could not find {} in '{}'.", + LIBYABRIDGE_NAME, + directory.display() + )) + } + } + None => { + // Search in the two common installation locations if no path was set explicitely + let system_path = Path::new("/usr/lib"); + let user_path = BaseDirectories::new() + .map_err(|err| format!("Error while parsing base directories:\n{}", err))? + .get_data_home(); + for directory in &[system_path, &user_path] { + let candidate = directory.join(LIBYABRIDGE_NAME); + if candidate.exists() { + return Ok(candidate); + } + } + + Err(format!( + "Could not find {} in either '{}' or '{}'. You can tell yabridgectl where \ + to search for it using 'yabridgectl set --path='.", + LIBYABRIDGE_NAME, + system_path.display(), + user_path.display() + )) + } + } + } +} + +/// Specifies how yabridge will be set up for the found plugins. +pub enum InstallationMethod { + /// Create a copy of `libyabridge.so` for every Windows VST2 plugin .dll file found. After + /// updating yabridge, the user will have to rerun `yabridgectl sync` to copy over the new + /// version. + Copy, + /// This will create a symlink to `libyabridge.so` for every VST2 .dll file in the plugin + /// directories. As explained in the readme, this makes updating easier and remvoes the need to + /// modify the `PATH` environment variable. + Symlink, +} diff --git a/tools/yabridgectl/src/main.rs b/tools/yabridgectl/src/main.rs index bdaf5c9d..02a1189e 100644 --- a/tools/yabridgectl/src/main.rs +++ b/tools/yabridgectl/src/main.rs @@ -14,6 +14,8 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . +mod config; + fn main() { println!("Hello, world!"); }