onpath 0.1.0

Get your tools on the PATH — cross-shell, cross-platform, zero fuss
Documentation
# onpath

Get your tools on the PATH — cross-shell, cross-platform, zero fuss.

Built for CLI tool installers that need to persistently add a directory to the user's `PATH`. Detects installed shells, writes the right config for each, and removes everything cleanly on uninstall. Linux, macOS, Windows.

## Quick start

```rust
// Add ~/.myapp/bin to PATH for all detected shells
let report = onpath::add("/home/user/.myapp/bin", "myapp")?;
println!("{report}");
// [sh]   wrote env script: /home/user/.myapp/env
// [sh]   added source line to /home/user/.profile
// [Bash] wrote env script: /home/user/.myapp/env
// [Bash] added source line to /home/user/.bashrc
// [Zsh]  wrote env script: /home/user/.myapp/env
// [Zsh]  added source line to /home/user/.zshenv
```

To undo everything during uninstall:

```rust
let report = onpath::remove("/home/user/.myapp/bin", "myapp")?;
```

Env scripts land in the parent of the directory you pass in (`~/.myapp/` for `~/.myapp/bin`). Override with `.env_dir()` on the builder.

**Shells:** Bash, Zsh, Fish, Nushell, PowerShell, Tcsh, Xonsh, POSIX sh.
**Windows:** Modifies `HKCU\Environment\PATH` in the registry directly.

## How it works

On Unix, onpath uses the same [two-layer approach as rustup](https://github.com/rust-lang/rustup/blob/e0e1f45454291049db50e1ea93455e696674fcd9/src/cli/self_update/shell.rs#L1-L24):

**1. Writes a self-guarding env script** that only adds the directory if it's not already in PATH:

```sh
#!/bin/sh
# Generated by onpath. Do not edit.
case ":${PATH}:" in
    *:"/home/user/.myapp/bin":*)
        ;;
    *)
        export PATH="/home/user/.myapp/bin:$PATH"
        ;;
esac
```

Fish, Nushell, PowerShell, Tcsh, and Xonsh each get a script in their native syntax (`.fish`, `.nu`, `.ps1`, etc.).

**2. Adds a source line** to the shell's RC file, wrapped in markers for clean removal:

```bash
# >>> onpath:myapp >>>
. "/home/user/.myapp/env"
# <<< onpath:myapp <<<
```

Multiple tools can coexist — each gets its own marker block. Adding the same directory twice is a no-op.

**On Windows**, onpath reads the raw `PATH` from `HKCU\Environment`, prepends or appends the directory, writes it back, and broadcasts `WM_SETTINGCHANGE` so running programs pick up the change. It preserves unexpanded `%VARIABLES%` like `%USERPROFILE%` and the original registry value type (`REG_SZ` vs `REG_EXPAND_SZ`).

## Builder API

For more control, use `PathManager`:

```rust
use onpath::{PathManager, Position};

let report = PathManager::new("/home/user/.myapp/bin", "myapp")
    .env_dir("/home/user/.myapp")  // where to write env scripts (default: dir.parent())
    .position(Position::Append)    // default is Prepend
    .backup(true)                  // back up RC files before modifying (default)
    .dry_run(true)                 // preview without writing anything
    .add()?;

for action in &report.actions {
    println!("{action}");
}
```

## Shell detection

Shells are auto-detected by checking for existing RC files and the `$SHELL` environment variable. POSIX sh (`.profile`) is always included on Unix. No configuration needed.

## Install

```toml
[dependencies]
onpath = "0.1"
```

MSRV: 1.71 (edition 2021)

## License

MIT OR Apache-2.0