Skip to content

Instantly share code, notes, and snippets.

@zlatent
Created February 6, 2026 01:13
Show Gist options
  • Select an option

  • Save zlatent/668528b935d7c848034f60e86ac225e9 to your computer and use it in GitHub Desktop.

Select an option

Save zlatent/668528b935d7c848034f60e86ac225e9 to your computer and use it in GitHub Desktop.
function uvt --description 'Manage tools in a shared global uv-env'
set -l global_env "$HOME/.local/share/uv-env"
set -l cmd $argv[1]
set -l args $argv[2..-1]
# 1. Show Help / Usage
if test (count $argv) -eq 0; or contains -- -h $argv; or contains -- --help $argv
echo "uvt: uv tool manager for a single shared environment"
echo "Usage: uvt <command> [args]"
echo ""
echo "Commands:"
echo " install|i <pkg> Add tool(s) to the global env"
echo " uninstall|rm|un <pkg> Remove tool(s)"
echo " list|ls List all tools and versions"
echo " outdated|o Show packages with available upgrades"
echo " search|q <query> Search PyPI for packages"
echo " run|r <script> Run a Python script with the global env"
echo " upgrade|up [pkg] Upgrade specific or all tools"
echo " update [pkg] Alias for upgrade"
echo " path Show the bin directory path"
echo ""
echo "Env: $global_env"
echo ""
echo "πŸ’‘ Tip: Add to your PATH with:"
echo " fish_add_path \"$global_env/bin\""
return 0
end
# 2. Ensure env exists
if not test -d $global_env
echo "πŸ“¦ Creating global environment at $global_env..."
uv venv $global_env
or begin
echo "❌ Failed to create virtual environment" >&2
return 1
end
echo "βœ… Environment created successfully"
end
# 3. Handle Commands
switch $cmd
case install i
if test (count $args) -eq 0
echo "❌ Error: No package specified" >&2
echo "Usage: uvt install <pkg>" >&2
return 1
end
uv pip install --python $global_env $args
or begin
echo "❌ Installation failed" >&2
return 1
end
echo "✨ Installed successfully. Binaries available at $global_env/bin"
case uninstall rm un
if test (count $args) -eq 0
echo "❌ Error: No package specified" >&2
echo "Usage: uvt uninstall <pkg>" >&2
return 1
end
uv pip uninstall --python $global_env $args
or begin
echo "❌ Uninstallation failed" >&2
return 1
end
echo "βœ… Uninstalled successfully"
case list ls
uv pip list --python $global_env
or begin
echo "❌ Failed to list packages" >&2
return 1
end
case outdated o
echo "πŸ” Checking for outdated packages (ignoring patches)..."
# Get the full outdated list
set -l outdated_raw (uv pip list --python $global_env --outdated 2>&1)
if test $status -ne 0
# If --outdated flag is not supported, use alternative method
echo "πŸ“‹ Installed packages:"
uv pip list --python $global_env
echo ""
echo "πŸ’‘ Tip: Run 'uvt upgrade' to upgrade all packages"
return 0
end
# Parse and filter for minor/major updates only
set -l has_updates false
set -l major_updates
set -l minor_updates
# Skip header lines and parse package data
for line in $outdated_raw
# Match lines with package info (skip headers and separators)
if string match -qr -- '^[a-zA-Z]' $line
# Skip the header line "Package Version Latest Type"
if string match -q "Package*" $line
continue
end
# Extract package name, current version, and latest version
set -l parts (string split -n ' ' $line)
if test (count $parts) -ge 3
set -l pkg_name $parts[1]
set -l current_ver $parts[2]
set -l latest_ver $parts[3]
# Parse semantic versions (major.minor.patch)
set -l curr_major (string split '.' $current_ver)[1]
set -l curr_minor (string split '.' $current_ver)[2]
set -l latest_major (string split '.' $latest_ver)[1]
set -l latest_minor (string split '.' $latest_ver)[2]
# Check for major or minor updates (ignore patch-only)
if test "$latest_major" -gt "$curr_major" 2>/dev/null
set has_updates true
set -a major_updates "$pkg_name ($current_ver β†’ $latest_ver)"
else if test "$latest_major" = "$curr_major" 2>/dev/null; and test "$latest_minor" -gt "$curr_minor" 2>/dev/null
set has_updates true
set -a minor_updates "$pkg_name ($current_ver β†’ $latest_ver)"
end
end
end
end
# Display results
if test "$has_updates" = true
if test (count $major_updates) -gt 0
echo ""
echo "πŸš€ Major updates available:"
for pkg in $major_updates
echo " β€’ $pkg"
end
end
if test (count $minor_updates) -gt 0
echo ""
echo "πŸ“¦ Minor updates available:"
for pkg in $minor_updates
echo " β€’ $pkg"
end
end
echo ""
echo "πŸ’‘ Upgrade with: uvt up <package-name>"
echo " or upgrade all: uvt up"
else
echo "βœ… All packages are up to date (ignoring patch updates)"
end
case search q
if test (count $args) -eq 0
echo "❌ Error: No search query specified" >&2
echo "Usage: uvt search <query>" >&2
return 1
end
# Check if pip-search is installed in the global env
if not test -f "$global_env/bin/pip-search"
echo "πŸ” 'pip-search' not found. Installing into global env..."
uv pip install --python $global_env pip-search >/dev/null 2>&1
or begin
echo "❌ Failed to install pip-search" >&2
return 1
end
end
# Run the search
"$global_env/bin/pip-search" $args
case upgrade update up
if test (count $args) -gt 0
echo "πŸš€ Upgrading specified tools: $args..."
uv pip install --python $global_env --upgrade $args
or begin
echo "❌ Upgrade failed" >&2
return 1
end
else
echo "πŸš€ Upgrading all global tools..."
set -l pkgs (uv pip list --python $global_env --format freeze 2>/dev/null | cut -d= -f1)
if test (count $pkgs) -gt 0
uv pip install --python $global_env --upgrade $pkgs
or begin
echo "❌ Upgrade failed" >&2
return 1
end
echo "βœ… All packages upgraded successfully"
else
echo "ℹ️ No packages to upgrade"
end
end
case run r
if test (count $args) -eq 0
echo "❌ Error: No script specified" >&2
echo "Usage: uvt run <script.py> [args]" >&2
return 1
end
uv run --python $global_env $args
or return $status
case path
echo "$global_env/bin"
case '*'
echo "❌ Unknown command: $cmd" >&2
echo "Run 'uvt --help' for usage information" >&2
return 1
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment