1
0
mirror of https://github.com/zplug/zplug synced 2025-04-09 09:09:08 +02:00

Add new spinners

This commit is contained in:
b4b4r07 2016-10-19 22:11:39 +09:00
parent 56a9f51bb7
commit c6c8b1742c
18 changed files with 1341 additions and 381 deletions

@ -5,10 +5,17 @@
local repo arg
local -aU repos
local -A tags
local -a failed_packages
local -A from
local -i max=0
local -F SECONDS=0 start_time finish_time
local -i status_code=0 cant_lock=0
local -A repo_pids states hook_build hook_finished hook_pids status_codes repo_dir
local -F SECONDS=0
local -a spinners sub_spinners
local -i spinner_idx subspinner_idx
local -i timeout=60
local is_parallel=""
spinners=(⠋ ⠙ ⠹ ⠸ ⠼ ⠴ ⠦ ⠧ ⠇ ⠏)
sub_spinners=(⠁ ⠁ ⠉ ⠙ ⠚ ⠒ ⠂ ⠂ ⠒ ⠲ ⠴ ⠤ ⠄ ⠄ ⠤ ⠠ ⠠ ⠤ ⠦ ⠖ ⠒ ⠐ ⠐ ⠒ ⠓ ⠋ ⠉ ⠈ ⠈)
while (( $# > 0 ))
do
@ -32,26 +39,37 @@ do
shift
done
# Initialize
{
start_time=$SECONDS
# If no argument is given,
# use non-installed plugins as an installation target
if (( $#repos == 0 )); then
__zplug::core::core::run_interfaces \
"check" \
2> >(__zplug::io::log::capture) >/dev/null \
|| repos=( "${reply[@]}" )
fi
if (( $#repos == 0 )); then
# Case of existing not installed repos
__zplug::core::core::run_interfaces \
"check" \
2> >(__zplug::io::log::capture) >/dev/null \
|| repos=( "${reply[@]}" )
fi
# No plugin to install
if (( $#repos == 0 )); then
return 0
fi
for repo in "${repos[@]}"
do
(( $#repo > $max )) && max=$#repo
done
}
# Check the number of arguments
if (( $#repos > 1 )); then
is_parallel=true
fi
# Main loop
for repo in "${repos[@]}"
rm -f \
"$_zplug_config[build_success]" \
"$_zplug_config[build_failure]" \
"$_zplug_config[build_timeout]" \
"$_zplug_config[install_status]"
touch "$_zplug_config[install_status]"
# Suppress outputs
setopt nonotify nomonitor
tput civis
for repo in "$repos[@]"
do
if ! __zplug::base::base::zpluged "$repo"; then
__zplug::io::print::f \
@ -62,127 +80,240 @@ do
return 1
fi
__zplug::core::tags::parse "$repo"
tags=( "${reply[@]}" )
tags[hook-build]="$(
__zplug::core::core::run_interfaces \
'hook-build' \
"$repo"
)"
tags[dir]="$(
__zplug::core::core::run_interfaces \
'dir' \
"$repo"
)"
tags[from]="$(
__zplug::core::core::run_interfaces \
'from' \
"$repo"
)"
# Skip items
# Run the installation in background
{
if [[ -n $tags[if] ]]; then
if ! eval "$tags[if]" 2> >(__zplug::io::log::capture) >/dev/null; then
__zplug::io::print::put \
"$fg[red]-$reset_color $fg[green]$repo$reset_color: skipped due to if tag\n"
continue
status_code=$_zplug_status[install_skip_if]
else
# Run 'install' handler
if __zplug::core::sources::is_handler_defined "install" "$tags[from]"; then
__zplug::core::sources::use_handler \
"install" \
"$tags[from]" \
"$repo"
status_code=$status
fi
fi
if __zplug::core::sources::is_handler_defined "check" "$tags[from]"; then
if __zplug::core::sources::use_handler "check" "$tags[from]" "$repo"; then
__zplug::io::print::put \
"$fg[red]-$reset_color $fg[green]$repo$reset_color: already installed\n"
continue
fi
fi
}
# For checking whether the repo's installation is success
from+=( "$repo" "$tags[from]" )
__zplug::job::spinner::lock
__zplug::job::spinner::spin &
# Run installation in subprocess
{
trap '__zplug::job::spinner::unlock; trap - SIGINT' SIGINT
# All variables are treated as local variable
# because of background job (subprocess)
local -i ret=2
local -F SECONDS=0
__zplug::job::spinner::echo \
"%-20s %s\n" \
"Installing..." \
"$repo"
if __zplug::core::sources::is_handler_defined "install" "$tags[from]"; then
__zplug::core::sources::use_handler \
"install" \
"$tags[from]" \
"$repo"
ret=$status
# Manage the status codes in a file
# to lock the file in order to write asynchronously
(
zsystem flock -t 180 "$_zplug_config[install_status]"
cant_lock=$status
if (( cant_lock > 0 )); then
{
printf "Can't acquire lock for $_zplug_config[install_status]."
if (( cant_lock == 2 )); then
printf " timeout."
fi
printf "\n"
} 1> >(__zplug::io::log::capture)
return 1
fi
case "$ret" in
0)
__zplug::job::spinner::echo \
"$fg[green]%-20s$reset_color %-${max}s\t(%.2fs)\n" \
"Installed!" \
"$repo" \
$SECONDS
# hook after installing
__zplug::job::hook::build "$repo"
;;
1)
__zplug::job::spinner::echo \
--die \
"$fg[red]%-20s$reset_color %-${max}s\t(%.2fs)\n" \
"Failed to install" \
"$repo" \
$SECONDS
;;
2)
__zplug::job::spinner::echo \
--die \
--zplug \
--error \
"sources/$tags[from] is not defined\n"
;;
esac
# Save the status code with LTSV
__zplug::io::print::f "repo:%s\tstatus:%s\n" \
"$repo" \
"$status_code" \
>>|"$_zplug_config[install_status]"
)
} &
__zplug::job::queue::enqueue "$!"
__zplug::job::queue::wait
repo_pids[$repo]=$!
repo_dir[$repo]="$tags[dir]"
hook_build[$repo]="$tags[hook-build]"
hook_finished[$repo]=false
states[$repo]="unfinished"
status_codes[$repo]=""
done
# Finalize
{
__zplug::job::queue::wait_all
__zplug::job::spinner::unlock
__zplug::io::print::f \
--zplug \
"Start to install %d plugin${is_parallel:+"s"} %s\n\n" \
$#repos \
"${is_parallel:+"in parallel"}"
failed_packages=()
for repo in "${(k)from[@]}"
repeat $(($#repos + 2))
do
printf "\n"
done
#
# Multiple progress bars
#
# Use printf command (not builtin) instead of __zplug::io::print::f function,
# because this loop is run the processing by interval of 0.1 second
# and there is a need to be called faster
while __zplug::job::state::running "$repo_pids[@]" "$hook_pids[@]" || (( ${(k)#states[(R)installing]} > 0 ))
do
sleep 0.1
__zplug::utils::ansi::cursor_up $(($#repos + 2))
# Count up within spinners index
if (( ( spinner_idx+=1 ) > $#spinners )); then
spinner_idx=1
fi
# Count up within sub_spinners index
if (( ( subspinner_idx+=1 ) > $#sub_spinners )); then
subspinner_idx=1
fi
# Processing pids
for repo in "${(k)repo_pids[@]}"
do
if __zplug::core::sources::is_handler_defined "check" "$from[$repo]"; then
if ! __zplug::core::sources::use_handler "check" "$from[$repo]" "$repo"; then
failed_packages+=( "$repo" )
if __zplug::job::state::running "$repo_pids[$repo]"; then
__zplug::job::message::installing \
$spinners[$spinner_idx] \
"$repo"
states[$repo]="installing"
else
# If $repo has build-hook tag
if [[ -n $hook_build[$repo] ]]; then
# Save status code for process cache
if [[ -z $status_codes[$repo] ]]; then
status_codes[$repo]="$(__zplug::job::state::get "$repo")"
fi
if [[ $status_codes[$repo] != 0 ]]; then
__zplug::job::message::failed_to_install_with_hook "$repo"
states[$repo]="finished"
continue
fi
if ! $hook_finished[$repo]; then
hook_finished[$repo]=true
# Run the hook-build in background
{
__zplug::job::hook::build "$repo"
if (( $status > 0 )); then
printf "$repo\n" >>|"$_zplug_config[build_failure]"
printf "$repo\n" >>|"$_zplug_config[build_rollback]"
else
printf "$repo\n" >>|"$_zplug_config[build_success]"
fi
} & hook_pids[$repo]=$!
# Run the timeout process in background
{
# kill the process for hook-build after sleeping
# during the number of seconds that has been set as a timeout
sleep "$timeout"
# Check if $repo_pids don't run
# and check if the process ($hook_pids[$repo]) that has should be killed
if __zplug::job::state::running $hook_pids[$repo] && ! __zplug::job::state::running "$repo_pids[@]"; then
__zplug::job::state::kill $hook_pids[$repo]
printf "$repo\n" >>|"$_zplug_config[build_timeout]"
printf "$repo\n" >>|"$_zplug_config[build_rollback]"
fi
} &
fi
if __zplug::job::state::running "$hook_pids[$repo]"; then
# running build-hook
__zplug::utils::ansi::erace_current_line
__zplug::job::message::installed_with_hook_spinning \
"$spinners[$spinner_idx]" \
"$repo" \
"$sub_spinners[$subspinner_idx]"
else
# finished build-hook
__zplug::utils::ansi::erace_current_line
if __zplug::job::hook::build_failure "$repo"; then
__zplug::job::message::installed_with_hook_failure "$repo"
elif __zplug::job::hook::build_timeout "$repo"; then
__zplug::job::message::installed_with_hook_timeout "$repo"
else
__zplug::job::message::installed_with_hook_success "$repo"
fi
fi
else
# Save status code for process cache
if [[ -z $status_codes[$repo] ]]; then
status_codes[$repo]="$(__zplug::job::state::get "$repo")"
fi
case $status_codes[$repo] in
$_zplug_status[install_success])
__zplug::job::message::installed "$repo"
;;
$_zplug_status[install_failure])
__zplug::job::message::failed_to_install "$repo"
;;
$_zplug_status[install_already])
__zplug::job::message::already_installed "$repo"
;;
$_zplug_status[install_skip_if])
__zplug::job::message::skipped_due_to_if_tag "$repo"
;;
*)
__zplug::job::message::unknown "$repo"
;;
esac
fi
states[$repo]="finished"
fi
done
# Skip footer prints
if (( $#from == 0 )); then
printf "\n"
if __zplug::job::state::running "$repo_pids[@]" "$hook_pids[@]"; then
__zplug::io::print::f \
--zplug \
"No package to install\n"
return 0
"Finished: %d/%d plugin%s\n" \
${(k)#states[(R)finished]} \
$#states \
${is_parallel:+"s"}
else
if (( $#failed_packages == 0 )); then
__zplug::io::print::put \
"$fg_bold[default] ==> Installation finished successfully!$reset_color\n"
else
__zplug::io::print::die \
"$fg_bold[red] ==> Installation failed for following packages:$reset_color\n"
__zplug::io::print::die \
"- $fg_bold[red]%s$reset_color\n" "${failed_packages[@]}"
fi
finish_time=$SECONDS
__zplug::utils::ansi::erace_current_line
__zplug::io::print::f \
--zplug \
--func \
"total wall-time %f sec.\n" \
$(( $finish_time - $start_time ))
return $#failed_packages
"Elapsed time: %.4f sec.\n" \
$SECONDS
fi
}
done
tput cnorm
if (( ${(k)#status_codes[(R)1]} == 0 )); then
printf "$fg_bold[default] ==> Installation finished successfully!$reset_color\n"
else
printf "$fg_bold[red] ==> Installation failed for following packages:$reset_color\n"
# Listing the packages that have failed to install
for repo in "${(k)status_codes[@]}"
do
if [[ $status_codes[$repo] == 1 ]]; then
printf " - %s\n" "$repo"
fi
done
fi
# Run rollback if hook-build failed
if [[ -s $_zplug_config[build_rollback] ]]; then
if [[ -f $_zplug_config[build_failure] ]] || [[ -f $_zplug_config[build_timeout] ]]; then
__zplug::io::print::f \
--zplug \
"\n$fg_bold[red]These hook-build were failed to run:$reset_color\n"
# Listing the packages that have failed to build
{
sed 's/^/ - /g' "$_zplug_config[build_failure]"
sed 's/^/ - /g' "$_zplug_config[build_timeout]"
} 2>/dev/null
__zplug::io::print::f \
--zplug \
"To retry these hook-build, please run '$fg_bold[default]%s$reset_color'.\n" \
"zplug --rollback=build"
fi
fi

@ -11,6 +11,13 @@ local is_releases=false is_select=false
local state arg filter repo
local -a repos
local -A repo_pids states status_codes repo_dir
local -a spinners
local -i spinner_idx
local is_parallel=""
spinners=(⠋ ⠙ ⠹ ⠸ ⠼ ⠴ ⠦ ⠧ ⠇ ⠏)
while (( $# > 0 ))
do
arg="$1"
@ -37,117 +44,217 @@ do
shift
done
# Initialize
{
if $is_select; then
__zplug::utils::shell::search_commands \
"$ZPLUG_FILTER" \
| read filter
if [[ -z $filter ]]; then
__zplug::io::print::f \
--die \
--zplug \
--error \
--func \
"There is no available filter in ZPLUG_FILTER\n"
return 1
fi
repos=( ${(@f)"$(echo "${(Fk)zplugs[@]}" | eval "$filter")"} )
# Cace of type Ctrl-C
if (( $#repos == 0 )); then
return 0
fi
fi
if (( $#repos == 0 )); then
repos=( "${(k)zplugs[@]:gs:@::}" )
fi
for repo in "${repos[@]}"
do
(( $#repo > $max )) && max=$#repo
done
max=$(( $max + 1 ))
}
if (( $#repos > 0 )); then
__zplug::io::print::put "Fetching the status of packages ...\n"
__zplug::io::print::put "Packages with from:'local' are skipped.\n"
__zplug::io::print::put "===\n"
__zplug::job::spinner::lock
__zplug::job::spinner::spin &
fi
for repo in "${repos[@]}"
do
if ! __zplug::base::base::zpluged "$repo"; then
if $is_select; then
__zplug::utils::shell::search_commands \
"$ZPLUG_FILTER" \
| read filter
if [[ -z $filter ]]; then
__zplug::io::print::f \
--die \
--zplug \
--error \
--func \
"$repo: no such package\n"
"There is no available filter in ZPLUG_FILTER\n"
return 1
fi
repos=( ${(@f)"$(echo "${(Fk)zplugs[@]}" | eval "$filter")"} )
__zplug::core::tags::parse "$repo"
tags=( "${reply[@]}" )
case "$tags[from]" in
"local")
is_releases=false
continue
;;
"gh-r")
is_releases=true
;;
*)
is_releases=false
;;
esac
if [[ ! -d $tags[dir] ]]; then
shift repos
continue
# Cace of type Ctrl-C
if (( $#repos == 0 )); then
return 0
fi
# Get package status in subprocess
{
trap '__zplug::job::spinner::unlock; trap - SIGINT' SIGINT
# Change directory to get the remote status
__zplug::utils::shell::cd \
"$tags[dir]"
if (( $status == 0 )); then
# Get the status of the repository (whether it is a latest)
if $is_releases; then
__zplug::utils::releases::get_state "$tags[name]" "$tags[dir]"
else
__zplug::utils::git::get_state "$tags[name]" "$tags[dir]"
fi \
| read state
# Adjust space sizes
dif=$(( $max - $#repo ))
__zplug::job::spinner::echo "%-${#repo}s %${dif}s %s\n" \
"$em[under]$repo$reset_color" \
"" \
"$state"
fi
} &
__zplug::job::queue::enqueue "$!"
__zplug::job::queue::wait
done
if (( $#repos > 0 )); then
__zplug::job::queue::wait_all
__zplug::job::spinner::unlock
__zplug::io::print::put "===\n"
__zplug::io::print::put "Finished %.6f\n" $SECONDS
__zplug::io::print::put "\n"
fi
return 0
if (( $#repos == 0 )); then
repos=( "${(k)zplugs[@]:gs:@::}" )
fi
# Check the number of arguments
if (( $#repos > 1 )); then
is_parallel=true
fi
if (( ($#repos + 2) >= $LINES )); then
# TODO:
__zplug::io::print::f \
--zplug \
--die \
--warn \
"Cannot acquire your terminal screen for display\n" \
"Needs %d lines\n" \
-- \
$(($#repos + 2))
return 1
fi
rm -f "$_zplug_config[status_status]"
touch "$_zplug_config[status_status]"
# Suppress outputs
setopt nonotify nomonitor
tput civis
for repo in "${repos[@]}"
do
{
if ! __zplug::base::base::zpluged "$repo"; then
__zplug::io::print::f \
--die \
--zplug \
--func \
"$repo: no such package\n"
return 1
fi
__zplug::core::tags::parse "$repo"
tags=( "${reply[@]}" )
if [[ -d $tags[dir] ]]; then
# Get package status in subprocess
# Change directory to get the remote status
__zplug::utils::shell::cd "$tags[dir]"
case "$tags[from]" in
"local")
status_code=$_zplug_status[status_skip_local_repo]
;;
"gh-r")
__zplug::utils::releases::get_state "$tags[name]" "$tags[dir]"
status_code=$status
;;
*)
__zplug::utils::git::get_state "$tags[name]" "$tags[dir]"
status_code=$status
;;
esac
else
status_code=$_zplug_status[status_repo_not_found]
fi
# Manage the status codes in a file
# to lock the file in order to write asynchronously
(
zsystem flock -t 180 "$_zplug_config[status_status]"
cant_lock=$status
if (( cant_lock > 0 )); then
{
printf "Can't acquire lock for $_zplug_config[status_status]."
if (( cant_lock == 2 )); then
printf " timeout."
fi
printf "\n"
} 1> >(__zplug::io::log::capture)
return 1
fi
# Save the status code with LTSV
__zplug::io::print::f "repo:%s\tstatus:%s\n" \
"$repo" \
"$status_code" \
>>|"$_zplug_config[status_status]"
)
} &
repo_pids[$repo]=$!
repo_dir[$repo]="$tags[dir]"
states[$repo]="unfinished"
status_codes[$repo]=""
done
__zplug::io::print::f \
--zplug \
"Start to get remote status %d plugin${is_parallel:+"s"} %s\n\n" \
$#repos \
"${is_parallel:+"in parallel"}"
repeat $(($#repos + 2))
do
printf "\n"
done
#
# Multiple progress bars
#
# Use printf command (not builtin) instead of __zplug::io::print::f function,
# because this loop is run the processing by interval of 0.1 second
# and there is a need to be called faster
while __zplug::job::state::running "$repo_pids[@]" || (( ${(k)#states[(R)fetching]} > 0 ))
do
sleep 0.1
__zplug::utils::ansi::cursor_up $(($#repos + 2))
# Count up within spinners index
if (( ( spinner_idx+=1 ) > $#spinners )); then
spinner_idx=1
fi
# Processing pids
for repo in "${(k)repo_pids[@]}"
do
if __zplug::job::state::running "$repo_pids[$repo]"; then
__zplug::job::message::fetching \
$spinners[$spinner_idx] \
"$repo"
states[$repo]="fetching"
else
# Save status code for process cache
if [[ -z $status_codes[$repo] ]]; then
status_codes[$repo]="$(__zplug::job::state::get "$repo" status)"
fi
case $status_codes[$repo] in
$_zplug_status[status_up_to_date])
__zplug::job::message::up_to_date "$repo"
;;
$_zplug_status[status_local_out_of_date])
__zplug::job::message::local_out_of_date "$repo"
;;
$_zplug_status[status_not_on_any_branch])
__zplug::job::message::not_on_any_branch "$repo"
;;
$_zplug_status[status_not_git_repo])
__zplug::job::message::not_git_repo "$repo"
;;
$_zplug_status[status_repo_not_found])
__zplug::job::message::repo_not_found "$repo"
;;
$_zplug_status[status_skip_local_repo])
__zplug::job::message::skip_local_repo "$repo"
;;
*)
__zplug::job::message::unknown "$repo"
;;
esac
states[$repo]="finished"
fi
done
printf "\n"
if __zplug::job::state::running "$repo_pids[@]"; then
__zplug::io::print::f \
--zplug \
"Finished: %d/%d plugin%s\n" \
${(k)#states[(R)finished]} \
$#states \
${is_parallel:+"s"}
else
__zplug::utils::ansi::erace_current_line
__zplug::io::print::f \
--zplug \
"Elapsed time: %.4f sec.\n" \
$SECONDS
fi
done
tput cnorm
if (( ${(k)#status_codes[(R)1]} == 0 )); then
printf "$fg_bold[default] ==> All packages are up-to-date!$reset_color\n"
else
printf "$fg_bold[red] ==> Run 'zplug update'. These packages are local out of date:$reset_color\n"
# Listing the packages that have failed to install
for repo in "${(k)status_codes[@]}"
do
if [[ $status_codes[$repo] == 1 ]]; then
printf " - %s\n" "$repo"
fi
done
fi

@ -2,8 +2,6 @@
# Description:
# Update installed packages in parallel
trap '__zplug::job::spinner::unlock; trap - SIGINT' SIGINT
local repo arg f_pkg c_pkg filter
local -aU repos
local -A tags
@ -13,20 +11,29 @@ local -i max=0 ret=0
local -F SECONDS=0 start_time finish_time
local is_select=false is_force=false
# All variables are treated as local variable
# because of background job (subprocess)
#local key
local -aU repos
local -A tags
local -i status_code=0 cant_lock=0
local -A repo_pids states hook_build hook_finished hook_pids status_codes repo_dir
local -F SECONDS=0
local -a spinners sub_spinners
local -i spinner_idx subspinner_idx
local -i timeout=60
local is_parallel=""
spinners=(⠋ ⠙ ⠹ ⠸ ⠼ ⠴ ⠦ ⠧ ⠇ ⠏)
sub_spinners=(⠁ ⠁ ⠉ ⠙ ⠚ ⠒ ⠂ ⠂ ⠒ ⠲ ⠴ ⠤ ⠄ ⠄ ⠤ ⠠ ⠠ ⠤ ⠦ ⠖ ⠒ ⠐ ⠐ ⠒ ⠓ ⠋ ⠉ ⠈ ⠈)
while (( $# > 0 ))
do
arg="$1"
case "$arg" in
--self)
__zplug::core::self::update \
${2:+"$argv[2,-1]"}
ret=$status
# Returns true if zplug is already up-to-date
if (( $ret == $_ZPLUG_STATUS_ZPLUG_IS_LATEST )); then
ret=0
fi
return $ret
;;
--select)
is_select=true
;;
@ -78,16 +85,24 @@ done
repos=( "${(k)zplugs[@]:gs:@::}" )
fi
for repo in "${repos[@]}"
do
(( $#repo > $max )) && max=$#repo
done
# Check the number of arguments
if (( $#repos > 1 )); then
is_parallel=true
fi
rm -f \
"$_zplug_config[build_success]" \
"$_zplug_config[build_failure]" \
"$_zplug_config[build_timeout]" \
"$_zplug_config[update_status]"
touch "$_zplug_config[update_status]"
}
__zplug::job::spinner::lock
__zplug::job::spinner::spin &
# Suppress outputs
setopt nonotify nomonitor
tput civis
for repo in "${repos[@]}"
for repo in "$repos[@]"
do
if ! __zplug::base::base::zpluged "$repo"; then
__zplug::job::spinner::unlock
@ -100,107 +115,266 @@ do
fi
# Run installation in subprocess
__zplug::core::tags::parse "$repo"
tags=( "${reply[@]}" )
{
# All variables are treated as local variable
# because of background job (subprocess)
local key
local -i ret=1
local -A tags
__zplug::core::tags::parse "$repo"
tags=( "${reply[@]}" )
if [[ -n $tags[if] ]]; then
if ! eval "$tags[if]" 2> >(__zplug::io::log::capture) >/dev/null; then
continue
fi
fi
# Run in anonymous function for using its exit code
function () {
__zplug::job::spinner::echo "%-20s %s\n" \
"Updating..." \
"$repo"
if $is_force; then
# DO update anyway
:
else
# if frozen:yes is given
if (( $_zplug_boolean_true[(I)$tags[frozen]] )); then
return $_ZPLUG_STATUS_REPO_FROZEN
fi
fi
if [[ -d $tags[dir] ]]; then
if (( $_zplug_boolean_true[(I)$tags[frozen]] )); then
status_code=$_zplug_status[update_skip_frozen]
else
if __zplug::core::sources::is_handler_defined "update" "$tags[from]"; then
__zplug::core::sources::use_handler \
"update" \
"$tags[from]" \
"$repo"
return $status
status_code=$status
else
status_code=$_zplug_status[update_local_repo]
fi
}
ret=$status
fi
else
status_code=$_zplug_status[update_repo_not_found]
fi
case "$ret" in
$_ZPLUG_STATUS_SUCCESS)
__zplug::job::spinner::echo "$fg[green]%-20s$reset_color %-${max}s\t(%.2fs)\n" \
"Updated!" \
"$repo" \
$SECONDS
# Manage the status codes in a file
# to lock the file in order to write asynchronously
(
zsystem flock -t 180 "$_zplug_config[update_status]"
cant_lock=$status
if (( cant_lock > 0 )); then
{
printf "Can't acquire lock for $_zplug_config[update_status]."
if (( cant_lock == 2 )); then
printf " timeout."
fi
printf "\n"
} 1> >(__zplug::io::log::capture)
return 1
fi
# hook after updating
__zplug::job::hook::build "$repo"
;;
$_ZPLUG_STATUS_FAILURE)
__zplug::job::spinner::echo "$fg[red]%-20s$reset_color %-${max}s\t(%.2fs)\n" \
--die \
"Failed to update" \
"$repo" \
$SECONDS
;;
$_ZPLUG_STATUS_REPO_NOT_FOUND)
sleep 1
__zplug::job::spinner::echo "$fg[magenta]%-20s$reset_color %-${max}s\t(%.2fs)\n" \
--die \
"Repo not found" \
"$repo" \
$(( SECONDS - 1 ))
;;
$_ZPLUG_STATUS_REPO_FROZEN)
sleep 1
__zplug::job::spinner::echo "$fg[blue]%-20s$reset_color %-${max}s\t(%.2fs)\n" \
--die \
"Frozen repo" \
"$repo" \
$(( SECONDS - 1 ))
;;
$_ZPLUG_STATUS_REPO_UP_TO_DATE)
__zplug::job::spinner::echo "$fg[white]%-20s$reset_color %-${max}s\t(%.2fs)\n" \
--die \
"Up-to-date" \
"$repo" \
$SECONDS
;;
$_ZPLUG_STATUS_REPO_LOCAL)
sleep 1
__zplug::job::spinner::echo "$fg[yellow]%-20s$reset_color %-${max}s\t(%.2fs)\n" \
--die \
"Skipped due to local repo" \
"$repo" \
$(( SECONDS - 1 ))
;;
$_ZPLUG_STATUS_ZPLUG_IS_LATEST)
# DO NOTHING
ret=0
;;
esac
# Save the status code with LTSV
__zplug::io::print::f "repo:%s\tstatus:%s\n" \
"$repo" \
"$status_code" \
>>|"$_zplug_config[update_status]"
)
} &
__zplug::job::queue::enqueue "$!"
__zplug::job::queue::wait
repo_pids[$repo]=$!
repo_dir[$repo]="$tags[dir]"
hook_build[$repo]="$tags[hook-build]"
hook_finished[$repo]=false
states[$repo]="unfinished"
status_codes[$repo]=""
done
__zplug::job::queue::wait_all
__zplug::job::spinner::unlock
__zplug::io::print::f \
--zplug \
"Start to update %d plugin${is_parallel:+"s"} %s\n\n" \
$#repos \
"${is_parallel:+"in parallel"}"
return $ret
repeat $(($#repos + 2))
do
printf "\n"
done
#
# Multiple progress bars
#
# Use printf command (not builtin) instead of __zplug::io::print::f function,
# because this loop is run the processing by interval of 0.1 second
# and there is a need to be called faster
while __zplug::job::state::running "$repo_pids[@]" "$hook_pids[@]" || (( ${(k)#states[(R)updating]} > 0 ))
do
sleep 0.1
__zplug::utils::ansi::cursor_up $(($#repos + 2))
# Count up within spinners index
if (( ( spinner_idx+=1 ) > $#spinners )); then
spinner_idx=1
fi
# Count up within sub_spinners index
if (( ( subspinner_idx+=1 ) > $#sub_spinners )); then
subspinner_idx=1
fi
# Processing pids
for repo in "${(k)repo_pids[@]}"
do
if __zplug::job::state::running "$repo_pids[$repo]"; then
__zplug::job::message::updating \
$spinners[$spinner_idx] \
"$repo"
states[$repo]="updating"
else
# If $repo has build-hook tag
if [[ -n $hook_build[$repo] ]]; then
# Save status code for process cache
if [[ -z $status_codes[$repo] ]]; then
status_codes[$repo]="$(__zplug::job::state::get "$repo" update)"
fi
if [[ $status_codes[$repo] != 0 ]]; then
#__zplug::job::message::failed_to_update_with_hook "$repo"
case $status_codes[$repo] in
$_zplug_status[update_success])
__zplug::job::message::updated "$repo"
;;
$_zplug_status[update_failure])
__zplug::job::message::failed_to_update "$repo"
;;
$_zplug_status[update_skip_if])
__zplug::job::message::skipped_due_to_if_tag "$repo"
;;
$_zplug_status[update_up_to_date])
__zplug::job::message::up_to_date "$repo"
;;
$_zplug_status[update_skip_frozen])
__zplug::job::message::skipped_due_to_frozen_tag "$repo"
;;
$_zplug_status[update_local_repo])
__zplug::job::message::local_repo "$repo"
;;
$_zplug_status[update_repo_not_found])
__zplug::job::message::repo_not_found "$repo"
;;
*)
__zplug::job::message::unknown "$repo"
;;
esac
states[$repo]="finished"
continue
fi
if ! $hook_finished[$repo]; then
hook_finished[$repo]=true
# Run the hook-build in background
{
__zplug::job::hook::build "$repo"
if (( $status > 0 )); then
printf "$repo\n" >>|"$_zplug_config[build_failure]"
printf "$repo\n" >>|"$_zplug_config[build_rollback]"
else
printf "$repo\n" >>|"$_zplug_config[build_success]"
fi
} & hook_pids[$repo]=$!
# Run the timeout process in background
{
# kill the process for hook-build after sleeping
# during the number of seconds that has been set as a timeout
sleep "$timeout"
# Check if $repo_pids don't run
# and check if the process ($hook_pids[$repo]) that has should be killed
if __zplug::job::state::running $hook_pids[$repo] && ! __zplug::job::state::running "$repo_pids[@]"; then
__zplug::job::state::kill $hook_pids[$repo]
printf "$repo\n" >>|"$_zplug_config[build_timeout]"
printf "$repo\n" >>|"$_zplug_config[build_rollback]"
fi
} &
fi
if __zplug::job::state::running "$hook_pids[$repo]"; then
# running build-hook
__zplug::utils::ansi::erace_current_line
__zplug::job::message::updated_with_hook_spinning \
"$spinners[$spinner_idx]" \
"$repo" \
"$sub_spinners[$subspinner_idx]"
else
# finished build-hook
__zplug::utils::ansi::erace_current_line
if __zplug::job::hook::build_failure "$repo"; then
__zplug::job::message::updated_with_hook_failure "$repo"
elif __zplug::job::hook::build_timeout "$repo"; then
__zplug::job::message::updated_with_hook_timeout "$repo"
else
__zplug::job::message::updated_with_hook_success "$repo"
fi
fi
else
# Save status code for process cache
if [[ -z $status_codes[$repo] ]]; then
status_codes[$repo]="$(__zplug::job::state::get "$repo" update)"
fi
case $status_codes[$repo] in
$_zplug_status[update_success])
__zplug::job::message::updated "$repo"
;;
$_zplug_status[update_failure])
__zplug::job::message::failed_to_update "$repo"
;;
$_zplug_status[update_skip_if])
__zplug::job::message::skipped_due_to_if_tag "$repo"
;;
$_zplug_status[update_up_to_date])
__zplug::job::message::up_to_date "$repo"
;;
$_zplug_status[update_skip_frozen])
__zplug::job::message::skipped_due_to_frozen_tag "$repo"
;;
$_zplug_status[update_local_repo])
__zplug::job::message::local_repo "$repo"
;;
$_zplug_status[update_repo_not_found])
__zplug::job::message::repo_not_found "$repo"
;;
*)
__zplug::job::message::unknown "$repo"
;;
esac
fi
states[$repo]="finished"
fi
done
printf "\n"
if __zplug::job::state::running "$repo_pids[@]" "$hook_pids[@]"; then
__zplug::io::print::f \
--zplug \
"Finished: %d/%d plugin%s\n" \
${(k)#states[(R)finished]} \
$#states \
${is_parallel:+"s"}
else
__zplug::utils::ansi::erace_current_line
__zplug::io::print::f \
--zplug \
"Elapsed time: %.4f sec.\n" \
$SECONDS
fi
done
tput cnorm
if (( ${(k)#status_codes[(R)1]} == 0 )); then
printf "$fg_bold[default] ==> Updating finished successfully!$reset_color\n"
else
printf "$fg_bold[red] ==> Updating failed for following packages:$reset_color\n"
# Listing the packages that have failed to update
for repo in "${(k)status_codes[@]}"
do
if [[ $status_codes[$repo] == 1 ]]; then
printf " - %s\n" "$repo"
fi
done
fi
# Run rollback if hook-build failed
if [[ -s $_zplug_config[build_rollback] ]]; then
if [[ -f $_zplug_config[build_failure] ]] || [[ -f $_zplug_config[build_timeout] ]]; then
__zplug::io::print::f \
--zplug \
"\n$fg_bold[red]These hook-build were failed to run:$reset_color\n"
# Listing the packages that have failed to build
{
sed 's/^/ - /g' "$_zplug_config[build_failure]"
sed 's/^/ - /g' "$_zplug_config[build_timeout]"
} 2>/dev/null
__zplug::io::print::f \
--zplug \
"To retry these hook-build, please run '$fg_bold[default]%s$reset_color'.\n" \
"zplug --rollback=build"
fi
fi

@ -7,6 +7,8 @@ fpath=(
"$fpath[@]"
)
zmodload zsh/system #for flock
zmodload zsh/parameter #for jobstates
autoload -Uz regexp-replace
autoload -Uz add-zsh-hook
autoload -Uz colors

@ -0,0 +1,31 @@
#!/usr/bin/env zsh
# Description:
# Rollback a failed package
local arg
while (( $# > 0 ))
do
arg="$1"
case "$arg" in
build)
__zplug::job::rollback::build
return $status
;;
"")
__zplug::io::print::f \
--die \
--zplug \
"argument is required\n"
return $_zplug_status[error]
;;
*)
__zplug::io::print::f \
--die \
--zplug \
"$arg: no such rollback operation\n"
return $_zplug_status[error]
;;
esac
shift
done

@ -153,6 +153,9 @@ __zplug::core::core::prepare()
mkdir -p "$ZPLUG_REPOS"
mkdir -p "$ZPLUG_HOME/bin"
# Setup manage directory
mkdir -p "$ZPLUG_MANAGE"/{var,tmp}/log
# Run compinit if zplug comp file hasn't load
if (( ! $+functions[_zplug] )); then
compinit
@ -195,6 +198,77 @@ __zplug::core::core::variable()
typeset -gx -i _ZPLUG_STATUS_ZPLUG_IS_LATEST=101
typeset -gx -i _ZPLUG_STATUS_=255
typeset -gx ZPLUG_MANAGE="$ZPLUG_HOME/.zplug"
# user-defined exit code 64..113
typeset -gx -A _zplug_status
_zplug_status=(
# compatible
"success" 0
"failure" 1
"true" 0
"false" 1
"repo_not_found" 2
"repo_frozen" 3
"repo_up_to_date" 4
"repo_local" 5
"invalid_argument" 6
"invalid_option" 7
"parse_error" 8
"latest_version" 101
# installation
"install_success" 0
"install_failure" 1
"install_already" 2
"install_skip_if" 3
"install_unknown" 4
# update
"update_success" 0
"update_failure" 1
"update_already" 2
"update_skip_if" 5
"update_up_to_date" 4
"update_skip_frozen" 3
"update_local_repo" 7
"update_repo_not_found" 9
"update_unknown" 8
# status
"status_up_to_date" 0
"status_local_out_of_date" 1
"status_not_on_any_branch" 2 # TODO
"status_not_git_repo" 3 # TODO
"status_unknown" 4
"status_repo_not_found" 5 # TODO
"status_skip_local_repo" 6 # TODO
# based on bash scripting
# - http://tldp.org/LDP/abs/html/exitcodes.html
"error" 1
"builtin_error" 2
"diff_binary" 2
"command_not_executable" 126
"command_not_found" 127
"exit_syntax_error" 128
"error_signal_hup" 129
"error_signal_int" 130
"error_signal_kill" 137
# TODO: add others
)
typeset -gx -A _zplug_config
_zplug_config=(
"install_status" "$ZPLUG_MANAGE/tmp/installed"
"update_status" "$ZPLUG_MANAGE/tmp/updated"
"status_status" "$ZPLUG_MANAGE/tmp/status_status"
"build_success" "$ZPLUG_MANAGE/tmp/build_success"
"build_failure" "$ZPLUG_MANAGE/tmp/build_failure"
"build_timeout" "$ZPLUG_MANAGE/tmp/build_timeout"
"build_rollback" "$ZPLUG_MANAGE/tmp/build_rollback"
"error_log" "$ZPLUG_MANAGE/var/log/error_log"
"execution_log" "$ZPLUG_MANAGE/var/log/execution_log"
)
if (( $+ZPLUG_SHALLOW )); then
__zplug::io::print::f \
--die \

@ -46,24 +46,10 @@ __zplug::core::sources::use_handler()
return 1
fi
case "$repo" in
"zplug/zplug")
# Search the handler that has a name including 'self' word
handler_name="__zplug::core::self::$subcommand"
(( $+functions[$handler_name] )) ||
handler_name="__zplug::sources::github::$subcommand"
# If it isn't found, search another handler
# Nevertheless, callback is undefined
(( $+functions[$handler_name] )) ||
return $_ZPLUG_STATUS_FAILURE
;;
*)
if ! __zplug::core::sources::is_handler_defined "$subcommand" "$source_name"; then
# Callback function is undefined
return $_ZPLUG_STATUS_FAILURE
fi
;;
esac
eval "$handler_name '$repo'"
return $status

@ -25,7 +25,9 @@ __zplug::io::log::with_json()
printf '"shlvl": %d,' "$SHLVL"
printf '"level": "%s",' "$level"
printf '"dir": "%s",' "$PWD"
printf '"message": %s,' "${(qqq)message[*]}"
printf '"message": "'
printf "${(F)message[@]}" | __zplug::utils::shell::json_escape
printf '",'
printf '"trace": {'
for ((i = 1; i < $#functrace; i++))
do
@ -105,6 +107,18 @@ __zplug::io::log::capture()
| >>|"$ZPLUG_ERROR_LOG"
}
__zplug::io::log::capture_error()
{
__zplug::io::log::with_json "ERROR" \
| >>|"$_zplug_config[error_log]"
}
__zplug::io::log::capture_execution()
{
__zplug::io::log::with_json "DEBUG" \
| >>|"$_zplug_config[execution_log]"
}
__zplug::io::log::info()
{
__zplug::io::log::new \

@ -91,7 +91,7 @@ __zplug::io::print::f()
# Change the output destination by the value of $fd
{
echo "${pre_formats[*]}" \
| __zplug::utils::shell::unansi \
| __zplug::utils::ansi::remove \
| read pre_format
repeat $#pre_format; do w="$w "; done

@ -28,15 +28,20 @@ __zplug::job::hook::service()
__zplug::utils::shell::cd "$tags[dir]"
alias sudo=__zplug::utils::shell::sudo
eval "$tags[$hook]" 2> >(__zplug::io::log::capture)
if (( $status != 0 )); then
__zplug::io::print::f \
--die \
--zplug \
--error \
"'%s' failed\n" \
"$tags[$hook]"
fi
# Save a result to the log file (stdout/stderr)
eval "$tags[$hook]" \
2> >(__zplug::io::log::capture_error) \
1> >(__zplug::io::log::capture_execution)
return $status
#if (( $status != 0 )); then
# __zplug::io::print::f \
# --die \
# --zplug \
# --error \
# "'%s' failed\n" \
# "$tags[$hook]"
#fi
)
fi
}
@ -54,6 +59,7 @@ __zplug::job::hook::build()
__zplug::job::hook::service \
"$repo" \
"hook-build"
return $status
}
__zplug::job::hook::load()
@ -69,4 +75,21 @@ __zplug::job::hook::load()
__zplug::job::hook::service \
"$repo" \
"hook-load"
return $status
}
__zplug::job::hook::build_failure()
{
local repo="$1"
[[ -f $_zplug_config[build_failure] ]] && grep -x "$repo" "$_zplug_config[build_failure]" &>/dev/null
return $status
}
__zplug::job::hook::build_timeout()
{
local repo="$1"
[[ -f $_zplug_config[build_timeout] ]] && grep -x "$repo" "$_zplug_config[build_timeout]" &>/dev/null
return $status
}

269
base/job/message.zsh Normal file

@ -0,0 +1,269 @@
__zplug::job::message::installing()
{
local \
spinner="$1" \
repo="$2"
printf " $fg[white]%s$reset_color %s %s\n" \
"$spinner" \
${(r,20,):-"Installing..."} \
"$repo"
}
__zplug::job::message::failed_to_install_with_hook()
{
local repo="$1"
printf " $fg_bold[red]\U2718$reset_color $fg[red]%s$reset_color %s --> hook-build: $fg[red]cancel$reset_color\n" \
${(r,20,):-"Failed to install"} \
"$repo"
}
__zplug::job::message::installed_with_hook_spinning()
{
local \
spinner="$1" \
repo="$2" \
subspinner="$3"
printf " $fg_bold[white]%s$reset_color $fg[green]%s$reset_color %s --> hook-build: %s\n" \
"$spinner" \
${(r,20,):-"Installed!"} \
"$repo" \
"$subspinner"
}
__zplug::job::message::installed_with_hook_failure()
{
local repo="$1"
printf " $fg_bold[white]\U2714$reset_color $fg[green]%s$reset_color %s --> hook-build: $fg[red]failure$reset_color\n" \
${(r,20,):-"Installed!"} \
"$repo"
}
__zplug::job::message::installed_with_hook_timeout()
{
local repo="$1"
printf " $fg_bold[white]\U2714$reset_color $fg[green]%s$reset_color %s --> hook-build: $fg[yellow]timeout$reset_color\n" \
${(r,20,):-"Installed!"} \
"$repo"
}
__zplug::job::message::installed_with_hook_success()
{
local repo="$1"
printf " $fg_bold[white]\U2714$reset_color $fg[green]%s$reset_color %s --> hook-build: $fg[green]success$reset_color\n" \
${(r,20,):-"Installed!"} \
"$repo"
}
__zplug::job::message::installed()
{
local repo="$1"
printf " $fg_bold[white]\U2714$reset_color $fg[green]%s$reset_color %s\n" \
${(r,20,):-"Installed!"} \
"$repo"
}
__zplug::job::message::failed_to_install()
{
local repo="$1"
printf " $fg_bold[red]\U2718$reset_color $fg[red]%s$reset_color %s\n" \
${(r,20,):-"Failed to install"} \
"$repo"
}
__zplug::job::message::already_installed()
{
local repo="$1"
printf " $fg[yellow]\U2714 %s$reset_color %s\n" \
${(r,20,):-"Already installed"} \
"$repo"
}
__zplug::job::message::skipped_due_to_frozen_tag()
{
local repo="$1"
printf " $fg[blue]\U279C %s$reset_color %s\n" \
${(r,20,):-"Frozen repo"} \
"$repo"
}
__zplug::job::message::skipped_due_to_if_tag()
{
local repo="$1"
printf " $fg[yellow]\U279C %s$reset_color %s\n" \
${(r,20,):-"Skipped due to if"} \
"$repo"
}
__zplug::job::message::unknown()
{
local repo="$1"
printf " $fg_bold[red]\U2718$reset_color $fg[red]%s$reset_color %s\n" \
${(r,20,):-"Unknown"} \
"$repo"
}
__zplug::job::message::fetching()
{
local \
spinner="$1" \
repo="$2"
printf " $fg[white]%s$reset_color %s %s\n" \
"$spinner" \
${(r,20,):-"Fetching..."} \
"$repo"
}
__zplug::job::message::local_out_of_date()
{
local repo="$1"
printf " $fg_bold[red]\U2718$reset_color $fg[red]%s$reset_color %s\n" \
${(r,20,):-"Local out of date"} \
"$repo"
}
__zplug::job::message::not_on_any_branch()
{
local repo="$1"
printf " $fg_bold[red]\U2718$reset_color $fg[white]%s$reset_color %s\n" \
${(r,20,):-"Not on any branch"} \
"$repo"
}
__zplug::job::message::not_git_repo()
{
local repo="$1"
printf " $fg_bold[red]\U2718$reset_color $fg[white]%s$reset_color %s\n" \
${(r,20,):-"Not git repo"} \
"$repo"
}
__zplug::job::message::repo_not_found()
{
local repo="$1"
printf " $fg_bold[red]\U2718$reset_color $fg[red]%s$reset_color %s\n" \
${(r,20,):-"Not found"} \
"$repo"
}
__zplug::job::message::skip_local_repo()
{
local repo="$1"
printf " $fg_bold[yellow]\U279C$reset_color $fg[yellow]%s$reset_color %s\n" \
${(r,20,):-"Skip local repo"} \
"$repo"
}
__zplug::job::message::updating()
{
local \
spinner="$1" \
repo="$2"
printf " $fg[white]%s$reset_color %s %s\n" \
"$spinner" \
${(r,20,):-"Updating..."} \
"$repo"
}
__zplug::job::message::failed_to_update_with_hook()
{
local repo="$1"
printf " $fg_bold[red]\U2718$reset_color $fg[red]%s$reset_color %s --> hook-build: $fg[red]cancel$reset_color\n" \
${(r,20,):-"Failed to update"} \
"$repo"
}
__zplug::job::message::updated_with_hook_spinning()
{
local \
spinner="$1" \
repo="$2" \
subspinner="$3"
printf " $fg_bold[white]%s$reset_color $fg[green]%s$reset_color %s --> hook-build: %s\n" \
"$spinner" \
${(r,20,):-"Updated!"} \
"$repo" \
"$subspinner"
}
__zplug::job::message::updated_with_hook_failure()
{
local repo="$1"
printf " $fg_bold[white]\U2714$reset_color $fg[green]%s$reset_color %s --> hook-build: $fg[red]failure$reset_color\n" \
${(r,20,):-"Updated!"} \
"$repo"
}
__zplug::job::message::updated_with_hook_timeout()
{
local repo="$1"
printf " $fg_bold[white]\U2714$reset_color $fg[green]%s$reset_color %s --> hook-build: $fg[yellow]timeout$reset_color\n" \
${(r,20,):-"Updated!"} \
"$repo"
}
__zplug::job::message::updated_with_hook_success()
{
local repo="$1"
printf " $fg_bold[white]\U2714$reset_color $fg[green]%s$reset_color %s --> hook-build: $fg[green]success$reset_color\n" \
${(r,20,):-"Updated!"} \
"$repo"
}
__zplug::job::message::updated()
{
local repo="$1"
printf " $fg_bold[white]\U2714$reset_color $fg[green]%s$reset_color %s\n" \
${(r,20,):-"Updated!"} \
"$repo"
}
__zplug::job::message::failed_to_update()
{
local repo="$1"
printf " $fg_bold[red]\U2718$reset_color $fg[red]%s$reset_color %s\n" \
${(r,20,):-"Failed to update"} \
"$repo"
}
__zplug::job::message::up_to_date()
{
local repo="$1"
printf " $fg[white]\U2714$reset_color %s %s\n" \
${(r,20,):-"Up-to-date"} \
"$repo"
}
__zplug::job::message::local_repo()
{
local repo="$1"
printf " $fg[yellow]\U279C$reset_color $fg[yellow]%s$reset_color %s\n" \
${(r,20,):-"Local repository"} \
"$repo"
}

47
base/job/rollback.zsh Normal file

@ -0,0 +1,47 @@
__zplug::job::rollback::build()
{
local repo
local -a failed
if [[ ! -f $_zplug_config[build_rollback] ]] || [[ ! -s $_zplug_config[build_rollback] ]]; then
__zplug::io::print::f \
--die \
--zplug \
"There is no package which have to be rollbacked.\n"
return 1
fi
while read repo
do
if [[ -z $repo ]]; then
continue
fi
printf "$fg_bold[default]%s$reset_color %s\n" \
${(r,20,):-"Building..."} \
"$repo"
__zplug::utils::ansi::cursor_up 1
__zplug::job::hook::build "$repo"
if (( $status > 0 )); then
failed+=( "$repo" )
printf "$fg[red]%s$reset_color %s\n" \
${(r,20,):-"Failed to build!"} \
"$repo"
else
printf "$fg[green]%s$reset_color %s\n" \
${(r,20,):-"Built successfully!"} \
"$repo"
fi
done <"$_zplug_config[build_rollback]"
# Overwrite
if (( $#failed == 0 )); then
rm -f "$_zplug_config[build_rollback]"
return 0
fi
printf "%s\n" "$failed[@]" >|"$_zplug_config[build_rollback]"
printf "Run '$fg_bold[default]zplug --log$reset_color' if you find cause of the failure of these build\n"
}

41
base/job/state.zsh Normal file

@ -0,0 +1,41 @@
__zplug::job::state::running()
{
local job
for job in "$argv[@]"
do
if kill -0 "$job" &>/dev/null; then
return 0
fi
done
return 1
}
__zplug::job::state::get() {
local repo="${1:?}"
local target="${2:-"install"}"
if [[ ! -f $_zplug_config[${target}_status] ]]; then
# TODO
return 1
fi
cat "$_zplug_config[${target}_status]" \
| grep "^repo:$repo" \
| awk '{print $2}' \
| cut -d: -f2
return $status
}
__zplug::job::state::kill() {
local pid="${1:?}"
if ! __zplug::job::state::running "$pid"; then
# TODO
return $status
fi
kill -9 $pid &>/dev/null
return $status
}

14
base/utils/ansi.zsh Normal file

@ -0,0 +1,14 @@
__zplug::utils::ansi::remove()
{
perl -pe 's/\e\[?.*?[\@-~]//g'
}
__zplug::utils::ansi::erace_current_line()
{
printf "\033[2K\r"
}
__zplug::utils::ansi::cursor_up()
{
printf "\033[%sA" "${1:-"1"}"
}

@ -26,6 +26,10 @@ __zplug::utils::git::clone()
__zplug::core::tags::parse "$repo"
tags=( "${reply[@]}" )
if [[ -d $tags[dir] ]]; then
return $_zplug_status[install_already]
fi
if [[ $tags[depth] == 0 ]]; then
depth_option=""
else
@ -66,12 +70,17 @@ __zplug::utils::git::clone()
${=depth_option} \
"$url_format" "$tags[dir]" \
2> >(__zplug::io::log::capture) >/dev/null
ret=$status
fi
# The revison (hash/branch/tag) lock
__zplug::utils::git::checkout "$repo"
return $status
if (( $ret == 0 )); then
return $_zplug_status[install_success]
else
return $_zplug_status[install_failure]
fi
}
__zplug::utils::git::checkout()
@ -342,11 +351,10 @@ __zplug::utils::git::get_state()
local state url
if [[ ! -e .git ]]; then
state="not git repo"
return $_zplug_status[status_not_git_repo]
fi
state="not on any branch"
branch="$(__zplug::utils::git::get_head_branch_name)"
if (( $status == 0 )); then
res=( ${(@f)"$(__zplug::utils::git::get_remote_state "$branch")"} )
@ -355,15 +363,19 @@ __zplug::utils::git::get_state()
fi
case "$state" in
"local out of date")
state="${fg[red]}${state}${reset_color}"
;;
"up to date")
state="${fg[green]}${state}${reset_color}"
return $_zplug_status[status_up_to_date]
;;
"local out of date")
return $_zplug_status[status_local_out_of_date]
;;
"not on any branch")
return $_zplug_status[status_not_on_any_branch]
;;
*)
return $_zplug_status[status_unknown]
;;
esac
printf "($state) '${url:-?}'\n"
}
__zplug::utils::git::remote_url()

@ -17,7 +17,7 @@ __zplug::utils::releases::get_latest()
fi
eval "$cmd $url" \
2> >(__zplug::io::log::capture) \
2>/dev/null \
| grep -o '/'"$repo"'/releases/download/[^"]*' \
| awk -F/ '{print $6}' \
| sort \
@ -27,7 +27,6 @@ __zplug::utils::releases::get_latest()
__zplug::utils::releases::get_state()
{
local state name="$1" dir="$2"
local url="https://github.com/$name/releases"
if (( $# < 2 )); then
__zplug::io::log::error \
@ -42,14 +41,16 @@ __zplug::utils::releases::get_state()
fi
case "$state" in
"local out of date")
state="${fg[red]}${state}${reset_color}"
;;
"up to date")
state="${fg[green]}${state}${reset_color}"
return $_zplug_status[status_up_to_date]
;;
"local out of date")
return $_zplug_status[status_local_out_of_date]
;;
*)
return $_zplug_status[status_unknown]
;;
esac
__zplug::io::print::put "($state) '${url:-?}'\n"
}
__zplug::utils::releases::is_64()
@ -130,7 +131,7 @@ __zplug::utils::releases::get_url()
candidates=(
${(@f)"$(
eval "$cmd $url" \
2> >(__zplug::io::log::capture) \
2>/dev/null \
| grep -o '/'"$repo"'/releases/download/[^"]*'
)"}
)
@ -195,12 +196,12 @@ __zplug::utils::releases::get()
# Grab artifact from G-R
eval "$cmd $url" \
2> >(__zplug::io::log::capture) >/dev/null
&>/dev/null
__zplug::utils::releases::index \
"$repo" \
"$artifact" \
2> >(__zplug::io::log::capture) >/dev/null &&
&>/dev/null &&
echo "$header" >"$tags[dir]/INDEX"
)

@ -201,3 +201,32 @@ __zplug::utils::shell::expand_glob()
print -l "${matches[@]}"
}
__zplug::utils::shell::eval()
{
local cmd
# Report stderr to error log
eval "${=cmd}" 2> >(__zplug::io::log::capture) >/dev/null
return $status
}
__zplug::utils::shell::json_escape()
{
#| perl -pe 's/\//\\\//g' \
if [[ -z $1 ]]; then
cat <&0
else
if [[ -f $1 ]]; then
cat "$1"
else
echo "$1"
fi
fi \
| perl -pe 's/\\/\\\\/g' \
| perl -pe 's/"/\\"/g' \
| perl -pe 's/\f/\\f/g' \
| perl -pe 's/\r/\\r/g' \
| perl -pe 's/\n/\\n/g' \
| perl -pe 's/\t/\\t/g'
}

@ -37,6 +37,7 @@ _arguments \
'(-)--help[show help message]: :->comp' \
'(-)--version[version information]: :' \
'(-)--log=[view zplug error log]: :->log' \
'(-)--rollback=[rollback paticular processings]: :->rollback' \
'*:: :->comp' && return 0
if (( CURRENT == 1 )); then
@ -150,7 +151,6 @@ case $state in
is_help="yes"
_describe -t help_cmds "commands" cmds
_describe -t help_tags "tags" tags
return 0
;;
"log")
compadd -J 'log/jq' -X "%F{yellow}Completing%f %Bwith jq%b" \
@ -165,6 +165,11 @@ case $state in
'clear' \
'count' \
'latest'
;;
"rollback")
compadd -J 'rollback' -X "%F{yellow}Completing%f %Bwith rollback%b" \
'build'
;;
esac
return ret