mirror of
https://github.com/robbert-vdh/yabridge.git
synced 2026-06-20 19:03:56 +02:00
Implement reading and writing of config files
This commit is contained in:
Generated
+13
@@ -290,6 +290,17 @@ version = "1.0.114"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5317f7588f0a5078ee60ef675ef96735a1442132dc645eb1d12c018620ed8cd3"
|
checksum = "5317f7588f0a5078ee60ef675ef96735a1442132dc645eb1d12c018620ed8cd3"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_derive"
|
||||||
|
version = "1.0.114"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2a0be94b04690fbaed37cddffc5c134bf537c8e3329d53e982fe04c374978f8e"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "strsim"
|
name = "strsim"
|
||||||
version = "0.10.0"
|
version = "0.10.0"
|
||||||
@@ -430,6 +441,8 @@ dependencies = [
|
|||||||
"aho-corasick",
|
"aho-corasick",
|
||||||
"clap",
|
"clap",
|
||||||
"rayon",
|
"rayon",
|
||||||
|
"serde",
|
||||||
|
"serde_derive",
|
||||||
"toml",
|
"toml",
|
||||||
"walkdir",
|
"walkdir",
|
||||||
"xdg",
|
"xdg",
|
||||||
|
|||||||
@@ -13,6 +13,8 @@ license = "GPL-3.0-or-later"
|
|||||||
aho-corasick = "0.7.13"
|
aho-corasick = "0.7.13"
|
||||||
clap = "3.0.0-beta.1"
|
clap = "3.0.0-beta.1"
|
||||||
rayon = "1.3.1"
|
rayon = "1.3.1"
|
||||||
|
serde = "1.0.114"
|
||||||
|
serde_derive = "1.0.114"
|
||||||
toml = "0.5.6"
|
toml = "0.5.6"
|
||||||
walkdir = "2.3.1"
|
walkdir = "2.3.1"
|
||||||
xdg = "2.2.0"
|
xdg = "2.2.0"
|
||||||
|
|||||||
@@ -14,13 +14,21 @@
|
|||||||
// 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 serde_derive::{Deserialize, Serialize};
|
||||||
|
use std::fs;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use xdg::BaseDirectories;
|
use xdg::BaseDirectories;
|
||||||
|
|
||||||
|
/// The name of the config file, relative to `$XDG_CONFIG_HOME/CONFIG_PREFIX`.
|
||||||
|
const CONFIG_FILE_NAME: &str = "config.toml";
|
||||||
|
/// The name of the configuration directory, relative to `$XDG_CONFIG_HOME`.
|
||||||
|
const CONFIG_PREFIX: &str = "yabridgectl";
|
||||||
|
|
||||||
const LIBYABRIDGE_NAME: &str = "libyabridge.so";
|
const LIBYABRIDGE_NAME: &str = "libyabridge.so";
|
||||||
|
|
||||||
/// The configuration used for yabridgectl. This will be serialized to and deserialized from
|
/// The configuration used for yabridgectl. This will be serialized to and deserialized from
|
||||||
/// `$XDG_CONFIG_HOME/yabridge/config.toml`.
|
/// `$XDG_CONFIG_HOME/yabridge/config.toml`.
|
||||||
|
#[derive(Deserialize, Serialize, Debug)]
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
/// The installation method to use. We will default to creating copies since that works
|
/// The installation method to use. We will default to creating copies since that works
|
||||||
/// everywehre.
|
/// everywehre.
|
||||||
@@ -34,6 +42,55 @@ pub struct Config {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Config {
|
impl Config {
|
||||||
|
/// Try to read the config file, creating a new default file if necessary. This will fail if the
|
||||||
|
/// file could not be created or if it could not be parsed.
|
||||||
|
pub fn read() -> Result<Config, String> {
|
||||||
|
match base_directories()?.find_config_file(CONFIG_FILE_NAME) {
|
||||||
|
Some(path) => {
|
||||||
|
let toml_str = fs::read_to_string(&path).map_err(|err| {
|
||||||
|
format!(
|
||||||
|
"Could not read config file at '{}': {}",
|
||||||
|
path.display(),
|
||||||
|
err
|
||||||
|
)
|
||||||
|
})?;
|
||||||
|
|
||||||
|
Ok(toml::from_str(&toml_str)
|
||||||
|
.map_err(|err| format!("Could not parse TOML: {:#?}", err))?)
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
let defaults = Config {
|
||||||
|
method: InstallationMethod::Copy,
|
||||||
|
yabridge_home: None,
|
||||||
|
plugin_dirs: Vec::new(),
|
||||||
|
};
|
||||||
|
|
||||||
|
// If no existing config file exists, then write a new config file with default
|
||||||
|
// values
|
||||||
|
defaults.write()?;
|
||||||
|
|
||||||
|
Ok(defaults)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Write the config to disk, creating the file if it does not yet exist.
|
||||||
|
pub fn write(&self) -> Result<(), String> {
|
||||||
|
let toml_str = toml::to_string_pretty(&self)
|
||||||
|
.map_err(|err| format!("Could not format TOML: {}", err))?;
|
||||||
|
let config_file = base_directories()?
|
||||||
|
.place_config_file(CONFIG_FILE_NAME)
|
||||||
|
.map_err(|err| format!("Could not write config file: {}", err))?;
|
||||||
|
|
||||||
|
fs::write(&config_file, toml_str).map_err(|err| {
|
||||||
|
format!(
|
||||||
|
"Could not write config file to '{}': {}",
|
||||||
|
config_file.display(),
|
||||||
|
err
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
/// Return the path to `libyabridge.so`, or a descriptive error if it can't be found. If
|
/// 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
|
/// `yabridge_home` is `None`, then we'll search in both `/usr/lib` and
|
||||||
/// `$XDG_DATA_HOME/yabridge`.
|
/// `$XDG_DATA_HOME/yabridge`.
|
||||||
@@ -54,9 +111,7 @@ impl Config {
|
|||||||
None => {
|
None => {
|
||||||
// Search in the two common installation locations if no path was set explicitely
|
// Search in the two common installation locations if no path was set explicitely
|
||||||
let system_path = Path::new("/usr/lib");
|
let system_path = Path::new("/usr/lib");
|
||||||
let user_path = BaseDirectories::new()
|
let user_path = base_directories()?.get_data_home();
|
||||||
.map_err(|err| format!("Error while parsing base directories:\n{}", err))?
|
|
||||||
.get_data_home();
|
|
||||||
for directory in &[system_path, &user_path] {
|
for directory in &[system_path, &user_path] {
|
||||||
let candidate = directory.join(LIBYABRIDGE_NAME);
|
let candidate = directory.join(LIBYABRIDGE_NAME);
|
||||||
if candidate.exists() {
|
if candidate.exists() {
|
||||||
@@ -77,6 +132,8 @@ impl Config {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Specifies how yabridge will be set up for the found plugins.
|
/// Specifies how yabridge will be set up for the found plugins.
|
||||||
|
#[derive(Deserialize, Serialize, Debug)]
|
||||||
|
#[serde(rename_all = "snake_case")]
|
||||||
pub enum InstallationMethod {
|
pub enum InstallationMethod {
|
||||||
/// Create a copy of `libyabridge.so` for every Windows VST2 plugin .dll file found. After
|
/// 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
|
/// updating yabridge, the user will have to rerun `yabridgectl sync` to copy over the new
|
||||||
@@ -87,3 +144,10 @@ pub enum InstallationMethod {
|
|||||||
/// modify the `PATH` environment variable.
|
/// modify the `PATH` environment variable.
|
||||||
Symlink,
|
Symlink,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Fetch the XDG base directories, converting any error messages if this somehow fails into a
|
||||||
|
/// printable string to reduce boiler plate.
|
||||||
|
fn base_directories() -> Result<BaseDirectories, String> {
|
||||||
|
BaseDirectories::with_prefix(CONFIG_PREFIX)
|
||||||
|
.map_err(|err| format!("Error while parsing base directories: {}", err))
|
||||||
|
}
|
||||||
|
|||||||
@@ -16,6 +16,21 @@
|
|||||||
|
|
||||||
mod config;
|
mod config;
|
||||||
|
|
||||||
|
use config::Config;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
println!("Hello, world!");
|
// TODO: Remove debug
|
||||||
|
match Config::read() {
|
||||||
|
Ok(config) => {
|
||||||
|
println!("Read config:\n\n{:#?}\n", config);
|
||||||
|
println!(
|
||||||
|
"Searching for libyabridge.toml:\n\n{:?}",
|
||||||
|
config.libyabridge()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Err(err) => {
|
||||||
|
eprintln!("Error while reading config:\n\n{}", err);
|
||||||
|
std::process::exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user