#!/usr/bin/env nix-shell #!nix-shell -i bash -p lix wget nix-locate man xz gzip bzip2 set -euo pipefail N_WORKERS=4 LRU_MAX_SIZE=50 # TODO: allow to pick which nix-index to fetch and use # https://github.com/numtide/nar-serve #HTTP_ADDR=localhost:8383 nar-serve & #NAR_SERVE_PID=$! #trap "set -x; kill $NAR_SERVE_PID" EXIT SIGHUP SIGINT SIGQUIT #let N_WORKERS+=1 nix_substituters=($(nix config show substituters)) nar-fetch() { local storepath="$1" local outpath="$2" # /nix/store/xxx-foobar/* -> xxx local storehash="$(cut -c12-43 <<<"$storepath")" if [[ -s "$outpath" ]]; then return 0 elif [[ -e "$storepath" ]]; then cp -v "$storepath" "$outpath" elif [[ -e .direnv/nar-cache/"$storehash".nar ]]; then mkdir -p "$(dirname "$outpath")" nix nar cat .direnv/nar-cache/"$storehash.nar" "/$(cut <<<"$storepath" -d/ -f5-)" >"$outpath" return 0 else mkdir -p .direnv/nar-cache local prev= for substituter in "${nix_substituters[@]}"; do [[ "$substituter" != "$prev" ]] || continue prev="$substituter" local location="$((set -x; curl -L "$substituter/$storehash.narinfo") | grep '^URL: ' | cut -d' ' -f2-)" || true [[ -n "$location" ]] || continue # lru the cache find .direnv/nar-cache/ -maxdepth 1 -printf "%T+ %p\n" | sort | cut -d' ' -f2- | tail "-n+$LRU_MAX_SIZE" | xargs -d$'\n' rm -v if [[ "$location" =~ .*\.nar\.xz$ ]]; then (set -x; curl -L "$substituter/$location") | xz --decompress --stdout > .direnv/nar-cache/"$storehash.nar" elif [[ "$location" =~ .*\.nar$ ]]; then (set -x; curl -L "$substituter/$location") > .direnv/nar-cache/"$storehash.nar" else return 1 fi mkdir -p "$(dirname "$outpath")" nix nar cat .direnv/nar-cache/"$storehash.nar" "/$(cut <<<"$storepath" -d/ -f5-)" >"$outpath" return 0 done fi } while read attrpath size type storepath _; do if ! [[ "$storepath" =~ /nix/store/.* ]]; then continue fi outpath="data/$attrpath/$(cut -d/ -f7- <<<"$storepath")" #test -s "$outpath" || ( # mkdir -vp "$(dirname "$outpath")" # set -x # wget http://localhost:8383"$storepath" -O "$outpath" || true #) nar-fetch "$storepath" "$outpath" || continue if [[ ! -s "$outpath" ]]; then continue fi ( if [[ "$outpath" =~ .*\.gz$ ]]; then htmlpath="html/$attrpath/$(cut -d/ -f7- <<<"$storepath" | rev | cut -d. -f2- | rev).html" test -s "$htmlpath" || ( set -x; mkdir -p "$(dirname "$htmlpath")"; man --html=cat <(zcat "$outpath") > "$htmlpath" ) elif [[ "$outpath" =~ .*\.bz2$ ]]; then htmlpath="html/$attrpath/$(cut -d/ -f7- <<<"$storepath" | rev | cut -d. -f2- | rev).html" test -s "$htmlpath" || ( set -x; mkdir -p "$(dirname "$htmlpath")"; man --html=cat <(bzcat "$outpath") > "$htmlpath" ) elif [[ "$outpath" =~ .*\.xz$ ]]; then htmlpath="html/$attrpath/$(cut -d/ -f7- <<<"$storepath" | rev | cut -d. -f2- | rev).html" test -s "$htmlpath" || ( set -x; mkdir -p "$(dirname "$htmlpath")"; man --html=cat <(xzcat "$outpath") > "$htmlpath" ) else htmlpath="html/$attrpath/$(cut -d/ -f7- <<<"$storepath").html" test -s "$htmlpath" || ( set -x; mkdir -p "$(dirname "$htmlpath")"; man --html=cat "$outpath" > "$htmlpath" ) fi ) & while [[ $(jobs -p | wc -l) -ge $N_WORKERS ]]; do >&2 echo "Waiting..." wait -n < <(jobs -p) || true done done < <(nix-locate --regex '^/share/man/man[0-9]*/.*' --top-level | tr -s ' ')