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

Tools run in a subshell

This commit is contained in:
Eric Nielsen 2023-03-31 20:23:01 -05:00
parent 67de6ec25b
commit f93e43e8a5
No known key found for this signature in database
GPG key ID: 678AF5E338C87D99
4 changed files with 209 additions and 217 deletions

View file

@ -1,12 +1,12 @@
_zimfw_pull_print_okay() { _zimfw_pull_print_okay() {
if [[ -n ${zonpull} ]]; then # Useb by tools, which run in a subshell
local zerr if [[ -n ${ONPULL} ]]; then
if ! zerr=$(builtin cd -q ${zdir} 2>&1 && builtin eval ${zonpull} 2>&1); then if ! ERR=$(builtin cd -q ${DIR} 2>&1 && builtin eval ${ONPULL} 2>&1); then
_zimfw_print_error 'Error during on-pull' ${zerr} _zimfw_print_error 'Error during on-pull' ${ERR}
return 1 return 1
elif [[ ${_zprintlevel} -gt 1 && -n ${zerr} ]]; then elif [[ ${_zprintlevel} -gt 1 && -n ${ERR} ]]; then
# Overrides ${3} to include the on-pull output, to be used by _zimfw_print_okay below. # Overrides ${3} to include the on-pull output, to be used by _zimfw_print_okay below.
builtin set ${1} ${2:-0} ${3:+${3}$'\n'}'On-pull output:'$'\n'${zerr} builtin set ${1} ${2:-0} ${3:+${3}$'\n'}'On-pull output:'$'\n'${ERR}
fi fi
fi fi
_zimfw_print_okay "${@}" _zimfw_print_okay "${@}"

View file

@ -1,152 +1,147 @@
_zimfw_download_tarball() { _zimfw_download_tarball() {
local host repo if [[ ${URL} =~ <%= url_regex %> ]]; then
if [[ ${zurl} =~ <%= url_regex %> ]]; then readonly HOST=${match[3]}
host=${match[3]} readonly REPO=${match[4]%.git}
repo=${match[4]%.git}
fi fi
if [[ ${host} != github.com || -z ${repo} ]]; then if [[ ${HOST} != github.com || -z ${REPO} ]]; then
_zimfw_print_error "${zurl} is not a valid GitHub zurl. Will not try to ${_zaction}." _zimfw_print_error "${URL} is not a valid GitHub URL. Will not try to ${_zaction}."
return 1 return 1
fi fi
local -r headers_target=${zdir}/${ztemp}_headers readonly HEADERS_TARGET=${DIR}/${TEMP}_headers
{ {
local info_header header etag zerr if [[ -r ${INFO_TARGET} ]]; then
if [[ -r ${zinfo_target} ]]; then readonly INFO=("${(@f)"$(<${INFO_TARGET})"}")
local -r info=("${(@f)"$(<${zinfo_target})"}") if [[ ${URL} != ${INFO[1]} ]]; then
if [[ ${zurl} != ${info[1]} ]]; then _zimfw_print_error "URL does not match. Expected ${URL}. Will not try to ${_zaction}."
_zimfw_print_error "zurl does not match. Expected ${zurl}. Will not try to ${_zaction}."
return 1 return 1
fi fi
# Previous zrev is in line 2, reserved for future use. # Previous REV is in line 2, reserved for future use.
info_header=${info[3]} readonly INFO_HEADER=${INFO[3]}
fi fi
local -r tarball_url=https://api.github.com/repos/${repo}/tarball/${zrev} readonly TARBALL_URL=https://api.github.com/repos/${REPO}/tarball/${REV}
if [[ ${_zaction} == check ]]; then if [[ ${_zaction} == check ]]; then
if [[ -z ${info_header} ]] return 0 if [[ -z ${INFO_HEADER} ]] return 0
if (( ${+commands[curl]} )); then if (( ${+commands[curl]} )); then
command curl -IfsL -H ${info_header} ${tarball_url} >${headers_target} command curl -IfsL -H ${INFO_HEADER} ${TARBALL_URL} >${HEADERS_TARGET}
else else
command wget --spider -qS --header=${info_header} ${tarball_url} 2>${headers_target} command wget --spider -qS --header=${INFO_HEADER} ${TARBALL_URL} 2>${HEADERS_TARGET}
fi fi
else else
if (( ${+commands[curl]} )); then if (( ${+commands[curl]} )); then
if ! zerr=$(command curl -fsSL ${info_header:+-H} ${info_header} -o ${ztarball_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
_zimfw_print_error "Error downloading ${tarball_url} with curl" ${zerr} _zimfw_print_error "Error downloading ${TARBALL_URL} with curl" ${ERR}
return 1 return 1
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 -qS ${info_header:+--header=${info_header}} -O ${ztarball_target} ${tarball_url} 2>${headers_target} command wget -qS ${INFO_HEADER:+--header=${INFO_HEADER}} -O ${TARBALL_TARGET} ${TARBALL_URL} 2>${HEADERS_TARGET}
fi fi
fi fi
local -i http_code while IFS= read -r HEADER; do
while IFS= read -r header; do HEADER=${${HEADER## ##}%%$'\r'##}
header=${${header## ##}%%$'\r'##} if [[ ${HEADER} == HTTP/* ]]; then
if [[ ${header} == HTTP/* ]]; then HTTP_CODE=${${(s: :)HEADER}[2]}
http_code=${${(s: :)header}[2]} elif [[ ${${(L)HEADER%%:*}%% ##} == etag ]]; then
elif [[ ${${(L)header%%:*}%% ##} == etag ]]; then ETAG=${${HEADER#*:}## ##}
etag=${${header#*:}## ##}
fi fi
done < ${headers_target} done < ${HEADERS_TARGET}
if (( http_code == 304 )); then if (( HTTP_CODE == 304 )); then
# Not Modified # Not Modified
command rm -f ${ztarball_target} 2>/dev/null command rm -f ${TARBALL_TARGET} 2>/dev/null
return 0 return 0
elif (( http_code != 200 )); then elif (( HTTP_CODE != 200 )); then
_zimfw_print_error "Error downloading ${tarball_url}, HTTP code ${http_code}" _zimfw_print_error "Error downloading ${TARBALL_URL}, HTTP code ${HTTP_CODE}"
return 1 return 1
fi fi
if [[ -z ${etag} ]]; then if [[ -z ${ETAG} ]]; then
_zimfw_print_error "Error downloading ${tarball_url}, no ETag header found in response" _zimfw_print_error "Error downloading ${TARBALL_URL}, no ETag header found in response"
return 1 return 1
fi fi
if [[ ${_zaction} == check ]]; then if [[ ${_zaction} == check ]]; then
command touch ${ztarball_target} # Update available command touch ${TARBALL_TARGET} # Update available
else else
if ! print -lR "${zurl}" "${zrev}" "If-None-Match: ${etag}" >! ${zinfo_target} 2>/dev/null; then if ! print -lR "${URL}" "${REV}" "If-None-Match: ${ETAG}" >! ${INFO_TARGET} 2>/dev/null; then
_zimfw_print_error "Error creating or updating ${zinfo_target}" _zimfw_print_error "Error creating or updating ${INFO_TARGET}"
return 1 return 1
fi fi
fi fi
} always { } always {
command rm -f ${headers_target} 2>/dev/null command rm -f ${HEADERS_TARGET} 2>/dev/null
} }
} }
_zimfw_untar_tarball() { _zimfw_untar_tarball() {
local zerr if ! ERR=$(command tar -C ${1} --strip=1 -xzf ${TARBALL_TARGET} 2>&1); then
if ! zerr=$(command tar -C ${1} --strip=1 -xzf ${ztarball_target} 2>&1); then _zimfw_print_error "Error extracting ${TARBALL_TARGET}" ${ERR}
_zimfw_print_error "Error extracting ${ztarball_target}" ${zerr}
return 1 return 1
fi fi
} }
_zimfw_create_dir() { _zimfw_create_dir() {
local zerr if ! ERR=$(command mkdir -p ${1} 2>&1); then
if ! zerr=$(command mkdir -p ${1} 2>&1); then _zimfw_print_error "Error creating ${1}" ${ERR}
_zimfw_print_error "Error creating ${1}" ${zerr}
return 1 return 1
fi fi
} }
_zimfw_tool_degit() { _zimfw_tool_degit() {
local -ri zsubmodules=${5} # This runs in a subshell
local -r zdir=${1} zurl=${2} zrev=${4} zonpull=${6} ztemp=.zdegit_${sysparams[pid]} readonly -i SUBMODULES=${5}
local -r ztarball_target=${zdir}/${ztemp}_tarball.tar.gz zinfo_target=${zdir}/.zdegit readonly DIR=${1} URL=${2} REV=${4} ONPULL=${6} TEMP=.zdegit_${sysparams[pid]}
readonly TARBALL_TARGET=${DIR}/${TEMP}_tarball.tar.gz INFO_TARGET=${DIR}/.zdegit
case ${_zaction} in case ${_zaction} in
install) install)
{ {
_zimfw_create_dir ${zdir} && _zimfw_download_tarball && _zimfw_untar_tarball ${zdir} && _zimfw_pull_print_okay Installed || return 1 _zimfw_create_dir ${DIR} && _zimfw_download_tarball && _zimfw_untar_tarball ${DIR} && _zimfw_pull_print_okay Installed || return 1
} 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 = ? ))
command rm -f ${ztarball_target} 2>/dev/null command rm -f ${TARBALL_TARGET} 2>/dev/null
if (( TRY_BLOCK_ERROR )) command rm -rf ${zdir} 2>/dev/null if (( TRY_BLOCK_ERROR )) command rm -rf ${DIR} 2>/dev/null
} }
;; ;;
check|update) check|update)
if [[ ! -r ${zinfo_target} ]]; then if [[ ! -r ${INFO_TARGET} ]]; then
if (( _zprintlevel > 0 )); then if (( _zprintlevel > 0 )); then
print -u2 -PR <%= clear_line %>"%F{yellow}<%= warn %>%B${_zname}:%b Module was not installed using Zim's degit. Will not try to ${_zaction}. Use zmodule option %B-z%b|%B--frozen%b to disable this warning.%f" print -u2 -PR <%= clear_line %>"%F{yellow}<%= warn %>%B${_zname}:%b Module was not installed using Zim's degit. Will not try to ${_zaction}. Use zmodule option %B-z%b|%B--frozen%b to disable this warning.%f"
fi fi
return 0 return 0
fi fi
readonly zdir_new=${zdir}${ztemp} readonly DIR_NEW=${DIR}${TEMP}
{ {
local zerr zlog
_zimfw_download_tarball || return 1 _zimfw_download_tarball || return 1
if [[ ${_zaction} == check ]]; then if [[ ${_zaction} == check ]]; then
if [[ -e ${ztarball_target} ]]; then if [[ -e ${TARBALL_TARGET} ]]; then
_zimfw_print_okay 'Update available' _zimfw_print_okay 'Update available'
return 4 return 4
fi fi
_zimfw_print_okay 'Already up to date' 1 _zimfw_print_okay 'Already up to date' 1
return 0 return 0
else else
if [[ -e ${ztarball_target} ]]; then if [[ -e ${TARBALL_TARGET} ]]; then
_zimfw_create_dir ${zdir_new} && _zimfw_untar_tarball ${zdir_new} || return 1 _zimfw_create_dir ${DIR_NEW} && _zimfw_untar_tarball ${DIR_NEW} || return 1
if (( ${+commands[diff]} )); then if (( ${+commands[diff]} )); then
zlog=$(command diff -x '.zdegit*' -x '*.zwc' -x '*.zwc.old' -qr ${zdir} ${zdir_new} 2>/dev/null) LOG=$(command diff -x '.zdegit*' -x '*.zwc' -x '*.zwc.old' -qr ${DIR} ${DIR_NEW} 2>/dev/null)
zlog=${${zlog//${zdir_new}/new}//${zdir}/old} LOG=${${LOG//${DIR_NEW}/new}//${DIR}/old}
fi fi
if ! zerr=$({ command cp -f ${zinfo_target} ${zdir_new} && \ if ! ERR=$({ command cp -f ${INFO_TARGET} ${DIR_NEW} && \
command rm -rf ${zdir} && command mv -f ${zdir_new} ${zdir} } 2>&1); then command rm -rf ${DIR} && command mv -f ${DIR_NEW} ${DIR} } 2>&1); then
_zimfw_print_error "Error updating ${zdir}" ${zerr} _zimfw_print_error "Error updating ${DIR}" ${ERR}
return 1 return 1
fi fi
_zimfw_pull_print_okay Updated 0 ${zlog} || return 1 _zimfw_pull_print_okay Updated 0 ${LOG} || return 1
else else
_zimfw_pull_print_okay 'Already up to date' || return 1 _zimfw_pull_print_okay 'Already up to date' || return 1
fi fi
fi fi
} always { } always {
command rm -f ${ztarball_target} 2>/dev/null command rm -f ${TARBALL_TARGET} 2>/dev/null
command rm -rf ${zdir_new} 2>/dev/null command rm -rf ${DIR_NEW} 2>/dev/null
} }
;; ;;
esac esac
# Check after successful install or update # Check after successful install or update
if [[ ${_zprintlevel} -gt 0 && ${zsubmodules} -ne 0 && -e ${zdir}/.gitmodules ]]; then if [[ ${_zprintlevel} -gt 0 && ${SUBMODULES} -ne 0 && -e ${DIR}/.gitmodules ]]; then
print -u2 -PR <%= clear_line %>"%F{yellow}<%= warn %>%B${_zname}:%b Module contains git submodules, which are not supported by Zim's degit. Use zmodule option %B--no-submodules%b to disable this warning.%f" print -u2 -PR <%= clear_line %>"%F{yellow}<%= warn %>%B${_zname}:%b Module contains git submodules, which are not supported by Zim's degit. Use zmodule option %B--no-submodules%b to disable this warning.%f"
fi fi
} }

View file

@ -1,50 +1,51 @@
_zimfw_tool_git() { _zimfw_tool_git() {
local -ri zsubmodules=${5} # This runs in a subshell
local -r zdir=${1} zurl=${2} ztype=${3} zonpull=${6} readonly -i SUBMODULES=${5}
local zrev=${4} ztorev zerr zout zlog readonly DIR=${1} URL=${2} TYPE=${3} ONPULL=${6}
REV=${4}
case ${_zaction} in case ${_zaction} in
install) install)
if zerr=$(command git clone ${zrev:+-b} ${zrev} -q --config core.autocrlf=false ${${zsubmodules:#0}:+--recursive} -- ${zurl} ${zdir} 2>&1); then if ERR=$(command git clone ${REV:+-b} ${REV} -q --config core.autocrlf=false ${${SUBMODULES:#0}:+--recursive} -- ${URL} ${DIR} 2>&1); then
_zimfw_pull_print_okay Installed _zimfw_pull_print_okay Installed
else else
_zimfw_print_error 'Error during git clone' ${zerr} _zimfw_print_error 'Error during git clone' ${ERR}
return 1 return 1
fi fi
;; ;;
check|update) check|update)
if [[ ! -r ${zdir}/.git ]]; then if [[ ! -r ${DIR}/.git ]]; then
if (( _zprintlevel > 0 )); then if (( _zprintlevel > 0 )); then
print -u2 -PR <%= clear_line %>"%F{yellow}<%= warn %>%B${_zname}:%b Module was not installed using git. Will not try to ${_zaction}. Use zmodule option %B-z%b|%B--frozen%b to disable this warning.%f" print -u2 -PR <%= clear_line %>"%F{yellow}<%= warn %>%B${_zname}:%b Module was not installed using git. Will not try to ${_zaction}. Use zmodule option %B-z%b|%B--frozen%b to disable this warning.%f"
fi fi
return 0 return 0
fi fi
if [[ ${zurl} != $(command git -C ${zdir} config --get remote.origin.url) ]]; then if [[ ${URL} != $(command git -C ${DIR} config --get remote.origin.url) ]]; then
_zimfw_print_error "zurl does not match. Expected ${zurl}. Will not try to ${_zaction}." _zimfw_print_error "URL does not match. Expected ${URL}. Will not try to ${_zaction}."
return 1 return 1
fi fi
if ! zerr=$(command git -C ${zdir} fetch -pqt origin 2>&1); then if ! ERR=$(command git -C ${DIR} fetch -pqt origin 2>&1); then
_zimfw_print_error 'Error during git fetch' ${zerr} _zimfw_print_error 'Error during git fetch' ${ERR}
return 1 return 1
fi fi
if [[ ${ztype} == branch ]]; then if [[ ${TYPE} == branch ]]; then
if [[ -z ${zrev} ]]; then if [[ -z ${REV} ]]; then
# Get HEAD remote branch # Get HEAD remote branch
if ! zerr=$(command git -C ${zdir} remote set-head origin -a 2>&1); then if ! ERR=$(command git -C ${DIR} remote set-head origin -a 2>&1); then
_zimfw_print_error 'Error during git remote set-head' ${zerr} _zimfw_print_error 'Error during git remote set-head' ${ERR}
return 1 return 1
fi fi
if zrev=$(command git -C ${zdir} symbolic-ref --short refs/remotes/origin/HEAD 2>&1); then if REV=$(command git -C ${DIR} symbolic-ref --short refs/remotes/origin/HEAD 2>&1); then
zrev=${zrev#origin/} REV=${REV#origin/}
else else
_zimfw_print_error 'Error during git symbolic-ref' ${zrev} _zimfw_print_error 'Error during git symbolic-ref' ${REV}
return 1 return 1
fi fi
fi fi
ztorev=${zrev}@{u} TO_REV=${REV}@{u}
if [[ ${_zaction} == check ]]; then if [[ ${_zaction} == check ]]; then
local -ri behind=$(command git -C ${zdir} rev-list --count ${zrev}..${ztorev} -- 2>/dev/null) readonly -i BEHIND=$(command git -C ${DIR} rev-list --count ${REV}..${TO_REV} -- 2>/dev/null)
if (( behind )); then if (( BEHIND )); then
_zimfw_print_okay "Update available [behind ${behind}]" _zimfw_print_okay "Update available [behind ${BEHIND}]"
return 4 return 4
else else
_zimfw_print_okay 'Already up to date' 1 _zimfw_print_okay 'Already up to date' 1
@ -52,7 +53,7 @@ _zimfw_tool_git() {
fi fi
fi fi
else else
if [[ ${zrev} == $(command git -C ${zdir} describe --tags --exact-match 2>/dev/null) ]]; then if [[ ${REV} == $(command git -C ${DIR} describe --tags --exact-match 2>/dev/null) ]]; then
if [[ ${_zaction} == check ]]; then if [[ ${_zaction} == check ]]; then
_zimfw_print_okay 'Already up to date' 1 _zimfw_print_okay 'Already up to date' 1
return 0 return 0
@ -65,30 +66,30 @@ _zimfw_tool_git() {
_zimfw_print_okay 'Update available' _zimfw_print_okay 'Update available'
return 4 return 4
fi fi
ztorev=${zrev} TO_REV=${REV}
fi fi
zlog=$(command git -C ${zdir} log --graph --color --format='%C(yellow)%h%C(reset) %s %C(cyan)(%cr)%C(reset)' ..${ztorev} -- 2>/dev/null) 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 ! zerr=$(command git -C ${zdir} checkout -q ${zrev} -- 2>&1); then if ! ERR=$(command git -C ${DIR} checkout -q ${REV} -- 2>&1); then
_zimfw_print_error 'Error during git checkout' ${zerr} _zimfw_print_error 'Error during git checkout' ${ERR}
return 1 return 1
fi fi
if [[ ${ztype} == branch ]]; then if [[ ${TYPE} == branch ]]; then
if ! zout=$(command git -C ${zdir} merge --ff-only --no-progress -n 2>&1); then if ! OUT=$(command git -C ${DIR} merge --ff-only --no-progress -n 2>&1); then
_zimfw_print_error 'Error during git merge' ${zout} _zimfw_print_error 'Error during git merge' ${OUT}
return 1 return 1
fi fi
# keep just first line of zout # keep just first line of OUT
zout=${zout%%($'\n'|$'\r')*} OUT=${OUT%%($'\n'|$'\r')*}
else else
zout="Updating to ${ztype} ${zrev}" OUT="Updating to ${TYPE} ${REV}"
fi fi
if (( zsubmodules )); then if (( SUBMODULES )); then
if ! zerr=$(command git -C ${zdir} submodule update --init --recursive -q -- 2>&1); then if ! ERR=$(command git -C ${DIR} submodule update --init --recursive -q -- 2>&1); then
_zimfw_print_error 'Error during git submodule update' ${zerr} _zimfw_print_error 'Error during git submodule update' ${ERR}
return 1 return 1
fi fi
fi fi
_zimfw_pull_print_okay ${zout} 0 ${zlog} _zimfw_pull_print_okay ${OUT} 0 ${LOG}
;; ;;
esac esac
} }

214
zimfw.zsh
View file

@ -433,7 +433,7 @@ _zimfw_compile() {
} }
_zimfw_info() { _zimfw_info() {
print -R 'zimfw version: '${_zversion}' (built at 2023-03-30 13:32:54 UTC, previous commit is ee93f79)' print -R 'zimfw version: '${_zversion}' (built at 2023-04-01 01:32:16 UTC, previous commit is 5db1155)'
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}
@ -527,219 +527,215 @@ _zimfw_print_okay() {
} }
_zimfw_pull_print_okay() { _zimfw_pull_print_okay() {
if [[ -n ${zonpull} ]]; then # Useb by tools, which run in a subshell
local zerr if [[ -n ${ONPULL} ]]; then
if ! zerr=$(builtin cd -q ${zdir} 2>&1 && builtin eval ${zonpull} 2>&1); then if ! ERR=$(builtin cd -q ${DIR} 2>&1 && builtin eval ${ONPULL} 2>&1); then
_zimfw_print_error 'Error during on-pull' ${zerr} _zimfw_print_error 'Error during on-pull' ${ERR}
return 1 return 1
elif [[ ${_zprintlevel} -gt 1 && -n ${zerr} ]]; then elif [[ ${_zprintlevel} -gt 1 && -n ${ERR} ]]; then
# Overrides ${3} to include the on-pull output, to be used by _zimfw_print_okay below. # Overrides ${3} to include the on-pull output, to be used by _zimfw_print_okay below.
builtin set ${1} ${2:-0} ${3:+${3}$'\n'}'On-pull output:'$'\n'${zerr} builtin set ${1} ${2:-0} ${3:+${3}$'\n'}'On-pull output:'$'\n'${ERR}
fi fi
fi fi
_zimfw_print_okay "${@}" _zimfw_print_okay "${@}"
} }
_zimfw_download_tarball() { _zimfw_download_tarball() {
local host repo if [[ ${URL} =~ ^([^:@/]+://)?([^@]+@)?([^:/]+)[:/]([^/]+/[^/]+)/?$ ]]; then
if [[ ${zurl} =~ ^([^:@/]+://)?([^@]+@)?([^:/]+)[:/]([^/]+/[^/]+)/?$ ]]; then readonly HOST=${match[3]}
host=${match[3]} readonly REPO=${match[4]%.git}
repo=${match[4]%.git}
fi fi
if [[ ${host} != github.com || -z ${repo} ]]; then if [[ ${HOST} != github.com || -z ${REPO} ]]; then
_zimfw_print_error "${zurl} is not a valid GitHub zurl. Will not try to ${_zaction}." _zimfw_print_error "${URL} is not a valid GitHub URL. Will not try to ${_zaction}."
return 1 return 1
fi fi
local -r headers_target=${zdir}/${ztemp}_headers readonly HEADERS_TARGET=${DIR}/${TEMP}_headers
{ {
local info_header header etag zerr if [[ -r ${INFO_TARGET} ]]; then
if [[ -r ${zinfo_target} ]]; then readonly INFO=("${(@f)"$(<${INFO_TARGET})"}")
local -r info=("${(@f)"$(<${zinfo_target})"}") if [[ ${URL} != ${INFO[1]} ]]; then
if [[ ${zurl} != ${info[1]} ]]; then _zimfw_print_error "URL does not match. Expected ${URL}. Will not try to ${_zaction}."
_zimfw_print_error "zurl does not match. Expected ${zurl}. Will not try to ${_zaction}."
return 1 return 1
fi fi
# Previous zrev is in line 2, reserved for future use. # Previous REV is in line 2, reserved for future use.
info_header=${info[3]} readonly INFO_HEADER=${INFO[3]}
fi fi
local -r tarball_url=https://api.github.com/repos/${repo}/tarball/${zrev} readonly TARBALL_URL=https://api.github.com/repos/${REPO}/tarball/${REV}
if [[ ${_zaction} == check ]]; then if [[ ${_zaction} == check ]]; then
if [[ -z ${info_header} ]] return 0 if [[ -z ${INFO_HEADER} ]] return 0
if (( ${+commands[curl]} )); then if (( ${+commands[curl]} )); then
command curl -IfsL -H ${info_header} ${tarball_url} >${headers_target} command curl -IfsL -H ${INFO_HEADER} ${TARBALL_URL} >${HEADERS_TARGET}
else else
command wget --spider -qS --header=${info_header} ${tarball_url} 2>${headers_target} command wget --spider -qS --header=${INFO_HEADER} ${TARBALL_URL} 2>${HEADERS_TARGET}
fi fi
else else
if (( ${+commands[curl]} )); then if (( ${+commands[curl]} )); then
if ! zerr=$(command curl -fsSL ${info_header:+-H} ${info_header} -o ${ztarball_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
_zimfw_print_error "Error downloading ${tarball_url} with curl" ${zerr} _zimfw_print_error "Error downloading ${TARBALL_URL} with curl" ${ERR}
return 1 return 1
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 -qS ${info_header:+--header=${info_header}} -O ${ztarball_target} ${tarball_url} 2>${headers_target} command wget -qS ${INFO_HEADER:+--header=${INFO_HEADER}} -O ${TARBALL_TARGET} ${TARBALL_URL} 2>${HEADERS_TARGET}
fi fi
fi fi
local -i http_code while IFS= read -r HEADER; do
while IFS= read -r header; do HEADER=${${HEADER## ##}%%$'\r'##}
header=${${header## ##}%%$'\r'##} if [[ ${HEADER} == HTTP/* ]]; then
if [[ ${header} == HTTP/* ]]; then HTTP_CODE=${${(s: :)HEADER}[2]}
http_code=${${(s: :)header}[2]} elif [[ ${${(L)HEADER%%:*}%% ##} == etag ]]; then
elif [[ ${${(L)header%%:*}%% ##} == etag ]]; then ETAG=${${HEADER#*:}## ##}
etag=${${header#*:}## ##}
fi fi
done < ${headers_target} done < ${HEADERS_TARGET}
if (( http_code == 304 )); then if (( HTTP_CODE == 304 )); then
# Not Modified # Not Modified
command rm -f ${ztarball_target} 2>/dev/null command rm -f ${TARBALL_TARGET} 2>/dev/null
return 0 return 0
elif (( http_code != 200 )); then elif (( HTTP_CODE != 200 )); then
_zimfw_print_error "Error downloading ${tarball_url}, HTTP code ${http_code}" _zimfw_print_error "Error downloading ${TARBALL_URL}, HTTP code ${HTTP_CODE}"
return 1 return 1
fi fi
if [[ -z ${etag} ]]; then if [[ -z ${ETAG} ]]; then
_zimfw_print_error "Error downloading ${tarball_url}, no ETag header found in response" _zimfw_print_error "Error downloading ${TARBALL_URL}, no ETag header found in response"
return 1 return 1
fi fi
if [[ ${_zaction} == check ]]; then if [[ ${_zaction} == check ]]; then
command touch ${ztarball_target} # Update available command touch ${TARBALL_TARGET} # Update available
else else
if ! print -lR "${zurl}" "${zrev}" "If-None-Match: ${etag}" >! ${zinfo_target} 2>/dev/null; then if ! print -lR "${URL}" "${REV}" "If-None-Match: ${ETAG}" >! ${INFO_TARGET} 2>/dev/null; then
_zimfw_print_error "Error creating or updating ${zinfo_target}" _zimfw_print_error "Error creating or updating ${INFO_TARGET}"
return 1 return 1
fi fi
fi fi
} always { } always {
command rm -f ${headers_target} 2>/dev/null command rm -f ${HEADERS_TARGET} 2>/dev/null
} }
} }
_zimfw_untar_tarball() { _zimfw_untar_tarball() {
local zerr if ! ERR=$(command tar -C ${1} --strip=1 -xzf ${TARBALL_TARGET} 2>&1); then
if ! zerr=$(command tar -C ${1} --strip=1 -xzf ${ztarball_target} 2>&1); then _zimfw_print_error "Error extracting ${TARBALL_TARGET}" ${ERR}
_zimfw_print_error "Error extracting ${ztarball_target}" ${zerr}
return 1 return 1
fi fi
} }
_zimfw_create_dir() { _zimfw_create_dir() {
local zerr if ! ERR=$(command mkdir -p ${1} 2>&1); then
if ! zerr=$(command mkdir -p ${1} 2>&1); then _zimfw_print_error "Error creating ${1}" ${ERR}
_zimfw_print_error "Error creating ${1}" ${zerr}
return 1 return 1
fi fi
} }
_zimfw_tool_degit() { _zimfw_tool_degit() {
local -ri zsubmodules=${5} # This runs in a subshell
local -r zdir=${1} zurl=${2} zrev=${4} zonpull=${6} ztemp=.zdegit_${sysparams[pid]} readonly -i SUBMODULES=${5}
local -r ztarball_target=${zdir}/${ztemp}_tarball.tar.gz zinfo_target=${zdir}/.zdegit readonly DIR=${1} URL=${2} REV=${4} ONPULL=${6} TEMP=.zdegit_${sysparams[pid]}
readonly TARBALL_TARGET=${DIR}/${TEMP}_tarball.tar.gz INFO_TARGET=${DIR}/.zdegit
case ${_zaction} in case ${_zaction} in
install) install)
{ {
_zimfw_create_dir ${zdir} && _zimfw_download_tarball && _zimfw_untar_tarball ${zdir} && _zimfw_pull_print_okay Installed || return 1 _zimfw_create_dir ${DIR} && _zimfw_download_tarball && _zimfw_untar_tarball ${DIR} && _zimfw_pull_print_okay Installed || return 1
} 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 = ? ))
command rm -f ${ztarball_target} 2>/dev/null command rm -f ${TARBALL_TARGET} 2>/dev/null
if (( TRY_BLOCK_ERROR )) command rm -rf ${zdir} 2>/dev/null if (( TRY_BLOCK_ERROR )) command rm -rf ${DIR} 2>/dev/null
} }
;; ;;
check|update) check|update)
if [[ ! -r ${zinfo_target} ]]; then if [[ ! -r ${INFO_TARGET} ]]; then
if (( _zprintlevel > 0 )); then if (( _zprintlevel > 0 )); then
print -u2 -PR $'\E[2K\r'"%F{yellow}! %B${_zname}:%b Module was not installed using Zim's degit. Will not try to ${_zaction}. Use zmodule option %B-z%b|%B--frozen%b to disable this warning.%f" print -u2 -PR $'\E[2K\r'"%F{yellow}! %B${_zname}:%b Module was not installed using Zim's degit. Will not try to ${_zaction}. Use zmodule option %B-z%b|%B--frozen%b to disable this warning.%f"
fi fi
return 0 return 0
fi fi
readonly zdir_new=${zdir}${ztemp} readonly DIR_NEW=${DIR}${TEMP}
{ {
local zerr zlog
_zimfw_download_tarball || return 1 _zimfw_download_tarball || return 1
if [[ ${_zaction} == check ]]; then if [[ ${_zaction} == check ]]; then
if [[ -e ${ztarball_target} ]]; then if [[ -e ${TARBALL_TARGET} ]]; then
_zimfw_print_okay 'Update available' _zimfw_print_okay 'Update available'
return 4 return 4
fi fi
_zimfw_print_okay 'Already up to date' 1 _zimfw_print_okay 'Already up to date' 1
return 0 return 0
else else
if [[ -e ${ztarball_target} ]]; then if [[ -e ${TARBALL_TARGET} ]]; then
_zimfw_create_dir ${zdir_new} && _zimfw_untar_tarball ${zdir_new} || return 1 _zimfw_create_dir ${DIR_NEW} && _zimfw_untar_tarball ${DIR_NEW} || return 1
if (( ${+commands[diff]} )); then if (( ${+commands[diff]} )); then
zlog=$(command diff -x '.zdegit*' -x '*.zwc' -x '*.zwc.old' -qr ${zdir} ${zdir_new} 2>/dev/null) LOG=$(command diff -x '.zdegit*' -x '*.zwc' -x '*.zwc.old' -qr ${DIR} ${DIR_NEW} 2>/dev/null)
zlog=${${zlog//${zdir_new}/new}//${zdir}/old} LOG=${${LOG//${DIR_NEW}/new}//${DIR}/old}
fi fi
if ! zerr=$({ command cp -f ${zinfo_target} ${zdir_new} && \ if ! ERR=$({ command cp -f ${INFO_TARGET} ${DIR_NEW} && \
command rm -rf ${zdir} && command mv -f ${zdir_new} ${zdir} } 2>&1); then command rm -rf ${DIR} && command mv -f ${DIR_NEW} ${DIR} } 2>&1); then
_zimfw_print_error "Error updating ${zdir}" ${zerr} _zimfw_print_error "Error updating ${DIR}" ${ERR}
return 1 return 1
fi fi
_zimfw_pull_print_okay Updated 0 ${zlog} || return 1 _zimfw_pull_print_okay Updated 0 ${LOG} || return 1
else else
_zimfw_pull_print_okay 'Already up to date' || return 1 _zimfw_pull_print_okay 'Already up to date' || return 1
fi fi
fi fi
} always { } always {
command rm -f ${ztarball_target} 2>/dev/null command rm -f ${TARBALL_TARGET} 2>/dev/null
command rm -rf ${zdir_new} 2>/dev/null command rm -rf ${DIR_NEW} 2>/dev/null
} }
;; ;;
esac esac
# Check after successful install or update # Check after successful install or update
if [[ ${_zprintlevel} -gt 0 && ${zsubmodules} -ne 0 && -e ${zdir}/.gitmodules ]]; then if [[ ${_zprintlevel} -gt 0 && ${SUBMODULES} -ne 0 && -e ${DIR}/.gitmodules ]]; then
print -u2 -PR $'\E[2K\r'"%F{yellow}! %B${_zname}:%b Module contains git submodules, which are not supported by Zim's degit. Use zmodule option %B--no-submodules%b to disable this warning.%f" print -u2 -PR $'\E[2K\r'"%F{yellow}! %B${_zname}:%b Module contains git submodules, which are not supported by Zim's degit. Use zmodule option %B--no-submodules%b to disable this warning.%f"
fi fi
} }
_zimfw_tool_git() { _zimfw_tool_git() {
local -ri zsubmodules=${5} # This runs in a subshell
local -r zdir=${1} zurl=${2} ztype=${3} zonpull=${6} readonly -i SUBMODULES=${5}
local zrev=${4} ztorev zerr zout zlog readonly DIR=${1} URL=${2} TYPE=${3} ONPULL=${6}
REV=${4}
case ${_zaction} in case ${_zaction} in
install) install)
if zerr=$(command git clone ${zrev:+-b} ${zrev} -q --config core.autocrlf=false ${${zsubmodules:#0}:+--recursive} -- ${zurl} ${zdir} 2>&1); then if ERR=$(command git clone ${REV:+-b} ${REV} -q --config core.autocrlf=false ${${SUBMODULES:#0}:+--recursive} -- ${URL} ${DIR} 2>&1); then
_zimfw_pull_print_okay Installed _zimfw_pull_print_okay Installed
else else
_zimfw_print_error 'Error during git clone' ${zerr} _zimfw_print_error 'Error during git clone' ${ERR}
return 1 return 1
fi fi
;; ;;
check|update) check|update)
if [[ ! -r ${zdir}/.git ]]; then if [[ ! -r ${DIR}/.git ]]; then
if (( _zprintlevel > 0 )); then if (( _zprintlevel > 0 )); then
print -u2 -PR $'\E[2K\r'"%F{yellow}! %B${_zname}:%b Module was not installed using git. Will not try to ${_zaction}. Use zmodule option %B-z%b|%B--frozen%b to disable this warning.%f" print -u2 -PR $'\E[2K\r'"%F{yellow}! %B${_zname}:%b Module was not installed using git. Will not try to ${_zaction}. Use zmodule option %B-z%b|%B--frozen%b to disable this warning.%f"
fi fi
return 0 return 0
fi fi
if [[ ${zurl} != $(command git -C ${zdir} config --get remote.origin.url) ]]; then if [[ ${URL} != $(command git -C ${DIR} config --get remote.origin.url) ]]; then
_zimfw_print_error "zurl does not match. Expected ${zurl}. Will not try to ${_zaction}." _zimfw_print_error "URL does not match. Expected ${URL}. Will not try to ${_zaction}."
return 1 return 1
fi fi
if ! zerr=$(command git -C ${zdir} fetch -pqt origin 2>&1); then if ! ERR=$(command git -C ${DIR} fetch -pqt origin 2>&1); then
_zimfw_print_error 'Error during git fetch' ${zerr} _zimfw_print_error 'Error during git fetch' ${ERR}
return 1 return 1
fi fi
if [[ ${ztype} == branch ]]; then if [[ ${TYPE} == branch ]]; then
if [[ -z ${zrev} ]]; then if [[ -z ${REV} ]]; then
# Get HEAD remote branch # Get HEAD remote branch
if ! zerr=$(command git -C ${zdir} remote set-head origin -a 2>&1); then if ! ERR=$(command git -C ${DIR} remote set-head origin -a 2>&1); then
_zimfw_print_error 'Error during git remote set-head' ${zerr} _zimfw_print_error 'Error during git remote set-head' ${ERR}
return 1 return 1
fi fi
if zrev=$(command git -C ${zdir} symbolic-ref --short refs/remotes/origin/HEAD 2>&1); then if REV=$(command git -C ${DIR} symbolic-ref --short refs/remotes/origin/HEAD 2>&1); then
zrev=${zrev#origin/} REV=${REV#origin/}
else else
_zimfw_print_error 'Error during git symbolic-ref' ${zrev} _zimfw_print_error 'Error during git symbolic-ref' ${REV}
return 1 return 1
fi fi
fi fi
ztorev=${zrev}@{u} TO_REV=${REV}@{u}
if [[ ${_zaction} == check ]]; then if [[ ${_zaction} == check ]]; then
local -ri behind=$(command git -C ${zdir} rev-list --count ${zrev}..${ztorev} -- 2>/dev/null) readonly -i BEHIND=$(command git -C ${DIR} rev-list --count ${REV}..${TO_REV} -- 2>/dev/null)
if (( behind )); then if (( BEHIND )); then
_zimfw_print_okay "Update available [behind ${behind}]" _zimfw_print_okay "Update available [behind ${BEHIND}]"
return 4 return 4
else else
_zimfw_print_okay 'Already up to date' 1 _zimfw_print_okay 'Already up to date' 1
@ -747,7 +743,7 @@ _zimfw_tool_git() {
fi fi
fi fi
else else
if [[ ${zrev} == $(command git -C ${zdir} describe --tags --exact-match 2>/dev/null) ]]; then if [[ ${REV} == $(command git -C ${DIR} describe --tags --exact-match 2>/dev/null) ]]; then
if [[ ${_zaction} == check ]]; then if [[ ${_zaction} == check ]]; then
_zimfw_print_okay 'Already up to date' 1 _zimfw_print_okay 'Already up to date' 1
return 0 return 0
@ -760,30 +756,30 @@ _zimfw_tool_git() {
_zimfw_print_okay 'Update available' _zimfw_print_okay 'Update available'
return 4 return 4
fi fi
ztorev=${zrev} TO_REV=${REV}
fi fi
zlog=$(command git -C ${zdir} log --graph --color --format='%C(yellow)%h%C(reset) %s %C(cyan)(%cr)%C(reset)' ..${ztorev} -- 2>/dev/null) 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 ! zerr=$(command git -C ${zdir} checkout -q ${zrev} -- 2>&1); then if ! ERR=$(command git -C ${DIR} checkout -q ${REV} -- 2>&1); then
_zimfw_print_error 'Error during git checkout' ${zerr} _zimfw_print_error 'Error during git checkout' ${ERR}
return 1 return 1
fi fi
if [[ ${ztype} == branch ]]; then if [[ ${TYPE} == branch ]]; then
if ! zout=$(command git -C ${zdir} merge --ff-only --no-progress -n 2>&1); then if ! OUT=$(command git -C ${DIR} merge --ff-only --no-progress -n 2>&1); then
_zimfw_print_error 'Error during git merge' ${zout} _zimfw_print_error 'Error during git merge' ${OUT}
return 1 return 1
fi fi
# keep just first line of zout # keep just first line of OUT
zout=${zout%%($'\n'|$'\r')*} OUT=${OUT%%($'\n'|$'\r')*}
else else
zout="Updating to ${ztype} ${zrev}" OUT="Updating to ${TYPE} ${REV}"
fi fi
if (( zsubmodules )); then if (( SUBMODULES )); then
if ! zerr=$(command git -C ${zdir} submodule update --init --recursive -q -- 2>&1); then if ! ERR=$(command git -C ${DIR} submodule update --init --recursive -q -- 2>&1); then
_zimfw_print_error 'Error during git submodule update' ${zerr} _zimfw_print_error 'Error during git submodule update' ${ERR}
return 1 return 1
fi fi
fi fi
_zimfw_pull_print_okay ${zout} 0 ${zlog} _zimfw_pull_print_okay ${OUT} 0 ${LOG}
;; ;;
esac esac
} }