summaryrefslogtreecommitdiff
path: root/lib/cli.zsh
diff options
context:
space:
mode:
Diffstat (limited to 'lib/cli.zsh')
-rw-r--r--lib/cli.zsh165
1 files changed, 144 insertions, 21 deletions
diff --git a/lib/cli.zsh b/lib/cli.zsh
index 561c1b98b..55938ba8a 100644
--- a/lib/cli.zsh
+++ b/lib/cli.zsh
@@ -1,6 +1,7 @@
#!/usr/bin/env zsh
function omz {
+ setopt localoptions noksharrays
[[ $# -gt 0 ]] || {
_omz::help
return 1
@@ -27,6 +28,7 @@ function _omz {
'plugin:Manage plugins'
'pr:Manage Oh My Zsh Pull Requests'
'reload:Reload the current zsh session'
+ 'shop:Open the Oh My Zsh shop'
'theme:Manage themes'
'update:Update Oh My Zsh'
'version:Show the version'
@@ -71,6 +73,10 @@ function _omz {
local -aU plugins
plugins=("$ZSH"/plugins/*/{_*,*.plugin.zsh}(-.N:h:t) "$ZSH_CUSTOM"/plugins/*/{_*,*.plugin.zsh}(-.N:h:t))
_describe 'plugin' plugins ;;
+ plugin::list)
+ local -a opts
+ opts=('--enabled:List enabled plugins only')
+ _describe -o 'options' opts ;;
theme::(set|use))
local -aU themes
themes=("$ZSH"/themes/*.zsh-theme(-.N:t:r) "$ZSH_CUSTOM"/**/*.zsh-theme(-.N:r:gs:"$ZSH_CUSTOM"/themes/:::gs:"$ZSH_CUSTOM"/:::))
@@ -168,6 +174,7 @@ Available commands:
plugin <command> Manage plugins
pr <command> Manage Oh My Zsh Pull Requests
reload Reload the current zsh session
+ shop Open the Oh My Zsh shop
theme <command> Manage themes
update Update Oh My Zsh
version Show the version
@@ -192,7 +199,7 @@ EOF
return 1
fi
- "$ZSH/tools/changelog.sh" "$version" "${2:-}" "$format"
+ ZSH="$ZSH" command zsh -f "$ZSH/tools/changelog.sh" "$version" "${2:-}" "$format"
}
function _omz::plugin {
@@ -205,7 +212,7 @@ Available commands:
disable <plugin> Disable plugin(s)
enable <plugin> Enable plugin(s)
info <plugin> Get information of a plugin
- list List all available Oh My Zsh plugins
+ list [--enabled] List Oh My Zsh plugins
load <plugin> Load plugin(s)
EOF
@@ -241,10 +248,18 @@ function _omz::plugin::disable {
# Remove plugins substitution awk script
local awk_subst_plugins="\
- gsub(/[ \t]+(${(j:|:)dis_plugins})/, \"\") # with spaces before
- gsub(/(${(j:|:)dis_plugins})[ \t]+/, \"\") # with spaces after
- gsub(/\((${(j:|:)dis_plugins})\)/, \"\") # without spaces (only plugin)
+ gsub(/[ \t]+(${(j:|:)dis_plugins})[ \t]+/, \" \") # with spaces before or after
+ gsub(/[ \t]+(${(j:|:)dis_plugins})$/, \"\") # with spaces before and EOL
+ gsub(/^(${(j:|:)dis_plugins})[ \t]+/, \"\") # with BOL and spaces after
+
+ gsub(/\((${(j:|:)dis_plugins})[ \t]+/, \"(\") # with parenthesis before and spaces after
+ gsub(/[ \t]+(${(j:|:)dis_plugins})\)/, \")\") # with spaces before or parenthesis after
+ gsub(/\((${(j:|:)dis_plugins})\)/, \"()\") # with only parentheses
+
+ gsub(/^(${(j:|:)dis_plugins})\)/, \")\") # with BOL and closing parenthesis
+ gsub(/\((${(j:|:)dis_plugins})$/, \"(\") # with opening parenthesis and EOL
"
+
# Disable plugins awk script
local awk_script="
# if plugins=() is in oneline form, substitute disabled plugins and go to next line
@@ -336,20 +351,40 @@ function _omz::plugin::enable {
next
}
-# if plugins=() is in multiline form, enable multi flag
+# if plugins=() is in multiline form, enable multi flag and indent by default with 2 spaces
/^[ \t]*plugins=\(/ {
multi=1
+ indent=\" \"
+ print \$0
+ next
}
# if multi flag is enabled and we find a valid closing parenthesis,
-# add new plugins and disable multi flag
+# add new plugins with proper indent and disable multi flag
multi == 1 && /^[^#]*\)/ {
multi=0
- sub(/\)/, \" $add_plugins&\")
+ split(\"$add_plugins\",p,\" \")
+ for (i in p) {
+ print indent p[i]
+ }
print \$0
next
}
+# if multi flag is enabled and we didnt find a closing parenthesis,
+# get the indentation level to match when adding plugins
+multi == 1 && /^[^#]*/ {
+ indent=\"\"
+ for (i = 1; i <= length(\$0); i++) {
+ char=substr(\$0, i, 1)
+ if (char == \" \" || char == \"\t\") {
+ indent = indent char
+ } else {
+ break
+ }
+ }
+}
+
{ print \$0 }
"
@@ -389,8 +424,23 @@ function _omz::plugin::info {
local readme
for readme in "$ZSH_CUSTOM/plugins/$1/README.md" "$ZSH/plugins/$1/README.md"; do
if [[ -f "$readme" ]]; then
- (( ${+commands[less]} )) && less "$readme" || cat "$readme"
- return 0
+ # If being piped, just cat the README
+ if [[ ! -t 1 ]]; then
+ cat "$readme"
+ return $?
+ fi
+
+ # Enrich the README display depending on the tools we have
+ # - glow: https://github.com/charmbracelet/glow
+ # - bat: https://github.com/sharkdp/bat
+ # - less: typical pager command
+ case 1 in
+ ${+commands[glow]}) glow -p "$readme" ;;
+ ${+commands[bat]}) bat -l md --style plain "$readme" ;;
+ ${+commands[less]}) less "$readme" ;;
+ *) cat "$readme" ;;
+ esac
+ return $?
fi
done
@@ -405,8 +455,21 @@ function _omz::plugin::info {
function _omz::plugin::list {
local -a custom_plugins builtin_plugins
- custom_plugins=("$ZSH_CUSTOM"/plugins/*(-/N:t))
- builtin_plugins=("$ZSH"/plugins/*(-/N:t))
+
+ # If --enabled is provided, only list what's enabled
+ if [[ "$1" == "--enabled" ]]; then
+ local plugin
+ for plugin in "${plugins[@]}"; do
+ if [[ -d "${ZSH_CUSTOM}/plugins/${plugin}" ]]; then
+ custom_plugins+=("${plugin}")
+ elif [[ -d "${ZSH}/plugins/${plugin}" ]]; then
+ builtin_plugins+=("${plugin}")
+ fi
+ done
+ else
+ custom_plugins=("$ZSH_CUSTOM"/plugins/*(-/N:t))
+ builtin_plugins=("$ZSH"/plugins/*(-/N:t))
+ fi
# If the command is being piped, print all found line by line
if [[ ! -t 1 ]]; then
@@ -448,7 +511,7 @@ function _omz::plugin::load {
if [[ ! -f "$base/_$plugin" && ! -f "$base/$plugin.plugin.zsh" ]]; then
_omz::log warn "'$plugin' is not a valid plugin"
continue
- # It it is a valid plugin, add its directory to $fpath unless it is already there
+ # It is a valid plugin, add its directory to $fpath unless it is already there
elif (( ! ${fpath[(Ie)$base]} )); then
fpath=("$base" $fpath)
fi
@@ -560,10 +623,48 @@ function _omz::pr::test {
done
(( $found )) || {
- _omz::log error "could not found the ohmyzsh git remote. Aborting..."
+ _omz::log error "could not find the ohmyzsh git remote. Aborting..."
return 1
}
+ # Check if Pull Request has the "testers needed" label
+ _omz::log info "checking if PR #$1 has the 'testers needed' label..."
+ local pr_json label label_id="MDU6TGFiZWw4NzY1NTkwNA=="
+ pr_json=$(
+ curl -fsSL \
+ -H "Accept: application/vnd.github+json" \
+ -H "X-GitHub-Api-Version: 2022-11-28" \
+ "https://api.github.com/repos/ohmyzsh/ohmyzsh/pulls/$1"
+ )
+
+ if [[ $? -gt 0 || -z "$pr_json" ]]; then
+ _omz::log error "error when trying to fetch PR #$1 from GitHub."
+ return 1
+ fi
+
+ # Check if the label is present with jq or grep
+ if (( $+commands[jq] )); then
+ label="$(command jq ".labels.[] | select(.node_id == \"$label_id\")" <<< "$pr_json")"
+ else
+ label="$(command grep "\"$label_id\"" <<< "$pr_json" 2>/dev/null)"
+ fi
+
+ # If a maintainer hasn't labeled the PR to test, explain the security risk
+ if [[ -z "$label" ]]; then
+ _omz::log warn "PR #$1 does not have the 'testers needed' label. This means that the PR"
+ _omz::log warn "has not been reviewed by a maintainer and may contain malicious code."
+
+ # Ask for explicit confirmation: user needs to type "yes" to continue
+ _omz::log prompt "Do you want to continue testing it? [yes/N] "
+ builtin read -r
+ if [[ "${REPLY:l}" != yes ]]; then
+ _omz::log error "PR test canceled. Please ask a maintainer to review and label the PR."
+ return 1
+ else
+ _omz::log warn "Continuing to check out and test PR #$1. Be careful!"
+ fi
+ fi
+
# Fetch pull request head
_omz::log info "fetching PR #$1 to ohmyzsh/pull-$1..."
command git fetch -f "$remote" refs/pull/$1/head:ohmyzsh/pull-$1 || {
@@ -622,6 +723,15 @@ function _omz::pr::test {
)
}
+function _omz::shop {
+ local shop_url="https://commitgoods.com/collections/oh-my-zsh"
+
+ _omz::log info "Opening Oh My Zsh shop in your browser..."
+ _omz::log info "$shop_url"
+
+ open_command "$shop_url"
+}
+
function _omz::reload {
# Delete current completion cache
command rm -f $_comp_dumpfile $ZSH_COMPDUMP
@@ -773,15 +883,28 @@ function _omz::theme::use {
}
function _omz::update {
- local last_commit=$(builtin cd -q "$ZSH"; git rev-parse HEAD)
+ # Check if git command is available
+ (( $+commands[git] )) || {
+ _omz::log error "git is not installed. Aborting..."
+ return 1
+ }
+
+ # Check if --unattended was passed
+ [[ "$1" != --unattended ]] || {
+ _omz::log error "the \`\e[2m--unattended\e[0m\` flag is no longer supported, use the \`\e[2mupgrade.sh\e[0m\` script instead."
+ _omz::log error "for more information see https://github.com/ohmyzsh/ohmyzsh/wiki/FAQ#how-do-i-update-oh-my-zsh"
+ return 1
+ }
+
+ local last_commit=$(builtin cd -q "$ZSH"; git rev-parse HEAD 2>/dev/null)
+ [[ $? -eq 0 ]] || {
+ _omz::log error "\`$ZSH\` is not a git directory. Aborting..."
+ return 1
+ }
# Run update script
zstyle -s ':omz:update' verbose verbose_mode || verbose_mode=default
- if [[ "$1" != --unattended ]]; then
- ZSH="$ZSH" command zsh -f "$ZSH/tools/upgrade.sh" -i -v $verbose_mode || return $?
- else
- ZSH="$ZSH" command zsh -f "$ZSH/tools/upgrade.sh" -v $verbose_mode || return $?
- fi
+ ZSH="$ZSH" command zsh -f "$ZSH/tools/upgrade.sh" -i -v $verbose_mode || return $?
# Update last updated file
zmodload zsh/datetime
@@ -790,7 +913,7 @@ function _omz::update {
command rm -rf "$ZSH/log/update.lock"
# Restart the zsh session if there were changes
- if [[ "$1" != --unattended && "$(builtin cd -q "$ZSH"; git rev-parse HEAD)" != "$last_commit" ]]; then
+ if [[ "$(builtin cd -q "$ZSH"; git rev-parse HEAD)" != "$last_commit" ]]; then
# Old zsh versions don't have ZSH_ARGZERO
local zsh="${ZSH_ARGZERO:-${functrace[-1]%:*}}"
# Check whether to run a login shell