fix!: rework POSIX entrypoint for greater shell support (#1480)

This commit is contained in:
Edwin Kofler 2023-03-20 22:06:57 -07:00 committed by GitHub
parent 58611c7ba4
commit 3379af845e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 187 additions and 53 deletions

100
asdf.sh
View File

@ -1,37 +1,77 @@
# For Korn shells (ksh, mksh, etc.), capture $_ (the final parameter passed to
# the last command) straightaway, as it will contain the path to this script.
# For Bash, ${BASH_SOURCE[0]} will be used to obtain this script's path.
# For Zsh and others, $0 (the path to the shell or script) will be used.
_under="$_"
if [ -z "${ASDF_DIR:-}" ]; then
if [ -n "${BASH_SOURCE[0]}" ]; then
current_script_path="${BASH_SOURCE[0]}"
elif [[ "$_under" == *".sh" ]]; then
current_script_path="$_under"
else
current_script_path="$0"
# shellcheck shell=sh
# shellcheck disable=SC1007
# This file is the entrypoint for all POSIX-compatible shells. If `ASDF_DIR` is
# not already set, this script is able to calculate it, but only if the shell is
# either Bash, Zsh, and Ksh. For other shells, `ASDF_DIR` must be manually set.
export ASDF_DIR="${ASDF_DIR:-}"
if [ -z "$ASDF_DIR" ]; then
if [ -n "$BASH_VERSION" ]; then
# Use BASH_SOURCE[0] to obtain the relative path to this source'd file. Since it's
# a relative path, 'cd' to its dirname and use '$PWD" to obtain the fullpath.
# Use 'builtin cd' to ensure user-defined 'cd()' functions aren't called.
# Use variable '_asdf_old_dir' to avoid using subshells.
_asdf_old_dir=$PWD
# shellcheck disable=SC3028,SC3054
if ! CDPATH= builtin cd -- "${BASH_SOURCE[0]%/*}"; then
printf '%s\n' 'asdf: Error: Failed to cd' >&2
unset -v _asdf_old_dir
return 1
fi
ASDF_DIR=$PWD
if ! CDPATH= builtin cd -- "$_asdf_old_dir"; then
printf '%s\n' 'asdf: Error: Failed to cd' >&2
unset -v _asdf_old_dir
return 1
fi
unset -v _asdf_old_dir
elif [ -n "$ZSH_VERSION" ]; then
# Use '%x' to expand to path of current file. It must be prefixed
# with '(%):-', so it expands in non-prompt-string contexts.
# shellcheck disable=SC2296
ASDF_DIR=${(%):-%x}
ASDF_DIR=${ASDF_DIR%/*}
elif [ -n "$KSH_VERSION" ] && [ -z "$PATHSEP" ]; then
# Only the original KornShell (kornshell.com) has a '.sh.file' variable with the path
# of the current file. To prevent errors with other variations, such as the MirBSD
# Korn shell (mksh), test for 'PATHSEP' which is _not_ set on the original Korn Shell.
# shellcheck disable=SC2296
ASDF_DIR=${.sh.file}
ASDF_DIR=${ASDF_DIR%/*}
fi
ASDF_DIR="$(dirname "$current_script_path")"
fi
export ASDF_DIR
# shellcheck disable=SC2016
[ -d "$ASDF_DIR" ] || printf "%s\n" "$ASDF_DIR is not a directory"
# Add asdf to PATH
#
# if in $PATH, remove, regardless of if it is in the right place (at the front) or not.
# replace all occurrences - ${parameter//pattern/string}
ASDF_BIN="${ASDF_DIR}/bin"
ASDF_USER_SHIMS="${ASDF_DATA_DIR:-$HOME/.asdf}/shims"
[[ ":$PATH:" == *":${ASDF_BIN}:"* ]] && PATH="${PATH//$ASDF_BIN:/}"
[[ ":$PATH:" == *":${ASDF_USER_SHIMS}:"* ]] && PATH="${PATH//$ASDF_USER_SHIMS:/}"
# add to front of $PATH
PATH="${ASDF_BIN}:$PATH"
PATH="${ASDF_USER_SHIMS}:$PATH"
if [ -z "$ASDF_DIR" ]; then
printf "%s\n" "asdf: Error: Source directory could not be calculated. Please set it manually before sourcing this file." >&2
return 1
fi
if [ ! -d "$ASDF_DIR" ]; then
printf "%s\n" "asdf: Error: Variable '\$ASDF_DIR' is not a directory: $ASDF_DIR" >&2
return 1
fi
_asdf_bin="${ASDF_DIR}/bin"
_asdf_shims="${ASDF_DATA_DIR:-$HOME/.asdf}/shims"
# shellcheck disable=SC3060
if [ -n "$BASH_VERSION" ] || [ -n "$ZSH_VERSION" ]; then
case ":$PATH:" in
*":${_asdf_bin}:"*) PATH="${PATH//$_asdf_bin:/}" ;;
esac
case ":$PATH:" in
*":${_asdf_shims}:"*) PATH="${PATH//$_asdf_shims:/}" ;;
esac
fi
PATH="${_asdf_bin}:${_asdf_shims}:$PATH"
unset -v _asdf_bin _asdf_shims
# shellcheck source=lib/asdf.sh
# Load the asdf wrapper function
. "${ASDF_DIR}/lib/asdf.sh"
unset _under current_script_path ASDF_BIN ASDF_USER_SHIMS

View File

@ -294,6 +294,39 @@ Add `asdf.nu` to your `~/.config/nushell/config.nu` with:
Completions are automatically configured.
:::
::: details POSIX Shell & Git
Add the following to `~/.profile`:
```shell
export ASDF_DIR="$HOME/.asdf"
. "$HOME/.asdf/asdf.sh"
```
:::
::: details POSIX Shell & Homebrew
Add `asdf.sh` to your `~/.profile` with:
```shell:no-line-numbers
echo -e "\nexport ASDF_DIR=\"$(brew --prefix asdf)/libexec/asdf.sh\"" >> ~/.profile
echo -e "\n. \"$(brew --prefix asdf)/libexec/asdf.sh\"" >> ~/.profile
```
:::
::: details POSIX Shell & Pacman
Add the following to `~/.profile`:
```shell
export ASDF_DIR="/opt/asdf-vm"
. /opt/asdf-vm/asdf.sh
```
:::
`asdf` scripts need to be sourced **after** you have set your `$PATH` and **after** you have sourced your framework (oh-my-zsh etc).
Restart your shell so that `PATH` changes take effect. Opening a new terminal tab will usually do it.

View File

@ -262,6 +262,39 @@ Adicione a seguinte linha ao seu `~/.zshrc`:
. /opt/asdf-vm/asdf.sh
```
::: details POSIX Shell & Git
Adicione a seguinte linha ao seu `~/.profile`:
```shell
export ASDF_DIR="$HOME/.asdf"
. "$HOME/.asdf/asdf.sh"
```
:::
::: details POSIX Shell & Homebrew
Adicione `asdf.sh` ao `~/.profile` através do comando:
```shell:no-line-numbers
echo -e "\nexport ASDF_DIR=\"$(brew --prefix asdf)/libexec/asdf.sh\"" >> ~/.profile
echo -e "\n. \"$(brew --prefix asdf)/libexec/asdf.sh\"" >> ~/.profile
```
:::
::: details POSIX Shell & Pacman
Adicione a seguinte linha ao seu `~/.profile`:
```shell
export ASDF_DIR="/opt/asdf-vm"
. /opt/asdf-vm/asdf.sh
```
:::
O auto completar é colocado em um local familiar para o ZSH, [mas o ZSH deve ser configurado para conseguir utilizá-lo](https://wiki.archlinux.org/index.php/zsh#Command_completion).
:::

View File

@ -263,6 +263,39 @@ echo -e "\n. $(brew --prefix asdf)/libexec/asdf.sh" >> ${ZDOTDIR:-~}/.zshrc
补全功能会被放在一个对 ZSH 很友好的位置,但是 [ZSH 必须使用自动补全完成配置](https://wiki.archlinux.org/index.php/zsh#Command_completion)。
:::
::: details POSIX Shell & Git
`~/.profile` 文件中加入以下内容:
```shell
export ASDF_DIR="$HOME/.asdf"
. "$HOME/.asdf/asdf.sh"
```
:::
::: details POSIX Shell & Homebrew
使用以下命令将 `asdf.sh` 加入到 `~/.profile` 文件中:
```shell:no-line-numbers
echo -e "\nexport ASDF_DIR=\"$(brew --prefix asdf)/libexec/asdf.sh\"" >> ~/.profile
echo -e "\n. \"$(brew --prefix asdf)/libexec/asdf.sh\"" >> ~/.profile
```
:::
::: details POSIX Shell & Pacman
`~/.profile` 文件中加入以下内容:
```shell
export ASDF_DIR="/opt/asdf-vm"
. /opt/asdf-vm/asdf.sh
```
:::
`asdf` 脚本需要在设置好的 `$PATH` **之后**和已经生效的框架(比如 oh-my-zsh 等等)**之后**的位置生效。
通常打开一个新的终端标签页来重启你的 shell 让 `PATH` 更改即时生效。

View File

@ -1,20 +1,20 @@
# shellcheck shell=sh
# The asdf function is a wrapper so we can export variables
asdf() {
local command
command="$1"
if [ "$#" -gt 0 ]; then
shift
fi
case "$command" in
case $1 in
"shell")
# commands that need to export variables
if ! shift; then
printf '%s\n' 'asdf: Error: Failed to shift' >&2
return 1
fi
# Invoke command that needs to export variables.
eval "$(asdf export-shell-version sh "$@")" # asdf_allow: eval
;;
*)
# forward other commands to asdf script
command asdf "$command" "$@" # asdf_allow: ' asdf '
# Forward other commands to asdf script.
command asdf "$@" # asdf_allow: ' asdf '
;;
esac
}

View File

@ -3,10 +3,8 @@
set -euo pipefail
# check .sh files
# TODO(jthegedus): unlock this check later
# TODO shfmt --language-dialect posix --indent 2 --write \
# TODO asdf.sh \
# TODO lib/*.sh
shfmt --language-dialect posix --indent 2 --write \
lib/*.sh
# check .bash files
shfmt --language-dialect bash --indent 2 --write \

View File

@ -3,10 +3,9 @@
set -euo pipefail
# check .sh files
# TODO(jthegedus): unlock this check later
# TODO shellcheck --shell sh --external-sources \
# TODO asdf.sh \
# TODO lib/*.sh
shellcheck --shell sh --external-sources \
asdf.sh \
lib/*.sh
# check .bash files
shellcheck --shell bash --external-sources \

View File

@ -3,10 +3,8 @@
set -euo pipefail
# check .sh files
# TODO(jthegedus): unlock this check later
# TODO shfmt --language-dialect posix --indent 2 --diff \
# TODO asdf.sh \
# TODO lib/*.sh
shfmt --language-dialect posix --indent 2 --diff \
lib/*.sh
# check .bash files
shfmt --language-dialect bash --indent 2 --diff \