Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(doctor): detect active preexec framework #1955

Merged
merged 2 commits into from
Apr 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 44 additions & 4 deletions atuin/src/command/client/doctor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ struct ShellInfo {
// Detect some shell plugins that the user has installed.
// I'm just going to start with preexec/blesh
pub plugins: Vec<String>,

// The preexec framework used in the current session, if Atuin is loaded.
pub preexec: Option<String>,
}

impl ShellInfo {
Expand All @@ -43,6 +46,31 @@ impl ShellInfo {
cmd.contains("ATUIN_DOCTOR_ENV_FOUND")
}

fn detect_preexec_framework(shell: &str) -> Option<String> {
if env::var("ATUIN_SESSION").ok().is_none() {
None
} else if shell.starts_with("bash") || shell == "sh" {
env::var("ATUIN_PREEXEC_BACKEND")
.ok()
.filter(|value| !value.is_empty())
.and_then(|atuin_preexec_backend| {
atuin_preexec_backend.rfind(':').and_then(|pos_colon| {
u32::from_str(&atuin_preexec_backend[..pos_colon])
.ok()
.is_some_and(|preexec_shlvl| {
env::var("SHLVL")
.ok()
.and_then(|shlvl| u32::from_str(&shlvl).ok())
.is_some_and(|shlvl| shlvl == preexec_shlvl)
})
.then(|| atuin_preexec_backend[pos_colon + 1..].to_string())
})
})
} else {
Some("built-in".to_string())
}
}

fn validate_plugin_blesh(
_shell: &str,
shell_process: &sysinfo::Process,
Expand Down Expand Up @@ -156,10 +184,13 @@ impl ShellInfo {

let default = Shell::default_shell().unwrap_or(Shell::Unknown).to_string();

let preexec = Self::detect_preexec_framework(name.as_str());

Self {
name,
default,
plugins,
preexec,
}
}
}
Expand Down Expand Up @@ -272,21 +303,30 @@ fn checks(info: &DoctorDump) {
//
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. 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();
let blesh_loading_order_error = "[Shell] Atuin seems to be loaded before ble.sh is sourced. In .bashrc, make sure to initialize Atuin after sourcing ble.sh.".bold().red();

// ZFS: https://github.com/atuinsh/atuin/issues/952
if info.system.disks.iter().any(|d| d.filesystem == "zfs") {
println!("{zfs_error}");
}

// Shell
if info.shell.name == "bash"
&& !info
if info.shell.name == "bash" {
if !info
.shell
.plugins
.iter()
.any(|p| p == "blesh" || p == "bash-preexec")
{
println!("{bash_plugin_error}");
{
println!("{bash_plugin_error}");
}

if info.shell.plugins.iter().any(|plugin| plugin == "atuin")
&& info.shell.plugins.iter().any(|plugin| plugin == "blesh")
&& info.shell.preexec.as_ref().is_some_and(|val| val == "none")
{
println!("{blesh_loading_order_error}");
}
}
}

Expand Down
17 changes: 17 additions & 0 deletions atuin/src/shell/atuin.bash
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,19 @@ ATUIN_STTY=$(stty -g)
export ATUIN_SESSION
ATUIN_HISTORY_ID=""

export ATUIN_PREEXEC_BACKEND=$SHLVL:none
__atuin_update_preexec_backend() {
if [[ ${BLE_ATTACHED-} ]]; then
ATUIN_PREEXEC_BACKEND=$SHLVL:blesh-${BLE_VERSION-}
elif [[ ${bash_preexec_imported-} ]]; then
ATUIN_PREEXEC_BACKEND=$SHLVL:bash-preexec
elif [[ ${__bp_imported-} ]]; then
ATUIN_PREEXEC_BACKEND="$SHLVL:bash-preexec (old)"
else
ATUIN_PREEXEC_BACKEND=$SHLVL:unknown
fi
}

__atuin_preexec() {
# Workaround for old versions of bash-preexec
if [[ ! ${BLE_ATTACHED-} ]]; then
Expand All @@ -33,6 +46,10 @@ __atuin_preexec() {
fi
fi

# Note: We update ATUIN_PREEXEC_BACKEND on every preexec because blesh's
# attaching state can dynamically change.
__atuin_update_preexec_backend

local id
id=$(atuin history start -- "$1")
export ATUIN_HISTORY_ID=$id
Expand Down
Loading