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

98
asdf.sh
View File

@ -1,37 +1,77 @@
# For Korn shells (ksh, mksh, etc.), capture $_ (the final parameter passed to # shellcheck shell=sh
# the last command) straightaway, as it will contain the path to this script. # shellcheck disable=SC1007
# 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. # This file is the entrypoint for all POSIX-compatible shells. If `ASDF_DIR` is
_under="$_" # not already set, this script is able to calculate it, but only if the shell is
if [ -z "${ASDF_DIR:-}" ]; then # either Bash, Zsh, and Ksh. For other shells, `ASDF_DIR` must be manually set.
if [ -n "${BASH_SOURCE[0]}" ]; then
current_script_path="${BASH_SOURCE[0]}" export ASDF_DIR="${ASDF_DIR:-}"
elif [[ "$_under" == *".sh" ]]; then
current_script_path="$_under" if [ -z "$ASDF_DIR" ]; then
else if [ -n "$BASH_VERSION" ]; then
current_script_path="$0" # 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
fi fi
ASDF_DIR="$(dirname "$current_script_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 fi
export ASDF_DIR
# shellcheck disable=SC2016
[ -d "$ASDF_DIR" ] || printf "%s\n" "$ASDF_DIR is not a directory"
# Add asdf to PATH if [ ! -d "$ASDF_DIR" ]; then
# printf "%s\n" "asdf: Error: Variable '\$ASDF_DIR' is not a directory: $ASDF_DIR" >&2
# if in $PATH, remove, regardless of if it is in the right place (at the front) or not. return 1
# replace all occurrences - ${parameter//pattern/string} fi
ASDF_BIN="${ASDF_DIR}/bin"
ASDF_USER_SHIMS="${ASDF_DATA_DIR:-$HOME/.asdf}/shims" _asdf_bin="${ASDF_DIR}/bin"
[[ ":$PATH:" == *":${ASDF_BIN}:"* ]] && PATH="${PATH//$ASDF_BIN:/}" _asdf_shims="${ASDF_DATA_DIR:-$HOME/.asdf}/shims"
[[ ":$PATH:" == *":${ASDF_USER_SHIMS}:"* ]] && PATH="${PATH//$ASDF_USER_SHIMS:/}"
# add to front of $PATH # shellcheck disable=SC3060
PATH="${ASDF_BIN}:$PATH" if [ -n "$BASH_VERSION" ] || [ -n "$ZSH_VERSION" ]; then
PATH="${ASDF_USER_SHIMS}:$PATH" 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 # shellcheck source=lib/asdf.sh
# Load the asdf wrapper function
. "${ASDF_DIR}/lib/asdf.sh" . "${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. 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). `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. 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 . /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). 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)。 补全功能会被放在一个对 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 等等)**之后**的位置生效。 `asdf` 脚本需要在设置好的 `$PATH` **之后**和已经生效的框架(比如 oh-my-zsh 等等)**之后**的位置生效。
通常打开一个新的终端标签页来重启你的 shell 让 `PATH` 更改即时生效。 通常打开一个新的终端标签页来重启你的 shell 让 `PATH` 更改即时生效。

View File

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

View File

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

View File

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

View File

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