Compare commits

..

1 Commits

Author SHA1 Message Date
AJ ONeal
77abc40e1f WIP: ref!(webi): cleanup for later 2023-11-12 02:30:09 -07:00
62 changed files with 785 additions and 1542 deletions

View File

@@ -16,22 +16,40 @@ export WEBI_CHECKSUM=06a7fb9f
# #
#########################################
# shellcheck disable=SC2005
fn_show_welcome() { (
echo ""
printf "%s %s\n" \
"$(t_strong 'Welcome to') $(t_stronger 'Webi')$(t_strong '!')" \
"$(t_dim "- Modern tools, instant installs.")"
echo "We expect your experience to be $(t_em 'absolutely perfect')!"
echo ""
# invert t_task and t_pkg for top-level welcome message
printf -- ">>> %s %s <<<\n" \
"$(t_pkg 'Welcome to') $(t_task 'Webi')$(t_pkg '!')" \
"$(t_dim "- modern tools, instant installs.")"
echo " We expect your experience to be $(t_em 'absolutely perfect')!"
echo " $(t_yellow 'Have a problem?') Please $(t_em 'let us know'):"
echo " $(t_url 'https://github.com/webinstall/webi-installers/issues')"
echo " $(t_dim "(your system is $(t_yellow "$(uname -s)")/$(t_yellow "$(uname -m)") with $(t_yellow "$(fn_get_libc)") & $(t_yellow "$(fn_get_http)"))")"
echo ""
echo " $(t_attn 'Success')? Star it! $(t_url 'https://github.com/webinstall/webi-installers')"
echo " $(t_attn 'Problem')? Report it: $(t_url 'https://github.com/webinstall/webi-installers/issues')"
echo " $(t_dim "(your system is") $(t_host "$(uname -s)")/$(t_host "$(uname -m)") $(t_dim "with") $(t_host "$(fn_get_libc)") $(t_dim "&") $(t_host "$(fn_get_http_client_name)")$(t_dim ")")"
echo " $(t_yellow 'Love it?') Star it!"
echo " $(t_url 'https://github.com/webinstall/webi-installers')"
sleep 0.2
); }
t_strong() { (printf '\e[36m%s\e[39m' "${1}"); }
t_stronger() { (printf '\e[1m\e[32m%s\e[39m\e[22m' "${1}"); }
t_url() { (printf '\e[2m%s\e[22m' "${1}"); }
t_path() { (printf '\e[2m\e[32m%s\e[39m\e[22m' "${1}"); }
t_cmd() { (printf '\e[2m\e[35m%s\e[39m\e[22m' "${1}"); }
t_err() { (printf '\e[31m%s\e[39m' "${1}"); }
t_bold() { (printf '\e[1m%s\e[22m' "${1}"); }
t_dim() { (printf '\e[2m%s\e[22m' "${1}"); }
t_em() { (printf '\e[3m%s\e[23m' "${1}"); }
t_under() { (printf '\e[4m%s\e[24m' "${1}"); }
t_green() { (printf '\e[32m%s\e[39m' "${1}"); }
t_yellow() { (printf '\e[33m%s\e[39m' "${1}"); }
t_magenta() { (printf '\e[35m%s\e[39m' "${1}"); }
t_cyan() { (printf '\e[36m%s\e[39m' "${1}"); }
fn_get_libc() { (
# Ex:
# musl
@@ -45,7 +63,7 @@ fn_get_libc() { (
fi
); }
fn_get_http_client_name() { (
fn_get_http() { (
# Ex:
# curl
# curl+wget
@@ -64,56 +82,6 @@ fn_get_http_client_name() { (
echo "${b_client}"
); }
#########################################
# #
# For Making the Display Nice #
# #
#########################################
# Term Types
t_cmd() { (fn_printf '\e[2m\e[35m%s\e[39m\e[22m' "${1}"); }
t_host() { (fn_printf '\e[2m\e[33m%s\e[39m\e[22m' "${1}"); }
t_link() { (fn_printf '\e[1m\e[36m%s\e[39m\e[22m' "${1}"); }
t_path() { (fn_printf '\e[2m\e[32m%s\e[39m\e[22m' "${1}"); }
t_pkg() { (fn_printf '\e[1m\e[32m%s\e[39m\e[22m' "${1}"); }
t_task() { (fn_printf '\e[36m%s\e[39m' "${1}"); }
t_url() { (fn_printf '\e[2m%s\e[22m' "${1}"); }
# Levels
t_info() { (fn_printf '\e[1m\e[36m%s\e[39m\e[22m' "${1}"); }
t_attn() { (fn_printf '\e[1m\e[33m%s\e[39m\e[22m' "${1}"); }
t_warn() { (fn_printf '\e[1m\e[33m%s\e[39m\e[22m' "${1}"); }
t_err() { (fn_printf '\e[31m%s\e[39m' "${1}"); }
# Styles
t_bold() { (fn_printf '\e[1m%s\e[22m' "${1}"); }
t_dim() { (fn_printf '\e[2m%s\e[22m' "${1}"); }
t_em() { (fn_printf '\e[3m%s\e[23m' "${1}"); }
t_under() { (fn_printf '\e[4m%s\e[24m' "${1}"); }
# FG Colors
t_cyan() { (fn_printf '\e[36m%s\e[39m' "${1}"); }
t_green() { (fn_printf '\e[32m%s\e[39m' "${1}"); }
t_magenta() { (fn_printf '\e[35m%s\e[39m' "${1}"); }
t_yellow() { (fn_printf '\e[33m%s\e[39m' "${1}"); }
fn_printf() { (
a_style="${1}"
a_text="${2}"
if fn_is_tty; then
#shellcheck disable=SC2059
printf -- "${a_style}" "${a_text}"
else
printf -- '%s' "${a_text}"
fi
); }
fn_sub_home() { (
my_rel=${HOME}
my_abs=${1}
echo "${my_abs}" | sed "s:^${my_rel}:~:"
); }
###################################
# #
# Detect HTTP Client #
@@ -127,7 +95,7 @@ fn_wget() { (
a_path="${2}"
cmd_wget="wget -q --user-agent"
if fn_is_tty; then
if fn_is_interactive; then
cmd_wget="wget -q --show-progress --user-agent"
fi
@@ -151,9 +119,9 @@ fn_curl() { (
a_url="${1}"
a_path="${2}"
cmd_curl="curl -f -sSL -#"
if fn_is_tty; then
cmd_curl="curl -f -sSL"
cmd_curl="curl --fail-with-body -sSL -#"
if fn_is_interactive; then
cmd_curl="curl --fail-with-body sSL"
fi
b_triple_ua="$(fn_get_target_triple_user_agent)"
@@ -170,6 +138,16 @@ fn_curl() { (
fi
); }
fn_is_interactive() {
# Ex:
# himBH
# hBc
case $- in
*i*) return 0 ;;
*) return 1 ;;
esac
}
fn_get_target_triple_user_agent() { (
# Ex:
# x86_64/unknown Linux/5.15.107-2-pve gnu
@@ -199,45 +177,31 @@ fn_download_to_path() { (
# #
##############################################
webi_bootstrap() { (
webi_upgrade() { (
a_path="${1}"
echo ""
echo "$(t_task 'Bootstrapping') $(t_pkg 'Webi')"
echo "$(t_strong 'Bootstrapping') $(t_stronger 'Webi')"
b_path_rel="$(fn_sub_home "${a_path}")"
b_checksum=""
if test -r "${a_path}"; then
echo " $(t_dim 'Found') $(t_path "${b_path_rel}")"
b_checksum="$(fn_checksum "${a_path}")"
fi
if test "$b_checksum" = "${WEBI_CHECKSUM}"; then
echo " $(t_dim 'Found') $(t_path "${b_path_rel}")"
sleep 0.1
return 0
fi
b_webi_file_url="${WEBI_HOST}/packages/webi/webi.sh"
b_tmp=''
if test -r "${a_path}"; then
b_ts="$(date -u '+%s')"
b_tmp="${a_path}.${b_ts}.bak"
mv "${a_path}" "${b_tmp}"
echo " Updating $(t_path "${b_path_rel}")"
fi
b_download_dir="$(dirname "${a_path}")"
if ! test -w "${b_download_dir}"; then
echo " Creating $(t_path "${b_download_dir}/")"
mkdir -p "${b_download_dir}"
fi
echo " Downloading $(t_url "${b_webi_file_url}")"
echo " to $(t_path "${b_path_rel}")"
fn_download_to_path "${b_webi_file_url}" "${a_path}"
chmod u+x "${a_path}"
if test -r "${b_tmp}"; then
rm -f "${b_tmp}"
fi
); }
fn_checksum() {
@@ -251,64 +215,29 @@ fn_checksum() {
$cmd_shasum "${a_filepath}" | cut -d' ' -f1 | cut -c 1-8
}
##############################################
# #
# Detect TTY and run main #
# #
##############################################
fn_is_tty() {
if test "${WEBI_TTY}" = 'tty'; then
return 0
fi
return 1
}
fn_detect_tty() { (
# stdin will NOT be a tty if it's being piped
# stdout & stderr WILL be a tty even when piped
# they are not a tty if being captured or redirected
# 'set -i' is NOT available in sh
if test -t 1 && test -t 2; then
return 0
fi
return 1
fn_sub_home() { (
my_rel=${HOME}
my_abs=${1}
echo "${my_abs}" | sed "s:^${my_rel}:~:"
); }
main() { (
set -e
set -u
WEBI_TTY="${WEBI_TTY:-}"
if test -z "${WEBI_TTY}"; then
if fn_detect_tty; then
WEBI_TTY="tty"
fi
export WEBI_TTY
fi
if test -z "${WEBI_WELCOME:-}"; then
fn_show_welcome
fi
export WEBI_WELCOME='shown'
fn_show_welcome
export WEBI_WELCOME=true
# note: we may support custom locations in the future
export WEBI_HOME="${HOME}/.local"
b_home="$(fn_sub_home "${WEBI_HOME}")"
b_webi_path="${WEBI_HOME}/bin/webi"
b_webi_path_rel="${b_home}/bin/webi"
webi_upgrade "${b_webi_path}"
WEBI_CURRENT="${WEBI_CURRENT:-}"
if test "${WEBI_CURRENT}" != "${WEBI_CHECKSUM}"; then
webi_bootstrap "${b_webi_path}"
export WEBI_CURRENT="${WEBI_CHECKSUM}"
fi
echo " Running $(t_cmd "${b_webi_path_rel} ${WEBI_PKG}")"
echo ""
echo "$(t_strong 'Installing') $(t_stronger "${WEBI_PKG}") $(t_strong '...')"
echo " Running $(t_cmd "${b_webi_path_rel} ${WEBI_PKG}")"
"${b_webi_path}" "${WEBI_PKG}"
); }
set -e
set -u
main

View File

@@ -69,7 +69,7 @@ function Invoke-DownloadUrl {
Write-Host " ?$Params"
$URL = "${URL}?${Params}"
}
curl.exe '-#' -f -sS -A $Env:WEBI_UA -L $URL | Out-File $TmpPath
curl.exe '-#' --fail-with-body -sS -A $Env:WEBI_UA $URL | Out-File $TmpPath
Remove-Item -Path $Path -Force -ErrorAction Ignore
Move-Item $TmpPath $Path

View File

@@ -1,10 +1,27 @@
#!/bin/sh
__bootstrap_webi() {
set -e
set -u
#set -x
my_libc=''
if ldd /bin/ls 2> /dev/null | grep -q 'musl' 2> /dev/null; then
my_libc='musl'
elif uname -o | grep -q 'GNU' || uname -s | grep -q 'Linux'; then
my_libc='gnu'
else
my_libc='libc'
fi
WEBI_UA="$(uname -s)/$(uname -r) $(uname -m)/unknown ${my_libc}"
#WEBI_PKG=
#PKG_NAME=
#WEBI_OS=
#WEBI_ARCH=
#WEBI_LIBC=
#WEBI_HOST=
#WEBI_RELEASES=
#WEBI_CSV=
#WEBI_TAG=
@@ -26,6 +43,7 @@ __bootstrap_webi() {
#PKG_ARCHES=
#PKG_LIBCS=
#PKG_FORMATS=
WEBI_UA="$(uname -s)/$(uname -r) $(uname -m)/unknown ${my_libc}"
WEBI_PKG_DOWNLOAD=""
WEBI_DOWNLOAD_DIR="${HOME}/Downloads"
if command -v xdg-user-dir > /dev/null; then
@@ -37,6 +55,43 @@ __bootstrap_webi() {
WEBI_PKG_PATH="${WEBI_DOWNLOAD_DIR}/webi/${PKG_NAME:-error}/${WEBI_VERSION:-latest}"
export WEBI_HOST
##
## Set up tmp, download, and install directories
##
WEBI_TMP=${WEBI_TMP:-"$(mktemp -d -t webinstall-"${WEBI_PKG-}".XXXXXXXX)"}
export _webi_tmp="${_webi_tmp:-"$HOME/.local/opt/webi-tmp.d"}"
mkdir -p "${WEBI_PKG_PATH}"
mkdir -p "$HOME/.local/bin"
mkdir -p "$HOME/.local/opt"
if test -e ~/.local/bin; then
echo "Found ~/.local/bin"
else
echo "Creating ~/.local/bin"
mkdir -p "$HOME/.local/bin"
fi
if test -e ~/.local/bin/webi; then
echo "Found ~/.local/bin/webi"
else
echo "Creating ~/.local/bin"
mkdir -p "$HOME/.local/bin"
fi
##
## Detect http client
##
set +e
WEBI_CURL="$(command -v curl)"
export WEBI_CURL
WEBI_WGET="$(command -v wget)"
export WEBI_WGET
set -e
# get the special formatted version
# (i.e. "go is go1.14" while node is "node v12.10.8")
my_versioned_name=""
@@ -87,30 +142,38 @@ __bootstrap_webi() {
if [ -n "$my_current_cmd" ]; then
my_canonical_name="$(_webi_canonical_name)"
if [ "$my_current_cmd" != "$pkg_dst_cmd" ]; then
echo >&2 " $(t_err "WARN: possible PATH conflict between $my_canonical_name and currently installed version")"
echo >&2 " $(t_path "${pkg_dst_cmd}") (new)"
echo >&2 " $(t_path "${my_current_cmd}") (existing)"
echo >&2 "WARN: possible PATH conflict between $my_canonical_name and currently installed version"
echo >&2 " ${pkg_dst_cmd} (new)"
echo >&2 " ${my_current_cmd} (existing)"
#my_current_version=false
fi
# 'readlink' can't read links in paths on macOS 🤦
# but that's okay, 'cmp -s' is good enough for us
if cmp -s "${pkg_src_cmd}" "${my_current_cmd}"; then
echo " $(t_pkg "${my_canonical_name}") already installed:"
my_dst_rel="$(fn_sub_home "${pkg_dst}")"
printf " %s" "$(t_link "${my_dst_rel}")"
echo "${my_canonical_name} already installed:"
my_dst_rel="$(
webi_sub_home "${pkg_dst}"
)"
printf " %s" "${my_dst_rel}"
if [ "${pkg_src_cmd}" != "${my_current_cmd}" ]; then
my_src_rel="$(fn_sub_home "${pkg_src}")"
printf " => %s" "$(t_path "${my_src_rel}")"
my_src_rel="$(
webi_sub_home "${pkg_src}"
)"
printf " => %s" "${my_src_rel}"
fi
echo ""
exit 0
fi
if [ -x "$pkg_src_cmd" ]; then
webi_link
echo " Switched to ${my_canonical_name}:"
my_src_rel="$(fn_sub_home "${pkg_src}")"
my_dst_rel="$(fn_sub_home "${pkg_dst}")"
echo " $(t_link "${my_dst_rel}") => $(t_path "${my_src_rel}")"
echo "switched to $my_canonical_name:"
my_src_rel="$(
webi_sub_home "${pkg_src}"
)"
my_dst_rel="$(
webi_sub_home "${pkg_dst}"
)"
echo " ${my_dst_rel} => ${my_src_rel}"
exit 0
fi
fi
@@ -122,61 +185,110 @@ __bootstrap_webi() {
return 0
fi
{
echo ""
echo " $(t_err "Error: no '${PKG_NAME:-"Unknown Package"}@${WEBI_TAG:-"Unknown Tag"}' release for '${WEBI_OS:-"Unknown OS"}' (${WEBI_LIBC:-"Unknown Libc"}) on '${WEBI_ARCH:-"Unknown CPU"}' as one of '${WEBI_FORMATS:-"Unknown File Type"}'")"
echo " '$PKG_NAME' is available for '$PKG_OSES' ($PKG_LIBCS) on '$PKG_ARCHES' as one of '$PKG_FORMATS'"
echo " (check that the package name and version are correct)"
echo ""
my_release_url="$(echo "$WEBI_RELEASES" | sed 's:?.*::')"
my_release_params="$(echo "$WEBI_RELEASES" | sed 's:.*?:?:')"
echo " Double check at ${my_release_url}"
echo " ${my_release_params}"
echo ""
} >&2
echo >&2 "Error: no '${PKG_NAME:-"Unknown Package"}@${WEBI_TAG:-"Unknown Tag"}' release for '${WEBI_OS:-"Unknown OS"}' (${WEBI_LIBC:-"Unknown Libc"}) on '${WEBI_ARCH:-"Unknown CPU"}' as one of '${WEBI_FORMATS:-"Unknown File Type"}'"
echo >&2 " '$PKG_NAME' is available for '$PKG_OSES' ($PKG_LIBCS) on '$PKG_ARCHES' as one of '$PKG_FORMATS'"
echo >&2 " (check that the package name and version are correct)"
echo >&2 ""
my_release_url="$(
echo "$WEBI_RELEASES" |
sed 's:?.*::'
)"
my_release_params="$(
echo "$WEBI_RELEASES" |
sed 's:.*?:?:'
)"
echo >&2 " Double check at ${my_release_url}"
echo >&2 " ${my_release_params}"
echo >&2 ""
exit 1
}
is_interactive_shell() {
# $- shows shell flags (error,unset,interactive,etc)
case $- in
*i*) return 0 ;;
*) return 1 ;;
esac
}
webi_sub_home() { (
my_rel=${HOME}
my_abs=${1}
echo "${my_abs}" | sed "s:^${my_rel}:~:"
); }
# detect if file is downloaded, and how to download it
webi_download() {
my_url="${1}"
my_dl="${2}"
my_dl_name="${3:-${PKG_NAME}}"
my_dl_rel="$(fn_sub_home "${my_dl}")"
my_dl_rel="$(
webi_sub_home "${my_dl}"
)"
WEBI_PKG_DOWNLOAD="${my_dl}"
export WEBI_PKG_DOWNLOAD
if [ -e "${my_dl}" ]; then
echo " $(t_dim 'Found') $(t_path "${my_dl_rel}")"
echo "Found ${my_dl_rel}"
return 0
fi
echo " Downloading $(t_pkg "${my_dl_name}") from"
echo " $(t_url "${my_url}")"
fn_download_to_path "${my_url}" "${my_dl}"
echo " $(t_dim 'Saved as') $(t_path "${my_dl_rel}")"
echo "Downloading ${my_dl_name} from"
echo "$my_url"
# It's only 2020, we can't expect to have reliable CLI tools
# to tell us the size of a file as part of a base system...
if [ -n "$WEBI_WGET" ]; then
# wget has resumable downloads
# TODO wget -c --content-disposition "$my_url"
set +e
my_show_progress=""
if is_interactive_shell; then
my_show_progress="--show-progress"
fi
if ! wget -q $my_show_progress --user-agent="wget $WEBI_UA" -c "$my_url" -O "$my_dl.part"; then
echo >&2 "failed to download from $WEBI_PKG_URL"
exit 1
fi
set -e
else
# Neither GNU nor BSD curl have sane resume download options, hence we don't bother
my_show_progress="-#"
if is_interactive_shell; then
my_show_progress=""
fi
# shellcheck disable=SC2086
# we want the flags to be split
curl -fSL $my_show_progress -H "User-Agent: curl $WEBI_UA" "$my_url" -o "$my_dl.part"
fi
mv "$my_dl.part" "$my_dl"
echo ""
echo "Saved as ${my_dl_rel}"
}
webi_git_clone() { (
my_url="${1}"
my_dl="${2}"
my_dl_rel="$(fn_sub_home "${my_dl}")"
my_dl_rel="$(
webi_sub_home "${my_dl}"
)"
if [ -e "${my_dl}" ]; then
echo " $(t_dim 'Found') $(t_path "${my_dl_rel}")"
echo "Found ${my_dl_rel}"
cp -RPp "${my_dl}" "${WEBI_TMP}/${WEBI_PKG_FILE}/"
return 0
fi
echo " Cloning $(t_url "${my_url}")"
echo "Cloning ${my_url}"
cmd_git="git clone --config advice.detachedHead=false --quiet --depth=1 --single-branch"
rm -rf "${my_dl}.part"
if ! $cmd_git "${my_url}" --branch "${WEBI_GIT_TAG}" "${my_dl}.part"; then
echo >&2 " $(t_err "failed to git clone ${WEBI_PKG_URL}")"
echo >&2 "failed to git clone ${WEBI_PKG_URL}"
exit 1
fi
mv "${my_dl}.part" "${my_dl}"
@@ -185,33 +297,34 @@ __bootstrap_webi() {
); }
# detect which archives can be used
webi_extract() { (
cd "$WEBI_TMP"
webi_extract() {
(
cd "$WEBI_TMP"
my_dl_rel="$(
fn_sub_home "${WEBI_PKG_PATH}/${WEBI_PKG_FILE}"
)"
if [ "tar" = "$WEBI_EXT" ]; then
echo " Extracting $(t_path "${my_dl_rel}")"
tar xf "${WEBI_PKG_PATH}/$WEBI_PKG_FILE"
elif [ "zip" = "$WEBI_EXT" ]; then
echo " Extracting $(t_path "${my_dl_rel}")"
unzip "${WEBI_PKG_PATH}/$WEBI_PKG_FILE" > __unzip__.log
elif [ "exe" = "$WEBI_EXT" ]; then
echo " Moving $(t_path "${my_dl_rel}")"
echo " to $(t_path "$(fn_sub_home "$(pwd)")")"
mv "${WEBI_PKG_PATH}/$WEBI_PKG_FILE" .
elif [ "git" = "$WEBI_EXT" ]; then
echo " Moving $(t_path "${my_dl_rel}")"
mv "${WEBI_PKG_PATH}/$WEBI_PKG_FILE" .
elif [ "xz" = "$WEBI_EXT" ]; then
echo " Inflating $(t_path "${my_dl_rel}")"
unxz -c "${WEBI_PKG_PATH}/$WEBI_PKG_FILE" > "$(basename "$WEBI_PKG_FILE")"
else
echo " $(t_err 'Failed to extract') $(t_path "${WEBI_PKG_PATH}/$WEBI_PKG_FILE")"
exit 1
fi
); }
my_dl_rel="$(
webi_sub_home "${WEBI_PKG_PATH}/${WEBI_PKG_FILE}"
)"
if [ "tar" = "$WEBI_EXT" ]; then
echo "Extracting ${my_dl_rel}"
tar xf "${WEBI_PKG_PATH}/$WEBI_PKG_FILE"
elif [ "zip" = "$WEBI_EXT" ]; then
echo "Extracting ${my_dl_rel}"
unzip "${WEBI_PKG_PATH}/$WEBI_PKG_FILE" > __unzip__.log
elif [ "exe" = "$WEBI_EXT" ]; then
echo "Moving ${my_dl_rel}"
mv "${WEBI_PKG_PATH}/$WEBI_PKG_FILE" .
elif [ "git" = "$WEBI_EXT" ]; then
echo "Moving ${my_dl_rel}"
mv "${WEBI_PKG_PATH}/$WEBI_PKG_FILE" .
elif [ "xz" = "$WEBI_EXT" ]; then
echo "Inflating ${my_dl_rel}"
unxz -c "${WEBI_PKG_PATH}/$WEBI_PKG_FILE" > "$(basename "$WEBI_PKG_FILE")"
else
echo "Failed to extract ${WEBI_PKG_PATH}/$WEBI_PKG_FILE"
exit 1
fi
)
}
# use 'pathman' to update $HOME/.config/envman/PATH.env
webi_path_add() {
@@ -409,19 +522,13 @@ __bootstrap_webi() {
# move commands from the extracted archive directory
# to $HOME/.local/opt or $HOME/.local/bin
webi_install() {
b_src=''
if test -n "${WEBI_SINGLE}"; then
b_src="${pkg_src_cmd}"
mkdir -p "$(dirname "$pkg_src_cmd")"
mv ./"$pkg_cmd_name"* "$pkg_src_cmd"
else
echo " Removing $(t_path "${pkg_src}")"
rm -rf "$pkg_src"
b_src="${pkg_src}"
mv ./"$pkg_cmd_name"* "$pkg_src"
fi
echo " Moving $(t_path "${pkg_cmd_name}")"
echo " to $(t_path "$(fn_sub_home "${b_src}")")"
mv ./"${pkg_cmd_name}"* "${b_src}"
}
# run post-install functions - just updating PATH by default
@@ -442,30 +549,15 @@ __bootstrap_webi() {
}
_webi_done_message() {
my_dst_rel="$(fn_sub_home "${pkg_dst_cmd}")"
my_canonical_name="$(_webi_canonical_name)"
echo ""
echo " Installed $(t_pkg "${my_canonical_name}") as $(t_link "${my_dst_rel}")"
my_dst_rel="$(
webi_sub_home "${pkg_dst_cmd}"
)"
my_canonical_name="$(
_webi_canonical_name
)"
echo "Installed ${my_canonical_name} as ${my_dst_rel}"
}
##
## Set up tmp, download, and install directories
##
WEBI_TMP=${WEBI_TMP:-"$(mktemp -d -t webinstall-"${WEBI_PKG-}".XXXXXXXX)"}
export _webi_tmp="${_webi_tmp:-"$HOME/.local/opt/webi-tmp.d"}"
mkdir -p "${WEBI_PKG_PATH}"
mkdir -p "$HOME/.local/bin"
mkdir -p "$HOME/.local/opt"
if test -e ~/.local/bin; then
echo " $(t_dim 'Found') $(t_path ' ~/.local/bin')"
else
echo " Creating$(t_path ' ~/.local/bin')"
mkdir -p "$HOME/.local/bin"
fi
##
##
## BEGIN custom override functions from <package>/install.sh
@@ -474,6 +566,20 @@ __bootstrap_webi() {
WEBI_SINGLE=
if [ -z "${WEBI_WELCOME-}" ]; then
echo ""
printf "Thanks for using webi to install '\e[32m%s\e[0m' on '\e[33m%s (%s) %s\e[0m'.\n" "${WEBI_PKG:-"Unknown Package"}" "$(uname -s)" "${WEBI_LIBC:-"Unknown Libc"}" "$(uname -m)"
echo "Have a problem? Experience a bug? Please let us know:"
printf " \e[2m\e[36mhttps://github.com/webinstall/webi-installers/issues\e[0m\n"
echo ""
printf "\e[35mLovin'\e[0m it? Say thanks with a \e[1m\e[33mStar on GitHub\e[0m:\n"
printf " \e[36mhttps://github.com/webinstall/webi-installers\e[0m\n"
echo ""
fi
WEBI_WELCOME=true
export WEBI_WELCOME
__init_installer() {
# the installer will be injected here
# {{ installer }}
@@ -536,12 +642,12 @@ __bootstrap_webi() {
(
cd "$WEBI_TMP"
my_src_rel="$(
fn_sub_home "${pkg_src_cmd}"
webi_sub_home "${pkg_src_cmd}"
)"
if test -e "${pkg_src_cmd}"; then
echo " $(t_dim 'Found') $(t_path "${my_src_rel}") $(t_dim '(remove to force reinstall)')"
echo "Found ${my_src_rel} (remove to force reinstall)"
else
echo " Installing to $(t_path "${my_src_rel}")"
echo "Installing to ${my_src_rel}"
if command -v pkg_install > /dev/null; then pkg_install; else webi_install; fi
chmod a+x "$pkg_src"
chmod a+x "$pkg_src_cmd"
@@ -568,328 +674,22 @@ __bootstrap_webi() {
webi_path_add "$HOME/.local/bin"
if [ -z "${_WEBI_CHILD-}" ] && [ -f "$_webi_tmp/.PATH.env" ]; then
if test -s "$_webi_tmp/.PATH.env"; then
# shellcheck disable=SC2088 # ~ should not expand here
echo " Updated $(t_path '~/.config/envman/PATH.env') updated with:"
printf 'PATH.env updated with:\n'
sort -u "$_webi_tmp/.PATH.env" | while read -r my_new_path; do
echo " $(t_path "${my_new_path}")"
echo " ${my_new_path}"
done
echo ""
printf "\n"
rm -f "$_webi_tmp/.PATH.env"
echo ">>> $(t_attn 'ACTION REQUIRED') <<<"
echo ""
echo " Copy, paste & run the following command:"
echo " $(t_attn 'source ~/.config/envman/PATH.env')"
echo " (newly opened terminal windows will update automatically)"
echo ""
echo "^^^ $(t_attn 'ACTION REQUIRED') ^^^"
printf "\e[1m\e[35mTO FINISH\e[0m: copy, paste & run the following command:\n"
printf "\n"
printf " \e[1m\e[32msource ~/.config/envman/PATH.env\e[0m\n"
printf " (newly opened terminal windows will update automatically)\n"
fi
fi
rm -rf "$WEBI_TMP"
}
#########################################
# #
# Display Debug Info in Case of Failure #
# #
#########################################
fn_show_welcome_back() { (
if test -n "${WEBI_WELCOME:-}"; then
return 0
fi
echo ""
# invert t_task and t_pkg for top-level welcome message
printf -- ">>> %s %s <<<\n" \
"$(t_pkg 'Welcome to') $(t_task 'Webi')$(t_pkg '!')" \
"$(t_dim "- modern tools, instant installs.")"
echo " We expect your experience to be $(t_em 'absolutely perfect')!"
echo ""
echo " $(t_attn 'Success')? Star it! $(t_url 'https://github.com/webinstall/webi-installers')"
echo " $(t_attn 'Problem')? Report it: $(t_url 'https://github.com/webinstall/webi-installers/issues')"
echo " $(t_dim "(your system is") $(t_host "$(uname -s)")/$(t_host "$(uname -m)") $(t_dim "with") $(t_host "$(fn_get_libc)") $(t_dim "&") $(t_host "$(fn_get_http_client_name)")$(t_dim ")")"
sleep 0.2
); }
fn_get_libc() { (
# Ex:
# musl
# libc
if ldd /bin/ls 2> /dev/null | grep -q 'musl' 2> /dev/null; then
echo 'musl'
elif uname -o | grep -q 'GNU' || uname -s | grep -q 'Linux'; then
echo 'gnu'
else
echo 'libc'
fi
); }
fn_get_http_client_name() { (
# Ex:
# curl
# curl+wget
b_client=""
if command -v curl > /dev/null; then
b_client="curl"
fi
if command -v wget > /dev/null; then
if test -z "${b_client}"; then
b_client="wget"
else
b_client="curl+wget"
fi
fi
echo "${b_client}"
); }
#########################################
# #
# For Making the Display Nice #
# #
#########################################
# Term Types
t_cmd() { (fn_printf '\e[2m\e[35m%s\e[39m\e[22m' "${1}"); }
t_host() { (fn_printf '\e[2m\e[33m%s\e[39m\e[22m' "${1}"); }
t_link() { (fn_printf '\e[1m\e[36m%s\e[39m\e[22m' "${1}"); }
t_path() { (fn_printf '\e[2m\e[32m%s\e[39m\e[22m' "${1}"); }
t_pkg() { (fn_printf '\e[1m\e[32m%s\e[39m\e[22m' "${1}"); }
t_task() { (fn_printf '\e[36m%s\e[39m' "${1}"); }
t_url() { (fn_printf '\e[2m%s\e[22m' "${1}"); }
# Levels
t_info() { (fn_printf '\e[1m\e[36m%s\e[39m\e[22m' "${1}"); }
t_attn() { (fn_printf '\e[1m\e[33m%s\e[39m\e[22m' "${1}"); }
t_warn() { (fn_printf '\e[1m\e[33m%s\e[39m\e[22m' "${1}"); }
t_err() { (fn_printf '\e[31m%s\e[39m' "${1}"); }
# Styles
t_bold() { (fn_printf '\e[1m%s\e[22m' "${1}"); }
t_dim() { (fn_printf '\e[2m%s\e[22m' "${1}"); }
t_em() { (fn_printf '\e[3m%s\e[23m' "${1}"); }
t_under() { (fn_printf '\e[4m%s\e[24m' "${1}"); }
# FG Colors
t_cyan() { (fn_printf '\e[36m%s\e[39m' "${1}"); }
t_green() { (fn_printf '\e[32m%s\e[39m' "${1}"); }
t_magenta() { (fn_printf '\e[35m%s\e[39m' "${1}"); }
t_yellow() { (fn_printf '\e[33m%s\e[39m' "${1}"); }
fn_printf() { (
a_style="${1}"
a_text="${2}"
if fn_is_tty; then
#shellcheck disable=SC2059
printf -- "${a_style}" "${a_text}"
else
printf -- '%s' "${a_text}"
fi
); }
fn_sub_home() { (
my_rel=${HOME}
my_abs=${1}
echo "${my_abs}" | sed "s:^${my_rel}:~:"
); }
###################################
# #
# Detect HTTP Client #
# #
###################################
fn_wget() { (
# Doc:
# Downloads the file at the given url to the given path
a_url="${1}"
a_path="${2}"
cmd_wget="wget -q --user-agent"
if fn_is_tty; then
cmd_wget="wget -q --show-progress --user-agent"
fi
b_triple_ua="$(fn_get_target_triple_user_agent)"
b_agent="webi/wget ${b_triple_ua}"
if command -v curl > /dev/null; then
b_agent="webi/wget+curl ${b_triple_ua}"
fi
if ! $cmd_wget "${b_agent}" -c "${a_url}" -O "${a_path}"; then
echo >&2 " $(t_err "failed to download (wget)") '$(t_url "${a_url}")'"
echo >&2 " $cmd_wget '${b_agent}' -c '${a_url}' -O '${a_path}'"
echo >&2 " $(wget -V)"
return 1
fi
); }
fn_curl() { (
# Doc:
# Downloads the file at the given url to the given path
a_url="${1}"
a_path="${2}"
cmd_curl="curl -f -sSL -#"
if fn_is_tty; then
cmd_curl="curl -f -sSL"
fi
b_triple_ua="$(fn_get_target_triple_user_agent)"
b_agent="webi/curl ${b_triple_ua}"
if command -v wget > /dev/null; then
b_agent="webi/curl+wget ${b_triple_ua}"
fi
if ! $cmd_curl -A "${b_agent}" "${a_url}" -o "${a_path}"; then
echo >&2 " $(t_err "failed to download (curl)") '$(t_url "${a_url}")'"
echo >&2 " $cmd_curl -A '${b_agent}' '${a_url}' -o '${a_path}'"
echo >&2 " $(curl -V)"
return 1
fi
); }
fn_get_target_triple_user_agent() { (
# Ex:
# x86_64/unknown Linux/5.15.107-2-pve gnu
# arm64/unknown Darwin/22.6.0 libc
echo "$(uname -m)/unknown $(uname -s)/$(uname -r) $(fn_get_libc)"
); }
fn_download_to_path() { (
a_url="${1}"
a_path="${2}"
mkdir -p "$(dirname "${a_path}")"
if command -v wget > /dev/null; then
fn_wget "${a_url}" "${a_path}.part"
elif command -v curl > /dev/null; then
fn_curl "${a_url}" "${a_path}.part"
else
echo >&2 " $(t_err "failed to detect HTTP client (curl, wget)")"
return 1
fi
mv "${a_path}.part" "${a_path}"
); }
##############################################
# #
# Install or Update Webi and Install Package #
# #
##############################################
webi_upgrade() { (
a_path="${1}"
b_path_rel="$(fn_sub_home "${a_path}")"
b_checksum=""
if test -r "${a_path}"; then
b_checksum="$(fn_checksum "${a_path}")"
fi
if test "$b_checksum" = "${WEBI_CHECKSUM}"; then
sleep 0.1
return 0
fi
b_webi_file_url="${WEBI_HOST}/packages/webi/webi.sh"
b_tmp=''
if test -r "${a_path}"; then
b_ts="$(date -u '+%s')"
b_tmp="${a_path}.${b_ts}.bak"
mv "${a_path}" "${b_tmp}"
echo ""
echo "$(t_task 'Updating') $(t_pkg 'Webi')"
fi
b_download_dir="$(dirname "${a_path}")"
if ! test -w "${b_download_dir}"; then
echo " Creating $(t_path "${b_download_dir}/")"
mkdir -p "${b_download_dir}"
fi
echo " Downloading $(t_url "${b_webi_file_url}")"
echo " to $(t_path "${b_path_rel}")"
fn_download_to_path "${b_webi_file_url}" "${a_path}"
chmod u+x "${a_path}"
if test -r "${b_tmp}"; then
rm -f "${b_tmp}"
fi
); }
fn_checksum() {
a_filepath="${1}"
cmd_shasum='sha1sum'
if command -v shasum > /dev/null; then
cmd_shasum='shasum'
fi
$cmd_shasum "${a_filepath}" | cut -d' ' -f1 | cut -c 1-8
}
##############################################
# #
# Detect TTY and run main #
# #
##############################################
fn_is_tty() {
if test "${WEBI_TTY}" = 'tty'; then
return 0
fi
return 1
}
fn_detect_tty() { (
# stdin will NOT be a tty if it's being piped
# stdout & stderr WILL be a tty even when piped
# they are not a tty if being captured or redirected
# 'set -i' is NOT available in sh
if test -t 1 && test -t 2; then
return 0
fi
return 1
); }
main() { (
set -e
set -u
#set -x
export WEBI_HOST=
export WEBI_CHECKSUM=
export WEBI_PKG=
WEBI_TTY="${WEBI_TTY:-}"
if test -z "${WEBI_TTY}"; then
if fn_detect_tty; then
WEBI_TTY="tty"
fi
export WEBI_TTY
fi
if test -z "${WEBI_WELCOME:-}"; then
fn_show_welcome_back
fi
export WEBI_WELCOME='shown'
# note: we may support custom locations in the future
export WEBI_HOME="${HOME}/.local"
b_webi_path="${WEBI_HOME}/bin/webi"
WEBI_CURRENT="${WEBI_CURRENT:-}"
if test "${WEBI_CURRENT}" != "${WEBI_CHECKSUM}"; then
webi_upgrade "${b_webi_path}"
export WEBI_CURRENT="${WEBI_CHECKSUM}"
fi
echo "$(t_task 'Installing') $(t_pkg "${WEBI_PKG}") $(t_task '...')"
__bootstrap_webi
); }
main
__bootstrap_webi

View File

@@ -29,14 +29,14 @@ formats.forEach(function (name) {
// evaluation order matters
// (i.e. otherwise x86 and x64 can cross match)
var arches = [
// arm64/aarch64 has very high specificity, so it comes first
'arm64',
// arm 7 is also generic aarch/arm/arm32
// arm 7 cannot be confused with arm64
'armv7l',
// arm6 can run on armv7
'armv6l',
// amd64 is more likely and less often specified than arm64
// amd64 is more likely than arm64
'amd64',
// arm6 has the same prefix as arm64
'armv6l',
// arm64 is more likely than arm6, and should be the default
'arm64',
'x86',
'ppc64le',
'ppc64',
@@ -50,13 +50,13 @@ var arches = [
// https://git.com/org/foo/releases/v0.7.9/foo-x86_64-linux-musl.tar.gz
//
var archMap = {
arm64: /(\b|_)(aarch64|arm64)/i,
armv7l: /(\b|_)(arm32|arm[_\-]?v?7l?)/i,
armv6l: /(\b|_)(arm|aarch32|arm[_\-]?v?6l?)(\b|_)/i,
armv7l: /(\b|_)(arm32|armv?7l?)/i,
//amd64: /(amd.?64|x64|[_\-]64)/i,
amd64:
/(\b|_|amd|(dar)?win(dows)?|mac(os)?|linux|osx|x)64([_\-]?bit)?(\b|_)/i,
//x86: /(86)(\b|_)/i,
armv6l: /(\b|_)(aarch32|armv?6l?)(\b|_)/i,
arm64: /(\b|_)((aarch|arm)64|arm)/i,
x86: /(\b|_|amd|(dar)?win(dows)?|mac(os)?|linux|osx|x)(86|32)([_\-]?bit)(\b|_)/i,
ppc64le: /(\b|_)(ppc64le)/i,
ppc64: /(\b|_)(ppc64)(\b|_)/i,

View File

@@ -1,10 +1,8 @@
'use strict';
var Crypto = require('crypto');
var Fs = require('node:fs/promises');
var fs = require('node:fs');
var path = require('node:path');
var request = require('@root/request');
var _normalize = require('../_webi/normalize.js');
var reInstallTpl = /\s*#?\s*{{ installer }}/;
@@ -41,7 +39,10 @@ Releases.renderBash = async function (
if (!tag) {
tag = '';
}
let installTxt = await Fs.readFile(path.join(pkgdir, 'install.sh'), 'utf8');
let installTxt = await fs.promises.readFile(
path.join(pkgdir, 'install.sh'),
'utf8',
);
installTxt = padScript(installTxt);
var vers = rel.version.split('.');
var v = {
@@ -54,8 +55,8 @@ Releases.renderBash = async function (
.replace(/^-/, ''),
};
var pkgFile = rel.filename || rel.name;
let tplTxt = await Fs.readFile(
path.join(__dirname, 'package-install.tpl.sh'),
let tplTxt = await fs.promises.readFile(
path.join(__dirname, 'install-package.tpl.sh'),
'utf8',
);
// ex: 'node@lts' or 'node'
@@ -89,10 +90,7 @@ Releases.renderBash = async function (
]
.join(',')
.replace(/'/g, '');
let webiChecksum = await Releases.getWebiShChecksum();
let envReplacements = [
['WEBI_CHECKSUM', webiChecksum],
['WEBI_PKG', webiPkg],
['WEBI_HOST', baseurl],
['WEBI_OS', os],
@@ -129,7 +127,7 @@ Releases.renderBash = async function (
// #export WEBI_FOO=xyz => export WEBI_FOO='123'
// export WEBI_FOO= => export WEBI_FOO='123'
let envRe = new RegExp(
`^[ \\t]*#?[ \\t]*(export[ \\t])?[ \\t]*(${name})=.*`,
`^[ \\t]*#?[ \\t]*(export\\s)?[ \\t]*(${name})=.*`,
'm',
);
if (BAD_SH_RE.test(value)) {
@@ -158,7 +156,10 @@ Releases.renderPowerShell = async function (
if (!tag) {
tag = '';
}
let installTxt = await Fs.readFile(path.join(pkgdir, 'install.ps1'), 'utf8');
let installTxt = await fs.promises.readFile(
path.join(pkgdir, 'install.ps1'),
'utf8',
);
installTxt = padScript(installTxt);
/*
var vers = rel.version.split('.');
@@ -172,8 +173,8 @@ Releases.renderPowerShell = async function (
.replace(/^-/, '')
};
*/
let tplTxt = await Fs.readFile(
path.join(__dirname, 'package-install.tpl.ps1'),
let tplTxt = await fs.promises.readFile(
path.join(__dirname, 'install-package.tpl.ps1'),
'utf8',
);
var pkgver = pkg + '@' + ver;
@@ -217,32 +218,3 @@ Releases.renderPowerShell = async function (
.replace(reInstallTpl, '\n' + installTxt)
);
};
var _webiShMeta = {
stale: 10 * 1000,
updated_at: 0,
checksum: '',
mtime: 0,
};
Releases.getWebiShChecksum = async function () {
let now = Date.now();
let ago = now - _webiShMeta.updated_at;
if (ago <= _webiShMeta.stale) {
return _webiShMeta.checksum;
}
let webiPath = path.join(__dirname, '../webi/webi.sh');
let stat = await Fs.stat(webiPath);
if (stat.mtimeMs === _webiShMeta.mtime) {
return _webiShMeta.checksum;
}
let webiBuf = await Fs.readFile(webiPath, null);
let webiHash = Crypto.createHash('sha1').update(webiBuf).digest('hex');
let webiChecksum = webiHash.slice(0, 8);
_webiShMeta.mtime = stat.mtimeMs;
_webiShMeta.updated_at = now;
_webiShMeta.checksum = webiChecksum;
return _webiShMeta.checksum;
};

View File

@@ -2,6 +2,7 @@
var Installers = module.exports;
var Crypto = require('crypto');
var Fs = require('fs/promises');
var path = require('path');
@@ -135,7 +136,7 @@ Installers.getPosixCurlPipeBootstrap = async function ({ baseurl, pkg, ver }) {
let bootTxt = await Fs.readFile(CURL_PIPE_SH_BOOT, 'utf8');
var webiPkg = [pkg, ver].filter(Boolean).join('@');
var webiChecksum = await Releases.getWebiShChecksum();
var webiChecksum = await Installers.getWebiShChecksum();
var envReplacements = [
['WEBI_PKG', webiPkg],
['WEBI_HOST', baseurl],
@@ -148,7 +149,7 @@ Installers.getPosixCurlPipeBootstrap = async function ({ baseurl, pkg, ver }) {
// TODO create REs once, in higher scope
let envRe = new RegExp(
`^[ \\t]*#?[ \\t]*(export[ \\t])?[ \\t]*(${name})=.*`,
`^[ \\t]*#?[ \\t]*(export\\s)?[ \\t]*(${name})=.*`,
'm',
);
@@ -173,7 +174,7 @@ Installers.getPwshCurlPipeBootstrap = async function ({
let bootTxt = await Fs.readFile(CURL_PIPE_PS1_BOOT, 'utf8');
var webiPkg = [pkg, ver].filter(Boolean).join('@');
//var webiChecksum = await Releases.getWebiPs1Checksum();
//var webiChecksum = await Installers.getWebiPs1Checksum();
var envReplacements = [
['Env:WEBI_PKG', webiPkg],
['Env:WEBI_HOST', baseurl],
@@ -208,3 +209,32 @@ Installers.getPwshCurlPipeBootstrap = async function ({
return bootTxt;
};
var _webiShMeta = {
stale: 10 * 1000,
updated_at: 0,
checksum: '',
mtime: 0,
};
Installers.getWebiShChecksum = async function () {
let now = Date.now();
let ago = now - _webiShMeta.updated_at;
if (ago <= _webiShMeta.stale) {
return _webiShMeta.checksum;
}
let webiPath = path.join(__dirname, '../webi/webi.sh');
let stat = await Fs.stat(webiPath);
if (stat.mtimeMs === _webiShMeta.mtime) {
return _webiShMeta.checksum;
}
let webiBuf = await Fs.readFile(webiPath, null);
let webiHash = Crypto.createHash('sha1').update(webiBuf).digest('hex');
let webiChecksum = webiHash.slice(0, 8);
_webiShMeta.mtime = stat.mtimeMs;
_webiShMeta.updated_at = now;
_webiShMeta.checksum = webiChecksum;
return _webiShMeta.checksum;
};

View File

@@ -278,16 +278,7 @@ module.exports = function getReleases({
console.error(err);
})
.then(function (releases) {
if (releases.length) {
return {
oses: all.oses,
arches: all.arches,
libcs: all.libcs,
formats: all.formats,
releases: releases,
};
}
if (_count < 1) {
if (!releases.length) {
// Apple Silicon M1 hacky-do workaround fix
if ('macos' === os && 'arm64' === arch) {
return getReleases({
@@ -316,7 +307,23 @@ module.exports = function getReleases({
limit,
});
}
// Raspberry Pi 3+ on Raspbian x86 (not Ubuntu arm64)
if (!_count && 'linux' === os && 'armv7l' === arch) {
return getReleases({
_count: _count + 1,
pkg,
ver,
os,
arch: 'arm64',
libc,
lts,
channel,
formats,
limit,
});
}
// Raspberry Pi 3+ on Ubuntu arm64 (via Bionic?)
// (this may be the same as the prior search, that's okay)
if ('linux' === os && 'arm64' === arch) {
return getReleases({
_count: _count + 1,
@@ -331,7 +338,7 @@ module.exports = function getReleases({
limit,
});
}
// armv7 can run armv6
// Raspberry Pi 3+ on Ubuntu arm64 (via Bionic?)
if ('linux' === os && 'armv7l' === arch) {
return getReleases({
_count: _count + 1,
@@ -346,43 +353,25 @@ module.exports = function getReleases({
limit,
});
}
releases = [
{
name: 'doesntexist.ext',
version: '0.0.0',
lts: '-',
channel: 'error',
date: '1970-01-01',
os: os || '-',
arch: arch || '-',
libc: libc || '-',
ext: 'err',
download: 'https://example.com/doesntexist.ext',
comment:
'No matches found. Could be bad or missing version info' +
',' +
"Check query parameters. Should be something like '/api/releases/{package}@{version}.tab?os={macos|linux|windows|-}&arch={amd64|x86|aarch64|arm64|armv7l|-}&libc={musl|gnu|msvc|libc|static}&limit=10'",
},
];
}
if (_count < 2) {
// Raspberry Pi 3+ on Raspbian arm7 (not Ubuntu arm64)
// hail mary
if ('linux' === os && 'armv7l' === arch) {
return getReleases({
_count: _count + 1,
pkg,
ver,
os,
arch: 'arm64',
libc,
lts,
channel,
formats,
limit,
});
}
}
releases = [
{
name: 'doesntexist.ext',
version: '0.0.0',
lts: '-',
channel: 'error',
date: '1970-01-01',
os: os || '-',
arch: arch || '-',
libc: libc || '-',
ext: 'err',
download: 'https://example.com/doesntexist.ext',
comment:
'No matches found. Could be bad or missing version info' +
',' +
"Check query parameters. Should be something like '/api/releases/{package}@{version}.tab?os={macos|linux|windows|-}&arch={amd64|x86|aarch64|arm64|armv7l|-}&libc={musl|gnu|msvc|libc|static}&limit=10'",
},
];
return {
oses: all.oses,
arches: all.arches,

View File

@@ -69,7 +69,7 @@ function getArch(ua) {
return 'arm64';
} else if (/aarch|arm7|armv7|arm32/i.test(ua)) {
return 'armv7l';
} else if (/arm6|armv6|arm(\b|_)/i.test(ua)) {
} else if (/arm6|armv6/i.test(ua)) {
return 'armv6l';
} else if (/ppc64le/i.test(ua)) {
return 'ppc64le';

View File

@@ -17,7 +17,6 @@ module.exports = function (request) {
];
let oses = ['freebsd', 'linux', 'macos', 'posix'];
return githubSource(request, owner, repo, oses, arches).then(function (all) {
all._names = ['aliasman', 'legacy'];
return all;
});
};

View File

@@ -6,7 +6,6 @@ var repo = 'archiver';
module.exports = function (request) {
return github(request, owner, repo).then(function (all) {
all._names = ['archiver', 'arc'];
return all;
});
};

View File

@@ -65,7 +65,6 @@ module.exports = function (request) {
continue;
}
}
all._names = ['AtomicParsley', 'atomicparsley'];
return all;
});
};

View File

@@ -8,17 +8,10 @@ module.exports = function (request) {
return github(request, owner, repo).then(function (all) {
all.releases = all.releases
.filter(function (r) {
let isDebug = r.name.includes('-profile');
if (isDebug) {
return false;
let isDebug = /-profile/.test(r.name);
if (!isDebug) {
return true;
}
let isAncient = r.name.includes('-baseline');
if (isAncient) {
return false;
}
return true;
})
.map(function (r) {
// bun-v0.5.1 => v0.5.1

View File

@@ -8,12 +8,7 @@ module.exports = function (request) {
return github(request, owner, repo).then(function (all) {
// remove checksums and .deb
all.releases = all.releases.filter(function (rel) {
let isOneOffAsset = rel.download.includes('buildable-artifact');
if (isOneOffAsset) {
return false;
}
return true;
return !/(\.txt)|(\.deb)$/i.test(rel.name);
});
return all;
});

View File

@@ -20,28 +20,20 @@ __init_chromedriver() {
# pkg_install must be defined by every package
pkg_install() {
# ~/.local/opt/chromedriver-v121.0.6130.0/bin
# ~/.local/opt/chromedriver-v88.0.4324.96/bin
mkdir -p "$(dirname "$pkg_src_cmd")"
# mv ./chromedriver-macos-arm64/chromedriver \
# ~/.local/opt/chromedriver-v121.0.6130.0/bin/chromedriver
mv ./chromedriver-*/chromedriver "$pkg_src_cmd"
echo ""
echo " $(t_warn 'MANUAL STEPS TO FINISH:') you may need to install libnss3:"
echo " $(t_cmd 'sudo apt install -y') $(t_warn 'libnss3')"
# mv ./chromedriver-*/chromedriver ~/.local/opt/chromedriver-v88.0.4324.96/bin/chromedriver
mv ./chromedriver* "$pkg_src_cmd"
}
# pkg_get_current_version is recommended, but (soon) not required
pkg_get_current_version() {
# 'chromedriver --version' has output in this format:
# ChromeDriver 121.0.6130.0 (5fc19c7ab5e88bb674c2efc65db4b7890a52a4ec-refs/branch-heads/6130@{#1})
# ChromeDriver 88.0.4324.96 (68dba2d8a0b149a1d3afac56fa74648032bcf46b-refs/branch-heads/4324@{#1784})
# This trims it down to just the version number:
# 121.0.6130.0
chromedriver --version 2> /dev/null |
head -n 1 |
tr -s ' ' |
cut -d' ' -f2
# 88.0.4324.96
chromedriver --version 2> /dev/null | head -n 1 | cut -d ' ' -f 2
}
}

View File

@@ -1,77 +1,81 @@
'use strict';
// See <https://googlechromelabs.github.io/chrome-for-testing/>
var releaseApiUrl =
'https://googlechromelabs.github.io/chrome-for-testing/known-good-versions-with-downloads.json';
var matchers = {
key: /.*Key>(.*)<\/Key.*/,
generation: /.*Generation>(.*)<\/Generation.*/,
metaGeneration: /.*MetaGeneration>(.*)<\/MetaGeneration.*/,
lastModified: /.*LastModified>(.*)<\/LastModified.*/,
etag: /.*ETag>(.*)<\/ETag.*/,
size: /.*Size>(.*)<\/Size.*/,
};
var baseUrl = 'https://chromedriver.storage.googleapis.com';
// {
// "timestamp": "2023-11-15T21:08:56.730Z",
// "versions": [
// {
// "version": "121.0.6120.0",
// "revision": "1222902",
// "downloads": {
// "chrome": [],
// "chromedriver": [
// {
// "platform": "linux64",
// "url": "https://edgedl.me.gvt1.com/edgedl/chrome/chrome-for-testing/121.0.6120.0/linux64/chromedriver-linux64.zip"
// },
// {
// "platform": "mac-arm64",
// "url": "https://edgedl.me.gvt1.com/edgedl/chrome/chrome-for-testing/121.0.6120.0/mac-arm64/chromedriver-mac-arm64.zip"
// },
// {
// "platform": "mac-x64",
// "url": "https://edgedl.me.gvt1.com/edgedl/chrome/chrome-for-testing/121.0.6120.0/mac-x64/chromedriver-mac-x64.zip"
// },
// {
// "platform": "win32",
// "url": "https://edgedl.me.gvt1.com/edgedl/chrome/chrome-for-testing/121.0.6120.0/win32/chromedriver-win32.zip"
// },
// {
// "platform": "win64",
// "url": "https://edgedl.me.gvt1.com/edgedl/chrome/chrome-for-testing/121.0.6120.0/win64/chromedriver-win64.zip"
// }
// ],
// "chrome-headless-shell": []
// }
// }
// ]
// }
module.exports = async function (request) {
let resp = await request({
url: releaseApiUrl,
json: true,
});
let builds = [];
for (let release of resp.body.versions) {
if (!release.downloads.chromedriver) {
continue;
}
let version = release.version;
for (let asset of release.downloads.chromedriver) {
let build = {
version: version,
download: asset.url,
// I' not sure that this is actually statically built but it
// seems to be and at worst we'll just get bug reports for Apline
libc: 'none',
};
builds.push(build);
}
}
let all = {
module.exports = function (request) {
var all = {
download: '',
releases: builds,
releases: [],
};
return all;
// XML
return request({
url: 'https://chromedriver.storage.googleapis.com/',
json: false,
})
.then(function (resp) {
var body = resp.body;
var groups = body.split(/<\/?Contents>/g);
// get rid of leading and trailing junk
groups.shift();
groups.pop();
var metas = groups.map(function (group) {
return {
key: group.replace(matchers.key, '$1'),
//generation: group.replace(matchers.generation, '$1'),
//metaGeneration: group.replace(matchers.metaGeneration, '$1'),
lastModified: group.replace(matchers.lastModified, '$1'),
//etag: group.replace(matchers.etag, '$1'),
//size: group.replace(matchers.size, '$1')
};
});
all.download = baseUrl + '/{{ download }}';
metas.forEach(function (asset) {
if (!asset.key.includes('chromedriver')) {
// skip the indexes, images, etc
return null;
}
var osname = asset.key.replace(/.*(win|mac|linux)/, '$1');
var arch;
if (asset.key.includes('linux')) {
osname = 'linux';
} else if (asset.key.includes('mac64')) {
osname = 'macos';
if (asset.key.includes('_m1.')) {
arch = 'arm64';
}
} else if (asset.key.includes('win')) {
osname = 'windows';
arch = 'amd64';
}
all.releases.push({
// 87.0.4280.88/chromedriver_win32.zip => 87.0.4280.88
version: asset.key.replace(/(.*)\/.*/, '$1'),
lts: false,
channel: 'stable',
date: asset.lastModified.replace(/T.*/, '$1'),
os: osname,
arch: arch,
hash: '-', // not sure about including etag as hash yet
download: asset.key,
});
});
})
.then(function () {
all.releases.sort(function (a, b) {
return new Date(b.date).valueOf() - new Date(a.date).valueOf();
});
return all;
});
};
if (module === require.main) {

View File

@@ -7,10 +7,6 @@ var repo = 'CMake';
module.exports = function (request) {
return github(request, owner, repo).then(function (all) {
for (let rel of all.releases) {
if (rel.version.startsWith('v')) {
rel._version = rel.version.slice(1);
}
{
let linuxRe = /(\b|_)(linux|gnu)(\b|_)/i;
let isLinux = linuxRe.test(rel.download) || linuxRe.test(rel.name);

View File

@@ -4,28 +4,8 @@ var github = require('../_common/github.js');
var owner = 'kivikakk';
var repo = 'comrak';
var ODDITIES = ['-musleabihf.1-'];
module.exports = function (request) {
return github(request, owner, repo).then(function (all) {
let builds = [];
loopBuilds: for (let build of all.releases) {
let isOddity;
for (let oddity of ODDITIES) {
isOddity = build.name.includes(oddity);
if (isOddity) {
break;
}
}
if (isOddity) {
continue;
}
builds.push(build);
}
all.releases = builds;
return all;
});
};

View File

@@ -6,7 +6,6 @@ var repo = 'curlie';
module.exports = function (request) {
return github(request, owner, repo).then(function (all) {
all._names = ['curlie', 'curl-httpie'];
return all;
});
};

View File

@@ -6,17 +6,14 @@ var repo = 'dash';
module.exports = function (request) {
return github(request, owner, repo).then(function (all) {
all.releases = all.releases.filter(function (rel) {
return !rel.name.endsWith('.asc');
});
all.releases.forEach(function (rel) {
if (rel.name.includes('osx64')) {
rel.os = 'macos';
}
if (rel.version.startsWith('v')) {
rel._version = rel.version.slice(1);
}
});
all._names = ['dashd', 'dashcore'];
return all;
});
};

View File

@@ -11,12 +11,7 @@ module.exports = function (request) {
// remove checksums and .deb
all.releases = all.releases
.filter(function (rel) {
let isMeta = rel.name.endsWith('.d.ts');
if (isMeta) {
return false;
}
return true;
return !/(\.txt)|(\.deb)$/i.test(rel.name);
})
.map(function (rel) {
var ext;

View File

@@ -17,7 +17,6 @@ module.exports = function (request) {
];
let oses = ['freebsd', 'linux', 'macos', 'posix'];
return githubSource(request, owner, repo, oses, arches).then(function (all) {
all._names = ['DuckDNS.sh', 'duckdns.sh', 'legacy'];
return all;
});
};

View File

@@ -6,17 +6,6 @@ var repo = 'fd';
module.exports = function (request) {
return github(request, owner, repo).then(function (all) {
let builds = [];
for (let build of all.releases) {
if (build.name === 'fd') {
continue;
}
builds.push(build);
}
all.releases = builds;
return all;
});
};

View File

@@ -10,11 +10,6 @@ module.exports = function (request) {
return github(request, owner, repo).then(function (all) {
all.releases = all.releases
.filter(function (rel) {
let isFfmpeg = rel.name.includes('ffmpeg');
if (!isFfmpeg) {
return;
}
// remove README and LICENSE
return !['.README', '.LICENSE'].includes(path.extname(rel.name));
})

View File

@@ -4,19 +4,10 @@ var github = require('../_common/github.js');
var owner = 'fish-shell';
var repo = 'fish-shell';
var ODDITIES = ['bundledpcre'];
module.exports = function (request) {
return github(request, owner, repo).then(function (all) {
all.releases = all.releases
.map(function (rel) {
for (let oddity of ODDITIES) {
let isOddity = rel.name.includes(oddity);
if (isOddity) {
return;
}
}
// We can extract the macos bins from the .app
if (/\.app\.zip$/.test(rel.name)) {
rel.os = 'macos';

View File

@@ -1,98 +1,59 @@
'use strict';
var FLUTTER_OSES = ['macos', 'linux', 'windows'];
var map = {};
// stable, beta, dev
var channelMap = {};
// This can be spot-checked against
// https://docs.flutter.dev/release/archive?tab=windows
// The release URLs are
// - https://storage.googleapis.com/flutter_infra_release/releases/releases_macos.json
// - https://storage.googleapis.com/flutter_infra_release/releases/releases_linux.json
// - https://storage.googleapis.com/flutter_infra_release/releases/releases_windows.json
// The old release URLs are
// - https://storage.googleapis.com/flutter_infra/releases/releases_macos.json
// - https://storage.googleapis.com/flutter_infra/releases/releases_linux.json
// - https://storage.googleapis.com/flutter_infra/releases/releases_windows.json
// The data looks like
// {
// "base_url": "https://storage.googleapis.com/flutter_infra/releases",
// "current_release": {
// "beta": "b22742018b3edf16c6cadd7b76d9db5e7f9064b5",
// "dev": "fa5883b78e566877613ad1ccb48dd92075cb5c23",
// "stable": "02c026b03cd31dd3f867e5faeb7e104cce174c5f"
// },
// "releases": [
// {
// "hash": "fa5883b78e566877613ad1ccb48dd92075cb5c23",
// "channel": "dev",
// "version": "2.3.0-16.0.pre",
// "release_date": "2021-05-27T23:58:47.683121Z",
// "archive": "dev/macos/flutter_macos_2.3.0-16.0.pre-dev.zip",
// "sha256": "f572b42d36714e6c58a3ed170b93bb414e2ced3ca4bde5094fbe18061cbcba6c"
// },
// {
// "hash": "02c026b03cd31dd3f867e5faeb7e104cce174c5f",
// "channel": "stable",
// "version": "2.2.1",
// "release_date": "2021-05-27T23:06:07.243882Z",
// "archive": "stable/macos/flutter_macos_2.2.1-stable.zip",
// "sha256": "6373d39ec563c337600baf42a42b258420208e4523d85479373e113d61d748df"
// },
// {
// "hash": "b22742018b3edf16c6cadd7b76d9db5e7f9064b5",
// "channel": "beta",
// "version": "2.2.0",
// "release_date": "2021-05-19T21:14:59.281482Z",
// "archive": "beta/macos/flutter_macos_2.2.0-beta.zip",
// "sha256": "31ab530e708f8d1274712211253a27a4ce7d676f139d30f2ec021df22382f052"
// }
// ]
// }
module.exports = async function (request) {
let all = {
module.exports = function (request) {
var all = {
download: '',
releases: [],
channels: [],
};
for (let osname of FLUTTER_OSES) {
let resp = await request({
url: `https://storage.googleapis.com/flutter_infra_release/releases/releases_${osname}.json`,
json: true,
});
let body = resp.body;
all.download = `${body.base_url}/{{ download }}`;
for (let asset of body.releases) {
if (!channelMap[asset.channel]) {
channelMap[asset.channel] = true;
}
all.releases.push({
version: asset.version,
_version: `${asset.version}-${asset.channel}`,
lts: false,
channel: asset.channel,
date: asset.release_date.replace(/T.*/, ''),
//sha256: asset.sha256,
download: asset.archive,
return Promise.all(
['macos', 'linux', 'windows'].map(function (osname) {
return request({
url:
'https://storage.googleapis.com/flutter_infra/releases/releases_' +
osname +
'.json',
json: true,
}).then(function (resp) {
var body = resp.body;
all.download = body.base_url + '/{{ download }}';
body.releases.forEach(function (asset) {
if (!map[asset.channel]) {
map[asset.channel] = true;
}
all.releases.push({
// nix leading 'v'
version: asset.version.replace(/v/, ''),
lts: false,
channel: asset.channel,
date: asset.release_date.replace(/T.*/, ''),
os: osname,
arch: 'amd64',
hash: '-', // not sure about including hash / sha256 yet
download: asset.archive,
});
});
});
}
}
all.channels = Object.keys(channelMap);
// note: versions have a waterfall relationship with channels:
// - a release that is in beta today may become stable tomorrow
// - semver prereleases are either beta or dev
return all;
}),
).then(function () {
all.releases.sort(function (a, b) {
if ('stable' === a.channel && a.channel !== b.channel) {
return -1;
}
if ('stable' === b.channel && a.channel !== b.channel) {
return 1;
}
if ('beta' === a.channel && a.channel !== b.channel) {
return -1;
}
if ('beta' === b.channel && a.channel !== b.channel) {
return 1;
}
return new Date(b.date).valueOf() - new Date(a.date).valueOf();
});
return all;
});
};
if (module === require.main) {

View File

@@ -12,15 +12,12 @@ module.exports = function (request) {
all.releases = all.releases
.filter(function (rel) {
rel.os = 'windows';
rel._version = rel.version.replace(/\.windows.1.*/, '');
rel._version = rel._version.replace(/\.windows(\.\d)/, '$1');
return (
/MinGit/i.test(rel.name || rel.download) &&
!/busybox/i.test(rel.name || rel.download)
);
})
.slice(0, 20);
all._names = ['MinGit', 'git'];
return all;
});
};

View File

@@ -18,12 +18,6 @@ $pkg_src = "$pkg_src_cmd"
New-Item "$Env:USERPROFILE\Downloads\webi" -ItemType Directory -Force | Out-Null
$pkg_download = "$Env:USERPROFILE\Downloads\webi\$Env:WEBI_PKG_FILE"
Write-Output "Checking for Git..."
IF (-Not (Get-Command -Name "git" -ErrorAction Silent)) {
& "$HOME\.local\bin\webi-pwsh.ps1" git
$null = Sync-EnvPath
}
# Fetch archive
IF (!(Test-Path -Path "$Env:USERPROFILE\Downloads\webi\$Env:WEBI_PKG_FILE")) {
Write-Output "Downloading gitea from $Env:WEBI_PKG_URL to $pkg_download"

View File

@@ -4,24 +4,12 @@ var github = require('../_common/github.js');
var owner = 'go-gitea';
var repo = 'gitea';
var ODDITIES = ['-gogit-', '-docs-'];
module.exports = function (request) {
return github(request, owner, repo).then(function (all) {
// remove checksums and .deb
all.releases = all.releases.filter(function (rel) {
for (let oddity of ODDITIES) {
let isOddity = rel.name.includes(oddity);
if (isOddity) {
return false;
}
}
return true;
return !/(\.txt)|(\.deb)|(\.asc)|(\.sha256)$/i.test(rel.name);
});
// "windows-4.0" as a nod to Windows NT ¯\_(ツ)_/¯
all._names = ['gitea', '-4.0-'];
return all;
});
};

View File

@@ -7,17 +7,6 @@ var archMap = {
386: 'x86',
};
let ODDITIES = ['bootstrap', '-arm6.'];
function isOdd(filename) {
for (let oddity of ODDITIES) {
let isOddity = filename.includes(oddity);
if (isOddity) {
return true;
}
}
}
function getAllReleases(request) {
/*
{
@@ -54,21 +43,13 @@ function getAllReleases(request) {
parts.push('0');
}
var version = parts.join('.');
// nix 'go' prefix
var fileversion = release.version.slice(2);
release.files.forEach((asset) => {
let odd = isOdd(asset.filename);
if (odd) {
return;
}
var filename = asset.filename;
var os = osMap[asset.os] || asset.os || '-';
var arch = archMap[asset.arch] || asset.arch || '-';
all.releases.push({
version: version,
_version: fileversion,
// all go versions >= 1.0.0 are effectively LTS
lts: (parts[0] > 0 && release.stable) || false,
channel: (release.stable && 'stable') || 'beta',

View File

@@ -41,6 +41,7 @@ function transformReleases(links) {
let releases = links
.map(function (link) {
// strip 'go' prefix, standardize version
let isLts = ltsRe.test(link);
let parts = link.match(matcher);
if (!parts || !parts[2]) {
@@ -51,12 +52,10 @@ function transformReleases(links) {
if (segs.length > 3) {
version += '+' + segs.slice(3);
}
let fileversion = segs.join('.');
return {
name: parts[1],
version: version,
_version: fileversion,
// all go versions >= 1.0.0 are effectively LTS
lts: isLts,
channel: 'stable',
@@ -71,7 +70,6 @@ function transformReleases(links) {
.filter(Boolean);
return {
_names: ['GnuPG', 'gpgosx'],
releases: releases,
};
}

View File

@@ -13,9 +13,12 @@ module.exports = async function (request) {
return false;
}
let isOldAlias = rel.name.includes('Linux-64bit');
if (isOldAlias) {
return false;
// remove checksums and .deb
for (let ignorableExt of ['.txt', '.deb']) {
let isIgnorable = rel.name.endsWith(ignorableExt);
if (isIgnorable) {
return false;
}
}
return true;

View File

@@ -13,9 +13,12 @@ module.exports = async function (request) {
return false;
}
let isOldAlias = rel.name.includes('Linux-64bit');
if (isOldAlias) {
return false;
// remove checksums and .deb
for (let ignorableExt of ['.txt', '.deb']) {
let isIgnorable = rel.name.endsWith(ignorableExt);
if (isIgnorable) {
return false;
}
}
return true;

View File

@@ -16,26 +16,9 @@ _install_iterm2() {
exit 1
fi
if test -d /Applications/iTerm.app; then
my_curver="$(
grep -A 2 CFBundleShortVersionString \
/Applications/iTerm.app/Contents/Info.plist |
tr '<> \t' '\n' |
grep -E '\d\.\d\.\d'
)"
if test "${my_curver}" = "${WEBI_VERSION}"; then
echo " Found /Applications/iTerm.app/ (${my_curver})"
return 0
fi
echo " Replacing /Applications/iTerm.app/ (${my_curver})"
mv /Applications/iTerm.app "${WEBI_TMP}/iTerm.app-webi.bak"
fi
webi_download \
"${WEBI_PKG_URL}" \
"${WEBI_PKG_PATH}/${WEBI_PKG_FILE}"
webi_extract
if [ ! -d "${WEBI_TMP}/iTerm.app" ]; then
@@ -44,9 +27,11 @@ _install_iterm2() {
exit 1
fi
if [ -d /Applications/iTerm.app ]; then
mv /Applications/iTerm.app "${WEBI_TMP}/iTerm.app-webi.bak"
fi
mkdir -p /Applications/
mv "${WEBI_TMP}/iTerm.app" /Applications/
echo " Installed to /Applications/iTerm.app/"
}
_install_iterm2

View File

@@ -24,24 +24,17 @@ function transformReleases(links) {
//console.log(links.length);
return {
_names: ['iTerm2', 'iterm2'],
releases: links
.map(function (link) {
// strip 'go' prefix, standardize version
var channel = /\/stable\//.test(link) ? 'stable' : 'beta';
var parts = link
.replace(/.*\/iTerm2[-_]v?(\d_.*)\.zip/, '$1')
.split('_');
var version = parts.join('.').replace(/([_-])?beta/, '-beta');
// ex: 3.5.0-beta17 => 3_5_0beta17
// ex: 3.0.2-preview => 3_0_2-preview
let fileversion = version.replace(/\./g, '_');
fileversion = fileversion.replace(/-beta/g, 'beta');
return {
version: version,
_version: fileversion,
// all go versions >= 1.0.0 are effectively LTS
lts: 'stable' === channel,
channel: channel,

View File

@@ -4,32 +4,11 @@ var github = require('../_common/github.js');
var owner = 'stedolan';
var repo = 'jq';
let ODDITIES = ['-no-oniguruma'];
function isOdd(build) {
for (let oddity of ODDITIES) {
let isOddity = build.name.includes(oddity);
if (isOddity) {
return true;
}
}
}
module.exports = function (request) {
return github(request, owner, repo).then(function (all) {
let builds = [];
for (let build of all.releases) {
let odd = isOdd(build);
if (odd) {
continue;
}
build.version = build.version.replace(/^jq\-/, '');
builds.push(build);
}
all.releases = builds;
all.releases.forEach(function (rel) {
rel.version = String(rel.version).replace(/^jq\-/, '');
});
return all;
});
};

View File

@@ -4,25 +4,16 @@ var github = require('../_common/github.js');
var owner = 'ahmetb';
var repo = 'kubectx';
/******************************************************************************/
/** Note: Delete this Comment! **/
/** **/
/** Need a an example that filters out miscellaneous release files? **/
/** See `deno`, `gitea`, or `caddy` **/
/** **/
/******************************************************************************/
module.exports = function (request) {
return github(request, owner, repo).then(function (all) {
let builds = [];
for (let build of all.releases) {
// this installs separately
if (build.name.includes('kubens')) {
continue;
}
// this is the legacy bash script
if (build.name === 'kubectx') {
continue;
}
builds.push(build);
}
all.releases = builds;
return all;
});
};

View File

@@ -6,23 +6,10 @@ var repo = 'kubectx';
module.exports = function (request) {
return github(request, owner, repo).then(function (all) {
let builds = [];
for (let build of all.releases) {
// this installs separately
if (build.name.includes('kubectx')) {
continue;
}
// this is the legacy bash script
if (build.name === 'kubens') {
continue;
}
builds.push(build);
}
all.releases = builds;
// remove kubectx, etc. from kubens list
all.releases = all.releases.filter(function (rel) {
return !/(\.txt)|(kubectx)|(kubectx_)$/i.test(rel.name);
});
return all;
});
};

View File

@@ -41,11 +41,7 @@ var headers = {
};
module.exports = function (request) {
var all = {
_names: ['InstallOS'],
download: '',
releases: [],
};
var all = { download: '', releases: [] };
return Promise.all(
oses.map(function (os) {

View File

@@ -40,7 +40,5 @@ pkg_link() {
}
pkg_done_message() {
b_dst="$(fn_sub_home "${pkg_dst}")"
echo ""
echo " Installed $(t_pkg 'node') and $(t_pkg 'npm') at $(t_path "${b_dst}/")"
echo "Installed 'node' and 'npm' at $pkg_dst"
}

View File

@@ -19,7 +19,6 @@ module.exports = async function (request) {
}
all.releases = releases;
all._names = ['Ollama', 'ollama'];
return all;
};

View File

@@ -8,14 +8,7 @@ var baseurl = 'https://git.rootprojects.org';
module.exports = function (request) {
return github(request, owner, repo, baseurl).then(function (all) {
all.releases = all.releases.filter(function (release) {
release._filename = release.name;
let isOldAlias = release.name.includes('armv8');
if (isOldAlias) {
return false;
}
return true;
return !/debug/.test(release.name);
});
return all;
});

View File

@@ -75,7 +75,6 @@ module.exports = async function () {
download: '',
},
].map(function (rel) {
rel._version = `${rel.version}-1`;
rel.download =
'https://get.enterprisedb.com/postgresql/' +
rel.name +
@@ -83,7 +82,6 @@ module.exports = async function () {
return rel;
}),
download: '',
_names: ['PostgreSQL', 'postgresql', 'Postgres', 'postgres', 'binaries'],
};
};

View File

@@ -1,11 +1,98 @@
---
title: PowerShell (pwsh alias)
homepage: https://webinstall.dev/pwsh
title: Microsoft PowerShell
homepage: https://docs.microsoft.com/en-us/powershell/
tagline: |
Alias for https://webinstall.dev/pwsh
alias: pwsh
description: |
See https://webinstall.dev/pwsh
PowerShell Core is a cross-platform (Windows, Linux, and macOS) automation and configuration tool/framework.
---
Alias for https://webinstall.dev/pwsh
To update or switch versions, run `webi pwsh@stable` (or `@v7.4`, `@beta`, etc).
## Cheat Sheet
> The core benefit of running `pwsh` on Mac or Linux is that you get a way to
> debug Windows scripts without having to boot up Windows.
>
> The core benefit of running `pwsh` on Windows is that it's years ahead of
> pre-installed version.
For example, if you want to create a `curl.exe | powershell` script for Windows
(as we do), it's helpful to be able to do some level of debugging on other
platforms.
## Table of Contents
- Files
- ProTips
- vim
- lint
- fmt
### Files
These are the files / directories that are created and/or modified with this
install:
```text
~/.config/envman/PATH.env
~/.local/opt/pwsh/
~/.local/share/powershell/Modules/
~/.local/opt/pwsh/Modules/
```
### ProTip: pwsh-essentials
Friends don't let friends PowerShell without
[pwsh-essentials](../pwsh-essentials/):
- [PSScriptAnalyzer](../psscriptanalyzer/)
- [pwsh-fmt](../pwsh-essentials/)
- [pwsh-lint](../pwsh-essentials/)
- [pwsh-fix](../pwsh-essentials/)
- [pwsh-run](../pwsh-essentials/)
Plus, important information for anyone **Getting Started with PowerShell**:
- Case-Sensitivity
- Returns vs Pipeline Streams
- Strict, Trace, & Verbose Modes
- The Call Operator "&"
- curl vs curl.exe
- Script Policies & Preferences
### How to Use PowerShell with Vim
Assuming you have [vim-ale](../vim-ale/) installed - which is included with
[vim-essentials](../vim-essentials/) - all you need to do is install the
`PSScriptAnalyzer` module.
See the "Lint & Fmt" section below.
### How to Use PowerShell with VSCode
_VS Code_ should also automatically recognize and use `PSScriptAnalyzer`.
### How to Lint, Fmt, & Fix ps1 Files
See [pwsh-essentials](../pwsh-essentials/) for more info but, in short:
```sh
pwsh -Command "Install-Module -Name PSScriptAnalyzer -Scope CurrentUser -AllowClobber"
```
```sh
my_ps1='./my-file.ps1'
pwsh -Command "Invoke-ScriptAnalyzer -Fix -ExcludeRule PSAvoidUsingWriteHost -Path '$my_ps1'"
```
To fmt:
```sh
my_ps1='./my-file.ps1'
my_text="$(
pwsh -Command "Invoke-Formatter -ScriptDefinition (Get-Content -Path '$my_ps1' -Raw)"
)"
printf '%s\n' "${my_text}" > "${my_ps1}"
```
Note: it is _several hundred times faster_ to lint and fmt from a native
PowerShell script than from invoking `pwsh -Command` each time.

View File

@@ -1,8 +1,56 @@
#!/bin/pwsh
#!/usr/bin/env pwsh
Write-Output "'powershell@$Env:WEBI_TAG' is an alias for 'pwsh@$Env:WEBI_VERSION'"
#################
# Install pwsh #
#################
$PwshBootUrl = "$Env:WEBI_HOST/pwsh@$Env:WEBI_VERSION"
$PwshBootScript = "$HOME\.local\tmp\install-pwsh-boot.ps1"
Invoke-DownloadUrl -Force -URL $PwshBootUrl -Path $PwshBootScript
pwsh -ExecutionPolicy Bypass $PwshBootScript
# Every package should define these variables
$pkg_cmd_name = "pwsh"
$pkg_dst_cmd = "$HOME\.local\opt\pwsh\${pkg_cmd_name}.exe"
$pkg_dst_bin = "$HOME\.local\opt\pwsh"
$pkg_dst_dir = "$HOME\.local\opt\pwsh"
$pkg_dst = "$pkg_dst_dir"
$pkg_src_cmd = "$HOME\.local\opt\pwsh-v$Env:WEBI_VERSION\${pkg_cmd_name}.exe"
$pkg_src_dir = "$HOME\.local\opt\pwsh-v$Env:WEBI_VERSION"
$pkg_src = "$pkg_src_dir"
New-Item "$HOME\Downloads\webi" -ItemType Directory -Force | Out-Null
$pkg_download = "$HOME\Downloads\webi\$Env:WEBI_PKG_FILE"
# Fetch archive
Invoke-DownloadURL -URL $Env:WEBI_PKG_URL -Path $pkg_download
IF (!(Test-Path -Path "$pkg_src_cmd")) {
Push-Location "$HOME\.local\tmp"
# Remove any leftover tmp cruft
Remove-Item -Path "$pkg_src_dir" -Recurse -ErrorAction Ignore | Out-Null
Remove-Item -Path "$HOME\.local\tmp\pwsh*" -Recurse -ErrorAction Ignore
# Unpack archive file into this temporary directory
# Windows BSD-tar handles zip. Imagine that.
New-Item ".\pwsh-v$Env:WEBI_VERSION" -ItemType Directory -Force | Out-Null
Push-Location ".\pwsh-v$Env:WEBI_VERSION"
Write-Output " Unpacking $pkg_download"
& tar xf "$pkg_download"
Pop-Location
# Settle unpacked archive into place
# TODO if .\pwsh-v$Env:WEBI_VERSION\pwsh*\ exists,
# then the nesting of the archive has changed
# so move either .\pwsh-v$Env:WEBI_VERSION\pwsh*\
# or .\pwsh-v$Env:WEBI_VERSION\ accordingly
Move-Item -Path ".\pwsh-v$Env:WEBI_VERSION" -Destination "$pkg_src_dir"
Write-Output " into ${TPath}${pkg_src_dir}${TReset}"
Pop-Location
}
Write-Output " Copying ${TDim}${pkg_src}${TReset}"
Write-Output " into ${TPath}${pkg_dst}${TReset}"
Remove-Item -Path "$pkg_dst" -Recurse -ErrorAction Ignore | Out-Null
Copy-Item -Path "$pkg_src" -Destination "$pkg_dst" -Recurse
webi_path_add "$pkg_dst_bin"
& "$pkg_dst_cmd" -V

View File

@@ -2,10 +2,45 @@
set -e
set -u
__redirect_alias_pwsh() {
echo "'powershell@${WEBI_TAG:-stable}' is an alias for 'pwsh@${WEBI_VERSION-}'"
WEBI_HOST=${WEBI_HOST:-"https://webinstall.dev"}
curl -fsSL "$WEBI_HOST/pwsh@${WEBI_VERSION-}" | sh
__init_powershell() {
pkg_cmd_name="pwsh"
# no ./bin prefix
pkg_src_cmd="$HOME/.local/opt/pwsh-v$WEBI_VERSION/pwsh"
pkg_dst_cmd="$HOME/.local/opt/pwsh/pwsh"
pkg_get_current_version() {
# 'pwsh --version' has output in this format:
# PowerShell 7.0.2
# This trims it down to just the version number:
# 7.0.2
pwsh --version 2> /dev/null | head -n 1 | cut -d' ' -f2
}
pkg_install() {
# mv ./* "$HOME/.local/opt/pwsh-v7.0.2"
mkdir -p "$pkg_src"
mv ./* "$pkg_src"
# symlink powershell to pwsh
(
cd "$pkg_src" > /dev/null
ln -s pwsh powershell
)
}
pkg_link() {
# rm -f "$HOME/.local/opt/pwsh"
rm -f "$pkg_dst"
# ln -s "$HOME/.local/opt/pwsh-v7.0.2" "$HOME/.local/opt/pwsh"
ln -s "$pkg_src" "$pkg_dst"
}
pkg_done_message() {
echo "Installed 'pwsh' at $pkg_dst"
pwsh -V
}
}
__redirect_alias_pwsh
__init_powershell

View File

@@ -15,8 +15,6 @@ module.exports = function (request) {
return !/(alpine)|(fxdependent)|(\.deb)|(\.pkg)|(\.rpm)$/i.test(rel.name);
});
all._names = ['PowerShell', 'powershell'];
return all;
});
};

View File

@@ -1,98 +1,11 @@
---
title: Microsoft PowerShell Core
homepage: https://docs.microsoft.com/powershell/
title: PowerShell (pwsh alias)
homepage: https://webinstall.dev/powershell
tagline: |
PowerShell Core is a cross-platform (Windows, Linux, and macOS) automation and configuration tool/framework.
Alias for https://webinstall.dev/powershell
alias: powershell
description: |
See https://webinstall.dev/powershell
---
To update or switch versions, run `webi pwsh@stable` (or `@v7.4`, `@beta`, etc).
## Cheat Sheet
> The core benefit of running `pwsh` on Mac or Linux is that you get a way to
> debug Windows scripts without having to boot up Windows.
>
> The core benefit of running `pwsh` on Windows is that it's years ahead of
> pre-installed version.
For example, if you want to create a `curl.exe | powershell` script for Windows
(as we do), it's helpful to be able to do some level of debugging on other
platforms.
## Table of Contents
- Files
- ProTips
- vim
- lint
- fmt
### Files
These are the files / directories that are created and/or modified with this
install:
```text
~/.config/envman/PATH.env
~/.local/opt/pwsh/
~/.local/share/powershell/Modules/
~/.local/opt/pwsh/Modules/
```
### ProTip: pwsh-essentials
Friends don't let friends PowerShell without
[pwsh-essentials](../pwsh-essentials/):
- [PSScriptAnalyzer](../psscriptanalyzer/)
- [pwsh-fmt](../pwsh-essentials/)
- [pwsh-lint](../pwsh-essentials/)
- [pwsh-fix](../pwsh-essentials/)
- [pwsh-run](../pwsh-essentials/)
Plus, important information for anyone **Getting Started with PowerShell**:
- Case-Sensitivity
- Returns vs Pipeline Streams
- Strict, Trace, & Verbose Modes
- The Call Operator "&"
- curl vs curl.exe
- Script Policies & Preferences
### How to Use PowerShell with Vim
Assuming you have [vim-ale](../vim-ale/) installed - which is included with
[vim-essentials](../vim-essentials/) - all you need to do is install the
`PSScriptAnalyzer` module.
See the "Lint & Fmt" section below.
### How to Use PowerShell with VSCode
_VS Code_ should also automatically recognize and use `PSScriptAnalyzer`.
### How to Lint, Fmt, & Fix ps1 Files
See [pwsh-essentials](../pwsh-essentials/) for more info but, in short:
```sh
pwsh -Command "Install-Module -Name PSScriptAnalyzer -Scope CurrentUser -AllowClobber"
```
```sh
my_ps1='./my-file.ps1'
pwsh -Command "Invoke-ScriptAnalyzer -Fix -ExcludeRule PSAvoidUsingWriteHost -Path '$my_ps1'"
```
To fmt:
```sh
my_ps1='./my-file.ps1'
my_text="$(
pwsh -Command "Invoke-Formatter -ScriptDefinition (Get-Content -Path '$my_ps1' -Raw)"
)"
printf '%s\n' "${my_text}" > "${my_ps1}"
```
Note: it is _several hundred times faster_ to lint and fmt from a native
PowerShell script than from invoking `pwsh -Command` each time.
Alias for https://webinstall.dev/powershell

View File

@@ -1,57 +1,8 @@
#!/usr/bin/env pwsh
#!/bin/pwsh
################
# Install pwsh #
################
Write-Output "'pwsh@$Env:WEBI_TAG' is an alias for 'powershell@$Env:WEBI_VERSION'"
# Every package should define these variables
$pkg_cmd_name = "pwsh"
$pkg_dst_cmd = "$HOME\.local\opt\pwsh\${pkg_cmd_name}.exe"
$pkg_dst_bin = "$HOME\.local\opt\pwsh"
$pkg_dst_dir = "$HOME\.local\opt\pwsh"
$pkg_dst = "$pkg_dst_dir"
$pkg_src_cmd = "$HOME\.local\opt\pwsh-v$Env:WEBI_VERSION\${pkg_cmd_name}.exe"
$pkg_src_dir = "$HOME\.local\opt\pwsh-v$Env:WEBI_VERSION"
$pkg_src = "$pkg_src_dir"
New-Item "$HOME\Downloads\webi" -ItemType Directory -Force | Out-Null
$pkg_download = "$HOME\Downloads\webi\$Env:WEBI_PKG_FILE"
# Fetch archive
Invoke-DownloadURL -URL $Env:WEBI_PKG_URL -Path $pkg_download
IF (!(Test-Path -Path "$pkg_src_cmd")) {
Push-Location "$HOME\.local\tmp"
# Remove any leftover tmp cruft
Remove-Item -Path "$pkg_src_dir" -Recurse -ErrorAction Ignore | Out-Null
Remove-Item -Path "$HOME\.local\tmp\pwsh*" -Recurse -ErrorAction Ignore
# Unpack archive file into this temporary directory
# Windows BSD-tar handles zip. Imagine that.
New-Item ".\pwsh-v$Env:WEBI_VERSION" -ItemType Directory -Force | Out-Null
Push-Location ".\pwsh-v$Env:WEBI_VERSION"
Write-Output " Unpacking $pkg_download"
& tar xf "$pkg_download"
Pop-Location
# Settle unpacked archive into place
# TODO if .\pwsh-v$Env:WEBI_VERSION\pwsh*\ exists,
# then the nesting of the archive has changed
# so move either .\pwsh-v$Env:WEBI_VERSION\pwsh*\
# or .\pwsh-v$Env:WEBI_VERSION\ accordingly
Move-Item -Path ".\pwsh-v$Env:WEBI_VERSION" -Destination "$pkg_src_dir"
Write-Output " into ${TPath}${pkg_src_dir}${TReset}"
Pop-Location
}
Write-Output " Copying ${TDim}${pkg_src}${TReset}"
Write-Output " into ${TPath}${pkg_dst}${TReset}"
Remove-Item -Path "$pkg_dst" -Recurse -ErrorAction Ignore | Out-Null
Copy-Item -Path "$pkg_src" -Destination "$pkg_dst" -Recurse
webi_path_add "$pkg_dst_bin"
& "$pkg_dst_cmd" -V
$PwshBootUrl = "$Env:WEBI_HOST/powershell@$Env:WEBI_VERSION"
$PwshBootScript = "$HOME\.local\tmp\install-pwsh-boot.ps1"
Invoke-DownloadUrl -Force -URL $PwshBootUrl -Path $PwshBootScript
powershell -ExecutionPolicy Bypass $PwshBootScript

View File

@@ -2,52 +2,10 @@
set -e
set -u
__init_pwsh() {
pkg_cmd_name="pwsh"
# note: no ./bin prefix
pkg_src_cmd="$HOME/.local/opt/pwsh-v$WEBI_VERSION/pwsh"
pkg_src_dir="$HOME/.local/opt/pwsh-v$WEBI_VERSION/"
pkg_src="$HOME/.local/opt/pwsh-v$WEBI_VERSION/"
pkg_dst_cmd="$HOME/.local/opt/pwsh/pwsh"
pkg_dst_dir="$HOME/.local/opt/pwsh"
pkg_dst="$HOME/.local/opt/pwsh"
pkg_get_current_version() {
# 'pwsh --version' has output in this format:
# PowerShell 7.0.2
# This trims it down to just the version number:
# 7.0.2
pwsh --version 2> /dev/null | head -n 1 | cut -d' ' -f2
}
pkg_install() {
# mv ./* "$HOME/.local/opt/pwsh-v7.0.2"
mkdir -p "$pkg_src"
mv ./* "$pkg_src"
# symlink pwsh as powershell
(
cd "$pkg_src" > /dev/null
rm -rf powershell
ln -s pwsh powershell
)
}
pkg_link() {
# rm -f "$HOME/.local/opt/pwsh"
rm -rf "$pkg_dst"
# ln -s "$HOME/.local/opt/pwsh-v7.0.2" "$HOME/.local/opt/pwsh"
ln -s "$pkg_src" "$pkg_dst"
}
pkg_done_message() {
echo "Installed 'pwsh' at $pkg_dst"
pwsh -V
}
__redirect_alias_powershell() {
echo "'pwsh@${WEBI_TAG:-stable}' is an alias for 'powershell@${WEBI_VERSION-}'"
WEBI_HOST=${WEBI_HOST:-"https://webinstall.dev"}
curl -fsSL "$WEBI_HOST/powershell@${WEBI_VERSION-}" | sh
}
__init_pwsh
__redirect_alias_powershell

View File

@@ -6,7 +6,6 @@ var repo = 'ripgrep';
module.exports = function (request) {
return github(request, owner, repo).then(function (all) {
all._names = ['ripgrep', 'rg'];
return all;
});
};

View File

@@ -6,7 +6,6 @@ var repo = 'dart-sass';
module.exports = function (request) {
return github(request, owner, repo).then(function (all) {
all._names = ['dart-sass', 'sass'];
return all;
});
};

View File

@@ -6,7 +6,6 @@ var repo = 'sqlpkg-cli';
module.exports = function (request) {
return github(request, owner, repo).then(function (all) {
all._names = ['sqlpkg-cli', 'sqlpkg'];
return all;
});
};

View File

@@ -61,7 +61,7 @@ main() {
sudo -i -u "$my_new_user" sh -c "curl -fsSL '$WEBI_HOST/ssh-pubkey' | sh > /dev/null" ||
sudo -i -u "$my_new_user" sh -c "wget -q -O - '$WEBI_HOST/ssh-pubkey' | sh > /dev/null"
if test -z "${SSH_ADDUSER_AUTO:-}"; then
if test -z "${SSH_ADDUSER_AUTO}"; then
echo ""
echo "!! BREAKING CHANGE !!"
echo ""

View File

@@ -166,7 +166,7 @@ function Add-AuthorizedKey($UrlOrPath) {
$TmpKeys = "new_authorized_keys.tmp.txt"
curl.exe -f -sS $UrlOrPath | Out-File -Force "${TmpKeys}.partial"
curl.exe --fail-with-body -sS $UrlOrPath | Out-File -Force "${TmpKeys}.partial"
$null = Move-Item -Force "${TmpKeys}.partial" $TmpKeys
IF ($IsHttp) {

View File

@@ -1,5 +1,15 @@
'use strict';
let convert = {
freebsd: 'freebsd',
macos: 'darwin',
linux: 'linux',
windows: 'windows',
amd64: 'amd64',
arm: 'arm64',
386: 'x86',
};
function getAllReleases(request) {
return request({
url: 'https://releases.hashicorp.com/terraform/index.json',
@@ -16,11 +26,9 @@ function getAllReleases(request) {
let r = {
version: build.version,
download: build.url,
// These are generic enough for the autodetect,
// and the per-file logic has proven to get outdated sooner
//os: convert[build.os],
//arch: convert[build.arch],
//channel: 'stable|-rc|-beta|-alpha',
os: convert[build.os],
arch: convert[build.arch],
channel: 'stable', // No other channels
};
all.releases.push(r);
});

View File

@@ -6,7 +6,6 @@ var repo = 'trippy';
module.exports = function (request) {
return github(request, owner, repo).then(function (all) {
all._names = ['trippy', 'trip'];
return all;
});
};

View File

@@ -1,2 +1,2 @@
echo >&2 " $(t_err 'Error: vcruntime140.dll is only for Windows')"
echo >&2 "vcruntime140.dll is only for Windows"
exit 1

View File

@@ -6,7 +6,6 @@ var gitUrl = 'https://github.com/ziglang/zig.vim.git';
module.exports = async function (request) {
let all = await git(gitUrl);
all._names = ['zig.vim', 'vim-zig'];
return all;
};

View File

@@ -4,7 +4,7 @@ Set-ExecutionPolicy -Scope Process Bypass
$ErrorActionPreference = 'Stop'
$ProgressPreference = 'SilentlyContinue'
$my_version = 'v1.1.16'
$my_version = 'v1.2.0'
IF ($null -eq $Env:WEBI_HOST -or $Env:WEBI_HOST -eq "") {
$Env:WEBI_HOST = "https://webinstall.dev"
@@ -71,7 +71,7 @@ function Invoke-DownloadUrl {
Write-Host " ?$Params"
$URL = "${URL}?${Params}"
}
curl.exe '-#' -f -sS -A $Env:WEBI_UA -L $URL | Out-File $TmpPath
curl.exe '-#' --fail-with-body -sS -A $Env:WEBI_UA $URL | Out-File $TmpPath
Remove-Item -Path $Path -Force -ErrorAction Ignore
Move-Item $TmpPath $Path
@@ -125,23 +125,25 @@ function Show-HowToUpdateEnv {
Write-Host ""
}
# Switch to userprofile
Push-Location $Env:USERPROFILE
function Install-Webi {
# Make paths if needed
# TODO replace all bin with opt\bin\
$null = New-Item -Path "$HOME\.local\bin\" -ItemType Directory -Force
$null = New-Item -Path "$HOME\.local\opt\" -ItemType Directory -Force
# Make paths if needed
# TODO replace all bin with opt\bin\
New-Item -Path "$HOME\.local\bin\" -ItemType Directory -Force | Out-Null
# See note on Set-ExecutionPolicy above
Set-Content -Path "$HOME\.local\bin\webi.bat" -Value "@echo off`r`npowershell -ExecutionPolicy Bypass %USERPROFILE%\.local\bin\webi-pwsh.ps1 %*"
# See note on Set-ExecutionPolicy above
Set-Content -Path "$HOME\.local\bin\webi.bat" -Value "@echo off`r`npowershell -ExecutionPolicy Bypass %USERPROFILE%\.local\bin\webi-pwsh.ps1 %*"
# Backwards-compat bugfix: remove old webi-pwsh.ps1 location
Remove-Item -Path "$HOME\.local\bin\webi.ps1" -Recurse -ErrorAction Ignore
if (!(Test-Path -Path "$HOME\.local\opt")) {
New-Item -Path "$HOME\.local\opt" -ItemType Directory -Force | Out-Null
}
# TODO windows version of mktemp -d
if (!(Test-Path -Path "$HOME\.local\tmp")) {
New-Item -Path "$HOME\.local\tmp" -ItemType Directory -Force | Out-Null
# Backwards-compat bugfix: remove old webi-pwsh.ps1 location
Remove-Item -Path "$HOME\.local\bin\webi.ps1" -Recurse -ErrorAction Ignore
# TODO windows version of mktemp -d
IF (Test-Path -Path "$HOME\.local\tmp") {
Write-Host " Found $HOME\.local\tmp\"
} ELSE {
Write-Host " Creating $HOME\.local\tmp\"
$null = New-Item -Path "$HOME\.local\tmp" -ItemType Directory -Force | Out-Null
}
}
## show help if no params given or help flags are used
@@ -180,6 +182,9 @@ if ($exename -eq "-V" -or $exename -eq "--version" -or $exename -eq "version" -o
exit 0
}
# Switch to userprofile
Push-Location $Env:USERPROFILE
$Env:WEBI_UA = Get-UserAgent
IF ($IsWebiParent) {

View File

@@ -1,219 +1,9 @@
#!/bin/sh
set -e
set -u
#set -x
#########################################
# #
# Display Debug Info in Case of Failure #
# #
#########################################
fn_show_welcome_back() { (
if test -n "${WEBI_WELCOME:-}"; then
return 0
fi
echo ""
# invert t_task and t_pkg for top-level welcome message
printf -- ">>> %s %s <<<\n" \
"$(t_pkg 'Welcome to') $(t_task 'Webi')$(t_pkg '!')" \
"$(t_dim "- modern tools, instant installs.")"
echo " We expect your experience to be $(t_em 'absolutely perfect')!"
echo ""
echo " $(t_attn 'Success')? Star it! $(t_url 'https://github.com/webinstall/webi-installers')"
echo " $(t_attn 'Problem')? Report it: $(t_url 'https://github.com/webinstall/webi-installers/issues')"
echo " $(t_dim "(your system is") $(t_host "$(uname -s)")/$(t_host "$(uname -m)") $(t_dim "with") $(t_host "$(fn_get_libc)") $(t_dim "&") $(t_host "$(fn_get_http_client_name)")$(t_dim ")")"
sleep 0.2
); }
fn_get_libc() { (
# Ex:
# musl
# libc
if ldd /bin/ls 2> /dev/null | grep -q 'musl' 2> /dev/null; then
echo 'musl'
elif uname -o | grep -q 'GNU' || uname -s | grep -q 'Linux'; then
echo 'gnu'
else
echo 'libc'
fi
); }
fn_get_http_client_name() { (
# Ex:
# curl
# curl+wget
b_client=""
if command -v curl > /dev/null; then
b_client="curl"
fi
if command -v wget > /dev/null; then
if test -z "${b_client}"; then
b_client="wget"
else
b_client="curl+wget"
fi
fi
echo "${b_client}"
); }
#########################################
# #
# For Making the Display Nice #
# #
#########################################
# Term Types
t_cmd() { (fn_printf '\e[2m\e[35m%s\e[39m\e[22m' "${1}"); }
t_host() { (fn_printf '\e[2m\e[33m%s\e[39m\e[22m' "${1}"); }
t_link() { (fn_printf '\e[1m\e[36m%s\e[39m\e[22m' "${1}"); }
t_path() { (fn_printf '\e[2m\e[32m%s\e[39m\e[22m' "${1}"); }
t_pkg() { (fn_printf '\e[1m\e[32m%s\e[39m\e[22m' "${1}"); }
t_task() { (fn_printf '\e[36m%s\e[39m' "${1}"); }
t_url() { (fn_printf '\e[2m%s\e[22m' "${1}"); }
# Levels
t_info() { (fn_printf '\e[1m\e[36m%s\e[39m\e[22m' "${1}"); }
t_attn() { (fn_printf '\e[1m\e[33m%s\e[39m\e[22m' "${1}"); }
t_warn() { (fn_printf '\e[1m\e[33m%s\e[39m\e[22m' "${1}"); }
t_err() { (fn_printf '\e[31m%s\e[39m' "${1}"); }
# Styles
t_bold() { (fn_printf '\e[1m%s\e[22m' "${1}"); }
t_dim() { (fn_printf '\e[2m%s\e[22m' "${1}"); }
t_em() { (fn_printf '\e[3m%s\e[23m' "${1}"); }
t_under() { (fn_printf '\e[4m%s\e[24m' "${1}"); }
# FG Colors
t_cyan() { (fn_printf '\e[36m%s\e[39m' "${1}"); }
t_green() { (fn_printf '\e[32m%s\e[39m' "${1}"); }
t_magenta() { (fn_printf '\e[35m%s\e[39m' "${1}"); }
t_yellow() { (fn_printf '\e[33m%s\e[39m' "${1}"); }
fn_printf() { (
a_style="${1}"
a_text="${2}"
if fn_is_tty; then
#shellcheck disable=SC2059
printf -- "${a_style}" "${a_text}"
else
printf -- '%s' "${a_text}"
fi
); }
fn_sub_home() { (
my_rel=${HOME}
my_abs=${1}
echo "${my_abs}" | sed "s:^${my_rel}:~:"
); }
###################################
# #
# Detect HTTP Client #
# #
###################################
fn_wget() { (
# Doc:
# Downloads the file at the given url to the given path
a_url="${1}"
a_path="${2}"
cmd_wget="wget -q --user-agent"
if fn_is_tty; then
cmd_wget="wget -q --show-progress --user-agent"
fi
b_triple_ua="$(fn_get_target_triple_user_agent)"
b_agent="webi/wget ${b_triple_ua}"
if command -v curl > /dev/null; then
b_agent="webi/wget+curl ${b_triple_ua}"
fi
if ! $cmd_wget "${b_agent}" -c "${a_url}" -O "${a_path}"; then
echo >&2 " $(t_err "failed to download (wget)") '$(t_url "${a_url}")'"
echo >&2 " $cmd_wget '${b_agent}' -c '${a_url}' -O '${a_path}'"
echo >&2 " $(wget -V)"
return 1
fi
); }
fn_curl() { (
# Doc:
# Downloads the file at the given url to the given path
a_url="${1}"
a_path="${2}"
cmd_curl="curl -f -sSL -#"
if fn_is_tty; then
cmd_curl="curl -f -sSL"
fi
b_triple_ua="$(fn_get_target_triple_user_agent)"
b_agent="webi/curl ${b_triple_ua}"
if command -v wget > /dev/null; then
b_agent="webi/curl+wget ${b_triple_ua}"
fi
if ! $cmd_curl -A "${b_agent}" "${a_url}" -o "${a_path}"; then
echo >&2 " $(t_err "failed to download (curl)") '$(t_url "${a_url}")'"
echo >&2 " $cmd_curl -A '${b_agent}' '${a_url}' -o '${a_path}'"
echo >&2 " $(curl -V)"
return 1
fi
); }
fn_get_target_triple_user_agent() { (
# Ex:
# x86_64/unknown Linux/5.15.107-2-pve gnu
# arm64/unknown Darwin/22.6.0 libc
echo "$(uname -m)/unknown $(uname -s)/$(uname -r) $(fn_get_libc)"
); }
fn_download_to_path() { (
a_url="${1}"
a_path="${2}"
mkdir -p "$(dirname "${a_path}")"
if command -v wget > /dev/null; then
fn_wget "${a_url}" "${a_path}.part"
elif command -v curl > /dev/null; then
fn_curl "${a_url}" "${a_path}.part"
else
echo >&2 " $(t_err "failed to detect HTTP client (curl, wget)")"
return 1
fi
mv "${a_path}.part" "${a_path}"
); }
##############################################
# #
# Detect TTY and run main #
# #
##############################################
fn_is_tty() {
if test "${WEBI_TTY}" = 'tty'; then
return 0
fi
return 1
}
fn_detect_tty() { (
# stdin will NOT be a tty if it's being piped
# stdout & stderr WILL be a tty even when piped
# they are not a tty if being captured or redirected
# 'set -i' is NOT available in sh
if test -t 1 && test -t 2; then
return 0
fi
return 1
); }
__webi_main() {
my_date="$(date +%F_%H-%M-%S)"
@@ -297,38 +87,39 @@ __webi_main() {
webinstall() {
b_package="${1:-}"
if test -z "${b_package}"; then
my_package="${1:-}"
if [ -z "$my_package" ]; then
echo >&2 "Usage: webi <package>@<version> ..."
echo >&2 "Example: webi node@lts rg"
exit 1
fi
b_install_tmpdir="$(
mktemp -d -t "${b_package}-install.${WEBI_TIMESTAMP}.XXXXXXXX"
WEBI_BOOT="$(
mktemp -d -t "$my_package-bootstrap.$WEBI_TIMESTAMP.XXXXXXXX"
)"
export WEBI_BOOT
my_installer_url="$WEBI_HOST/api/installers/${b_package}.sh?formats=${my_ext}"
my_installer_url="$WEBI_HOST/api/installers/$my_package.sh?formats=$my_ext"
if [ -n "$WEBI_CURL" ]; then
if ! curl -fsSL "$my_installer_url" -H "User-Agent: curl $WEBI_UA" \
-o "${b_install_tmpdir}/${b_package}-install.sh"; then
-o "$WEBI_BOOT/$my_package-bootstrap.sh"; then
echo >&2 "error fetching '$my_installer_url'"
exit 1
fi
else
if ! wget -q "$my_installer_url" --user-agent="wget $WEBI_UA" \
-O "${b_install_tmpdir}/${b_package}-install.sh"; then
-O "$WEBI_BOOT/$my_package-bootstrap.sh"; then
echo >&2 "error fetching '$my_installer_url'"
exit 1
fi
fi
(
cd "${b_install_tmpdir}"
sh "${b_package}-install.sh"
cd "$WEBI_BOOT"
sh "$my_package-bootstrap.sh"
)
rm -rf "${b_install_tmpdir}"
rm -rf "$WEBI_BOOT"
}
@@ -494,7 +285,6 @@ __webi_main() {
for pkgname in "$@"; do
webinstall "$pkgname"
export WEBI_WELCOME='shown'
done
show_path_updates

View File

@@ -4,31 +4,8 @@ var github = require('../_common/github.js');
var owner = 'mikefarah';
var repo = 'yq';
let ODDITIES = ['man_page_only'];
function isOdd(build) {
for (let oddity of ODDITIES) {
let isOddity = build.name.includes(oddity);
if (isOddity) {
return true;
}
}
}
module.exports = function (request) {
return github(request, owner, repo).then(function (all) {
let builds = [];
for (let build of all.releases) {
let odd = isOdd(build);
if (odd) {
continue;
}
builds.push(build);
}
all.releases = builds;
return all;
});
};

View File

@@ -1,7 +1,5 @@
'use strict';
var NON_BUILDS = ['bootstrap', 'src'];
module.exports = function (request) {
return request({
url: 'https://ziglang.org/download/index.json',
@@ -13,7 +11,6 @@ module.exports = function (request) {
let refs = Object.keys(versions);
refs.forEach(function (ref) {
let pkgs = versions[ref];
let version = pkgs.version || ref;
// "platform" = arch + os combo
let platforms = Object.keys(pkgs);
@@ -27,11 +24,6 @@ module.exports = function (request) {
return;
}
let isNonBuild = NON_BUILDS.includes(platform);
if (isNonBuild) {
return;
}
// Ex: aarch64-macos => ['aarch64', 'macos']
let parts = platform.split('-');
//let arch = parts[0];
@@ -44,7 +36,7 @@ module.exports = function (request) {
}
let p = {
version: version,
version: ref,
date: pkgs.date,
channel: 'stable',
// linux, macos, windows