mirror of
https://github.com/atuinsh/atuin.git
synced 2024-11-22 16:23:54 +01:00
fix(doctor): detect preexec plugin using env ATUIN_PREEXEC_BACKEND (#1856)
* refactor(doctor): update func names and desc to match current impl * fix(doctor): use environment variable to detect plugin if possible In this patch, if the plugin provides an environment variable, we use the environment variable to test the existence of the plugin. When an environment variable is not available, we continue to use the mock interactive session by "shell -ic command". We also test shell-specific plugins only in the corresponding shells. An additional test can be performed by a custom function for each plugin.
This commit is contained in:
parent
616dabc2a1
commit
f881ce5c87
@ -1,5 +1,5 @@
|
|||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
use std::{collections::HashMap, path::PathBuf};
|
use std::{env, path::PathBuf, str::FromStr};
|
||||||
|
|
||||||
use atuin_client::settings::Settings;
|
use atuin_client::settings::Settings;
|
||||||
use colored::Colorize;
|
use colored::Colorize;
|
||||||
@ -19,12 +19,12 @@ struct ShellInfo {
|
|||||||
|
|
||||||
impl ShellInfo {
|
impl ShellInfo {
|
||||||
// HACK ALERT!
|
// HACK ALERT!
|
||||||
// Many of the env vars we need to detect are not exported :(
|
// Many of the shell vars we need to detect are not exported :(
|
||||||
// So, we're going to run `env` in a subshell and parse the output
|
// So, we're going to run a interactive session and directly check the
|
||||||
// There's a chance this won't work, so it should not be fatal.
|
// variable. There's a chance this won't work, so it should not be fatal.
|
||||||
//
|
//
|
||||||
// Every shell we support handles `shell -c 'command'`
|
// Every shell we support handles `shell -ic 'command'`
|
||||||
fn env_exists(shell: &str, var: &str) -> bool {
|
fn shellvar_exists(shell: &str, var: &str) -> bool {
|
||||||
let cmd = Command::new(shell)
|
let cmd = Command::new(shell)
|
||||||
.args([
|
.args([
|
||||||
"-ic",
|
"-ic",
|
||||||
@ -39,23 +39,96 @@ impl ShellInfo {
|
|||||||
cmd.contains("ATUIN_DOCTOR_ENV_FOUND")
|
cmd.contains("ATUIN_DOCTOR_ENV_FOUND")
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn plugins(shell: &str) -> Vec<String> {
|
fn validate_plugin_blesh(
|
||||||
|
_shell: &str,
|
||||||
|
shell_process: &sysinfo::Process,
|
||||||
|
ble_session_id: &str,
|
||||||
|
) -> Option<String> {
|
||||||
|
ble_session_id
|
||||||
|
.split('/')
|
||||||
|
.nth(1)
|
||||||
|
.and_then(|field| u32::from_str(field).ok())
|
||||||
|
.filter(|&blesh_pid| blesh_pid == shell_process.pid().as_u32())
|
||||||
|
.map(|_| "blesh".to_string())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn plugins(shell: &str, shell_process: &sysinfo::Process) -> Vec<String> {
|
||||||
// consider a different detection approach if there are plugins
|
// consider a different detection approach if there are plugins
|
||||||
// that don't set env vars
|
// that don't set shell vars
|
||||||
|
|
||||||
let map = HashMap::from([
|
enum PluginShellType {
|
||||||
("ATUIN_SESSION", "atuin"),
|
Any,
|
||||||
("BLE_ATTACHED", "blesh"),
|
Bash,
|
||||||
("bash_preexec_imported", "bash-preexec"),
|
|
||||||
]);
|
|
||||||
|
|
||||||
map.into_iter()
|
// Note: these are currently unused
|
||||||
.filter_map(|(env, plugin)| {
|
#[allow(dead_code)]
|
||||||
if ShellInfo::env_exists(shell, env) {
|
Zsh,
|
||||||
return Some(plugin.to_string());
|
#[allow(dead_code)]
|
||||||
|
Fish,
|
||||||
|
#[allow(dead_code)]
|
||||||
|
Nushell,
|
||||||
|
#[allow(dead_code)]
|
||||||
|
Xonsh,
|
||||||
|
}
|
||||||
|
|
||||||
|
enum PluginProbeType {
|
||||||
|
EnvironmentVariable(&'static str),
|
||||||
|
InteractiveShellVariable(&'static str),
|
||||||
|
}
|
||||||
|
|
||||||
|
type PluginValidator = fn(&str, &sysinfo::Process, &str) -> Option<String>;
|
||||||
|
|
||||||
|
let plugin_list: [(
|
||||||
|
&str,
|
||||||
|
PluginShellType,
|
||||||
|
PluginProbeType,
|
||||||
|
Option<PluginValidator>,
|
||||||
|
); 3] = [
|
||||||
|
(
|
||||||
|
"atuin",
|
||||||
|
PluginShellType::Any,
|
||||||
|
PluginProbeType::EnvironmentVariable("ATUIN_SESSION"),
|
||||||
|
None,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"blesh",
|
||||||
|
PluginShellType::Bash,
|
||||||
|
PluginProbeType::EnvironmentVariable("BLE_SESSION_ID"),
|
||||||
|
Some(Self::validate_plugin_blesh),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"bash-preexec",
|
||||||
|
PluginShellType::Bash,
|
||||||
|
PluginProbeType::InteractiveShellVariable("bash_preexec_imported"),
|
||||||
|
None,
|
||||||
|
),
|
||||||
|
];
|
||||||
|
|
||||||
|
plugin_list
|
||||||
|
.into_iter()
|
||||||
|
.filter(|(_, shell_type, _, _)| match shell_type {
|
||||||
|
PluginShellType::Any => true,
|
||||||
|
PluginShellType::Bash => shell.starts_with("bash") || shell == "sh",
|
||||||
|
PluginShellType::Zsh => shell.starts_with("zsh"),
|
||||||
|
PluginShellType::Fish => shell.starts_with("fish"),
|
||||||
|
PluginShellType::Nushell => shell.starts_with("nu"),
|
||||||
|
PluginShellType::Xonsh => shell.starts_with("xonsh"),
|
||||||
|
})
|
||||||
|
.filter_map(|(plugin, _, probe_type, validator)| -> Option<String> {
|
||||||
|
match probe_type {
|
||||||
|
PluginProbeType::EnvironmentVariable(env) => {
|
||||||
|
env::var(env).ok().filter(|value| !value.is_empty())
|
||||||
|
}
|
||||||
|
PluginProbeType::InteractiveShellVariable(shellvar) => {
|
||||||
|
ShellInfo::shellvar_exists(shell, shellvar).then_some(String::default())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
.and_then(|value| {
|
||||||
None
|
validator.map_or_else(
|
||||||
|
|| Some(plugin.to_string()),
|
||||||
|
|validator| validator(shell, shell_process, &value),
|
||||||
|
)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
@ -75,7 +148,7 @@ impl ShellInfo {
|
|||||||
let shell = shell.strip_prefix('-').unwrap_or(&shell);
|
let shell = shell.strip_prefix('-').unwrap_or(&shell);
|
||||||
let name = shell.to_string();
|
let name = shell.to_string();
|
||||||
|
|
||||||
let plugins = ShellInfo::plugins(name.as_str());
|
let plugins = ShellInfo::plugins(name.as_str(), parent);
|
||||||
|
|
||||||
Self { name, plugins }
|
Self { name, plugins }
|
||||||
}
|
}
|
||||||
@ -188,7 +261,7 @@ fn checks(info: &DoctorDump) {
|
|||||||
println!(); // spacing
|
println!(); // spacing
|
||||||
//
|
//
|
||||||
let zfs_error = "[Filesystem] ZFS is known to have some issues with SQLite. Atuin uses SQLite heavily. If you are having poor performance, there are some workarounds here: https://github.com/atuinsh/atuin/issues/952".bold().red();
|
let zfs_error = "[Filesystem] ZFS is known to have some issues with SQLite. Atuin uses SQLite heavily. If you are having poor performance, there are some workarounds here: https://github.com/atuinsh/atuin/issues/952".bold().red();
|
||||||
let bash_plugin_error = "[Shell] If you are using Bash, Atuin requires that either bash-preexec or ble.sh be installed. We cannot currently detect ble, so if you have it setup then ignore this! Read more here: https://docs.atuin.sh/guide/installation/#bash".bold().red();
|
let bash_plugin_error = "[Shell] If you are using Bash, Atuin requires that either bash-preexec or ble.sh be installed. An older ble.sh may not be detected. so ignore this if you have it set up! Read more here: https://docs.atuin.sh/guide/installation/#bash".bold().red();
|
||||||
|
|
||||||
// ZFS: https://github.com/atuinsh/atuin/issues/952
|
// ZFS: https://github.com/atuinsh/atuin/issues/952
|
||||||
if info.system.disks.iter().any(|d| d.filesystem == "zfs") {
|
if info.system.disks.iter().any(|d| d.filesystem == "zfs") {
|
||||||
|
@ -271,6 +271,11 @@ if [[ ${BLE_VERSION-} ]] && ((_ble_version >= 400)); then
|
|||||||
}
|
}
|
||||||
ble/util/import/eval-after-load core-complete '
|
ble/util/import/eval-after-load core-complete '
|
||||||
ble/array#unshift _ble_complete_auto_source atuin-history'
|
ble/array#unshift _ble_complete_auto_source atuin-history'
|
||||||
|
|
||||||
|
# @env BLE_SESSION_ID: `atuin doctor` references the environment variable
|
||||||
|
# BLE_SESSION_ID. We explicitly export the variable because it was not
|
||||||
|
# exported in older versions of ble.sh.
|
||||||
|
[[ ${BLE_SESSION_ID-} ]] && export BLE_SESSION_ID
|
||||||
fi
|
fi
|
||||||
precmd_functions+=(__atuin_precmd)
|
precmd_functions+=(__atuin_precmd)
|
||||||
preexec_functions+=(__atuin_preexec)
|
preexec_functions+=(__atuin_preexec)
|
||||||
|
Loading…
Reference in New Issue
Block a user