Files
uv/crates/uv-shell/Cargo.toml
Ed Rogers 4b88b1379a Add fallback parent process detection to uv tool update-shell (#15356)
## Summary

Closes #15355

This PR adds a fallback mechanism to `Shell::from_env()` that inspects
the parent process when shell environment variables are not available on
Unix-like systems.

Currently, `uv tool update-shell` fails with "the current shell could
not be determined" when environment variables like `ZSH_VERSION`,
`BASH_VERSION`, or `SHELL` are not exported. This commonly occurs in
automated environments such as GitHub Actions runners.

The fallback approach:
1. Uses `nix::unistd::getppid()` to get the parent process ID
2. Reads `/proc/<ppid>/exe` to determine the parent executable path
3. Falls back to `/proc/<ppid>/comm` if the exe symlink fails  
4. Uses existing `parse_shell_from_path()` to identify the shell type

This maintains full backward compatibility - the fallback only activates
when environment variables are unavailable and an error would otherwise
occur.

## Test Plan

Tested locally with:

```bash
env -u ZSH_VERSION -u SHELL PATH="/usr/bin:/bin" $(which cargo) run -- tool update-shell --verbose
```
```text
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.30s
     Running `target/debug/uv tool update-shell --verbose`
DEBUG uv 0.8.11
DEBUG Ensuring that the executable directory is in PATH: /home/user/.local/bin
DEBUG Detected parent process ID: 4147396
DEBUG Parent process executable: /usr/bin/zsh
Updated configuration file: /home/user/.zshenv
Restart your shell to apply changes
```
2025-08-18 13:48:34 -05:00

34 lines
728 B
TOML

[package]
name = "uv-shell"
version = "0.0.1"
edition = { workspace = true }
description = "Utilities for detecting and manipulating shell environments"
[lib]
doctest = false
[lints]
workspace = true
[dependencies]
uv-fs = { workspace = true }
uv-static = { workspace = true }
anyhow = { workspace = true }
fs-err = { workspace = true }
home = { workspace = true }
same-file = { workspace = true }
tracing = { workspace = true }
[target.'cfg(unix)'.dependencies]
nix = { workspace = true }
[target.'cfg(windows)'.dependencies]
windows-registry = { workspace = true }
windows-result = { workspace = true }
windows-sys = { workspace = true }
[dev-dependencies]
fs-err = { workspace = true }
tempfile = { workspace = true }