Skip to content

Commit

Permalink
patched in json parsing so direnv_watches works again for now
Browse files Browse the repository at this point in the history
  • Loading branch information
mawwwrk committed Jun 16, 2022
1 parent 42476d2 commit 80f8233
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 43 deletions.
51 changes: 8 additions & 43 deletions fn/-z4h-direnv-hook
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
#!/usr/bin/env zsh

eval "$_z4h_opt"

unset _z4h_direnv_err
Expand All @@ -23,54 +22,20 @@ if (( $#envrc )); then
${XDG_CONFIG_HOME:-~/.config}/{,direnv/}{direnv.toml,config.toml,direnvrc})
fi

setopt localoptions extendedglob
local -a elements
elements=( "${=${unpacked:1:-1}//,\{/ {}" )

for obj in $elements[@]; do
(){
local field
local -A found
data=${${obj//$'\r'}##[[:space:]]#}

[[ $data == '{'* ]] || return
data[1]=
while true; do
data=${data##[[:space:]]#}
[[ -n $data ]] || return
case $data[1] in
':') local tail=${data##([^,\\]|\\?)#}
local s=${data:1:-$#tail}
data=$tail
if [[ $field == (Path|Modtime) ]]; then
(( ! $+found[$field] )) || return
[[ -n $s ]] || return
[[ $s != *($'\n'|'\')* ]] || return
found[$field]=${(Q)s}
[[ ${(k)found} == 'Path' ]] && break
# (( $#found == 2 )) && break
fi
;;
',') data[1]=; field=;;
'"') local tail=${data##\"([^\"\\]|\\?)#}
local s=${data:1:-$#tail}
data=${tail:1}
[[ -z $field ]] && field=${s:-x}
;;
*) return 1;;
esac
done
watched+=( ${(v)found} )
}
done
unsetopt localoptions extendedglob
if [[ -v DIRENV_WATCHES ]]; then
() {
local REPLY json
-z4h-base64-decode ${${DIRENV_WATCHES//-/+}//_//} || return
json=$(printf '\x1f\x8b\x08\x00\x00\x00\x00\x00%s' $REPLY | -z4h-zcat 2>/dev/null) || return
json=$(printf '\x1f\x8b\x08\x00\x00\x00\x00\x00%s' $REPLY | -z4h-zcat 2>/dev/null) #|| return
[[ $json == '['*']' ]] || return
# TODO: extract $(jq '.[] | .Path') from $json and append it to deps.

jsons=( $( -z4h-json-parse $json ) )

for object in $jsons; do
deps+=$( -z4h-json-parse $object Path )
done

# TODO: cache those elements with $DIRENV_WATCHES as the key.
}
# TODO: handle errors from the above intelligently.
Expand Down
85 changes: 85 additions & 0 deletions fn/-z4h-json-parse
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
#!/usr/bin/env zsh
# Redneck json parsing. Yields correct results for any well-formed json document.
# Produces random garbage for invalid json.

local data
local -a params

data=$1; shift; params=( $@ );

data="${${data//$'\r'}##[[:space:]]#}"
[[ $data == ('{'|'[')* ]] || return
if [[ $data == '['*']' ]]
then
local arrayitem=''
local -a arraycontents
local -i depth=1
data[1]=
while (( depth > 0 ))
do
data=${data##[[:space:]]#}
[[ -n $data ]] || return
case $data[1] in
'{'|'[') arrayitem+=$data[1]; data[1]=; (( ++depth )) ;;
'}'|']') arrayitem+=$data[1]; data[1]=
(( --depth == 1 )) && { arraycontents+=($arrayitem); arrayitem='' } ;;
',') (( depth == 1 )) || arrayitem+=$data[1];
data[1]= ;;
':') arrayitem+=$data[1] data[1]= ;;
'"'|[[:alnum:].])
if [[ $data[1] == '"' ]]; then
local tail=${data##\"([^\"\\]|\\?)#\"}
else
local tail=${data##[[:alnum:].]#}
fi
[[ $tail == [[:space:][:punct:]]* ]] || return
arrayitem+=${data::-$#tail}; data=${tail}
;;
*) return 1 ;;
esac
done
(( ${#data##[[:space:]]#} == 0 )) || return
echo $arraycontents

elif [[ $data == '{'*'}' ]]
then
local field
local -A found
local -i depth=1
data[1]=
while (( depth > 0 ))
do
data=${data##[[:space:]]#}
[[ -n $data ]] || return
case $data[1] in
'{'|'[') data[1]=; (( ++depth )) ;;
'}'|']') data[1]=; (( --depth > 0 )) || return ;;
':') data[1]= ;;
',') data[1]=; field= ;;
'"'|[[:alnum:].])
if [[ $data[1] == '"' ]]; then
local tail=${data##\"([^\"\\]|\\?)#\"}
else
local tail=${data##[[:alnum:].]#}
fi
[[ $tail == [[:space:][:punct:]]* ]] || return
local s=${data::-$#tail}
data=${tail}
(( depth == 1 )) || continue
if [[ -z $field ]]; then
field=${s:-x}
elif [[ $field:*params ]]
then
(( ! $+found[$field] )) || return
[[ -n $s ]] || return
[[ $s != *($'\n'|'\')* ]] || return
found[$field]=$s
(( $#found == $#params )) && break
fi
;;
*) return 1 ;;
esac
done
echo ${(Q)found}
fi

0 comments on commit 80f8233

Please sign in to comment.