diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index cdadc1434..50e00f9c9 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -10,6 +10,10 @@ on: branches: - master +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + jobs: tests: name: Run tests diff --git a/.github/workflows/project.yml b/.github/workflows/project.yml index 800761554..4b671d449 100644 --- a/.github/workflows/project.yml +++ b/.github/workflows/project.yml @@ -5,6 +5,10 @@ on: pull_request_target: types: [opened, synchronize] +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + jobs: add-to-project: name: Add to project diff --git a/lib/vcs_info.zsh b/lib/vcs_info.zsh index 01dcd90b6..e60938c14 100644 --- a/lib/vcs_info.zsh +++ b/lib/vcs_info.zsh @@ -1,8 +1,11 @@ -# Impacted versions go from v5.0.3 to v5.8 (v5.8.1 is the first patched version) -autoload -Uz is-at-least -if is-at-least 5.8.1 || ! is-at-least 5.0.3; then - return -fi +# Don't skip this file until a Zsh release does the necessary quoting. +# This is because even though 5.8.1 undid recursive prompt_subst inside +# prompt sequences, % characters in relevant fields will still be rendered +# incorrectly in vcs_info, on all Zsh releases up to writing this. +# +# There is no release yet that does this right, since it requires changing +# how what vcs_info hooks expect to receive. Even so, I'd rather be correct +# and break custom vcs_info hooks than have a broken prompt. # Quote necessary $hook_com[] items just before they are used # in the line "VCS_INFO_hook 'post-backend'" of the VCS_INFO_formats @@ -35,7 +38,7 @@ fi # due to malicious input as a consequence of CVE-2021-45444, which affects # zsh versions from 5.0.3 to 5.8. # -autoload -Uz +X regexp-replace VCS_INFO_formats +autoload -Uz +X regexp-replace VCS_INFO_formats 2>/dev/null || return # We use $tmp here because it's already a local variable in VCS_INFO_formats typeset PATCH='for tmp (base base-name branch misc revision subdir) hook_com[$tmp]="${hook_com[$tmp]//\%/%%}"' diff --git a/plugins/copydir/README.md b/plugins/copydir/README.md index 594bf1065..cf24b789f 100644 --- a/plugins/copydir/README.md +++ b/plugins/copydir/README.md @@ -1,10 +1,3 @@ # copydir plugin -Copies the path of your current folder to the system clipboard. - -To use, add `copydir` to your plugins array: -``` -plugins=(... copydir) -``` - -Then use the command `copydir` to copy the $PWD. +This plugin is deprecated. Use the [`copypath` plugin](https://github.com/ohmyzsh/ohmyzsh/tree/master/plugins/copypath) instead. diff --git a/plugins/copydir/copydir.plugin.zsh b/plugins/copydir/copydir.plugin.zsh index c45106240..a2b489ec0 100644 --- a/plugins/copydir/copydir.plugin.zsh +++ b/plugins/copydir/copydir.plugin.zsh @@ -1,5 +1,7 @@ -# Copies the pathname of the current directory to the system or X Windows clipboard +echo ${(%):-'%F{yellow}The `%Bcopydir%b` plugin is deprecated. Use the `%Bcopypath%b` plugin instead.%f'} +source "$ZSH/plugins/copypath/copypath.plugin.zsh" + +# TODO: 2022-02-22: Remove deprecated copydir function. function copydir { - emulate -L zsh - print -n $PWD | clipcopy + copypath } diff --git a/plugins/copypath/README.md b/plugins/copypath/README.md new file mode 100644 index 000000000..1e5a463a6 --- /dev/null +++ b/plugins/copypath/README.md @@ -0,0 +1,15 @@ +# copypath plugin + +Copies the path of given directory or file to the system clipboard. + +To use it, add `copypath` to the plugins array in your zshrc file: + +```zsh +plugins=(... copypath) +``` + +## Usage + +- `copypath`: copies the absolute path of the current directory. + +- `copypath `: copies the absolute path of the given file. diff --git a/plugins/copypath/copypath.plugin.zsh b/plugins/copypath/copypath.plugin.zsh new file mode 100644 index 000000000..8fe0a85f4 --- /dev/null +++ b/plugins/copypath/copypath.plugin.zsh @@ -0,0 +1,15 @@ +# Copies the path of given directory or file to the system or X Windows clipboard. +# Copy current directory if no parameter. +function copypath { + # If no argument passed, use current directory + local file="${1:-.}" + + # If argument is not an absolute path, prepend $PWD + [[ $file = /* ]] || file="$PWD/$file" + + # Copy the absolute path without resolving symlinks + # If clipcopy fails, exit the function with an error + print -n "${file:a}" | clipcopy || return 1 + + echo ${(%):-"%B${file:a}%b copied to clipboard."} +} diff --git a/plugins/dotenv/dotenv.plugin.zsh b/plugins/dotenv/dotenv.plugin.zsh index 394455ae1..46cd4b10a 100644 --- a/plugins/dotenv/dotenv.plugin.zsh +++ b/plugins/dotenv/dotenv.plugin.zsh @@ -52,7 +52,10 @@ source_env() { fi # test .env syntax - zsh -fn $ZSH_DOTENV_FILE || echo "dotenv: error when sourcing '$ZSH_DOTENV_FILE' file" >&2 + zsh -fn $ZSH_DOTENV_FILE || { + echo "dotenv: error when sourcing '$ZSH_DOTENV_FILE' file" >&2 + return 1 + } setopt localoptions allexport source $ZSH_DOTENV_FILE diff --git a/plugins/helm/helm.plugin.zsh b/plugins/helm/helm.plugin.zsh index cadfa551a..05bb19a44 100644 --- a/plugins/helm/helm.plugin.zsh +++ b/plugins/helm/helm.plugin.zsh @@ -14,9 +14,9 @@ command mkdir -p "$ZSH_CACHE_DIR/completions" # If the completion file does not exist, generate it and then source it # Otherwise, source it and regenerate in the background if [[ ! -f "$ZSH_CACHE_DIR/completions/_helm" ]]; then - helm completion zsh >| "$ZSH_CACHE_DIR/completions/_helm" + helm completion zsh | tee "$ZSH_CACHE_DIR/completions/_helm" >/dev/null source "$ZSH_CACHE_DIR/completions/_helm" else source "$ZSH_CACHE_DIR/completions/_helm" - helm completion zsh >| "$ZSH_CACHE_DIR/completions/_helm" &| + helm completion zsh | tee "$ZSH_CACHE_DIR/completions/_helm" >/dev/null &| fi diff --git a/plugins/kubectl/kubectl.plugin.zsh b/plugins/kubectl/kubectl.plugin.zsh index eed5727d1..89efeaca5 100644 --- a/plugins/kubectl/kubectl.plugin.zsh +++ b/plugins/kubectl/kubectl.plugin.zsh @@ -11,11 +11,11 @@ if (( $+commands[kubectl] )); then # If the completion file does not exist, generate it and then source it # Otherwise, source it and regenerate in the background if [[ ! -f "$ZSH_CACHE_DIR/completions/_kubectl" ]]; then - kubectl completion zsh >| "$ZSH_CACHE_DIR/completions/_kubectl" + kubectl completion zsh | tee "$ZSH_CACHE_DIR/completions/_kubectl" >/dev/null source "$ZSH_CACHE_DIR/completions/_kubectl" else source "$ZSH_CACHE_DIR/completions/_kubectl" - kubectl completion zsh >| "$ZSH_CACHE_DIR/completions/_kubectl" &| + kubectl completion zsh | tee "$ZSH_CACHE_DIR/completions/_kubectl" >/dev/null &| fi fi diff --git a/themes/michelebologna.zsh-theme b/themes/michelebologna.zsh-theme index 7ff6a7ffe..bb86d68db 100644 --- a/themes/michelebologna.zsh-theme +++ b/themes/michelebologna.zsh-theme @@ -35,23 +35,17 @@ local reset="%{$reset_color%}" local -a color_array color_array=($green $red $cyan $yellow $blue $magenta $white) -local username_normal_color=$white -local username_root_color=$red -local hostname_root_color=$red - -# calculating hostname color with hostname characters -for i in `hostname`; local hostname_normal_color=$color_array[$[((#i))%7+1]] -local -a hostname_color -hostname_color=%(!.$hostname_root_color.$hostname_normal_color) - +local username_color=$white +local hostname_color=$color_array[$[((#HOST))%7+1]] # choose hostname color based on first character local current_dir_color=$blue -local username_command="%n" -local hostname_command="%m" + +local username="%n" +local hostname="%m" local current_dir="%~" -local username_output="%(!..$username_normal_color$username_command$reset@)" -local hostname_output="$hostname_color$hostname_command$reset" -local current_dir_output="$current_dir_color$current_dir$reset" +local username_output="%(!..${username_color}${username}${reset}@)" +local hostname_output="${hostname_color}${hostname}${reset}" +local current_dir_output="${current_dir_color}${current_dir}${reset}" local jobs_bg="${red}fg: %j$reset" local last_command_output="%(?.%(!.$red.$green).$yellow)" @@ -68,8 +62,18 @@ ZSH_THEME_GIT_PROMPT_AHEAD_REMOTE=">" ZSH_THEME_GIT_PROMPT_BEHIND_REMOTE="<" ZSH_THEME_GIT_PROMPT_DIVERGED_REMOTE="$red<>" -PROMPT='$username_output$hostname_output:$current_dir_output%1(j. [$jobs_bg].)' -GIT_PROMPT='$(out=$(git_prompt_info)$(git_prompt_status)$(git_remote_status);if [[ -n $out ]]; then printf %s " $white($green$out$white)$reset";fi)' -PROMPT+="$GIT_PROMPT" +function michelebologna_git_prompt { + local out=$(git_prompt_info)$(git_prompt_status)$(git_remote_status) + [[ -n $out ]] || return + printf " %s(%s%s%s)%s" \ + "%{$fg_bold[white]%}" \ + "%{$fg_bold[green]%}" \ + "$out" \ + "%{$fg_bold[white]%}" \ + "%{$reset_color%}" +} + +PROMPT="$username_output$hostname_output:$current_dir_output%1(j. [$jobs_bg].)" +PROMPT+='$(michelebologna_git_prompt)' PROMPT+=" $last_command_output%#$reset " RPROMPT='' diff --git a/tools/check_for_upgrade.sh b/tools/check_for_upgrade.sh index a36aecb84..76d42d388 100644 --- a/tools/check_for_upgrade.sh +++ b/tools/check_for_upgrade.sh @@ -65,18 +65,27 @@ function is_update_available() { local remote_head remote_head=$( if (( ${+commands[curl]} )); then - curl -fsSL -H 'Accept: application/vnd.github.v3.sha' $api_url 2>/dev/null + curl -m 2 -fsSL -H 'Accept: application/vnd.github.v3.sha' $api_url 2>/dev/null elif (( ${+commands[wget]} )); then - wget -O- --header='Accept: application/vnd.github.v3.sha' $api_url 2>/dev/null + wget -T 2 -O- --header='Accept: application/vnd.github.v3.sha' $api_url 2>/dev/null elif (( ${+commands[fetch]} )); then - HTTP_ACCEPT='Accept: application/vnd.github.v3.sha' fetch -o - $api_url 2>/dev/null + HTTP_ACCEPT='Accept: application/vnd.github.v3.sha' fetch -T 2 -o - $api_url 2>/dev/null else exit 0 fi ) || return 1 - # Compare local and remote HEADs - [[ "$local_head" != "$remote_head" ]] + # Compare local and remote HEADs (if they're equal there are no updates) + [[ "$local_head" != "$remote_head" ]] || return 1 + + # If local and remote HEADs don't match, check if there's a common ancestor + # If the merge-base call fails, $remote_head might not be downloaded so assume there are updates + local base + base=$(cd -q "$ZSH"; git merge-base $local_head $remote_head 2>/dev/null) || return 0 + + # If the common ancestor ($base) is not $remote_head, + # the local HEAD is older than the remote HEAD + [[ $base != $remote_head ]] } function update_last_updated_file() { diff --git a/tools/install.sh b/tools/install.sh index e64e39063..7953ad112 100755 --- a/tools/install.sh +++ b/tools/install.sh @@ -42,13 +42,17 @@ set -e # $USER is defined by login(1) which is not always executed (e.g. containers) # POSIX: https://pubs.opengroup.org/onlinepubs/009695299/utilities/id.html USER=${USER:-$(id -u -n)} +# $HOME is defined at the time of login, but it could be unset. If it is unset, +# a tilde by itself (~) will not be expanded to the current user's home directory. +# POSIX: https://pubs.opengroup.org/onlinepubs/009696899/basedefs/xbd_chap08.html#tag_08_03 +HOME="${HOME:-$(getent passwd $USER | cut -d: -f6)}" # Track if $ZSH was provided custom_zsh=${ZSH:+yes} # Default settings -ZSH=${ZSH:-~/.oh-my-zsh} +ZSH="${ZSH:-$HOME/.oh-my-zsh}" REPO=${REPO:-ohmyzsh/ohmyzsh} REMOTE=${REMOTE:-https://github.com/${REPO}.git} BRANCH=${BRANCH:-master} @@ -268,7 +272,7 @@ setup_ohmyzsh() { fi # Manual clone with git config options to support git < v1.7.2 - git init "$ZSH" && cd "$ZSH" \ + git init --quiet "$ZSH" && cd "$ZSH" \ && git config core.eol lf \ && git config core.autocrlf false \ && git config fsck.zeroPaddedFilemode ignore \