Skip to content

Jnm/customize install order use pkgx #293

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

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
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
285 changes: 151 additions & 134 deletions commands/setup-util
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,95 @@
# https://github.com/zyedidia/eget
# https://github.com/marwanhawari/stew

# prefer precompiled with autoupdate with extras
# extras = man packages, autocompletes, etc
default_all_installers=(
# +precompiled +compiling +autoupdate +extras
brew
cask

# +precompiled +compiling +autoupdate +extras
apt # debian package manager (includes DEB, successor to aptitude)
apk # alpine package manager (includes APK)
zypper # opensuse package manager (includes RPM, supports YaST2)
dnf # fedora package manager (includes RPM, successor to yum)
yum # fedora package manager (includes RPM, predecessor to dnf)

# +precompiled[containers] +autoupdate +extras
snap # dependencies are within the snap
flatpak # dependencies are their own flatpaks, but everything is precompiled

# +precompiled[first-class AUR support] +autoupdate +extras
pamac # manjaro package manager (includes AUR): GUI+CLI, vala, wraps libalpm, snap, flatpak: https://gitlab.manjaro.org/applications/pamac/
pacman # arch package manager (includes AUR): CLI, c, wraps libalpm: https://wiki.archlinux.org/title/pacman

# +precompiled[third-party AUR wrappers] +autoupdate +extras
# https://wiki.archlinux.org/title/AUR_helpers
# https://wiki.manjaro.org/index.php?title=Pamac
# https://wiki.manjaro.org/index.php/Arch_User_Repository
# https://itsfoss.com/paru-aur-helper/
# https://itsfoss.com/best-aur-helpers/
yay # GUI, go, wraps pacman: https://github.com/Jguer/yay
paru # CLI, rust, wraps pacman: https://github.com/Morganamilo/paru
pakku # CLI, nim, wraps pacman: https://github.com/kitsunyan/pakku
aurutils # CLI, shell, wraps pacman: https://github.com/AladW/aurutils

# +precompiled -autoupdate +extras
dpkg # prefer apt wrapper
rpm # prefer dnf wrapper, note this is also available on opensuse however zypper is preferred there

# +precompiled -autoupdate -extras
download # remote download from url

# +compiling +autoupdate
cargo # prefer over go
go

# +jit +autoupdate
npm # prefer over python and ruby
gem # prefer over python
pipx # prefer over pip
pip

# +precompiled +autoupdate
mas

# windows, unknown features
scoop # installs exes to consistent path location
winget # installs apps to windows, installs exes to windows, paths inherited but custom
choco # choco/chocolatey/cinst, interferes with WSL, so should be last preference on windows

# solaris/bsd, unknown features
pkgin
pkgadd
pkg

# unknown features
cabal
conda
emerge
eopkg
guix
nix
port
xbps
urpmi

# disable/removed as no documentation
# pkgutil
# pkgman
# huber
# eget
# stack
# kiss

# these just trigger one of the above with special wrapping
pkgx # +precompiled -autoupdate -extras +experimental
installer # local or remote installer
'eval' # run a function or another script
generic # generic uninstaller, for cleaning up leftovers
)

function setup_util() (
source "$DOROTHY/sources/bash.bash"
__require_array 'mapfile'
Expand All @@ -21,95 +110,6 @@ function setup_util() (
fi
}

# prefer precompiled with autoupdate with extras
# extras = man packages, autocompletes, etc
local installers=(
# +precompiled +compiling +autoupdate +extras
brew
cask

# +precompiled +compiling +autoupdate +extras
apt # debian package manager (includes DEB, successor to aptitude)
apk # alpine package manager (includes APK)
zypper # opensuse package manager (includes RPM, supports YaST2)
dnf # fedora package manager (includes RPM, successor to yum)
yum # fedora package manager (includes RPM, predecessor to dnf)

# +precompiled[containers] +autoupdate +extras
snap # dependencies are within the snap
flatpak # dependencies are their own flatpaks, but everything is precompiled

# +precompiled[first-class AUR support] +autoupdate +extras
pamac # manjaro package manager (includes AUR): GUI+CLI, vala, wraps libalpm, snap, flatpak: https://gitlab.manjaro.org/applications/pamac/
pacman # arch package manager (includes AUR): CLI, c, wraps libalpm: https://wiki.archlinux.org/title/pacman

# +precompiled[third-party AUR wrappers] +autoupdate +extras
# https://wiki.archlinux.org/title/AUR_helpers
# https://wiki.manjaro.org/index.php?title=Pamac
# https://wiki.manjaro.org/index.php/Arch_User_Repository
# https://itsfoss.com/paru-aur-helper/
# https://itsfoss.com/best-aur-helpers/
yay # GUI, go, wraps pacman: https://github.com/Jguer/yay
paru # CLI, rust, wraps pacman: https://github.com/Morganamilo/paru
pakku # CLI, nim, wraps pacman: https://github.com/kitsunyan/pakku
aurutils # CLI, shell, wraps pacman: https://github.com/AladW/aurutils

# +precompiled -autoupdate +extras
dpkg # prefer apt wrapper
rpm # prefer dnf wrapper, note this is also available on opensuse however zypper is preferred there

# +precompiled -autoupdate -extras
download # remote download from url

# +compiling +autoupdate
cargo # prefer over go
go

# +jit +autoupdate
npm # prefer over python and ruby
gem # prefer over python
pipx # prefer over pip
pip

# +precompiled +autoupdate
mas

# windows, unknown features
scoop # installs exes to consistent path location
winget # installs apps to windows, installs exes to windows, paths inherited but custom
choco # choco/chocolatey/cinst, interferes with WSL, so should be last preference on windows

# solaris/bsd, unknown features
pkgin
pkgadd
pkg

# unknown features
cabal
conda
emerge
eopkg
guix
nix
port
xbps
urpmi

# disable/removed as no documentation
# pkgutil
# pkgman
# huber
# eget
# stack
# kiss

# these just trigger one of the above with special wrapping
tea # +precompiled -autoupdate -extras +experimental
installer # local or remote installer
'eval' # run a function or another script
generic # generic uninstaller, for cleaning up leftovers
)

# =====================================
# Arguments

Expand Down Expand Up @@ -257,7 +257,7 @@ function setup_util() (
local RPM=()
local SCOOP=()
local SNAP=() SNAP_CHANNEL=''
local TEA=()
local PKGX=()
local URPMI=()
local WINGET=()
local XBPS=()
Expand Down Expand Up @@ -413,7 +413,7 @@ function setup_util() (
'SCOOP='*) SCOOP+=("${item#*=}") ;;
'SNAP_CHANNEL='*) SNAP_CHANNEL="${item#*=}" ;;
'SNAP='*) SNAP+=("${item#*=}") ;;
'TEA='*) TEA+=("${item#*=}") ;;
'PKGX='*) PKGX+=("${item#*=}") ;;
'URPMI='* | 'MAGEIA='*) URPMI+=("${item#*=}") ;;
'WINGET='*) WINGET+=("${item#*=}") ;;
'XBPS='* | 'VOID='*) XBPS+=("${item#*=}") ;;
Expand Down Expand Up @@ -566,10 +566,33 @@ function setup_util() (
fi
fi

# ensure order
attempt_handle_setup_utils_order() {
if [[ "$(declare -p SETUP_UTILS_ORDER)" =~ "declare -a" && "${#SETUP_UTILS_ORDER[@]}" -gt 0 ]]; then
option_order=(${SETUP_UTILS_ORDER[@]})
elif [[ ${#SETUP_UTILS_ORDER} -gt 0 ]]; then
# in case SETUP_UTILS_ORDER provided as a string/proper env var
mapfile -t option_order < <(echo-split --needle=' ' --needle=',' -- "${SETUP_UTILS_ORDER}")
fi
}

# ensure order is set appropriately
if [[ ${#option_order[@]} -eq 0 ]]; then
option_order=("${installers[@]}")
else
if declare -p SETUP_UTIL_ORDER &> /dev/null; then
# if SETUP_UTIL_ORDER variable is set at all,
attempt_handle_setup_utils_order
else
# if SETUP_UTIL_ORDER variable unset in env, try to load from config
source "$DOROTHY/sources/config.sh"
load_dorothy_config "setup.bash"
attempt_handle_setup_utils_order
fi

if ((${#option_order[@]} == 0)); then
option_order=("${default_all_installers[@]}")
fi
fi

if [[ "${#option_order[@]}" -ne 0 ]]; then
# custom order, handle ...
# so [snap ...] means snap first, then everything else, whereas [... apt] means everything then apt
# as such, the specified installers need to be trimmed from the ... substitution
Expand All @@ -578,7 +601,7 @@ function setup_util() (
temp_order=()
for installer in "${option_order[@]}"; do
if [[ $installer == '...' ]]; then
for inject_installer in "${installers[@]}"; do
for inject_installer in "${default_all_installers[@]}"; do
if is-needle --needle="$inject_installer" -- "${option_order[@]}"; then
continue
else
Expand Down Expand Up @@ -3244,34 +3267,34 @@ function setup_util() (
}

# ---------------------------------
# Tea
# Pkgx

# note that tea doesn't provide man pages, even via [tea man bat]
function remove_tea_cache {
# note that pkgx doesn't provide man pages, even via [pkgx man bat]
function remove_pkgx_cache {
local package="$1" subpath path
# this entire cache of the package must be removed, not just [tea -n "$option_cli"]
# this entire cache of the package must be removed, not just [pkgx -n "$option_cli"]
# see https://discord.com/channels/906608167901876256/906608288026734622/1134327807544135770
subpath="${package:1}" # get everything after the +
path="$HOME/.tea/$subpath"

path="$HOME/.pkgx/$package"
if [[ -d $path ]]; then
rm_helper "$path"
return 0
fi
return 200 # ECUSTOM 200 Not applicable to this package system
}
function remove_tea_xdg_bin_alias {
function remove_pkgx_xdg_bin_alias {
if [[ -L "$XDG_BIN_HOME/$option_cli" ]]; then
if [[ "$(fs-realpath -- "$XDG_BIN_HOME/$option_cli")" == "$(type -P tea)" ]]; then
if [[ "$(fs-realpath -- "$XDG_BIN_HOME/$option_cli")" == "$(type -P pkgx)" ]]; then
rm_helper "$XDG_BIN_HOME/$option_cli"
return 0 # is applicable
fi
fi
return 200 # ECUSTOM 200 Not applicable to this package system
}
function remove_tea_package {
function remove_pkgx_package {
local package="$1" ec1 ec2
eval_capture --statusvar=ec1 -- remove_tea_xdg_bin_alias
eval_capture --statusvar=ec2 -- remove_tea_cache "$package"
eval_capture --statusvar=ec1 -- remove_pkgx_xdg_bin_alias
eval_capture --statusvar=ec2 -- remove_pkgx_cache "$package"
if [[ $ec1 -ne 0 && $ec1 -ne 200 ]]; then
return "$ec1" # error
elif [[ $ec2 -ne 0 && $ec2 -ne 200 ]]; then
Expand All @@ -3282,69 +3305,63 @@ function setup_util() (
return 200 # ECUSTOM 200 Not applicable to this package system
fi
}
function __check_tea {
function __check_pkgx {
local packages=()
if [[ ${#TEA[@]} -ne 0 ]]; then
packages+=("${TEA[@]}")
if [[ ${#PKGX[@]} -ne 0 ]]; then
packages+=("${PKGX[@]}")
fi

# check if applicable
if [[ ${#packages[@]} -eq 0 ]]; then
return 200 # ECUSTOM 200 Not applicable to this utility
fi
if __command_missing -- tea; then
fallbacks+=('tea')
if __command_missing -- pkgx; then
fallbacks+=('pkgx')
return 200 # ECUSTOM 200 Not applicable yet but provided fallback
fi
if [[ -z $option_cli ]]; then
echo-style --error='TEA requires <cli>' >/dev/stderr
echo-style --error='PKGX requires <cli>' >/dev/stderr
return 22 # EINVAL 22 Invalid argument
fi
if [[ -z $option_cli ]]; then
echo-style --error='TEA requires <cli>' >/dev/stderr
echo-style --error='PKGX requires <cli>' >/dev/stderr
return 22 # EINVAL 22 Invalid argument
fi
}
function do_tea {
local packages=() repo tea_status result=200
if [[ ${#TEA[@]} -ne 0 ]]; then
packages+=("${TEA[@]}")
function do_pkgx {
local packages=() repo pkgx_status result=200
if [[ ${#PKGX[@]} -ne 0 ]]; then
packages+=("${PKGX[@]}")
fi

# handle each package
for package in "${packages[@]}"; do
# check
if [[ $package != '+'* ]]; then
echo-style --error1='TEA packages must begin with a plus sign ' --code-error1='+' --error1=' e.g. ' --code-error1="--cli='jq' TEA='+stedolan.github.io/jq'" >/dev/stderr
return 22 # EINVAL 22 Invalid argument
fi

# uninstall
if [[ $option_action == 'uninstall' ]]; then
eval_capture --statusvar=tea_status -- remove_tea_package "$package"
if [[ $tea_status -eq 0 ]]; then
eval_capture --statusvar=pkgx_status -- remove_pkgx_package "$package"
if [[ $pkgx_status -eq 0 ]]; then
result=0
fi
else
# install / upgrade
result=0

# install it by doing [tea $package --version]
# it would be nice to use [command-working] however [command-working] currently expects multiple commands as arguments so it would become [command-working -- tea, command-working $package, command-working --version]
tea "$package" "$option_cli" --version
# install it by doing [pkgx +$package /usr/bin/true]
# (saves path to tool immediately after installing)
installed_path="$(pkgx +"$package" -- which "$option_cli")"

# make tea alias available
# make pkgx alias available
__mkdirp "$XDG_BIN_HOME"
symlink-helper --quiet="$option_quiet" --existing="$(type -P tea)" --symlink="$XDG_BIN_HOME/$option_cli"
symlink-helper --quiet="$option_quiet" --existing="$installed_path" --symlink="$XDG_BIN_HOME/$option_cli"
fi
done
return "$result"
}
function do_tea_fallback {
log_fallback 'Tea'
setup-util-tea --quiet="$option_quiet"
function do_pkgx_fallback {
log_fallback 'Pkgx'
setup-util-pkgx --quiet="$option_quiet"
source "$DOROTHY/sources/environment.sh"
do_tea "$@"
do_pkgx "$@"
}

# ---------------------------------
Expand Down
Loading