Compare commits

..

48 Commits

Author SHA1 Message Date
AJ ONeal
b96f457496 wip: feat: log whenever directories are created 2023-11-20 00:05:35 +00:00
AJ ONeal
0b3f73f661 wip: feat: add convenience functions to webi script 2023-11-20 00:05:35 +00:00
AJ ONeal
a4a386dd8a ref: rename to package-install.tpl.sh to match namespace style 2023-11-18 23:57:33 -07:00
AJ ONeal
e39e9722d7 ref(posix): various whitespace and text style updates 2023-11-18 23:00:26 -07:00
AJ ONeal
b56229ca62 ref(install): minor tweaks to differences from bootstrap 2023-11-18 23:00:25 -07:00
AJ ONeal
98ed726ec4 ref(install): bring into parity with curl-pipe-bootstrap 2023-11-18 23:00:25 -07:00
AJ ONeal
37201dc257 ref(bootstrap): organize functions into commented sections 2023-11-18 19:04:37 -07:00
AJ ONeal
4f53a412e5 ref(bootstrap): word order, wording, & style cleanup 2023-11-18 19:04:37 -07:00
AJ ONeal
e4c4fd8c08 fix(bootstrap): preserve file handle: mv & rm rather overwrite webi 2023-11-18 19:04:37 -07:00
AJ ONeal
7fe17220b7 ref(bootstrap): use -- in printf -- '%s' "${foo}" just to be safe 2023-11-18 19:04:37 -07:00
AJ ONeal
24f6703a2d fix(bootstrap): POSIX doesn't define 'interactive', detect TTY instead 2023-11-18 19:04:37 -07:00
AJ ONeal
6296dece2a ref(bootstrap): organize text styles 2023-11-18 19:04:36 -07:00
AJ ONeal
3908a7df9f fix(bootstrap): only apply text style & color to TTYs 2023-11-18 19:04:36 -07:00
AJ ONeal
1267272902 fix(bootstrap): track if just upgraded to limit upgrade attempts 2023-11-18 19:04:36 -07:00
AJ ONeal
4869336b24 fix(webi): track if welcome message was already shown 2023-11-18 19:04:36 -07:00
AJ ONeal
ddda72daac fix(bootstrap): track if welcome message was already shown 2023-11-18 19:03:45 -07:00
AJ ONeal
bfb54691e8 fix(bootstrap): typo '-f sSL' => '-f -sSL' 2023-11-18 18:09:32 -07:00
AJ ONeal
8aa665be56 fix(posix): set WEBI_CHECKSUM in both bootstrap and installer 2023-11-18 18:09:31 -07:00
AJ ONeal
c0c7e61cb5 fix: revert curl --fail-with-body to --fail 2023-11-17 08:57:24 -07:00
AJ ONeal
993e2dd75b fix!(chromedriver): rewrite for latest releases URL 2023-11-15 21:59:33 -07:00
AJ ONeal
286efb7898 fix(yq): filter out special non-build files 2023-11-15 21:31:20 -07:00
AJ ONeal
5ee4ecde56 fix(terraform): remove incorrect arch detection 2023-11-15 21:31:20 -07:00
AJ ONeal
af645df848 fix(kube*): filter out companion util and legacy scripts 2023-11-15 21:31:20 -07:00
AJ ONeal
18b1effadd fix(jq): filter out special non-build files 2023-11-15 21:31:20 -07:00
AJ ONeal
0f96b709f0 fix(go): filter out typoed beta release 2023-11-15 21:31:20 -07:00
AJ ONeal
b908672f12 fix(flutter): add _version to match version in filepath 2023-11-15 21:31:20 -07:00
AJ ONeal
b925ebe746 fix(flutter): remove incorrect os/arch detection 2023-11-15 21:31:19 -07:00
AJ ONeal
777b28a924 fix(fd): filter out unmatchable legacy build 2023-11-15 21:31:19 -07:00
AJ ONeal
46374beb68 ref(dashcore): remove custom filtering on generic asset type 2023-11-15 21:31:19 -07:00
AJ ONeal
852bae9d3d fix(dashcore): add _version to match version in filepath 2023-11-15 21:31:19 -07:00
AJ ONeal
afbebb8676 fix(cmake): add _version to match version in filepath 2023-11-15 21:31:19 -07:00
AJ ONeal
b63eb6d839 fix(ssh-adduser): check if SSH_ADDUSER_AUTO is set 2023-11-14 14:46:04 -07:00
AJ ONeal
8ea2e01f4c fix(iterm2): don't update to the same version 2023-11-14 13:58:34 -07:00
AJ ONeal
b843c689a0 ref(releases): filter out various one-offs and non-builds 2023-11-14 12:10:04 -07:00
AJ ONeal
dc1ab03aeb ref(releases): add classification helpers: _names, _version, _filenames 2023-11-14 12:10:04 -07:00
AJ ONeal
e9485d85ad chore: burn junk comments 2023-11-14 12:10:04 -07:00
AJ ONeal
42f9e73b55 ref(flutter): cleanup releases.js, add hash, don't resort 2023-11-14 12:10:04 -07:00
AJ ONeal
e49ba2ba92 fix(flutter): update release URLs for v3.x 2023-11-14 12:09:53 -07:00
AJ ONeal
3d2280b026 fix(pwsh): '$pkg_dst' is a link, not a directory 2023-11-14 12:08:18 -07:00
AJ ONeal
aa03b9e4f1 fix(flutter): fix bad 'v' match: don't replace 'dev' with 'de' 2023-11-14 10:55:08 -07:00
AJ ONeal
e0820b5517 fix(gitea): check for and install 'git' on Windows 2023-11-14 10:55:07 -07:00
AJ ONeal
e05551cb06 fix(zig): use semver version for beta / 'master' 2023-11-14 10:55:07 -07:00
AJ ONeal
cf621183b4 fix(windows): use -L with curl (for redirects from Github assets, etc) 2023-11-14 10:55:07 -07:00
AJ ONeal
3c05298c6a fix(arm): don't match 'arm64' for 'arm' without bit or version specifier 2023-11-14 10:55:07 -07:00
AJ ONeal
0c438aff8f ref!: make 'pwsh' canonical package for PowerShell Core 2023-11-12 02:32:27 -07:00
AJ ONeal
fc8cef1308 ref!: add 'powershell' as alias for 'pwsh' 2023-11-12 02:32:27 -07:00
AJ ONeal
8ed7909e15 ref!: transitory rename of 'powershell' to 'pwsh' 2023-11-12 02:32:27 -07:00
AJ ONeal
de36cf6b10 ref!: delete alias 'pwsh' in prep for powershell => pwsh transition 2023-11-12 02:32:27 -07:00
128 changed files with 1602 additions and 835 deletions

View File

@@ -30,7 +30,7 @@ IF (!(Test-Path -Path "$pkg_src_cmd")) {
# TODO: create package-specific temp directory # TODO: create package-specific temp directory
# Enter tmp # Enter tmp
Push-Location $HOME\.local\tmp Push-Location .local\tmp
# Remove any leftover tmp cruft # Remove any leftover tmp cruft
Remove-Item -Path ".\foobar-v*" -Recurse -ErrorAction Ignore Remove-Item -Path ".\foobar-v*" -Recurse -ErrorAction Ignore

View File

@@ -16,40 +16,22 @@ export WEBI_CHECKSUM=06a7fb9f
# # # #
######################################### #########################################
# shellcheck disable=SC2005
fn_show_welcome() { ( fn_show_welcome() { (
echo "" 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 "" echo ""
echo " $(t_yellow 'Have a problem?') Please $(t_em 'let us know'):" # invert t_task and t_pkg for top-level welcome message
echo " $(t_url 'https://github.com/webinstall/webi-installers/issues')" printf -- ">>> %s %s <<<\n" \
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)"))")" "$(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 ""
echo " $(t_yellow 'Love it?') Star it!" echo " $(t_attn 'Success')? Star it! $(t_url 'https://github.com/webinstall/webi-installers')"
echo " $(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 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() { ( fn_get_libc() { (
# Ex: # Ex:
# musl # musl
@@ -63,7 +45,7 @@ fn_get_libc() { (
fi fi
); } ); }
fn_get_http() { ( fn_get_http_client_name() { (
# Ex: # Ex:
# curl # curl
# curl+wget # curl+wget
@@ -82,6 +64,56 @@ fn_get_http() { (
echo "${b_client}" 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 # # Detect HTTP Client #
@@ -95,7 +127,7 @@ fn_wget() { (
a_path="${2}" a_path="${2}"
cmd_wget="wget -q --user-agent" cmd_wget="wget -q --user-agent"
if fn_is_interactive; then if fn_is_tty; then
cmd_wget="wget -q --show-progress --user-agent" cmd_wget="wget -q --show-progress --user-agent"
fi fi
@@ -119,9 +151,9 @@ fn_curl() { (
a_url="${1}" a_url="${1}"
a_path="${2}" a_path="${2}"
cmd_curl="curl --fail-with-body -sSL -#" cmd_curl="curl -f -sSL -#"
if fn_is_interactive; then if fn_is_tty; then
cmd_curl="curl --fail-with-body sSL" cmd_curl="curl -f -sSL"
fi fi
b_triple_ua="$(fn_get_target_triple_user_agent)" b_triple_ua="$(fn_get_target_triple_user_agent)"
@@ -138,16 +170,6 @@ fn_curl() { (
fi fi
); } ); }
fn_is_interactive() {
# Ex:
# himBH
# hBc
case $- in
*i*) return 0 ;;
*) return 1 ;;
esac
}
fn_get_target_triple_user_agent() { ( fn_get_target_triple_user_agent() { (
# Ex: # Ex:
# x86_64/unknown Linux/5.15.107-2-pve gnu # x86_64/unknown Linux/5.15.107-2-pve gnu
@@ -177,31 +199,45 @@ fn_download_to_path() { (
# # # #
############################################## ##############################################
webi_upgrade() { ( webi_bootstrap() { (
a_path="${1}" a_path="${1}"
echo "" echo ""
echo "$(t_strong 'Bootstrapping') $(t_stronger 'Webi')" echo "$(t_task 'Bootstrapping') $(t_pkg 'Webi')"
b_path_rel="$(fn_sub_home "${a_path}")" b_path_rel="$(fn_sub_home "${a_path}")"
b_checksum="" b_checksum=""
if test -r "${a_path}"; then if test -r "${a_path}"; then
echo " $(t_dim 'Found') $(t_path "${b_path_rel}")"
b_checksum="$(fn_checksum "${a_path}")" b_checksum="$(fn_checksum "${a_path}")"
fi fi
if test "$b_checksum" = "${WEBI_CHECKSUM}"; then if test "$b_checksum" = "${WEBI_CHECKSUM}"; then
echo " $(t_dim 'Found') $(t_path "${b_path_rel}")"
sleep 0.1 sleep 0.1
return 0 return 0
fi fi
b_webi_file_url="${WEBI_HOST}/packages/webi/webi.sh" b_webi_file_url="${WEBI_HOST}/packages/webi/webi.sh"
b_tmp=''
if test -r "${a_path}"; then 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}")" echo " Updating $(t_path "${b_path_rel}")"
fi 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 " Downloading $(t_url "${b_webi_file_url}")"
echo " to $(t_path "${b_path_rel}")" echo " to $(t_path "${b_path_rel}")"
fn_download_to_path "${b_webi_file_url}" "${a_path}" fn_download_to_path "${b_webi_file_url}" "${a_path}"
chmod u+x "${a_path}" chmod u+x "${a_path}"
if test -r "${b_tmp}"; then
rm -f "${b_tmp}"
fi
); } ); }
fn_checksum() { fn_checksum() {
@@ -215,29 +251,64 @@ fn_checksum() {
$cmd_shasum "${a_filepath}" | cut -d' ' -f1 | cut -c 1-8 $cmd_shasum "${a_filepath}" | cut -d' ' -f1 | cut -c 1-8
} }
fn_sub_home() { ( ##############################################
my_rel=${HOME} # #
my_abs=${1} # Detect TTY and run main #
echo "${my_abs}" | sed "s:^${my_rel}:~:" # #
##############################################
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() { ( main() { (
fn_show_welcome set -e
export WEBI_WELCOME=true 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'
# note: we may support custom locations in the future # note: we may support custom locations in the future
export WEBI_HOME="${HOME}/.local" export WEBI_HOME="${HOME}/.local"
b_home="$(fn_sub_home "${WEBI_HOME}")" b_home="$(fn_sub_home "${WEBI_HOME}")"
b_webi_path="${WEBI_HOME}/bin/webi" b_webi_path="${WEBI_HOME}/bin/webi"
b_webi_path_rel="${b_home}/bin/webi" b_webi_path_rel="${b_home}/bin/webi"
webi_upgrade "${b_webi_path}"
echo "" WEBI_CURRENT="${WEBI_CURRENT:-}"
echo "$(t_strong 'Installing') $(t_stronger "${WEBI_PKG}") $(t_strong '...')" 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 " Running $(t_cmd "${b_webi_path_rel} ${WEBI_PKG}")"
echo ""
"${b_webi_path}" "${WEBI_PKG}" "${b_webi_path}" "${WEBI_PKG}"
); } ); }
set -e
set -u
main main

View File

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

View File

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

View File

@@ -1,27 +1,10 @@
#!/bin/sh #!/bin/sh
__bootstrap_webi() { __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= #PKG_NAME=
#WEBI_OS= #WEBI_OS=
#WEBI_ARCH= #WEBI_ARCH=
#WEBI_LIBC= #WEBI_LIBC=
#WEBI_HOST=
#WEBI_RELEASES= #WEBI_RELEASES=
#WEBI_CSV= #WEBI_CSV=
#WEBI_TAG= #WEBI_TAG=
@@ -43,7 +26,6 @@ __bootstrap_webi() {
#PKG_ARCHES= #PKG_ARCHES=
#PKG_LIBCS= #PKG_LIBCS=
#PKG_FORMATS= #PKG_FORMATS=
WEBI_UA="$(uname -s)/$(uname -r) $(uname -m)/unknown ${my_libc}"
WEBI_PKG_DOWNLOAD="" WEBI_PKG_DOWNLOAD=""
WEBI_DOWNLOAD_DIR="${HOME}/Downloads" WEBI_DOWNLOAD_DIR="${HOME}/Downloads"
if command -v xdg-user-dir > /dev/null; then if command -v xdg-user-dir > /dev/null; then
@@ -55,43 +37,6 @@ __bootstrap_webi() {
WEBI_PKG_PATH="${WEBI_DOWNLOAD_DIR}/webi/${PKG_NAME:-error}/${WEBI_VERSION:-latest}" 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 # get the special formatted version
# (i.e. "go is go1.14" while node is "node v12.10.8") # (i.e. "go is go1.14" while node is "node v12.10.8")
my_versioned_name="" my_versioned_name=""
@@ -142,38 +87,30 @@ __bootstrap_webi() {
if [ -n "$my_current_cmd" ]; then if [ -n "$my_current_cmd" ]; then
my_canonical_name="$(_webi_canonical_name)" my_canonical_name="$(_webi_canonical_name)"
if [ "$my_current_cmd" != "$pkg_dst_cmd" ]; then if [ "$my_current_cmd" != "$pkg_dst_cmd" ]; then
echo >&2 "WARN: possible PATH conflict between $my_canonical_name and currently installed version" echo >&2 " $(t_err "WARN: possible PATH conflict between $my_canonical_name and currently installed version")"
echo >&2 " ${pkg_dst_cmd} (new)" echo >&2 " $(t_path "${pkg_dst_cmd}") (new)"
echo >&2 " ${my_current_cmd} (existing)" echo >&2 " $(t_path "${my_current_cmd}") (existing)"
#my_current_version=false #my_current_version=false
fi fi
# 'readlink' can't read links in paths on macOS 🤦 # 'readlink' can't read links in paths on macOS 🤦
# but that's okay, 'cmp -s' is good enough for us # but that's okay, 'cmp -s' is good enough for us
if cmp -s "${pkg_src_cmd}" "${my_current_cmd}"; then if cmp -s "${pkg_src_cmd}" "${my_current_cmd}"; then
echo "${my_canonical_name} already installed:" echo " $(t_pkg "${my_canonical_name}") already installed:"
my_dst_rel="$( my_dst_rel="$(fn_sub_home "${pkg_dst}")"
webi_sub_home "${pkg_dst}" printf " %s" "$(t_link "${my_dst_rel}")"
)"
printf " %s" "${my_dst_rel}"
if [ "${pkg_src_cmd}" != "${my_current_cmd}" ]; then if [ "${pkg_src_cmd}" != "${my_current_cmd}" ]; then
my_src_rel="$( my_src_rel="$(fn_sub_home "${pkg_src}")"
webi_sub_home "${pkg_src}" printf " => %s" "$(t_path "${my_src_rel}")"
)"
printf " => %s" "${my_src_rel}"
fi fi
echo "" echo ""
exit 0 exit 0
fi fi
if [ -x "$pkg_src_cmd" ]; then if [ -x "$pkg_src_cmd" ]; then
webi_link webi_link
echo "switched to $my_canonical_name:" echo " Switched to ${my_canonical_name}:"
my_src_rel="$( my_src_rel="$(fn_sub_home "${pkg_src}")"
webi_sub_home "${pkg_src}" my_dst_rel="$(fn_sub_home "${pkg_dst}")"
)" echo " $(t_link "${my_dst_rel}") => $(t_path "${my_src_rel}")"
my_dst_rel="$(
webi_sub_home "${pkg_dst}"
)"
echo " ${my_dst_rel} => ${my_src_rel}"
exit 0 exit 0
fi fi
fi fi
@@ -185,110 +122,61 @@ __bootstrap_webi() {
return 0 return 0
fi fi
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 ""
echo >&2 " (check that the package name and version are correct)" 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 >&2 "" echo " '$PKG_NAME' is available for '$PKG_OSES' ($PKG_LIBCS) on '$PKG_ARCHES' as one of '$PKG_FORMATS'"
my_release_url="$( echo " (check that the package name and version are correct)"
echo "$WEBI_RELEASES" |
sed 's:?.*::' echo ""
)" my_release_url="$(echo "$WEBI_RELEASES" | sed 's:?.*::')"
my_release_params="$( my_release_params="$(echo "$WEBI_RELEASES" | sed 's:.*?:?:')"
echo "$WEBI_RELEASES" | echo " Double check at ${my_release_url}"
sed 's:.*?:?:' echo " ${my_release_params}"
)" echo ""
echo >&2 " Double check at ${my_release_url}" } >&2
echo >&2 " ${my_release_params}"
echo >&2 ""
exit 1 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 # detect if file is downloaded, and how to download it
webi_download() { webi_download() {
my_url="${1}" my_url="${1}"
my_dl="${2}" my_dl="${2}"
my_dl_name="${3:-${PKG_NAME}}" my_dl_name="${3:-${PKG_NAME}}"
my_dl_rel="$( my_dl_rel="$(fn_sub_home "${my_dl}")"
webi_sub_home "${my_dl}"
)"
WEBI_PKG_DOWNLOAD="${my_dl}" WEBI_PKG_DOWNLOAD="${my_dl}"
export WEBI_PKG_DOWNLOAD export WEBI_PKG_DOWNLOAD
if [ -e "${my_dl}" ]; then if [ -e "${my_dl}" ]; then
echo "Found ${my_dl_rel}" echo " $(t_dim 'Found') $(t_path "${my_dl_rel}")"
return 0 return 0
fi fi
echo " Downloading $(t_pkg "${my_dl_name}") from"
echo "Downloading ${my_dl_name} from" echo " $(t_url "${my_url}")"
echo "$my_url" fn_download_to_path "${my_url}" "${my_dl}"
echo " $(t_dim 'Saved as') $(t_path "${my_dl_rel}")"
# 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() { ( webi_git_clone() { (
my_url="${1}" my_url="${1}"
my_dl="${2}" my_dl="${2}"
my_dl_rel="$( my_dl_rel="$(fn_sub_home "${my_dl}")"
webi_sub_home "${my_dl}"
)"
if [ -e "${my_dl}" ]; then if [ -e "${my_dl}" ]; then
echo "Found ${my_dl_rel}" echo " $(t_dim 'Found') $(t_path "${my_dl_rel}")"
cp -RPp "${my_dl}" "${WEBI_TMP}/${WEBI_PKG_FILE}/" cp -RPp "${my_dl}" "${WEBI_TMP}/${WEBI_PKG_FILE}/"
return 0 return 0
fi fi
echo "Cloning ${my_url}" echo " Cloning $(t_url "${my_url}")"
cmd_git="git clone --config advice.detachedHead=false --quiet --depth=1 --single-branch" cmd_git="git clone --config advice.detachedHead=false --quiet --depth=1 --single-branch"
rm -rf "${my_dl}.part" rm -rf "${my_dl}.part"
if ! $cmd_git "${my_url}" --branch "${WEBI_GIT_TAG}" "${my_dl}.part"; then if ! $cmd_git "${my_url}" --branch "${WEBI_GIT_TAG}" "${my_dl}.part"; then
echo >&2 "failed to git clone ${WEBI_PKG_URL}" echo >&2 " $(t_err "failed to git clone ${WEBI_PKG_URL}")"
exit 1 exit 1
fi fi
mv "${my_dl}.part" "${my_dl}" mv "${my_dl}.part" "${my_dl}"
@@ -297,34 +185,33 @@ __bootstrap_webi() {
); } ); }
# detect which archives can be used # detect which archives can be used
webi_extract() { webi_extract() { (
( cd "$WEBI_TMP"
cd "$WEBI_TMP"
my_dl_rel="$( my_dl_rel="$(
webi_sub_home "${WEBI_PKG_PATH}/${WEBI_PKG_FILE}" fn_sub_home "${WEBI_PKG_PATH}/${WEBI_PKG_FILE}"
)" )"
if [ "tar" = "$WEBI_EXT" ]; then if [ "tar" = "$WEBI_EXT" ]; then
echo "Extracting ${my_dl_rel}" echo " Extracting $(t_path "${my_dl_rel}")"
tar xf "${WEBI_PKG_PATH}/$WEBI_PKG_FILE" tar xf "${WEBI_PKG_PATH}/$WEBI_PKG_FILE"
elif [ "zip" = "$WEBI_EXT" ]; then elif [ "zip" = "$WEBI_EXT" ]; then
echo "Extracting ${my_dl_rel}" echo " Extracting $(t_path "${my_dl_rel}")"
unzip "${WEBI_PKG_PATH}/$WEBI_PKG_FILE" > __unzip__.log unzip "${WEBI_PKG_PATH}/$WEBI_PKG_FILE" > __unzip__.log
elif [ "exe" = "$WEBI_EXT" ]; then elif [ "exe" = "$WEBI_EXT" ]; then
echo "Moving ${my_dl_rel}" echo " Moving $(t_path "${my_dl_rel}")"
mv "${WEBI_PKG_PATH}/$WEBI_PKG_FILE" . echo " to $(t_path "$(fn_sub_home "$(pwd)")")"
elif [ "git" = "$WEBI_EXT" ]; then mv "${WEBI_PKG_PATH}/$WEBI_PKG_FILE" .
echo "Moving ${my_dl_rel}" elif [ "git" = "$WEBI_EXT" ]; then
mv "${WEBI_PKG_PATH}/$WEBI_PKG_FILE" . echo " Moving $(t_path "${my_dl_rel}")"
elif [ "xz" = "$WEBI_EXT" ]; then mv "${WEBI_PKG_PATH}/$WEBI_PKG_FILE" .
echo "Inflating ${my_dl_rel}" elif [ "xz" = "$WEBI_EXT" ]; then
unxz -c "${WEBI_PKG_PATH}/$WEBI_PKG_FILE" > "$(basename "$WEBI_PKG_FILE")" echo " Inflating $(t_path "${my_dl_rel}")"
else unxz -c "${WEBI_PKG_PATH}/$WEBI_PKG_FILE" > "$(basename "$WEBI_PKG_FILE")"
echo "Failed to extract ${WEBI_PKG_PATH}/$WEBI_PKG_FILE" else
exit 1 echo " $(t_err 'Failed to extract') $(t_path "${WEBI_PKG_PATH}/$WEBI_PKG_FILE")"
fi exit 1
) fi
} ); }
# use 'pathman' to update $HOME/.config/envman/PATH.env # use 'pathman' to update $HOME/.config/envman/PATH.env
webi_path_add() { webi_path_add() {
@@ -522,13 +409,19 @@ __bootstrap_webi() {
# move commands from the extracted archive directory # move commands from the extracted archive directory
# to $HOME/.local/opt or $HOME/.local/bin # to $HOME/.local/opt or $HOME/.local/bin
webi_install() { webi_install() {
b_src=''
if test -n "${WEBI_SINGLE}"; then if test -n "${WEBI_SINGLE}"; then
b_src="${pkg_src_cmd}"
mkdir -p "$(dirname "$pkg_src_cmd")" mkdir -p "$(dirname "$pkg_src_cmd")"
mv ./"$pkg_cmd_name"* "$pkg_src_cmd"
else else
echo " Removing $(t_path "${pkg_src}")"
rm -rf "$pkg_src" rm -rf "$pkg_src"
mv ./"$pkg_cmd_name"* "$pkg_src" b_src="${pkg_src}"
fi 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 # run post-install functions - just updating PATH by default
@@ -549,15 +442,30 @@ __bootstrap_webi() {
} }
_webi_done_message() { _webi_done_message() {
my_dst_rel="$( my_dst_rel="$(fn_sub_home "${pkg_dst_cmd}")"
webi_sub_home "${pkg_dst_cmd}" my_canonical_name="$(_webi_canonical_name)"
)" echo ""
my_canonical_name="$( echo " Installed $(t_pkg "${my_canonical_name}") as $(t_link "${my_dst_rel}")"
_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 ## BEGIN custom override functions from <package>/install.sh
@@ -566,20 +474,6 @@ __bootstrap_webi() {
WEBI_SINGLE= 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() { __init_installer() {
# the installer will be injected here # the installer will be injected here
# {{ installer }} # {{ installer }}
@@ -642,12 +536,12 @@ __bootstrap_webi() {
( (
cd "$WEBI_TMP" cd "$WEBI_TMP"
my_src_rel="$( my_src_rel="$(
webi_sub_home "${pkg_src_cmd}" fn_sub_home "${pkg_src_cmd}"
)" )"
if test -e "${pkg_src_cmd}"; then if test -e "${pkg_src_cmd}"; then
echo "Found ${my_src_rel} (remove to force reinstall)" echo " $(t_dim 'Found') $(t_path "${my_src_rel}") $(t_dim '(remove to force reinstall)')"
else else
echo "Installing to ${my_src_rel}" echo " Installing to $(t_path "${my_src_rel}")"
if command -v pkg_install > /dev/null; then pkg_install; else webi_install; fi if command -v pkg_install > /dev/null; then pkg_install; else webi_install; fi
chmod a+x "$pkg_src" chmod a+x "$pkg_src"
chmod a+x "$pkg_src_cmd" chmod a+x "$pkg_src_cmd"
@@ -674,22 +568,328 @@ __bootstrap_webi() {
webi_path_add "$HOME/.local/bin" webi_path_add "$HOME/.local/bin"
if [ -z "${_WEBI_CHILD-}" ] && [ -f "$_webi_tmp/.PATH.env" ]; then if [ -z "${_WEBI_CHILD-}" ] && [ -f "$_webi_tmp/.PATH.env" ]; then
if test -s "$_webi_tmp/.PATH.env"; then if test -s "$_webi_tmp/.PATH.env"; then
printf 'PATH.env updated with:\n' # shellcheck disable=SC2088 # ~ should not expand here
echo " Updated $(t_path '~/.config/envman/PATH.env') updated with:"
sort -u "$_webi_tmp/.PATH.env" | while read -r my_new_path; do sort -u "$_webi_tmp/.PATH.env" | while read -r my_new_path; do
echo " ${my_new_path}" echo " $(t_path "${my_new_path}")"
done done
printf "\n" echo ""
rm -f "$_webi_tmp/.PATH.env" rm -f "$_webi_tmp/.PATH.env"
printf "\e[1m\e[35mTO FINISH\e[0m: copy, paste & run the following command:\n" echo ">>> $(t_attn 'ACTION REQUIRED') <<<"
printf "\n" echo ""
printf " \e[1m\e[32msource ~/.config/envman/PATH.env\e[0m\n" echo " Copy, paste & run the following command:"
printf " (newly opened terminal windows will update automatically)\n" echo " $(t_attn 'source ~/.config/envman/PATH.env')"
echo " (newly opened terminal windows will update automatically)"
echo ""
echo "^^^ $(t_attn 'ACTION REQUIRED') ^^^"
fi fi
fi fi
rm -rf "$WEBI_TMP" rm -rf "$WEBI_TMP"
} }
__bootstrap_webi #########################################
# #
# 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

View File

@@ -1,8 +1,10 @@
'use strict'; 'use strict';
var fs = require('node:fs'); var Crypto = require('crypto');
var Fs = require('node:fs/promises');
var path = require('node:path'); var path = require('node:path');
var request = require('@root/request'); var request = require('@root/request');
var _normalize = require('../_webi/normalize.js'); var _normalize = require('../_webi/normalize.js');
var reInstallTpl = /\s*#?\s*{{ installer }}/; var reInstallTpl = /\s*#?\s*{{ installer }}/;
@@ -39,10 +41,7 @@ Releases.renderBash = async function (
if (!tag) { if (!tag) {
tag = ''; tag = '';
} }
let installTxt = await fs.promises.readFile( let installTxt = await Fs.readFile(path.join(pkgdir, 'install.sh'), 'utf8');
path.join(pkgdir, 'install.sh'),
'utf8',
);
installTxt = padScript(installTxt); installTxt = padScript(installTxt);
var vers = rel.version.split('.'); var vers = rel.version.split('.');
var v = { var v = {
@@ -55,8 +54,8 @@ Releases.renderBash = async function (
.replace(/^-/, ''), .replace(/^-/, ''),
}; };
var pkgFile = rel.filename || rel.name; var pkgFile = rel.filename || rel.name;
let tplTxt = await fs.promises.readFile( let tplTxt = await Fs.readFile(
path.join(__dirname, 'install-package.tpl.sh'), path.join(__dirname, 'package-install.tpl.sh'),
'utf8', 'utf8',
); );
// ex: 'node@lts' or 'node' // ex: 'node@lts' or 'node'
@@ -90,7 +89,10 @@ Releases.renderBash = async function (
] ]
.join(',') .join(',')
.replace(/'/g, ''); .replace(/'/g, '');
let webiChecksum = await Releases.getWebiShChecksum();
let envReplacements = [ let envReplacements = [
['WEBI_CHECKSUM', webiChecksum],
['WEBI_PKG', webiPkg], ['WEBI_PKG', webiPkg],
['WEBI_HOST', baseurl], ['WEBI_HOST', baseurl],
['WEBI_OS', os], ['WEBI_OS', os],
@@ -127,7 +129,7 @@ Releases.renderBash = async function (
// #export WEBI_FOO=xyz => export WEBI_FOO='123' // #export WEBI_FOO=xyz => export WEBI_FOO='123'
// export WEBI_FOO= => export WEBI_FOO='123' // export WEBI_FOO= => export WEBI_FOO='123'
let envRe = new RegExp( let envRe = new RegExp(
`^[ \\t]*#?[ \\t]*(export\\s)?[ \\t]*(${name})=.*`, `^[ \\t]*#?[ \\t]*(export[ \\t])?[ \\t]*(${name})=.*`,
'm', 'm',
); );
if (BAD_SH_RE.test(value)) { if (BAD_SH_RE.test(value)) {
@@ -156,10 +158,7 @@ Releases.renderPowerShell = async function (
if (!tag) { if (!tag) {
tag = ''; tag = '';
} }
let installTxt = await fs.promises.readFile( let installTxt = await Fs.readFile(path.join(pkgdir, 'install.ps1'), 'utf8');
path.join(pkgdir, 'install.ps1'),
'utf8',
);
installTxt = padScript(installTxt); installTxt = padScript(installTxt);
/* /*
var vers = rel.version.split('.'); var vers = rel.version.split('.');
@@ -173,8 +172,8 @@ Releases.renderPowerShell = async function (
.replace(/^-/, '') .replace(/^-/, '')
}; };
*/ */
let tplTxt = await fs.promises.readFile( let tplTxt = await Fs.readFile(
path.join(__dirname, 'install-package.tpl.ps1'), path.join(__dirname, 'package-install.tpl.ps1'),
'utf8', 'utf8',
); );
var pkgver = pkg + '@' + ver; var pkgver = pkg + '@' + ver;
@@ -218,3 +217,32 @@ Releases.renderPowerShell = async function (
.replace(reInstallTpl, '\n' + installTxt) .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,7 +2,6 @@
var Installers = module.exports; var Installers = module.exports;
var Crypto = require('crypto');
var Fs = require('fs/promises'); var Fs = require('fs/promises');
var path = require('path'); var path = require('path');
@@ -136,7 +135,7 @@ Installers.getPosixCurlPipeBootstrap = async function ({ baseurl, pkg, ver }) {
let bootTxt = await Fs.readFile(CURL_PIPE_SH_BOOT, 'utf8'); let bootTxt = await Fs.readFile(CURL_PIPE_SH_BOOT, 'utf8');
var webiPkg = [pkg, ver].filter(Boolean).join('@'); var webiPkg = [pkg, ver].filter(Boolean).join('@');
var webiChecksum = await Installers.getWebiShChecksum(); var webiChecksum = await Releases.getWebiShChecksum();
var envReplacements = [ var envReplacements = [
['WEBI_PKG', webiPkg], ['WEBI_PKG', webiPkg],
['WEBI_HOST', baseurl], ['WEBI_HOST', baseurl],
@@ -149,7 +148,7 @@ Installers.getPosixCurlPipeBootstrap = async function ({ baseurl, pkg, ver }) {
// TODO create REs once, in higher scope // TODO create REs once, in higher scope
let envRe = new RegExp( let envRe = new RegExp(
`^[ \\t]*#?[ \\t]*(export\\s)?[ \\t]*(${name})=.*`, `^[ \\t]*#?[ \\t]*(export[ \\t])?[ \\t]*(${name})=.*`,
'm', 'm',
); );
@@ -174,7 +173,7 @@ Installers.getPwshCurlPipeBootstrap = async function ({
let bootTxt = await Fs.readFile(CURL_PIPE_PS1_BOOT, 'utf8'); let bootTxt = await Fs.readFile(CURL_PIPE_PS1_BOOT, 'utf8');
var webiPkg = [pkg, ver].filter(Boolean).join('@'); var webiPkg = [pkg, ver].filter(Boolean).join('@');
//var webiChecksum = await Installers.getWebiPs1Checksum(); //var webiChecksum = await Releases.getWebiPs1Checksum();
var envReplacements = [ var envReplacements = [
['Env:WEBI_PKG', webiPkg], ['Env:WEBI_PKG', webiPkg],
['Env:WEBI_HOST', baseurl], ['Env:WEBI_HOST', baseurl],
@@ -209,32 +208,3 @@ Installers.getPwshCurlPipeBootstrap = async function ({
return bootTxt; 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,7 +278,16 @@ module.exports = function getReleases({
console.error(err); console.error(err);
}) })
.then(function (releases) { .then(function (releases) {
if (!releases.length) { if (releases.length) {
return {
oses: all.oses,
arches: all.arches,
libcs: all.libcs,
formats: all.formats,
releases: releases,
};
}
if (_count < 1) {
// Apple Silicon M1 hacky-do workaround fix // Apple Silicon M1 hacky-do workaround fix
if ('macos' === os && 'arm64' === arch) { if ('macos' === os && 'arm64' === arch) {
return getReleases({ return getReleases({
@@ -307,23 +316,7 @@ module.exports = function getReleases({
limit, 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?) // 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) { if ('linux' === os && 'arm64' === arch) {
return getReleases({ return getReleases({
_count: _count + 1, _count: _count + 1,
@@ -338,7 +331,7 @@ module.exports = function getReleases({
limit, limit,
}); });
} }
// Raspberry Pi 3+ on Ubuntu arm64 (via Bionic?) // armv7 can run armv6
if ('linux' === os && 'armv7l' === arch) { if ('linux' === os && 'armv7l' === arch) {
return getReleases({ return getReleases({
_count: _count + 1, _count: _count + 1,
@@ -353,25 +346,43 @@ module.exports = function getReleases({
limit, 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 { return {
oses: all.oses, oses: all.oses,
arches: all.arches, arches: all.arches,

View File

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

View File

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

View File

@@ -30,7 +30,7 @@ IF (!(Test-Path -Path "$pkg_src_cmd")) {
# TODO: create package-specific temp directory # TODO: create package-specific temp directory
# Enter tmp # Enter tmp
Push-Location $HOME\.local\tmp Push-Location .local\tmp
# Remove any leftover tmp cruft # Remove any leftover tmp cruft
Remove-Item -Path ".\arc-*" -Recurse -ErrorAction Ignore Remove-Item -Path ".\arc-*" -Recurse -ErrorAction Ignore

View File

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

View File

@@ -34,7 +34,7 @@ IF (!(Test-Path -Path "$pkg_src_cmd")) {
# TODO: create package-specific temp directory # TODO: create package-specific temp directory
# Enter tmp # Enter tmp
Push-Location $HOME\.local\tmp Push-Location .local\tmp
# Remove any leftover tmp cruft # Remove any leftover tmp cruft
Remove-Item -Path ".\AtomicParsley-v*" -Recurse -ErrorAction Ignore Remove-Item -Path ".\AtomicParsley-v*" -Recurse -ErrorAction Ignore

View File

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

View File

@@ -31,7 +31,7 @@ IF (!(Test-Path -Path "$pkg_src_cmd")) {
# TODO: create package-specific temp directory # TODO: create package-specific temp directory
# Enter tmp # Enter tmp
Push-Location $HOME\.local\tmp Push-Location .local\tmp
# Remove any leftover tmp cruft # Remove any leftover tmp cruft
Remove-Item -Path ".\awless-v*" -Recurse -ErrorAction Ignore Remove-Item -Path ".\awless-v*" -Recurse -ErrorAction Ignore

View File

@@ -20,7 +20,7 @@ IF (!(Test-Path -Path "$Env:USERPROFILE\.local\bin\$VERNAME")) {
# TODO: temp directory # TODO: temp directory
# Enter tmp # Enter tmp
Push-Location $HOME\.local\tmp Push-Location .local\tmp
# Remove any leftover tmp cruft # Remove any leftover tmp cruft
Remove-Item -Path "$Env:PKG_NAME-v*" -Recurse -ErrorAction Ignore Remove-Item -Path "$Env:PKG_NAME-v*" -Recurse -ErrorAction Ignore

View File

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

View File

@@ -31,7 +31,7 @@ IF (!(Test-Path -Path "$pkg_src_cmd")) {
# TODO: create package-specific temp directory # TODO: create package-specific temp directory
# Enter tmp # Enter tmp
Push-Location $HOME\.local\tmp Push-Location .local\tmp
# Remove any leftover tmp cruft # Remove any leftover tmp cruft
Remove-Item -Path ".\caddy-v*" -Recurse -ErrorAction Ignore Remove-Item -Path ".\caddy-v*" -Recurse -ErrorAction Ignore

View File

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

View File

@@ -30,7 +30,7 @@ IF (!(Test-Path -Path "$pkg_src_cmd")) {
# TODO: create package-specific temp directory # TODO: create package-specific temp directory
# Enter tmp # Enter tmp
Push-Location $HOME\.local\tmp Push-Location .local\tmp
# Remove any leftover tmp cruft # Remove any leftover tmp cruft
Remove-Item -Path ".\chromedriver.exe" -Recurse -ErrorAction Ignore Remove-Item -Path ".\chromedriver.exe" -Recurse -ErrorAction Ignore

View File

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

View File

@@ -1,81 +1,77 @@
'use strict'; 'use strict';
var matchers = { // See <https://googlechromelabs.github.io/chrome-for-testing/>
key: /.*Key>(.*)<\/Key.*/, var releaseApiUrl =
generation: /.*Generation>(.*)<\/Generation.*/, 'https://googlechromelabs.github.io/chrome-for-testing/known-good-versions-with-downloads.json';
metaGeneration: /.*MetaGeneration>(.*)<\/MetaGeneration.*/,
lastModified: /.*LastModified>(.*)<\/LastModified.*/,
etag: /.*ETag>(.*)<\/ETag.*/,
size: /.*Size>(.*)<\/Size.*/,
};
var baseUrl = 'https://chromedriver.storage.googleapis.com';
module.exports = function (request) { // {
var all = { // "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 = {
download: '', download: '',
releases: [], releases: builds,
}; };
// XML return all;
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) { if (module === require.main) {

View File

@@ -31,7 +31,7 @@ IF (!(Test-Path -Path "$pkg_src_dir")) {
# TODO: create package-specific temp directory # TODO: create package-specific temp directory
# Enter tmp # Enter tmp
Push-Location $HOME\.local\tmp Push-Location .local\tmp
# Remove any leftover tmp cruft # Remove any leftover tmp cruft
Remove-Item -Path ".\cmake*" -Recurse -ErrorAction Ignore Remove-Item -Path ".\cmake*" -Recurse -ErrorAction Ignore

View File

@@ -7,6 +7,10 @@ var repo = 'CMake';
module.exports = function (request) { module.exports = function (request) {
return github(request, owner, repo).then(function (all) { return github(request, owner, repo).then(function (all) {
for (let rel of all.releases) { 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 linuxRe = /(\b|_)(linux|gnu)(\b|_)/i;
let isLinux = linuxRe.test(rel.download) || linuxRe.test(rel.name); let isLinux = linuxRe.test(rel.download) || linuxRe.test(rel.name);

View File

@@ -14,7 +14,7 @@ IF (!(Test-Path -Path "$Env:USERPROFILE\.local\opt\$Env:PKG_NAME-v$Env:WEBI_VERS
# TODO: temp directory # TODO: temp directory
# Enter tmp # Enter tmp
Push-Location $HOME\.local\tmp Push-Location .local\tmp
# Remove any leftover tmp cruft # Remove any leftover tmp cruft
Remove-Item -Path "$Env:PKG_NAME-v*" -Recurse -ErrorAction Ignore Remove-Item -Path "$Env:PKG_NAME-v*" -Recurse -ErrorAction Ignore

View File

@@ -4,8 +4,28 @@ var github = require('../_common/github.js');
var owner = 'kivikakk'; var owner = 'kivikakk';
var repo = 'comrak'; var repo = 'comrak';
var ODDITIES = ['-musleabihf.1-'];
module.exports = function (request) { module.exports = function (request) {
return github(request, owner, repo).then(function (all) { 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; return all;
}); });
}; };

View File

@@ -31,7 +31,7 @@ IF (!(Test-Path -Path "$pkg_src_cmd")) {
# TODO: create package-specific temp directory # TODO: create package-specific temp directory
# Enter tmp # Enter tmp
Push-Location $HOME\.local\tmp Push-Location .local\tmp
# Settle unpacked archive into place # Settle unpacked archive into place
Write-Output "Install Location: $pkg_src_cmd" Write-Output "Install Location: $pkg_src_cmd"

View File

@@ -14,7 +14,7 @@ IF (!(Test-Path -Path "$Env:USERPROFILE\.local\bin\$VERNAME")) {
# TODO: temp directory # TODO: temp directory
# Enter tmp # Enter tmp
Push-Location $HOME\.local\tmp Push-Location .local\tmp
# Remove any leftover tmp cruft # Remove any leftover tmp cruft
Remove-Item -Path "$Env:PKG_NAME-v*" -Recurse -ErrorAction Ignore Remove-Item -Path "$Env:PKG_NAME-v*" -Recurse -ErrorAction Ignore

View File

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

View File

@@ -31,7 +31,7 @@ IF (!(Test-Path -Path "$pkg_src_dir")) {
# TODO: create package-specific temp directory # TODO: create package-specific temp directory
# Enter tmp # Enter tmp
Push-Location $HOME\.local\tmp Push-Location .local\tmp
# Remove any leftover tmp cruft # Remove any leftover tmp cruft
Remove-Item -Path ".\dashcore*" -Recurse -ErrorAction Ignore Remove-Item -Path ".\dashcore*" -Recurse -ErrorAction Ignore

View File

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

View File

@@ -31,7 +31,7 @@ IF (!(Test-Path -Path "$pkg_src_dir")) {
# TODO: create package-specific temp directory # TODO: create package-specific temp directory
# Enter tmp # Enter tmp
Push-Location $HOME\.local\tmp Push-Location .local\tmp
# Remove any leftover tmp cruft # Remove any leftover tmp cruft
Remove-Item -Path ".\dashcore*" -Recurse -ErrorAction Ignore Remove-Item -Path ".\dashcore*" -Recurse -ErrorAction Ignore

View File

@@ -30,7 +30,7 @@ IF (!(Test-Path -Path "$pkg_src_cmd")) {
# TODO: create package-specific temp directory # TODO: create package-specific temp directory
# Enter tmp # Enter tmp
Push-Location $HOME\.local\tmp Push-Location .local\tmp
# Remove any leftover tmp cruft # Remove any leftover tmp cruft
Remove-Item -Path ".\dashmsg-v*" -Recurse -ErrorAction Ignore Remove-Item -Path ".\dashmsg-v*" -Recurse -ErrorAction Ignore

View File

@@ -30,7 +30,7 @@ IF (!(Test-Path -Path "$pkg_src_cmd")) {
# TODO: create package-specific temp directory # TODO: create package-specific temp directory
# Enter tmp # Enter tmp
Push-Location $HOME\.local\tmp Push-Location .local\tmp
# Remove any leftover tmp cruft # Remove any leftover tmp cruft
Remove-Item -Path ".\delta-v*" -Recurse -ErrorAction Ignore Remove-Item -Path ".\delta-v*" -Recurse -ErrorAction Ignore

View File

@@ -13,7 +13,7 @@ IF (!(Test-Path -Path "$Env:USERPROFILE\.local\opt\$Env:PKG_NAME-v$Env:WEBI_VERS
# TODO: temp directory # TODO: temp directory
# Enter opt # Enter opt
Push-Location $HOME\.local\tmp Push-Location .local\tmp
# Remove any leftover tmp cruft # Remove any leftover tmp cruft
Remove-Item -Path "deno-v*" -Recurse -ErrorAction Ignore Remove-Item -Path "deno-v*" -Recurse -ErrorAction Ignore

View File

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

View File

@@ -36,7 +36,7 @@ IF (!(Test-Path -Path "$pkg_src_cmd")) {
# TODO: create package-specific temp directory # TODO: create package-specific temp directory
# Enter tmp # Enter tmp
Push-Location $HOME\.local\tmp Push-Location .local\tmp
# Remove any leftover tmp cruft # Remove any leftover tmp cruft
Remove-Item -Path ".\dotenv-linter-v*" -Recurse -ErrorAction Ignore Remove-Item -Path ".\dotenv-linter-v*" -Recurse -ErrorAction Ignore

View File

@@ -30,7 +30,7 @@ IF (!(Test-Path -Path "$pkg_src_cmd")) {
# TODO: create package-specific temp directory # TODO: create package-specific temp directory
# Enter tmp # Enter tmp
Push-Location $HOME\.local\tmp Push-Location .local\tmp
# Remove any leftover tmp cruft # Remove any leftover tmp cruft
Remove-Item -Path ".\dotenv-v*" -Recurse -ErrorAction Ignore Remove-Item -Path ".\dotenv-v*" -Recurse -ErrorAction Ignore

View File

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

View File

@@ -14,7 +14,7 @@ IF (!(Test-Path -Path "$Env:USERPROFILE\.local\bin\$VERNAME")) {
# TODO: temp directory # TODO: temp directory
# Enter tmp # Enter tmp
Push-Location $HOME\.local\tmp Push-Location .local\tmp
# Remove any leftover tmp cruft # Remove any leftover tmp cruft
Remove-Item -Path "$Env:PKG_NAME-v*" -Recurse -ErrorAction Ignore Remove-Item -Path "$Env:PKG_NAME-v*" -Recurse -ErrorAction Ignore

View File

@@ -6,6 +6,17 @@ var repo = 'fd';
module.exports = function (request) { module.exports = function (request) {
return github(request, owner, repo).then(function (all) { 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; return all;
}); });
}; };

View File

@@ -30,7 +30,7 @@ IF (!(Test-Path -Path "$pkg_src_cmd")) {
# TODO: create package-specific temp directory # TODO: create package-specific temp directory
# Enter tmp # Enter tmp
Push-Location $HOME\.local\tmp Push-Location .local\tmp
# Remove any leftover tmp cruft # Remove any leftover tmp cruft
Remove-Item -Path ".\win32-*" -Recurse -ErrorAction Ignore Remove-Item -Path ".\win32-*" -Recurse -ErrorAction Ignore

View File

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

View File

@@ -31,7 +31,7 @@ IF (-Not (Test-Path -Path "$pkg_src_cmd")) {
# TODO: create package-specific temp directory # TODO: create package-specific temp directory
# Enter tmp # Enter tmp
Push-Location $HOME\.local\tmp Push-Location .local\tmp
# Remove any leftover tmp cruft # Remove any leftover tmp cruft
Remove-Item -Path ".\ffuf-v*" -Recurse -ErrorAction Ignore Remove-Item -Path ".\ffuf-v*" -Recurse -ErrorAction Ignore

View File

@@ -4,10 +4,19 @@ var github = require('../_common/github.js');
var owner = 'fish-shell'; var owner = 'fish-shell';
var repo = 'fish-shell'; var repo = 'fish-shell';
var ODDITIES = ['bundledpcre'];
module.exports = function (request) { module.exports = function (request) {
return github(request, owner, repo).then(function (all) { return github(request, owner, repo).then(function (all) {
all.releases = all.releases all.releases = all.releases
.map(function (rel) { .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 // We can extract the macos bins from the .app
if (/\.app\.zip$/.test(rel.name)) { if (/\.app\.zip$/.test(rel.name)) {
rel.os = 'macos'; rel.os = 'macos';

View File

@@ -1,59 +1,98 @@
'use strict'; 'use strict';
var map = {}; var FLUTTER_OSES = ['macos', 'linux', 'windows'];
module.exports = function (request) { // stable, beta, dev
var all = { 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 = {
download: '', download: '',
releases: [], releases: [],
channels: [],
}; };
return Promise.all(
['macos', 'linux', 'windows'].map(function (osname) { for (let osname of FLUTTER_OSES) {
return request({ let resp = await request({
url: url: `https://storage.googleapis.com/flutter_infra_release/releases/releases_${osname}.json`,
'https://storage.googleapis.com/flutter_infra/releases/releases_' + json: true,
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,
});
});
});
}),
).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;
}); 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,
});
}
}
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;
}; };
if (module === require.main) { if (module === require.main) {

View File

@@ -14,7 +14,7 @@ IF (!(Test-Path -Path "$Env:USERPROFILE\.local\bin\$VERNAME")) {
# TODO: temp directory # TODO: temp directory
# Enter tmp # Enter tmp
Push-Location $HOME\.local\tmp Push-Location .local\tmp
# Remove any leftover tmp cruft # Remove any leftover tmp cruft
Remove-Item -Path "$Env:PKG_NAME-v*" -Recurse -ErrorAction Ignore Remove-Item -Path "$Env:PKG_NAME-v*" -Recurse -ErrorAction Ignore

View File

@@ -30,7 +30,7 @@ IF (!(Test-Path -Path "$pkg_src_cmd")) {
# TODO: create package-specific temp directory # TODO: create package-specific temp directory
# Enter tmp # Enter tmp
Push-Location $HOME\.local\tmp Push-Location .local\tmp
# Remove any leftover tmp cruft # Remove any leftover tmp cruft
Remove-Item -Path ".\gh-v*" -Recurse -ErrorAction Ignore Remove-Item -Path ".\gh-v*" -Recurse -ErrorAction Ignore

View File

@@ -22,7 +22,7 @@ IF (!(Test-Path -Path "$pkg_src")) {
# TODO: temp directory # TODO: temp directory
# Enter opt # Enter opt
($none = Push-Location $HOME\.local\tmp) | Out-Null ($none = Push-Location .local\tmp) | Out-Null
# Remove any leftover tmp cruft # Remove any leftover tmp cruft
Remove-Item -Path "$pkg_cmd_name*" -Recurse -ErrorAction Ignore Remove-Item -Path "$pkg_cmd_name*" -Recurse -ErrorAction Ignore

View File

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

View File

@@ -30,7 +30,7 @@ IF (!(Test-Path -Path "$pkg_src_cmd")) {
# TODO: create package-specific temp directory # TODO: create package-specific temp directory
# Enter tmp # Enter tmp
Push-Location $HOME\.local\tmp Push-Location .local\tmp
# Remove any leftover tmp cruft # Remove any leftover tmp cruft
Remove-Item -Path ".\gitdeploy-v*" -Recurse -ErrorAction Ignore Remove-Item -Path ".\gitdeploy-v*" -Recurse -ErrorAction Ignore

View File

@@ -18,6 +18,12 @@ $pkg_src = "$pkg_src_cmd"
New-Item "$Env:USERPROFILE\Downloads\webi" -ItemType Directory -Force | Out-Null New-Item "$Env:USERPROFILE\Downloads\webi" -ItemType Directory -Force | Out-Null
$pkg_download = "$Env:USERPROFILE\Downloads\webi\$Env:WEBI_PKG_FILE" $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 # Fetch archive
IF (!(Test-Path -Path "$Env:USERPROFILE\Downloads\webi\$Env:WEBI_PKG_FILE")) { IF (!(Test-Path -Path "$Env:USERPROFILE\Downloads\webi\$Env:WEBI_PKG_FILE")) {
Write-Output "Downloading gitea from $Env:WEBI_PKG_URL to $pkg_download" Write-Output "Downloading gitea from $Env:WEBI_PKG_URL to $pkg_download"
@@ -30,7 +36,7 @@ IF (!(Test-Path -Path "$pkg_src_cmd")) {
# TODO: create package-specific temp directory # TODO: create package-specific temp directory
# Enter tmp # Enter tmp
Push-Location $HOME\.local\tmp Push-Location .local\tmp
# Remove any leftover tmp cruft # Remove any leftover tmp cruft
Remove-Item -Path ".\gitea-*" -Recurse -ErrorAction Ignore Remove-Item -Path ".\gitea-*" -Recurse -ErrorAction Ignore

View File

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

View File

@@ -27,7 +27,7 @@ IF (!(Test-Path -Path "$pkg_src")) {
# TODO: temp directory # TODO: temp directory
# Enter opt # Enter opt
Push-Location $HOME\.local\tmp Push-Location .local\tmp
# Remove any leftover tmp cruft # Remove any leftover tmp cruft
Remove-Item -Path "$pkg_cmd_name*" -Recurse -ErrorAction Ignore Remove-Item -Path "$pkg_cmd_name*" -Recurse -ErrorAction Ignore

View File

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

View File

@@ -27,7 +27,7 @@ IF (!(Test-Path -Path "$pkg_src")) {
# TODO: temp directory # TODO: temp directory
# Enter opt # Enter opt
Push-Location $HOME\.local\tmp Push-Location .local\tmp
# Remove any leftover tmp cruft # Remove any leftover tmp cruft
Remove-Item -Path "$pkg_cmd_name*" -Recurse -ErrorAction Ignore Remove-Item -Path "$pkg_cmd_name*" -Recurse -ErrorAction Ignore

View File

@@ -30,7 +30,7 @@ IF (!(Test-Path -Path "$pkg_src_cmd")) {
# TODO: create package-specific temp directory # TODO: create package-specific temp directory
# Enter tmp # Enter tmp
Push-Location $HOME\.local\tmp Push-Location .local\tmp
# Remove any leftover tmp cruft # Remove any leftover tmp cruft
Remove-Item -Path ".\goreleaser-v*" -Recurse -ErrorAction Ignore Remove-Item -Path ".\goreleaser-v*" -Recurse -ErrorAction Ignore

View File

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

View File

@@ -30,7 +30,7 @@ IF (!(Test-Path -Path "$pkg_src_cmd")) {
# TODO: create package-specific temp directory # TODO: create package-specific temp directory
# Enter tmp # Enter tmp
Push-Location $HOME\.local\tmp Push-Location .local\tmp
# Remove any leftover tmp cruft # Remove any leftover tmp cruft
Remove-Item -Path ".\gprox-v*" -Recurse -ErrorAction Ignore Remove-Item -Path ".\gprox-v*" -Recurse -ErrorAction Ignore

View File

@@ -31,7 +31,7 @@ IF (!(Test-Path -Path "$pkg_src_cmd")) {
# TODO: create package-specific temp directory # TODO: create package-specific temp directory
# Enter tmp # Enter tmp
Push-Location $HOME\.local\tmp Push-Location .local\tmp
# Remove any leftover tmp cruft # Remove any leftover tmp cruft
Remove-Item -Path ".\grype-v*" -Recurse -ErrorAction Ignore Remove-Item -Path ".\grype-v*" -Recurse -ErrorAction Ignore

View File

@@ -31,7 +31,7 @@ IF (!(Test-Path -Path "$pkg_src_cmd")) {
# TODO: create package-specific temp directory # TODO: create package-specific temp directory
# Enter tmp # Enter tmp
Push-Location $HOME\.local\tmp Push-Location .local\tmp
# Remove any leftover tmp cruft # Remove any leftover tmp cruft
Remove-Item -Path ".\hugo-extended-v*" -Recurse -ErrorAction Ignore Remove-Item -Path ".\hugo-extended-v*" -Recurse -ErrorAction Ignore

View File

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

View File

@@ -31,7 +31,7 @@ IF (!(Test-Path -Path "$pkg_src_cmd")) {
# TODO: create package-specific temp directory # TODO: create package-specific temp directory
# Enter tmp # Enter tmp
Push-Location $HOME\.local\tmp Push-Location .local\tmp
# Remove any leftover tmp cruft # Remove any leftover tmp cruft
Remove-Item -Path ".\hugo-v*" -Recurse -ErrorAction Ignore Remove-Item -Path ".\hugo-v*" -Recurse -ErrorAction Ignore

View File

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

View File

@@ -16,9 +16,26 @@ _install_iterm2() {
exit 1 exit 1
fi 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_download \
"${WEBI_PKG_URL}" \ "${WEBI_PKG_URL}" \
"${WEBI_PKG_PATH}/${WEBI_PKG_FILE}" "${WEBI_PKG_PATH}/${WEBI_PKG_FILE}"
webi_extract webi_extract
if [ ! -d "${WEBI_TMP}/iTerm.app" ]; then if [ ! -d "${WEBI_TMP}/iTerm.app" ]; then
@@ -27,11 +44,9 @@ _install_iterm2() {
exit 1 exit 1
fi fi
if [ -d /Applications/iTerm.app ]; then
mv /Applications/iTerm.app "${WEBI_TMP}/iTerm.app-webi.bak"
fi
mkdir -p /Applications/ mkdir -p /Applications/
mv "${WEBI_TMP}/iTerm.app" /Applications/ mv "${WEBI_TMP}/iTerm.app" /Applications/
echo " Installed to /Applications/iTerm.app/"
} }
_install_iterm2 _install_iterm2

View File

@@ -24,17 +24,24 @@ function transformReleases(links) {
//console.log(links.length); //console.log(links.length);
return { return {
_names: ['iTerm2', 'iterm2'],
releases: links releases: links
.map(function (link) { .map(function (link) {
// strip 'go' prefix, standardize version
var channel = /\/stable\//.test(link) ? 'stable' : 'beta'; var channel = /\/stable\//.test(link) ? 'stable' : 'beta';
var parts = link var parts = link
.replace(/.*\/iTerm2[-_]v?(\d_.*)\.zip/, '$1') .replace(/.*\/iTerm2[-_]v?(\d_.*)\.zip/, '$1')
.split('_'); .split('_');
var version = parts.join('.').replace(/([_-])?beta/, '-beta'); 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 { return {
version: version, version: version,
_version: fileversion,
// all go versions >= 1.0.0 are effectively LTS // all go versions >= 1.0.0 are effectively LTS
lts: 'stable' === channel, lts: 'stable' === channel,
channel: channel, channel: channel,

View File

@@ -14,7 +14,7 @@ IF (!(Test-Path -Path "$Env:USERPROFILE\.local\bin\$VERNAME")) {
# TODO: temp directory # TODO: temp directory
# Enter tmp # Enter tmp
Push-Location $HOME\.local\tmp Push-Location .local\tmp
# Remove any leftover tmp cruft # Remove any leftover tmp cruft
Remove-Item -Path "$Env:PKG_NAME-v*" -Recurse -ErrorAction Ignore Remove-Item -Path "$Env:PKG_NAME-v*" -Recurse -ErrorAction Ignore

View File

@@ -4,11 +4,32 @@ var github = require('../_common/github.js');
var owner = 'stedolan'; var owner = 'stedolan';
var repo = 'jq'; 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) { module.exports = function (request) {
return github(request, owner, repo).then(function (all) { return github(request, owner, repo).then(function (all) {
all.releases.forEach(function (rel) { let builds = [];
rel.version = String(rel.version).replace(/^jq\-/, '');
}); 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;
return all; return all;
}); });
}; };

View File

@@ -30,7 +30,7 @@ IF (!(Test-Path -Path "$pkg_src_cmd")) {
# TODO: create package-specific temp directory # TODO: create package-specific temp directory
# Enter tmp # Enter tmp
Push-Location $HOME\.local\tmp Push-Location .local\tmp
# Remove any leftover tmp cruft # Remove any leftover tmp cruft
Remove-Item -Path ".\k9s-v*" -Recurse -ErrorAction Ignore Remove-Item -Path ".\k9s-v*" -Recurse -ErrorAction Ignore

View File

@@ -30,7 +30,7 @@ IF (!(Test-Path -Path "$pkg_src_cmd")) {
# TODO: create package-specific temp directory # TODO: create package-specific temp directory
# Enter tmp # Enter tmp
Push-Location $HOME\.local\tmp Push-Location .local\tmp
# Remove any leftover tmp cruft # Remove any leftover tmp cruft
Remove-Item -Path ".\keypairs-v*" -Recurse -ErrorAction Ignore Remove-Item -Path ".\keypairs-v*" -Recurse -ErrorAction Ignore

View File

@@ -25,7 +25,7 @@ IF (!(Test-Path -Path "$Env:USERPROFILE\Downloads\webi\$Env:WEBI_PKG_FILE")) {
IF (!(Test-Path -Path "$pkg_src_cmd")) { IF (!(Test-Path -Path "$pkg_src_cmd")) {
Write-Output "Installing kind" Write-Output "Installing kind"
Push-Location $HOME\.local\tmp Push-Location .local\tmp
Remove-Item -Path ".\kind-v*" -Recurse -ErrorAction Ignore Remove-Item -Path ".\kind-v*" -Recurse -ErrorAction Ignore
Remove-Item -Path ".\kind.exe" -Recurse -ErrorAction Ignore Remove-Item -Path ".\kind.exe" -Recurse -ErrorAction Ignore

View File

@@ -30,7 +30,7 @@ IF (!(Test-Path -Path "$pkg_src_cmd")) {
# TODO: create package-specific temp directory # TODO: create package-specific temp directory
# Enter tmp # Enter tmp
Push-Location $HOME\.local\tmp Push-Location .local\tmp
# Remove any leftover tmp cruft # Remove any leftover tmp cruft
Remove-Item -Path ".\kubectx-v*" -Recurse -ErrorAction Ignore Remove-Item -Path ".\kubectx-v*" -Recurse -ErrorAction Ignore

View File

@@ -4,16 +4,25 @@ var github = require('../_common/github.js');
var owner = 'ahmetb'; var owner = 'ahmetb';
var repo = 'kubectx'; 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) { module.exports = function (request) {
return github(request, owner, repo).then(function (all) { 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; return all;
}); });
}; };

View File

@@ -30,7 +30,7 @@ IF (!(Test-Path -Path "$pkg_src_cmd")) {
# TODO: create package-specific temp directory # TODO: create package-specific temp directory
# Enter tmp # Enter tmp
Push-Location $HOME\.local\tmp Push-Location .local\tmp
# Remove any leftover tmp cruft # Remove any leftover tmp cruft
Remove-Item -Path ".\kubens-v*" -Recurse -ErrorAction Ignore Remove-Item -Path ".\kubens-v*" -Recurse -ErrorAction Ignore

View File

@@ -6,10 +6,23 @@ var repo = 'kubectx';
module.exports = function (request) { module.exports = function (request) {
return github(request, owner, repo).then(function (all) { return github(request, owner, repo).then(function (all) {
// remove kubectx, etc. from kubens list let builds = [];
all.releases = all.releases.filter(function (rel) {
return !/(\.txt)|(kubectx)|(kubectx_)$/i.test(rel.name); 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;
return all; return all;
}); });
}; };

View File

@@ -26,7 +26,7 @@ IF (!(Test-Path -Path "$Env:USERPROFILE\Downloads\webi\$Env:WEBI_PKG_FILE")) {
IF (!(Test-Path -Path "$pkg_src_cmd")) { IF (!(Test-Path -Path "$pkg_src_cmd")) {
Write-Output "Installing lf" Write-Output "Installing lf"
Push-Location $HOME\.local\tmp Push-Location .local\tmp
Remove-Item -Path ".\lf.exe" -Recurse -ErrorAction Ignore Remove-Item -Path ".\lf.exe" -Recurse -ErrorAction Ignore

View File

@@ -30,7 +30,7 @@ IF (!(Test-Path -Path "$pkg_src_cmd")) {
# TODO: create package-specific temp directory # TODO: create package-specific temp directory
# Enter tmp # Enter tmp
Push-Location $HOME\.local\tmp Push-Location .local\tmp
# Remove any leftover tmp cruft # Remove any leftover tmp cruft
Remove-Item -Path ".\lsd-v*" -Recurse -ErrorAction Ignore Remove-Item -Path ".\lsd-v*" -Recurse -ErrorAction Ignore

View File

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

View File

@@ -26,7 +26,7 @@ IF (!(Test-Path -Path "$Env:USERPROFILE\Downloads\webi\$Env:WEBI_PKG_FILE")) {
IF (!(Test-Path -Path "$pkg_src_cmd")) { IF (!(Test-Path -Path "$pkg_src_cmd")) {
Write-Output "Installing mutagen" Write-Output "Installing mutagen"
Push-Location $HOME\.local\tmp Push-Location .local\tmp
Remove-Item -Path ".\mutagen.exe" -Recurse -ErrorAction Ignore Remove-Item -Path ".\mutagen.exe" -Recurse -ErrorAction Ignore

View File

@@ -14,7 +14,7 @@ IF (!(Test-Path -Path "$Env:USERPROFILE\.local\opt\$Env:PKG_NAME-v$Env:WEBI_VERS
# TODO: temp directory # TODO: temp directory
# Enter opt # Enter opt
Push-Location $HOME\.local\tmp Push-Location .local\tmp
# Remove any leftover tmp cruft # Remove any leftover tmp cruft
Remove-Item -Path "node-v*" -Recurse -ErrorAction Ignore Remove-Item -Path "node-v*" -Recurse -ErrorAction Ignore

View File

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

View File

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

View File

@@ -27,7 +27,7 @@ IF (!(Test-Path -Path "$Env:USERPROFILE\Downloads\webi\$Env:WEBI_PKG_FILE")) {
IF (!(Test-Path -Path "$pkg_src_cmd")) { IF (!(Test-Path -Path "$pkg_src_cmd")) {
Write-Output "Installing ots" Write-Output "Installing ots"
Push-Location $HOME\.local\tmp Push-Location .local\tmp
# Remove any leftover tmp cruft # Remove any leftover tmp cruft
Remove-Item -Path ".\ots-v*" -Recurse -ErrorAction Ignore Remove-Item -Path ".\ots-v*" -Recurse -ErrorAction Ignore

View File

@@ -30,7 +30,7 @@ IF (!(Test-Path -Path "$pkg_src_cmd")) {
# TODO: create package-specific temp directory # TODO: create package-specific temp directory
# Enter tmp # Enter tmp
Push-Location $HOME\.local\tmp Push-Location .local\tmp
# Remove any leftover tmp cruft # Remove any leftover tmp cruft
Remove-Item -Path ".\pandoc-v*" -Recurse -ErrorAction Ignore Remove-Item -Path ".\pandoc-v*" -Recurse -ErrorAction Ignore

View File

@@ -30,7 +30,7 @@ IF (!(Test-Path -Path "$pkg_src_cmd")) {
# TODO: create package-specific temp directory # TODO: create package-specific temp directory
# Enter tmp # Enter tmp
Push-Location $HOME\.local\tmp Push-Location .local\tmp
# Remove any leftover tmp cruft # Remove any leftover tmp cruft
Remove-Item -Path ".\pathman-v*" -Recurse -ErrorAction Ignore Remove-Item -Path ".\pathman-v*" -Recurse -ErrorAction Ignore

View File

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

View File

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

View File

@@ -1,98 +1,11 @@
--- ---
title: Microsoft PowerShell title: PowerShell (pwsh alias)
homepage: https://docs.microsoft.com/en-us/powershell/ homepage: https://webinstall.dev/pwsh
tagline: | tagline: |
PowerShell Core is a cross-platform (Windows, Linux, and macOS) automation and configuration tool/framework. Alias for https://webinstall.dev/pwsh
alias: pwsh
description: |
See https://webinstall.dev/pwsh
--- ---
To update or switch versions, run `webi pwsh@stable` (or `@v7.4`, `@beta`, etc). Alias for https://webinstall.dev/pwsh
## 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,56 +1,8 @@
#!/usr/bin/env pwsh #!/bin/pwsh
################# Write-Output "'powershell@$Env:WEBI_TAG' is an alias for 'pwsh@$Env:WEBI_VERSION'"
# Install pwsh #
#################
# Every package should define these variables $PwshBootUrl = "$Env:WEBI_HOST/pwsh@$Env:WEBI_VERSION"
$pkg_cmd_name = "pwsh" $PwshBootScript = "$HOME\.local\tmp\install-pwsh-boot.ps1"
Invoke-DownloadUrl -Force -URL $PwshBootUrl -Path $PwshBootScript
$pkg_dst_cmd = "$HOME\.local\opt\pwsh\${pkg_cmd_name}.exe" pwsh -ExecutionPolicy Bypass $PwshBootScript
$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,45 +2,10 @@
set -e set -e
set -u set -u
__init_powershell() { __redirect_alias_pwsh() {
echo "'powershell@${WEBI_TAG:-stable}' is an alias for 'pwsh@${WEBI_VERSION-}'"
pkg_cmd_name="pwsh" WEBI_HOST=${WEBI_HOST:-"https://webinstall.dev"}
# no ./bin prefix curl -fsSL "$WEBI_HOST/pwsh@${WEBI_VERSION-}" | sh
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
}
} }
__init_powershell __redirect_alias_pwsh

View File

@@ -1,11 +1,98 @@
--- ---
title: PowerShell (pwsh alias) title: Microsoft PowerShell Core
homepage: https://webinstall.dev/powershell homepage: https://docs.microsoft.com/powershell/
tagline: | tagline: |
Alias for https://webinstall.dev/powershell PowerShell Core is a cross-platform (Windows, Linux, and macOS) automation and configuration tool/framework.
alias: powershell
description: |
See https://webinstall.dev/powershell
--- ---
Alias for 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.

View File

@@ -1,8 +1,57 @@
#!/bin/pwsh #!/usr/bin/env pwsh
Write-Output "'pwsh@$Env:WEBI_TAG' is an alias for 'powershell@$Env:WEBI_VERSION'" ################
# Install pwsh #
################
$PwshBootUrl = "$Env:WEBI_HOST/powershell@$Env:WEBI_VERSION" # Every package should define these variables
$PwshBootScript = "$HOME\.local\tmp\install-pwsh-boot.ps1" $pkg_cmd_name = "pwsh"
Invoke-DownloadUrl -Force -URL $PwshBootUrl -Path $PwshBootScript
powershell -ExecutionPolicy Bypass $PwshBootScript $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,52 @@
set -e set -e
set -u set -u
__redirect_alias_powershell() { __init_pwsh() {
echo "'pwsh@${WEBI_TAG:-stable}' is an alias for 'powershell@${WEBI_VERSION-}'"
WEBI_HOST=${WEBI_HOST:-"https://webinstall.dev"} pkg_cmd_name="pwsh"
curl -fsSL "$WEBI_HOST/powershell@${WEBI_VERSION-}" | sh
# 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 __init_pwsh

View File

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

View File

@@ -30,7 +30,7 @@ IF (!(Test-Path -Path "$pkg_src_cmd")) {
# TODO: create package-specific temp directory # TODO: create package-specific temp directory
# Enter tmp # Enter tmp
Push-Location $HOME\.local\tmp Push-Location .local\tmp
# Remove any leftover tmp cruft # Remove any leftover tmp cruft
Remove-Item -Path ".\rclone-v*" -Recurse -ErrorAction Ignore Remove-Item -Path ".\rclone-v*" -Recurse -ErrorAction Ignore

View File

@@ -30,7 +30,7 @@ IF (!(Test-Path -Path "$pkg_src_cmd")) {
# TODO: create package-specific temp directory # TODO: create package-specific temp directory
# Enter tmp # Enter tmp
Push-Location $HOME\.local\tmp Push-Location .local\tmp
# Remove any leftover tmp cruft # Remove any leftover tmp cruft
Remove-Item -Path ".\ripgrep-v*" -Recurse -ErrorAction Ignore Remove-Item -Path ".\ripgrep-v*" -Recurse -ErrorAction Ignore

View File

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

View File

@@ -29,7 +29,7 @@ IF (!(Test-Path -Path "$Env:USERPROFILE\Downloads\webi\$Env:WEBI_PKG_FILE")) {
IF (!(Test-Path -Path "$pkg_src_cmd")) { IF (!(Test-Path -Path "$pkg_src_cmd")) {
Write-Output "Installing sass (dart-sass)" Write-Output "Installing sass (dart-sass)"
Push-Location $HOME\.local\tmp Push-Location .local\tmp
# Remove any leftover tmp cruft # Remove any leftover tmp cruft
Remove-Item -Path ".\dart-sass-v*" -Recurse -ErrorAction Ignore Remove-Item -Path ".\dart-sass-v*" -Recurse -ErrorAction Ignore

View File

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

View File

@@ -30,7 +30,7 @@ IF (!(Test-Path -Path "$pkg_src_cmd")) {
# TODO: create package-specific temp directory # TODO: create package-specific temp directory
# Enter tmp # Enter tmp
Push-Location $HOME\.local\tmp Push-Location .local\tmp
# Remove any leftover tmp cruft # Remove any leftover tmp cruft
Remove-Item -Path ".\sclient-*" -Recurse -ErrorAction Ignore Remove-Item -Path ".\sclient-*" -Recurse -ErrorAction Ignore

Some files were not shown because too many files have changed in this diff Show More