1
0
Fork 0
mirror of synced 2024-11-26 09:15:34 -05:00

Add check and rename version-check to check-version

actions. Return 4 if there's a zimfw update from check-version. Don't
return a specific error code if there are module updates from check, as
it uses zargs to check all and each check runs in a separate shell. Need
to figure out how to propagate all that to a final error code.

See #503
This commit is contained in:
Eric Nielsen 2023-03-26 09:34:07 -05:00
parent b7b33f3786
commit 903e0e5249
No known key found for this signature in database
GPG key ID: 678AF5E338C87D99
7 changed files with 269 additions and 165 deletions

View file

@ -1,5 +1,5 @@
_zimfw_version_check() { _zimfw_check_version() {
if [[ ${1} -ne 0 || ! -f ${_zversion_target} ]]; then if [[ ${1} -ne 0 ]]; then
# Get latest version (get all `v*` tags from repo, delete `*v` from beginning, # Get latest version (get all `v*` tags from repo, delete `*v` from beginning,
# sort in descending `O`rder `n`umerically, and get the `[1]` first) # sort in descending `O`rder `n`umerically, and get the `[1]` first)
local tags local tags
@ -11,6 +11,6 @@ _zimfw_version_check() {
if (( _zprintlevel > 0 )); then if (( _zprintlevel > 0 )); then
print -u2 -PR "%F{yellow}Latest zimfw version is %B${zlatest_version}%b. You're using version %B${_zversion}%b. Run %Bzimfw upgrade%b to upgrade.%f" print -u2 -PR "%F{yellow}Latest zimfw version is %B${zlatest_version}%b. You're using version %B${_zversion}%b. Run %Bzimfw upgrade%b to upgrade.%f"
fi fi
return 1 return 4
fi fi
} }

View file

@ -16,12 +16,16 @@ _zimfw_run_tool() {
fi fi
_zimfw_print -nR <%= clear_line %>"Installing ${zname}<%= ellipsis %>" _zimfw_print -nR <%= clear_line %>"Installing ${zname}<%= ellipsis %>"
;; ;;
update) check|update)
if [[ ! -d ${_zdirs[${zname}]} ]]; then if [[ ! -d ${_zdirs[${zname}]} ]]; then
print -u2 -PR <%= clear_line %>"%F{red}<%= error %>%B${zname}:%b Not installed. Run %Bzimfw install%b to install.%f" print -u2 -PR <%= clear_line %>"%F{red}<%= error %>%B${zname}:%b Not installed. Run %Bzimfw install%b to install.%f"
return 1 return 1
fi fi
if [[ ${_zargs_action} == check ]]; then
if (( _zprintlevel > 1 )) print -nR <%= clear_line %>"Checking ${zname}<%= ellipsis %>"
else
_zimfw_print -nR <%= clear_line %>"Updating ${zname}<%= ellipsis %>" _zimfw_print -nR <%= clear_line %>"Updating ${zname}<%= ellipsis %>"
fi
;; ;;
*) *)
print -u2 -PR <%= clear_line %>"%F{red}<%= error %>%B${zname}:%b Unknown action ${_zargs_action}%f" print -u2 -PR <%= clear_line %>"%F{red}<%= error %>%B${zname}:%b Unknown action ${_zargs_action}%f"

View file

@ -1,6 +1,6 @@
_zimfw_install_update() { _zimfw_run_tool_action() {
local -r _zargs_action=${1} local -r _zargs_action=${1}
_zimfw_source_zimrc 1 && zargs -n 1 -P 0 -- "${_znames[@]}" -- _zimfw_run_tool zargs -n 1 -P 0 -- "${_znames[@]}" -- _zimfw_run_tool
# Ignore return from zargs with -P. Was missing values before zsh 5.9, and # Ignore return from zargs with -P. Was missing values before zsh 5.9, and
# it's intermittently failing in zsh 5.9 and macOS. See https://www.zsh.org/mla/workers/2022/msg00611.html # it's intermittently failing in zsh 5.9 and macOS. See https://www.zsh.org/mla/workers/2022/msg00611.html
return 0 return 0

View file

@ -17,11 +17,13 @@ Actions:
%Binstall%b Install new modules. Also does %Bbuild%b, %Bcompile%b. Use %B-v%b to also see their %Binstall%b Install new modules. Also does %Bbuild%b, %Bcompile%b. Use %B-v%b to also see their
output, any on-pull output and skipped modules. output, any on-pull output and skipped modules.
%Buninstall%b Delete unused modules. Prompts for confirmation. Use %B-q%b for quiet uninstall. %Buninstall%b Delete unused modules. Prompts for confirmation. Use %B-q%b for quiet uninstall.
%Bcheck%b Check if updates for current modules are available. Use %B-v%b to also see
skipped and up to date modules.
%Bupdate%b Update current modules. Also does %Bbuild%b, %Bcompile%b. Use %B-v%b to also see their %Bupdate%b Update current modules. Also does %Bbuild%b, %Bcompile%b. Use %B-v%b to also see their
output, any on-pull output and skipped modules. output, any on-pull output and skipped modules.
%Bcheck-version%b Check if a new version of zimfw is available.
%Bupgrade%b Upgrade zimfw. Also does %Bcompile%b. Use %B-v%b to also see its output. %Bupgrade%b Upgrade zimfw. Also does %Bcompile%b. Use %B-v%b to also see its output.
%Bversion%b Print zimfw version. %Bversion%b Print zimfw version.
%Bversion-check%b Check if a new version of zimfw is available.
Options: Options:
%B-q%b Quiet (yes to prompts and only outputs errors) %B-q%b Quiet (yes to prompts and only outputs errors)
@ -44,11 +46,10 @@ Options:
esac esac
fi fi
if ! zstyle -t ':zim' disable-version-check && [[ ${1} != version-check ]]; then if ! zstyle -t ':zim' disable-version-check && [[ ${1} != check-version ]]; then
# If .latest_version does not exist or was not modified in the last 30 days # If .latest_version does not exist or was not modified in the last 30 days
[[ -f ${_zversion_target}(#qNm-30) ]]; local -r zversion_check_force=${?} [[ -f ${_zversion_target}(#qNm-30) ]]; local -r zversion_check_force=${?}
_zimfw_version_check ${zversion_check_force} _zimfw_check_version ${zversion_check_force}
print
fi fi
local _zrestartmsg=' Restart your terminal for changes to take effect.' local _zrestartmsg=' Restart your terminal for changes to take effect.'
@ -69,27 +70,33 @@ Options:
_zimfw_source_zimrc 3 && zargs -n 1 -- "${_znames[@]}" -- _zimfw_run_list && \ _zimfw_source_zimrc 3 && zargs -n 1 -- "${_znames[@]}" -- _zimfw_run_list && \
_zimfw_list_unuseds ' (unused)' _zimfw_list_unuseds ' (unused)'
;; ;;
check)
_zrestartmsg=
_zimfw_source_zimrc 3 && _zimfw_run_tool_action ${1} || return 1
(( _zprintlevel-- ))
_zimfw_print -PR "<%= done %>Done with ${1}." # Only printed in verbose mode
;;
init) init)
_zrestartmsg= _zrestartmsg=
_zimfw_install_update install || return 1 _zimfw_source_zimrc 3 && _zimfw_run_tool_action install || return 1
(( _zprintlevel-- )) (( _zprintlevel-- ))
_zimfw_print -PR "<%= done %>Done with install.${_zrestartmsg}" # Only printed in verbose mode _zimfw_print -PR "<%= done %>Done with install." # Only printed in verbose mode
_zimfw_source_zimrc 2 && _zimfw_build && _zimfw_compile _zimfw_build && _zimfw_compile
;; ;;
install|update) install|update)
_zimfw_install_update ${1} || return 1 _zimfw_source_zimrc 3 && _zimfw_run_tool_action ${1} || return 1
_zimfw_print -PR "<%= done %>Done with ${1}.${_zrestartmsg}" _zimfw_print -PR "<%= done %>Done with ${1}.${_zrestartmsg}"
(( _zprintlevel-- )) (( _zprintlevel-- ))
_zimfw_source_zimrc 2 && _zimfw_build && _zimfw_compile _zimfw_build && _zimfw_compile
;; ;;
uninstall) _zimfw_source_zimrc 2 && _zimfw_list_unuseds && _zimfw_uninstall ;; uninstall) _zimfw_source_zimrc 2 && _zimfw_list_unuseds && _zimfw_uninstall ;;
check-version) _zimfw_check_version 1 ;;
upgrade) upgrade)
_zimfw_upgrade || return 1 _zimfw_upgrade || return 1
(( _zprintlevel-- )) (( _zprintlevel-- ))
_zimfw_source_zimrc 2 && _zimfw_compile _zimfw_source_zimrc 2 && _zimfw_compile
;; ;;
version) print -PR ${_zversion} ;; version) print -PR ${_zversion} ;;
version-check) _zimfw_version_check 1 ;;
*) *)
print -u2 -PlR "%F{red}${0}: Unknown action ${1}%f" '' ${zusage} print -u2 -PlR "%F{red}${0}: Unknown action ${1}%f" '' ${zusage}
return 2 return 2

View file

@ -1,6 +1,7 @@
# This runs in a new shell # This runs in a new shell
builtin emulate -L zsh -o EXTENDED_GLOB builtin emulate -L zsh -o EXTENDED_GLOB
readonly -i PRINTLEVEL=${1} SUBMODULES=${8} integer PRINTLEVEL=${1}
readonly -i SUBMODULES=${8}
readonly ACTION=${2} MODULE=${3} DIR=${4} URL=${5} REV=${7} ONPULL=${9} TEMP=.zdegit_${sysparams[pid]} readonly ACTION=${2} MODULE=${3} DIR=${4} URL=${5} REV=${7} ONPULL=${9} TEMP=.zdegit_${sysparams[pid]}
readonly TARBALL_TARGET=${DIR}/${TEMP}_tarball.tar.gz INFO_TARGET=${DIR}/.zdegit readonly TARBALL_TARGET=${DIR}/${TEMP}_tarball.tar.gz INFO_TARGET=${DIR}/.zdegit
@ -19,7 +20,7 @@ print_okay() {
fi fi
} }
handle() { on_pull() {
if [[ -n ${ONPULL} ]]; then if [[ -n ${ONPULL} ]]; then
if ! ERR=$(builtin cd -q ${DIR} 2>&1 && builtin eval ${ONPULL} 2>&1); then if ! ERR=$(builtin cd -q ${DIR} 2>&1 && builtin eval ${ONPULL} 2>&1); then
print_error 'Error during on-pull' ${ERR} print_error 'Error during on-pull' ${ERR}
@ -28,7 +29,6 @@ handle() {
builtin set ${1} ${2:+${2}$'\n'}"On-pull output:"$'\n'${ERR} builtin set ${1} ${2:+${2}$'\n'}"On-pull output:"$'\n'${ERR}
fi fi
fi fi
print_okay "${@}"
} }
download_tarball() { download_tarball() {
@ -54,6 +54,14 @@ download_tarball() {
info_header=${info[3]} info_header=${info[3]}
fi fi
local -r tarball_url=https://api.github.com/repos/${repo}/tarball/${REV} local -r tarball_url=https://api.github.com/repos/${repo}/tarball/${REV}
if [[ ${ACTION} == check ]]; then
if [[ -z ${info_header} ]] return 0
if (( ${+commands[curl]} )); then
command curl -IfsL -H ${info_header} ${tarball_url} >${headers_target}
else
command wget --spider -qS --header=${info_header} ${tarball_url} 2>${headers_target}
fi
else
if (( ${+commands[curl]} )); then if (( ${+commands[curl]} )); then
if ! ERR=$(command curl -fsSL ${info_header:+-H} ${info_header} -o ${TARBALL_TARGET} -D ${headers_target} ${tarball_url} 2>&1); then if ! ERR=$(command curl -fsSL ${info_header:+-H} ${info_header} -o ${TARBALL_TARGET} -D ${headers_target} ${tarball_url} 2>&1); then
print_error "Error downloading ${tarball_url} with curl" ${ERR} print_error "Error downloading ${tarball_url} with curl" ${ERR}
@ -61,7 +69,8 @@ download_tarball() {
fi fi
else else
# wget returns 8 when 304 Not Modified, so we cannot use wget's error codes # wget returns 8 when 304 Not Modified, so we cannot use wget's error codes
command wget -q ${info_header:+--header=${info_header}} -O ${TARBALL_TARGET} -S ${tarball_url} 2>${headers_target} command wget -qS ${info_header:+--header=${info_header}} -O ${TARBALL_TARGET} ${tarball_url} 2>${headers_target}
fi
fi fi
local -i http_code local -i http_code
while IFS= read -r header; do while IFS= read -r header; do
@ -84,10 +93,14 @@ download_tarball() {
print_error "Error downloading ${tarball_url}, no ETag header found in response" print_error "Error downloading ${tarball_url}, no ETag header found in response"
return 1 return 1
fi fi
if [[ ${ACTION} == check ]]; then
command touch ${TARBALL_TARGET} # Update available
else
if ! print -lR "${URL}" "${REV}" "If-None-Match: ${etag}" >! ${INFO_TARGET} 2>/dev/null; then if ! print -lR "${URL}" "${REV}" "If-None-Match: ${etag}" >! ${INFO_TARGET} 2>/dev/null; then
print_error "Error creating or updating ${INFO_TARGET}" print_error "Error creating or updating ${INFO_TARGET}"
return 1 return 1
fi fi
fi
} always { } always {
command rm -f ${headers_target} 2>/dev/null command rm -f ${headers_target} 2>/dev/null
} }
@ -110,7 +123,7 @@ create_dir() {
case ${ACTION} in case ${ACTION} in
install) install)
{ {
create_dir ${DIR} && download_tarball && untar_tarball ${DIR} && handle Installed create_dir ${DIR} && download_tarball && untar_tarball ${DIR} && on_pull && print_okay Installed
} always { } always {
# return 1 does not change ${TRY_BLOCK_ERROR}, only changes ${?} # return 1 does not change ${TRY_BLOCK_ERROR}, only changes ${?}
(( TRY_BLOCK_ERROR = ? )) (( TRY_BLOCK_ERROR = ? ))
@ -118,18 +131,26 @@ case ${ACTION} in
if (( TRY_BLOCK_ERROR )) command rm -rf ${DIR} 2>/dev/null if (( TRY_BLOCK_ERROR )) command rm -rf ${DIR} 2>/dev/null
} }
;; ;;
update) check|update)
if [[ ! -r ${INFO_TARGET} ]]; then if [[ ! -r ${INFO_TARGET} ]]; then
if (( PRINTLEVEL > 0 )); then if (( PRINTLEVEL > 0 )); then
print -u2 -PR <%= clear_line %>"%F{yellow}<%= warn %>%B${MODULE}:%b Module was not installed using Zim's degit. Will not try to update. Use zmodule option %B-z%b|%B--frozen%b to disable this warning.%f" print -u2 -PR <%= clear_line %>"%F{yellow}<%= warn %>%B${MODULE}:%b Module was not installed using Zim's degit. Will not try to ${ACTION}. Use zmodule option %B-z%b|%B--frozen%b to disable this warning.%f"
fi fi
return 0 return 0
fi fi
readonly DIR_NEW=${DIR}${TEMP} readonly DIR_NEW=${DIR}${TEMP}
{ {
download_tarball || return 1 download_tarball || return 1
if [[ ${ACTION} == check ]]; then
if [[ -e ${TARBALL_TARGET} ]]; then
print_okay 'Update available'
else
(( PRINTLEVEL-- ))
print_okay 'Already up to date'
fi
else
if [[ ! -e ${TARBALL_TARGET} ]]; then if [[ ! -e ${TARBALL_TARGET} ]]; then
handle 'Already up to date' on_pull && print_okay 'Already up to date'
return ${?} return ${?}
fi fi
create_dir ${DIR_NEW} && untar_tarball ${DIR_NEW} || return 1 create_dir ${DIR_NEW} && untar_tarball ${DIR_NEW} || return 1
@ -142,7 +163,8 @@ case ${ACTION} in
print_error "Error updating ${DIR}" ${ERR} print_error "Error updating ${DIR}" ${ERR}
return 1 return 1
fi fi
handle Updated ${LOG} on_pull && print_okay Updated ${LOG}
fi
} always { } always {
command rm -f ${TARBALL_TARGET} 2>/dev/null command rm -f ${TARBALL_TARGET} 2>/dev/null
command rm -rf ${DIR_NEW} 2>/dev/null command rm -rf ${DIR_NEW} 2>/dev/null

View file

@ -1,6 +1,7 @@
# This runs in a new shell # This runs in a new shell
builtin emulate -L zsh builtin emulate -L zsh
readonly -i PRINTLEVEL=${1} SUBMODULES=${8} integer PRINTLEVEL=${1}
readonly -i SUBMODULES=${8}
readonly ACTION=${2} MODULE=${3} DIR=${4} URL=${5} TYPE=${6} ONPULL=${9} readonly ACTION=${2} MODULE=${3} DIR=${4} URL=${5} TYPE=${6} ONPULL=${9}
REV=${7} REV=${7}
@ -12,48 +13,43 @@ print_okay() {
if (( PRINTLEVEL > 0 )) print -PlR <%= clear_line %>"<%= okay %>%B${MODULE}:%b ${1}" ${2:+${(F):- ${(f)^2}}} if (( PRINTLEVEL > 0 )) print -PlR <%= clear_line %>"<%= okay %>%B${MODULE}:%b ${1}" ${2:+${(F):- ${(f)^2}}}
} }
handle() { on_pull() {
if [[ -n ${ONPULL} ]]; then if [[ -n ${ONPULL} ]]; then
if ! ERR=$(builtin cd -q ${DIR} 2>&1 && builtin eval ${ONPULL} 2>&1); then if ! ERR=$(builtin cd -q ${DIR} 2>&1 && builtin eval ${ONPULL} 2>&1); then
print_error 'Error during on-pull' ${ERR} print_error 'Error during on-pull' ${ERR}
return 1 return 1
elif [[ ${PRINTLEVEL} -gt 1 && -n ${ERR} ]]; then elif [[ ${PRINTLEVEL} -gt 1 && -n ${ERR} ]]; then
builtin set ${1} ${2:+${2}$'\n'}"On-pull output:"$'\n'${ERR} builtin set ${1} ${2:+${2}$'\n'}'On-pull output:'$'\n'${ERR}
fi fi
fi fi
print_okay "${@}"
} }
case ${ACTION} in case ${ACTION} in
install) install)
if ERR=$(command git clone ${REV:+-b} ${REV} -q --config core.autocrlf=false ${${SUBMODULES:#0}:+--recursive} -- ${URL} ${DIR} 2>&1); then if ERR=$(command git clone ${REV:+-b} ${REV} -q --config core.autocrlf=false ${${SUBMODULES:#0}:+--recursive} -- ${URL} ${DIR} 2>&1); then
handle Installed on_pull && print_okay Installed
else else
print_error 'Error during git clone' ${ERR} print_error 'Error during git clone' ${ERR}
return 1 return 1
fi fi
;; ;;
update) check|update)
if [[ ! -r ${DIR}/.git ]]; then if [[ ! -r ${DIR}/.git ]]; then
if (( PRINTLEVEL > 0 )); then if (( PRINTLEVEL > 0 )); then
print -u2 -PR <%= clear_line %>"%F{yellow}<%= warn %>%B${MODULE}:%b Module was not installed using git. Will not try to update. Use zmodule option %B-z%b|%B--frozen%b to disable this warning.%f" print -u2 -PR <%= clear_line %>"%F{yellow}<%= warn %>%B${MODULE}:%b Module was not installed using git. Will not try to ${ACTION}. Use zmodule option %B-z%b|%B--frozen%b to disable this warning.%f"
fi fi
return 0 return 0
fi fi
if [[ ${URL} != $(command git -C ${DIR} config --get remote.origin.url) ]]; then if [[ ${URL} != $(command git -C ${DIR} config --get remote.origin.url) ]]; then
print_error "URL does not match. Expected ${URL}. Will not try to update." print_error "URL does not match. Expected ${URL}. Will not try to ${ACTION}."
return 1 return 1
fi fi
if ! ERR=$(command git -C ${DIR} fetch -pq origin 2>&1); then if ! ERR=$(command git -C ${DIR} fetch -pqt origin 2>&1); then
print_error 'Error during git fetch' ${ERR} print_error 'Error during git fetch' ${ERR}
return 1 return 1
fi fi
if [[ ${TYPE} == tag ]]; then if [[ ${TYPE} == branch ]]; then
if [[ ${REV} == $(command git -C ${DIR} describe --tags --exact-match 2>/dev/null) ]]; then if [[ -z ${REV} ]]; then
handle 'Already up to date'
return ${?}
fi
elif [[ -z ${REV} ]]; then
# Get HEAD remote branch # Get HEAD remote branch
if ! ERR=$(command git -C ${DIR} remote set-head origin -a 2>&1); then if ! ERR=$(command git -C ${DIR} remote set-head origin -a 2>&1); then
print_error 'Error during git remote set-head' ${ERR} print_error 'Error during git remote set-head' ${ERR}
@ -66,12 +62,35 @@ case ${ACTION} in
return 1 return 1
fi fi
fi fi
if [[ ${TYPE} == branch ]]; then TO_REV=${REV}@{u}
LOG_REV=${REV}@{u} if [[ ${ACTION} == check ]]; then
local -ri behind=$(command git rev-list --count ${REV}..${TO_REV} -- 2>/dev/null)
if (( behind )); then
print_okay "Update available [behind ${behind}]"
else else
LOG_REV=${REV} (( PRINTLEVEL-- ))
print_okay 'Already up to date'
fi fi
LOG=$(command git -C ${DIR} log --graph --color --format='%C(yellow)%h%C(reset) %s %C(cyan)(%cr)%C(reset)' ..${LOG_REV} -- 2>/dev/null) return 0
fi
else
if [[ ${REV} == $(command git -C ${DIR} describe --tags --exact-match 2>/dev/null) ]]; then
if [[ ${ACTION} == check ]]; then
(( PRINTLEVEL-- ))
print_okay 'Already up to date'
return 0
else
on_pull && print_okay 'Already up to date'
return ${?}
fi
fi
if [[ ${ACTION} == check ]]; then
print_okay 'Update available'
return 0
fi
TO_REV=${REV}
fi
LOG=$(command git -C ${DIR} log --graph --color --format='%C(yellow)%h%C(reset) %s %C(cyan)(%cr)%C(reset)' ..${TO_REV} -- 2>/dev/null)
if ! ERR=$(command git -C ${DIR} checkout -q ${REV} -- 2>&1); then if ! ERR=$(command git -C ${DIR} checkout -q ${REV} -- 2>&1); then
print_error 'Error during git checkout' ${ERR} print_error 'Error during git checkout' ${ERR}
return 1 return 1
@ -92,6 +111,6 @@ case ${ACTION} in
return 1 return 1
fi fi
fi fi
handle ${OUT} ${LOG} on_pull && print_okay ${OUT} ${LOG}
;; ;;
esac esac

164
zimfw.zsh
View file

@ -382,8 +382,12 @@ _zimfw_list_unuseds() {
for zunused (${_zunused_dirs}) _zimfw_print -PR "%B${zunused:t}:%b ${zunused}${1}" for zunused (${_zunused_dirs}) _zimfw_print -PR "%B${zunused:t}:%b ${zunused}${1}"
} }
_zimfw_version_check() { _zimfw_check_dumpfile() {
if [[ ${1} -ne 0 || ! -f ${_zversion_target} ]]; then _zimfw_print -u2 -PR '%F{yellow}! Deprecated action. This is now handled by the completion module alone.'
}
_zimfw_check_version() {
if [[ ${1} -ne 0 ]]; then
# Get latest version (get all `v*` tags from repo, delete `*v` from beginning, # Get latest version (get all `v*` tags from repo, delete `*v` from beginning,
# sort in descending `O`rder `n`umerically, and get the `[1]` first) # sort in descending `O`rder `n`umerically, and get the `[1]` first)
local tags local tags
@ -395,14 +399,10 @@ _zimfw_version_check() {
if (( _zprintlevel > 0 )); then if (( _zprintlevel > 0 )); then
print -u2 -PR "%F{yellow}Latest zimfw version is %B${zlatest_version}%b. You're using version %B${_zversion}%b. Run %Bzimfw upgrade%b to upgrade.%f" print -u2 -PR "%F{yellow}Latest zimfw version is %B${zlatest_version}%b. You're using version %B${_zversion}%b. Run %Bzimfw upgrade%b to upgrade.%f"
fi fi
return 1 return 4
fi fi
} }
_zimfw_check_dumpfile() {
_zimfw_print -u2 -PR '%F{yellow}! Deprecated action. This is now handled by the completion module alone.'
}
_zimfw_clean_compiled() { _zimfw_clean_compiled() {
# Array with unique dirs. ${ZIM_HOME} or any subdirectory should only occur once. # Array with unique dirs. ${ZIM_HOME} or any subdirectory should only occur once.
local -Ur zscriptdirs=(${ZIM_HOME} ${${(v)_zdirs##${ZIM_HOME}/*}:A}) local -Ur zscriptdirs=(${ZIM_HOME} ${${(v)_zdirs##${ZIM_HOME}/*}:A})
@ -434,21 +434,13 @@ _zimfw_compile() {
} }
_zimfw_info() { _zimfw_info() {
print -R 'zimfw version: '${_zversion}' (built at 2023-03-24 14:45:38 UTC, previous commit is a34b8da)' print -R 'zimfw version: '${_zversion}' (built at 2023-03-26 14:32:46 UTC, previous commit is b7b33f3)'
local zparam local zparam
for zparam in LANG ${(Mk)parameters:#LC_*} OSTYPE TERM TERM_PROGRAM TERM_PROGRAM_VERSION ZIM_HOME ZSH_VERSION; do for zparam in LANG ${(Mk)parameters:#LC_*} OSTYPE TERM TERM_PROGRAM TERM_PROGRAM_VERSION ZIM_HOME ZSH_VERSION; do
print -R ${(r.22....:.)zparam}${(P)zparam} print -R ${(r.22....:.)zparam}${(P)zparam}
done done
} }
_zimfw_install_update() {
local -r _zargs_action=${1}
_zimfw_source_zimrc 1 && zargs -n 1 -P 0 -- "${_znames[@]}" -- _zimfw_run_tool
# Ignore return from zargs with -P. Was missing values before zsh 5.9, and
# it's intermittently failing in zsh 5.9 and macOS. See https://www.zsh.org/mla/workers/2022/msg00611.html
return 0
}
_zimfw_uninstall() { _zimfw_uninstall() {
local zopt local zopt
if (( _zprintlevel > 0 )) zopt=-v if (( _zprintlevel > 0 )) zopt=-v
@ -545,12 +537,16 @@ _zimfw_run_tool() {
fi fi
_zimfw_print -nR $'\E[2K\r'"Installing ${zname} ..." _zimfw_print -nR $'\E[2K\r'"Installing ${zname} ..."
;; ;;
update) check|update)
if [[ ! -d ${_zdirs[${zname}]} ]]; then if [[ ! -d ${_zdirs[${zname}]} ]]; then
print -u2 -PR $'\E[2K\r'"%F{red}x %B${zname}:%b Not installed. Run %Bzimfw install%b to install.%f" print -u2 -PR $'\E[2K\r'"%F{red}x %B${zname}:%b Not installed. Run %Bzimfw install%b to install.%f"
return 1 return 1
fi fi
if [[ ${_zargs_action} == check ]]; then
if (( _zprintlevel > 1 )) print -nR $'\E[2K\r'"Checking ${zname} ..."
else
_zimfw_print -nR $'\E[2K\r'"Updating ${zname} ..." _zimfw_print -nR $'\E[2K\r'"Updating ${zname} ..."
fi
;; ;;
*) *)
print -u2 -PR $'\E[2K\r'"%F{red}x %B${zname}:%b Unknown action ${_zargs_action}%f" print -u2 -PR $'\E[2K\r'"%F{red}x %B${zname}:%b Unknown action ${_zargs_action}%f"
@ -561,7 +557,8 @@ _zimfw_run_tool() {
case ${_ztools[${zname}]} in case ${_ztools[${zname}]} in
degit) zcmd="# This runs in a new shell degit) zcmd="# This runs in a new shell
builtin emulate -L zsh -o EXTENDED_GLOB builtin emulate -L zsh -o EXTENDED_GLOB
readonly -i PRINTLEVEL=\${1} SUBMODULES=\${8} integer PRINTLEVEL=\${1}
readonly -i SUBMODULES=\${8}
readonly ACTION=\${2} MODULE=\${3} DIR=\${4} URL=\${5} REV=\${7} ONPULL=\${9} TEMP=.zdegit_\${sysparams[pid]} readonly ACTION=\${2} MODULE=\${3} DIR=\${4} URL=\${5} REV=\${7} ONPULL=\${9} TEMP=.zdegit_\${sysparams[pid]}
readonly TARBALL_TARGET=\${DIR}/\${TEMP}_tarball.tar.gz INFO_TARGET=\${DIR}/.zdegit readonly TARBALL_TARGET=\${DIR}/\${TEMP}_tarball.tar.gz INFO_TARGET=\${DIR}/.zdegit
@ -580,7 +577,7 @@ print_okay() {
fi fi
} }
handle() { on_pull() {
if [[ -n \${ONPULL} ]]; then if [[ -n \${ONPULL} ]]; then
if ! ERR=\$(builtin cd -q \${DIR} 2>&1 && builtin eval \${ONPULL} 2>&1); then if ! ERR=\$(builtin cd -q \${DIR} 2>&1 && builtin eval \${ONPULL} 2>&1); then
print_error 'Error during on-pull' \${ERR} print_error 'Error during on-pull' \${ERR}
@ -589,7 +586,6 @@ handle() {
builtin set \${1} \${2:+\${2}$'\n'}\"On-pull output:\"$'\n'\${ERR} builtin set \${1} \${2:+\${2}$'\n'}\"On-pull output:\"$'\n'\${ERR}
fi fi
fi fi
print_okay \"\${@}\"
} }
download_tarball() { download_tarball() {
@ -615,6 +611,14 @@ download_tarball() {
info_header=\${info[3]} info_header=\${info[3]}
fi fi
local -r tarball_url=https://api.github.com/repos/\${repo}/tarball/\${REV} local -r tarball_url=https://api.github.com/repos/\${repo}/tarball/\${REV}
if [[ \${ACTION} == check ]]; then
if [[ -z \${info_header} ]] return 0
if (( \${+commands[curl]} )); then
command curl -IfsL -H \${info_header} \${tarball_url} >\${headers_target}
else
command wget --spider -qS --header=\${info_header} \${tarball_url} 2>\${headers_target}
fi
else
if (( \${+commands[curl]} )); then if (( \${+commands[curl]} )); then
if ! ERR=\$(command curl -fsSL \${info_header:+-H} \${info_header} -o \${TARBALL_TARGET} -D \${headers_target} \${tarball_url} 2>&1); then if ! ERR=\$(command curl -fsSL \${info_header:+-H} \${info_header} -o \${TARBALL_TARGET} -D \${headers_target} \${tarball_url} 2>&1); then
print_error \"Error downloading \${tarball_url} with curl\" \${ERR} print_error \"Error downloading \${tarball_url} with curl\" \${ERR}
@ -622,7 +626,8 @@ download_tarball() {
fi fi
else else
# wget returns 8 when 304 Not Modified, so we cannot use wget's error codes # wget returns 8 when 304 Not Modified, so we cannot use wget's error codes
command wget -q \${info_header:+--header=\${info_header}} -O \${TARBALL_TARGET} -S \${tarball_url} 2>\${headers_target} command wget -qS \${info_header:+--header=\${info_header}} -O \${TARBALL_TARGET} \${tarball_url} 2>\${headers_target}
fi
fi fi
local -i http_code local -i http_code
while IFS= read -r header; do while IFS= read -r header; do
@ -645,10 +650,14 @@ download_tarball() {
print_error \"Error downloading \${tarball_url}, no ETag header found in response\" print_error \"Error downloading \${tarball_url}, no ETag header found in response\"
return 1 return 1
fi fi
if [[ \${ACTION} == check ]]; then
command touch \${TARBALL_TARGET} # Update available
else
if ! print -lR \"\${URL}\" \"\${REV}\" \"If-None-Match: \${etag}\" >! \${INFO_TARGET} 2>/dev/null; then if ! print -lR \"\${URL}\" \"\${REV}\" \"If-None-Match: \${etag}\" >! \${INFO_TARGET} 2>/dev/null; then
print_error \"Error creating or updating \${INFO_TARGET}\" print_error \"Error creating or updating \${INFO_TARGET}\"
return 1 return 1
fi fi
fi
} always { } always {
command rm -f \${headers_target} 2>/dev/null command rm -f \${headers_target} 2>/dev/null
} }
@ -671,7 +680,7 @@ create_dir() {
case \${ACTION} in case \${ACTION} in
install) install)
{ {
create_dir \${DIR} && download_tarball && untar_tarball \${DIR} && handle Installed create_dir \${DIR} && download_tarball && untar_tarball \${DIR} && on_pull && print_okay Installed
} always { } always {
# return 1 does not change \${TRY_BLOCK_ERROR}, only changes \${?} # return 1 does not change \${TRY_BLOCK_ERROR}, only changes \${?}
(( TRY_BLOCK_ERROR = ? )) (( TRY_BLOCK_ERROR = ? ))
@ -679,18 +688,26 @@ case \${ACTION} in
if (( TRY_BLOCK_ERROR )) command rm -rf \${DIR} 2>/dev/null if (( TRY_BLOCK_ERROR )) command rm -rf \${DIR} 2>/dev/null
} }
;; ;;
update) check|update)
if [[ ! -r \${INFO_TARGET} ]]; then if [[ ! -r \${INFO_TARGET} ]]; then
if (( PRINTLEVEL > 0 )); then if (( PRINTLEVEL > 0 )); then
print -u2 -PR $'\E[2K\r'\"%F{yellow}! %B\${MODULE}:%b Module was not installed using Zim's degit. Will not try to update. Use zmodule option %B-z%b|%B--frozen%b to disable this warning.%f\" print -u2 -PR $'\E[2K\r'\"%F{yellow}! %B\${MODULE}:%b Module was not installed using Zim's degit. Will not try to \${ACTION}. Use zmodule option %B-z%b|%B--frozen%b to disable this warning.%f\"
fi fi
return 0 return 0
fi fi
readonly DIR_NEW=\${DIR}\${TEMP} readonly DIR_NEW=\${DIR}\${TEMP}
{ {
download_tarball || return 1 download_tarball || return 1
if [[ \${ACTION} == check ]]; then
if [[ -e \${TARBALL_TARGET} ]]; then
print_okay 'Update available'
else
(( PRINTLEVEL-- ))
print_okay 'Already up to date'
fi
else
if [[ ! -e \${TARBALL_TARGET} ]]; then if [[ ! -e \${TARBALL_TARGET} ]]; then
handle 'Already up to date' on_pull && print_okay 'Already up to date'
return \${?} return \${?}
fi fi
create_dir \${DIR_NEW} && untar_tarball \${DIR_NEW} || return 1 create_dir \${DIR_NEW} && untar_tarball \${DIR_NEW} || return 1
@ -703,7 +720,8 @@ case \${ACTION} in
print_error \"Error updating \${DIR}\" \${ERR} print_error \"Error updating \${DIR}\" \${ERR}
return 1 return 1
fi fi
handle Updated \${LOG} on_pull && print_okay Updated \${LOG}
fi
} always { } always {
command rm -f \${TARBALL_TARGET} 2>/dev/null command rm -f \${TARBALL_TARGET} 2>/dev/null
command rm -rf \${DIR_NEW} 2>/dev/null command rm -rf \${DIR_NEW} 2>/dev/null
@ -713,7 +731,8 @@ esac
" ;; " ;;
git) zcmd="# This runs in a new shell git) zcmd="# This runs in a new shell
builtin emulate -L zsh builtin emulate -L zsh
readonly -i PRINTLEVEL=\${1} SUBMODULES=\${8} integer PRINTLEVEL=\${1}
readonly -i SUBMODULES=\${8}
readonly ACTION=\${2} MODULE=\${3} DIR=\${4} URL=\${5} TYPE=\${6} ONPULL=\${9} readonly ACTION=\${2} MODULE=\${3} DIR=\${4} URL=\${5} TYPE=\${6} ONPULL=\${9}
REV=\${7} REV=\${7}
@ -725,48 +744,43 @@ print_okay() {
if (( PRINTLEVEL > 0 )) print -PlR $'\E[2K\r'\"%F{green})%f %B\${MODULE}:%b \${1}\" \${2:+\${(F):- \${(f)^2}}} if (( PRINTLEVEL > 0 )) print -PlR $'\E[2K\r'\"%F{green})%f %B\${MODULE}:%b \${1}\" \${2:+\${(F):- \${(f)^2}}}
} }
handle() { on_pull() {
if [[ -n \${ONPULL} ]]; then if [[ -n \${ONPULL} ]]; then
if ! ERR=\$(builtin cd -q \${DIR} 2>&1 && builtin eval \${ONPULL} 2>&1); then if ! ERR=\$(builtin cd -q \${DIR} 2>&1 && builtin eval \${ONPULL} 2>&1); then
print_error 'Error during on-pull' \${ERR} print_error 'Error during on-pull' \${ERR}
return 1 return 1
elif [[ \${PRINTLEVEL} -gt 1 && -n \${ERR} ]]; then elif [[ \${PRINTLEVEL} -gt 1 && -n \${ERR} ]]; then
builtin set \${1} \${2:+\${2}$'\n'}\"On-pull output:\"$'\n'\${ERR} builtin set \${1} \${2:+\${2}$'\n'}'On-pull output:'$'\n'\${ERR}
fi fi
fi fi
print_okay \"\${@}\"
} }
case \${ACTION} in case \${ACTION} in
install) install)
if ERR=\$(command git clone \${REV:+-b} \${REV} -q --config core.autocrlf=false \${\${SUBMODULES:#0}:+--recursive} -- \${URL} \${DIR} 2>&1); then if ERR=\$(command git clone \${REV:+-b} \${REV} -q --config core.autocrlf=false \${\${SUBMODULES:#0}:+--recursive} -- \${URL} \${DIR} 2>&1); then
handle Installed on_pull && print_okay Installed
else else
print_error 'Error during git clone' \${ERR} print_error 'Error during git clone' \${ERR}
return 1 return 1
fi fi
;; ;;
update) check|update)
if [[ ! -r \${DIR}/.git ]]; then if [[ ! -r \${DIR}/.git ]]; then
if (( PRINTLEVEL > 0 )); then if (( PRINTLEVEL > 0 )); then
print -u2 -PR $'\E[2K\r'\"%F{yellow}! %B\${MODULE}:%b Module was not installed using git. Will not try to update. Use zmodule option %B-z%b|%B--frozen%b to disable this warning.%f\" print -u2 -PR $'\E[2K\r'\"%F{yellow}! %B\${MODULE}:%b Module was not installed using git. Will not try to \${ACTION}. Use zmodule option %B-z%b|%B--frozen%b to disable this warning.%f\"
fi fi
return 0 return 0
fi fi
if [[ \${URL} != \$(command git -C \${DIR} config --get remote.origin.url) ]]; then if [[ \${URL} != \$(command git -C \${DIR} config --get remote.origin.url) ]]; then
print_error \"URL does not match. Expected \${URL}. Will not try to update.\" print_error \"URL does not match. Expected \${URL}. Will not try to \${ACTION}.\"
return 1 return 1
fi fi
if ! ERR=\$(command git -C \${DIR} fetch -pq origin 2>&1); then if ! ERR=\$(command git -C \${DIR} fetch -pqt origin 2>&1); then
print_error 'Error during git fetch' \${ERR} print_error 'Error during git fetch' \${ERR}
return 1 return 1
fi fi
if [[ \${TYPE} == tag ]]; then if [[ \${TYPE} == branch ]]; then
if [[ \${REV} == \$(command git -C \${DIR} describe --tags --exact-match 2>/dev/null) ]]; then if [[ -z \${REV} ]]; then
handle 'Already up to date'
return \${?}
fi
elif [[ -z \${REV} ]]; then
# Get HEAD remote branch # Get HEAD remote branch
if ! ERR=\$(command git -C \${DIR} remote set-head origin -a 2>&1); then if ! ERR=\$(command git -C \${DIR} remote set-head origin -a 2>&1); then
print_error 'Error during git remote set-head' \${ERR} print_error 'Error during git remote set-head' \${ERR}
@ -779,12 +793,35 @@ case \${ACTION} in
return 1 return 1
fi fi
fi fi
if [[ \${TYPE} == branch ]]; then TO_REV=\${REV}@{u}
LOG_REV=\${REV}@{u} if [[ \${ACTION} == check ]]; then
local -ri behind=\$(command git rev-list --count \${REV}..\${TO_REV} -- 2>/dev/null)
if (( behind )); then
print_okay \"Update available [behind \${behind}]\"
else else
LOG_REV=\${REV} (( PRINTLEVEL-- ))
print_okay 'Already up to date'
fi fi
LOG=\$(command git -C \${DIR} log --graph --color --format='%C(yellow)%h%C(reset) %s %C(cyan)(%cr)%C(reset)' ..\${LOG_REV} -- 2>/dev/null) return 0
fi
else
if [[ \${REV} == \$(command git -C \${DIR} describe --tags --exact-match 2>/dev/null) ]]; then
if [[ \${ACTION} == check ]]; then
(( PRINTLEVEL-- ))
print_okay 'Already up to date'
return 0
else
on_pull && print_okay 'Already up to date'
return \${?}
fi
fi
if [[ \${ACTION} == check ]]; then
print_okay 'Update available'
return 0
fi
TO_REV=\${REV}
fi
LOG=\$(command git -C \${DIR} log --graph --color --format='%C(yellow)%h%C(reset) %s %C(cyan)(%cr)%C(reset)' ..\${TO_REV} -- 2>/dev/null)
if ! ERR=\$(command git -C \${DIR} checkout -q \${REV} -- 2>&1); then if ! ERR=\$(command git -C \${DIR} checkout -q \${REV} -- 2>&1); then
print_error 'Error during git checkout' \${ERR} print_error 'Error during git checkout' \${ERR}
return 1 return 1
@ -805,7 +842,7 @@ case \${ACTION} in
return 1 return 1
fi fi
fi fi
handle \${OUT} \${LOG} on_pull && print_okay \${OUT} \${LOG}
;; ;;
esac esac
" ;; " ;;
@ -817,6 +854,14 @@ esac
zsh -c ${zcmd} ${_ztools[${zname}]} "${_zprintlevel}" "${_zargs_action}" "${zname}" "${_zdirs[${zname}]}" "${_zurls[${zname}]}" "${_ztypes[${zname}]}" "${_zrevs[${zname}]}" "${_zsubmodules[${zname}]}" "${_zonpulls[${zname}]}" zsh -c ${zcmd} ${_ztools[${zname}]} "${_zprintlevel}" "${_zargs_action}" "${zname}" "${_zdirs[${zname}]}" "${_zurls[${zname}]}" "${_ztypes[${zname}]}" "${_zrevs[${zname}]}" "${_zsubmodules[${zname}]}" "${_zonpulls[${zname}]}"
} }
_zimfw_run_tool_action() {
local -r _zargs_action=${1}
zargs -n 1 -P 0 -- "${_znames[@]}" -- _zimfw_run_tool
# Ignore return from zargs with -P. Was missing values before zsh 5.9, and
# it's intermittently failing in zsh 5.9 and macOS. See https://www.zsh.org/mla/workers/2022/msg00611.html
return 0
}
zimfw() { zimfw() {
builtin emulate -L zsh -o EXTENDED_GLOB builtin emulate -L zsh -o EXTENDED_GLOB
local -r _zversion='1.12.0-SNAPSHOT' _zversion_target=${ZIM_HOME}/.latest_version zusage="Usage: %B${0}%b <action> [%B-q%b|%B-v%b] local -r _zversion='1.12.0-SNAPSHOT' _zversion_target=${ZIM_HOME}/.latest_version zusage="Usage: %B${0}%b <action> [%B-q%b|%B-v%b]
@ -836,11 +881,13 @@ Actions:
%Binstall%b Install new modules. Also does %Bbuild%b, %Bcompile%b. Use %B-v%b to also see their %Binstall%b Install new modules. Also does %Bbuild%b, %Bcompile%b. Use %B-v%b to also see their
output, any on-pull output and skipped modules. output, any on-pull output and skipped modules.
%Buninstall%b Delete unused modules. Prompts for confirmation. Use %B-q%b for quiet uninstall. %Buninstall%b Delete unused modules. Prompts for confirmation. Use %B-q%b for quiet uninstall.
%Bcheck%b Check if updates for current modules are available. Use %B-v%b to also see
skipped and up to date modules.
%Bupdate%b Update current modules. Also does %Bbuild%b, %Bcompile%b. Use %B-v%b to also see their %Bupdate%b Update current modules. Also does %Bbuild%b, %Bcompile%b. Use %B-v%b to also see their
output, any on-pull output and skipped modules. output, any on-pull output and skipped modules.
%Bcheck-version%b Check if a new version of zimfw is available.
%Bupgrade%b Upgrade zimfw. Also does %Bcompile%b. Use %B-v%b to also see its output. %Bupgrade%b Upgrade zimfw. Also does %Bcompile%b. Use %B-v%b to also see its output.
%Bversion%b Print zimfw version. %Bversion%b Print zimfw version.
%Bversion-check%b Check if a new version of zimfw is available.
Options: Options:
%B-q%b Quiet (yes to prompts and only outputs errors) %B-q%b Quiet (yes to prompts and only outputs errors)
@ -863,11 +910,10 @@ Options:
esac esac
fi fi
if ! zstyle -t ':zim' disable-version-check && [[ ${1} != version-check ]]; then if ! zstyle -t ':zim' disable-version-check && [[ ${1} != check-version ]]; then
# If .latest_version does not exist or was not modified in the last 30 days # If .latest_version does not exist or was not modified in the last 30 days
[[ -f ${_zversion_target}(#qNm-30) ]]; local -r zversion_check_force=${?} [[ -f ${_zversion_target}(#qNm-30) ]]; local -r zversion_check_force=${?}
_zimfw_version_check ${zversion_check_force} _zimfw_check_version ${zversion_check_force}
print
fi fi
local _zrestartmsg=' Restart your terminal for changes to take effect.' local _zrestartmsg=' Restart your terminal for changes to take effect.'
@ -888,27 +934,33 @@ Options:
_zimfw_source_zimrc 3 && zargs -n 1 -- "${_znames[@]}" -- _zimfw_run_list && \ _zimfw_source_zimrc 3 && zargs -n 1 -- "${_znames[@]}" -- _zimfw_run_list && \
_zimfw_list_unuseds ' (unused)' _zimfw_list_unuseds ' (unused)'
;; ;;
check)
_zrestartmsg=
_zimfw_source_zimrc 3 && _zimfw_run_tool_action ${1} || return 1
(( _zprintlevel-- ))
_zimfw_print -PR "Done with ${1}." # Only printed in verbose mode
;;
init) init)
_zrestartmsg= _zrestartmsg=
_zimfw_install_update install || return 1 _zimfw_source_zimrc 3 && _zimfw_run_tool_action install || return 1
(( _zprintlevel-- )) (( _zprintlevel-- ))
_zimfw_print -PR "Done with install.${_zrestartmsg}" # Only printed in verbose mode _zimfw_print -PR "Done with install." # Only printed in verbose mode
_zimfw_source_zimrc 2 && _zimfw_build && _zimfw_compile _zimfw_build && _zimfw_compile
;; ;;
install|update) install|update)
_zimfw_install_update ${1} || return 1 _zimfw_source_zimrc 3 && _zimfw_run_tool_action ${1} || return 1
_zimfw_print -PR "Done with ${1}.${_zrestartmsg}" _zimfw_print -PR "Done with ${1}.${_zrestartmsg}"
(( _zprintlevel-- )) (( _zprintlevel-- ))
_zimfw_source_zimrc 2 && _zimfw_build && _zimfw_compile _zimfw_build && _zimfw_compile
;; ;;
uninstall) _zimfw_source_zimrc 2 && _zimfw_list_unuseds && _zimfw_uninstall ;; uninstall) _zimfw_source_zimrc 2 && _zimfw_list_unuseds && _zimfw_uninstall ;;
check-version) _zimfw_check_version 1 ;;
upgrade) upgrade)
_zimfw_upgrade || return 1 _zimfw_upgrade || return 1
(( _zprintlevel-- )) (( _zprintlevel-- ))
_zimfw_source_zimrc 2 && _zimfw_compile _zimfw_source_zimrc 2 && _zimfw_compile
;; ;;
version) print -PR ${_zversion} ;; version) print -PR ${_zversion} ;;
version-check) _zimfw_version_check 1 ;;
*) *)
print -u2 -PlR "%F{red}${0}: Unknown action ${1}%f" '' ${zusage} print -u2 -PlR "%F{red}${0}: Unknown action ${1}%f" '' ${zusage}
return 2 return 2