mirror of
https://github.com/robbert-vdh/yabridge.git
synced 2026-05-07 03:50:11 +02:00
Verify that the PATH has been set up correctly
When creating copies with yabridgectl. This should at least give an advance warning that some additional steps are required when first setting up yabridge.
This commit is contained in:
Generated
+1
@@ -679,6 +679,7 @@ dependencies = [
|
||||
"rayon",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"textwrap",
|
||||
"toml",
|
||||
"walkdir",
|
||||
"xdg",
|
||||
|
||||
@@ -19,6 +19,7 @@ promptly = "0.3.0"
|
||||
rayon = "1.3.1"
|
||||
serde = "1.0.114"
|
||||
serde_derive = "1.0.114"
|
||||
textwrap = "*"
|
||||
toml = "0.5.6"
|
||||
walkdir = "2.3.1"
|
||||
xdg = "2.2.0"
|
||||
|
||||
@@ -26,6 +26,7 @@ use std::path::{Path, PathBuf};
|
||||
use crate::config::{Config, InstallationMethod};
|
||||
use crate::files;
|
||||
use crate::files::FoundFile;
|
||||
use crate::utils::{verify_path_setup, wrap};
|
||||
|
||||
/// 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) -> Result<()> {
|
||||
@@ -46,7 +47,7 @@ pub fn remove_directory(config: &mut Config, path: &Path) -> Result<()> {
|
||||
let orphan_files = files::index_so_files(path);
|
||||
if !orphan_files.is_empty() {
|
||||
println!(
|
||||
"WARNING: Found {} leftover '.so' files still in this directory:",
|
||||
"Warning: Found {} leftover '.so' files still in this directory:",
|
||||
orphan_files.len()
|
||||
);
|
||||
|
||||
@@ -248,5 +249,26 @@ pub fn do_sync(config: &Config, prune: bool, verbose: bool) -> Result<()> {
|
||||
num_skipped_files
|
||||
);
|
||||
|
||||
if config.method == InstallationMethod::Copy {
|
||||
if let Err(shell_name) = verify_path_setup() {
|
||||
println!(
|
||||
"\n{}",
|
||||
wrap(&format!(
|
||||
"Warning: 'yabridge-host.exe' is not present in your login shell's search \
|
||||
path. Yabridge won't be able to run using the copy-based installatin method \
|
||||
until this is fixed.\n\
|
||||
Add '{}' to {}'s login shell {} environment variable. See the \
|
||||
troubleshooting section of the readme for more details. Rerun this command to \
|
||||
verify that this has been set up correctly, and then reboot your system.\n\
|
||||
\n\
|
||||
https://github.com/robbert-vdh/yabridge#troubleshooting-common-issues",
|
||||
libyabridge_path.parent().unwrap().display(),
|
||||
shell_name.bright_white(),
|
||||
"PATH".bright_white()
|
||||
))
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ pub struct Config {
|
||||
}
|
||||
|
||||
/// Specifies how yabridge will be set up for the found plugins.
|
||||
#[derive(Deserialize, Serialize, Debug)]
|
||||
#[derive(Deserialize, Serialize, Debug, PartialEq, Eq)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum InstallationMethod {
|
||||
/// Create a copy of `libyabridge.so` for every Windows VST2 plugin .dll file found. After
|
||||
|
||||
@@ -24,9 +24,9 @@ use crate::config::Config;
|
||||
mod actions;
|
||||
mod config;
|
||||
mod files;
|
||||
mod utils;
|
||||
|
||||
// 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: Reward parts of the readme
|
||||
|
||||
fn main() -> Result<()> {
|
||||
|
||||
@@ -0,0 +1,106 @@
|
||||
// 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/>.
|
||||
|
||||
//! Small helper utilities.
|
||||
|
||||
use colored::Colorize;
|
||||
use std::env;
|
||||
use std::path::Path;
|
||||
use std::process::{Command, Stdio};
|
||||
use textwrap::Wrapper;
|
||||
|
||||
/// Verify that `yabridge-host.exe` is accessible in a login shell. Returns unit if it is, or if we
|
||||
/// the login shell is set to an unknown shell. In the last case we'll just print a warning since we
|
||||
/// don't know how to invoke the shell as a login shell. This is needed when using copies to ensure
|
||||
/// that yabridge can find the host binaries when the VST host is launched from the desktop
|
||||
/// enviornment.
|
||||
///
|
||||
/// When we could not find `yabridge-host.exe`, we'll return `Err(shell_name)` so we can print a
|
||||
/// descriptive warning message.
|
||||
///
|
||||
/// # TODO
|
||||
///
|
||||
/// Starting from Rust 1.45 we can just modify `argv[0]` to start with a dash instead, see
|
||||
/// https://doc.rust-lang.org/std/os/unix/process/trait.CommandExt.html#tymethod.arg0
|
||||
/// https://github.com/rust-lang/rust/issues/66510
|
||||
pub fn verify_path_setup() -> Result<(), String> {
|
||||
match env::var("SHELL") {
|
||||
Ok(shell_path) => {
|
||||
// `$SHELL` will often contain a full path, but it doesn't have to
|
||||
let shell = Path::new(&shell_path)
|
||||
.file_name()
|
||||
.and_then(|os_str| os_str.to_str())
|
||||
.unwrap_or_else(|| shell_path.as_str());
|
||||
|
||||
let mut command = Command::new(&shell_path);
|
||||
let command = match shell {
|
||||
// All of these shells support the `-l` flag to start a login shell and
|
||||
// "-c<command>" to directly run a command under that login shell
|
||||
"ash" | "bash" | "csh" | "ksh" | "dash" | "fish" | "sh" | "tcsh" | "zsh" => command
|
||||
.arg("-l")
|
||||
.arg("-c")
|
||||
.arg("command -v yabridge-host.exe"),
|
||||
// I don't know if anyone uses PowerShell as their login shell under Linux, but it
|
||||
// doesn't implement the POSIX `command` function so we'll just use which instead
|
||||
"pwsh" => command.arg("-l").arg("-c").arg("which yabridge-host.exe"),
|
||||
shell => {
|
||||
eprintln!(
|
||||
"{}",
|
||||
wrap(&format!(
|
||||
"WARNING: Yabridgectl does not know how to handle your login shell, \
|
||||
'{}', skipping PATH setup check. Feel free to open a bug report to \
|
||||
get yabridgectl to support your shell.\n\
|
||||
\n\
|
||||
https://github.com/robbert-vdh/yabridge/issues",
|
||||
shell.bright_white(),
|
||||
))
|
||||
);
|
||||
return Ok(());
|
||||
}
|
||||
};
|
||||
|
||||
// For the login shell we want to a clean environment, but we still have to set `$HOME`
|
||||
// or else most shells won't know which profile to load
|
||||
command
|
||||
.env_clear()
|
||||
.env("HOME", env::var("HOME").unwrap_or_default());
|
||||
|
||||
match command.stdout(Stdio::null()).stderr(Stdio::null()).status() {
|
||||
Ok(status) if status.success() => Ok(()),
|
||||
Ok(_) => Err(shell.to_string()),
|
||||
Err(err) => {
|
||||
eprintln!(
|
||||
"Warning: could not run login shell, skipping PATH setup check: {}",
|
||||
err
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(_) => {
|
||||
eprintln!("\nWarning: Could not determine login shell, skipping PATH setup check");
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Wrap a long paragraph of text to terminal width, or 80 characters if the width of the terminal
|
||||
/// can't be determined. Everything after the first line gets indented with four spaces.
|
||||
pub fn wrap(text: &str) -> String {
|
||||
let wrapper = Wrapper::with_termwidth().subsequent_indent(" ");
|
||||
|
||||
wrapper.fill(text)
|
||||
}
|
||||
Reference in New Issue
Block a user