A Rust-based plugin manager for fish
Experimental — use at your own risk.
Ensure you have Rust installed on your system. You can install pez using Cargo:
# From crates.io (if available)
cargo install pez
# From source (in this repo)
cargo install --path .# 1) Initialize configuration (creates pez.toml)
pez init
# 2) Add a plugin to pez.toml (choose one of repo/url/path)
# [[plugins]]
# repo = "owner/repo" # GitHub shorthand
# # version = "v3" # Or: tag = "...", branch = "...", commit = "..."
#
# # [[plugins]]
# # url = "https://gitlab.com/owner/repo" # Any Git host URL
# # branch = "main"
#
# # [[plugins]]
# # path = "~/path/to/local/plugin" # Local directory (absolute or ~/ only)
# # Note: when specifying a relative path at the CLI (e.g., ./plugin), pez normalizes it to an absolute path in pez.toml.
# 3) Install plugins listed in pez.toml
pez install
# 4) Verify installation
pez list --format table
# 5) (Optional) Enable completions for pez itself
pez completions fish > ~/.config/fish/completions/pez.fishpez completions fish > ~/.config/fish/completions/pez.fishUsage: pez [OPTIONS] <COMMAND>
Commands:
init | install | uninstall | upgrade | list | prune | completions | doctor | migrate
Options:
-v, --verbose Increase output verbosity (-v for info, -vv for debug)
-h, --help Print help
-V, --version Print versionCommon examples
pez init
pez install # install from pez.toml
pez install owner/repo # install a specific plugin
pez upgrade # update non-local plugins to remote HEAD
pez list --outdated --format table
pez prune --dry-runSee the full command reference in docs/commands.md.
pez uses two main configuration files: pez.toml and pez-lock.toml.
By default, these files are created in the fish configuration directory,
but you can specify a different location using environment variables.
Configuration file locations
pez looks for pez.toml and pez-lock.toml in the following order:
$PEZ_CONFIG_DIR > $__fish_config_dir > $XDG_CONFIG_HOME/fish > ~/.config/fish.
PEZ_TARGET_DIR only affects where plugin files are copied. If you previously relied on
PEZ_TARGET_DIR to relocate your configuration files, move pez.toml and
pez-lock.toml into the directory referenced by PEZ_CONFIG_DIR (or set
PEZ_CONFIG_DIR to that path) before running newer versions of pez.
pez.toml is the primary configuration file where you define the plugins
you want to manage. Below is an example structure:
# GitHub shorthand
[[plugins]]
repo = "owner/repo"
# version = "latest" # default if omitted
# version = "v3" # branch or tag name; branches preferred over tags
# branch = "develop"
# tag = "v1.0.0"
# commit = "<sha>" # 7+ chars recommended (unique per repo)
# Generic Git host URL
[[plugins]]
url = "https://gitlab.com/owner/repo"
# branch = "main"
# Local path (absolute or ~/ only)
[[plugins]]
path = "~/path/to/local/plugin"pez-lock.toml is automatically generated and maintained by pez.
It records detailed information about the installed plugins,
including their source repositories and specific commit SHAs.
Do not edit this file manually.
pez clones plugin repositories into a designated data directory,
prioritized as follows:
$PEZ_DATA_DIR > $__fish_user_data_dir/pez > $XDG_DATA_HOME/fish/pez > ~/.local/share/fish/pez
When you install a plugin, pez clones its repository into pez_data_dir.
If the directory doesn’t exist, pez will create it.
Remote repositories that specify a host are stored under <host>/<owner>/<repo>
within that data directory (for example gitlab.com/owner/tool). GitHub shorthand
targets (owner/repo) continue to resolve to github.com/owner/repo.
If the repository is already cloned:
- For explicit CLI targets (
pez install owner/repo ...), pez logs a warning and skips the reinstall unless you pass--force. - For installs driven by
pez.toml(pez installwith no targets), entries that already exist inpez-lock.tomland on disk are treated as up to date and skipped unless you pass--force. If a clone exists without a matching lockfile entry, pez returns an error unless you pass--force.
After cloning, if the repository contains functions, completions, conf.d, or themes directories, pez will recursively copy files from these directories to the corresponding fish configuration directories:
~/.config/fish/functions~/.config/fish/completions~/.config/fish/conf.d~/.config/fish/themes
When installing plugins (either from pez.toml or explicit targets), pez detects duplicate destination paths across all plugins in the same run and skips the conflicting plugin with a warning to avoid overwriting existing files.
The destination fish configuration directory can be overridden using
PEZ_TARGET_DIR; when it is unset, pez falls back to
$__fish_config_dir > $XDG_CONFIG_HOME/fish > ~/.config/fish.
Additionally, pez-lock.toml records information about the installed plugins
and the files copied. It is created in the same directory as pez.toml
and is updated if it already exists.
Control job parallelism with the global --jobs <N> flag or the PEZ_JOBS
environment variable (default: 4). The CLI flag takes precedence over the
environment variable.
install(when CLI explicit targets are given): cloning is bounded by the configured job limitupgrade/uninstall/prunealso honor the same job limit
- CLI explicit targets: skip with a warning unless
--force(re‑clone). - From
pez.toml(no targets): entries already tracked inpez-lock.tomlwith an existing clone are skipped unless you pass--force. If a clone exists without a matching lockfile entry, pez returns an error unless you pass--force.
pez is inspired by the following projects:
MIT
tetzng