Git fork
at reftables-rust 186 lines 4.6 kB view raw
1#!/bin/sh 2# 3# Build two documentation trees and diff the resulting formatted output. 4# Compared to a source diff, this can reveal mistakes in the formatting. 5# For example: 6# 7# ./doc-diff origin/master HEAD 8# 9# would show the differences introduced by a branch based on master. 10 11OPTIONS_SPEC="\ 12doc-diff [options] <from> <to> [-- <diff-options>] 13doc-diff (-c|--clean) 14-- 15j=n parallel argument to pass to make 16f force rebuild; do not rely on cached results 17c,clean cleanup temporary working files 18from-asciidoc use asciidoc with the 'from'-commit 19from-asciidoctor use asciidoctor with the 'from'-commit 20asciidoc use asciidoc with both commits 21to-asciidoc use asciidoc with the 'to'-commit 22to-asciidoctor use asciidoctor with the 'to'-commit 23asciidoctor use asciidoctor with both commits 24cut-footer cut away footer 25" 26SUBDIRECTORY_OK=1 27. "$(git --exec-path)/git-sh-setup" 28 29parallel= 30force= 31clean= 32from_program= 33to_program= 34cut_footer= 35while test $# -gt 0 36do 37 case "$1" in 38 -j) 39 parallel=$2; shift ;; 40 -c|--clean) 41 clean=t ;; 42 -f) 43 force=t ;; 44 --from-asciidoctor) 45 from_program=-asciidoctor ;; 46 --to-asciidoctor) 47 to_program=-asciidoctor ;; 48 --asciidoctor) 49 from_program=-asciidoctor 50 to_program=-asciidoctor ;; 51 --from-asciidoc) 52 from_program=-asciidoc ;; 53 --to-asciidoc) 54 to_program=-asciidoc ;; 55 --asciidoc) 56 from_program=-asciidoc 57 to_program=-asciidoc ;; 58 --cut-footer) 59 cut_footer=-cut-footer ;; 60 --) 61 shift; break ;; 62 *) 63 usage ;; 64 esac 65 shift 66done 67 68tmp="$(git rev-parse --show-toplevel)/Documentation/tmp-doc-diff" || exit 1 69 70if test -n "$clean" 71then 72 test $# -eq 0 || usage 73 git worktree remove --force "$tmp/worktree" 2>/dev/null 74 rm -rf "$tmp" 75 exit 0 76fi 77 78if test -z "$parallel" 79then 80 parallel=$(getconf _NPROCESSORS_ONLN 2>/dev/null) 81 if test $? != 0 || test -z "$parallel" 82 then 83 parallel=1 84 fi 85fi 86 87test $# -gt 1 || usage 88from=$1; shift 89to=$1; shift 90 91from_oid=$(git rev-parse --verify "$from") || exit 1 92to_oid=$(git rev-parse --verify "$to") || exit 1 93 94if test -n "$force" 95then 96 rm -rf "$tmp" 97fi 98 99# We'll do both builds in a single worktree, which lets "make" reuse 100# results that don't differ between the two trees. 101if ! test -d "$tmp/worktree" 102then 103 git worktree add -f --detach "$tmp/worktree" "$from" && 104 dots=$(echo "$tmp/worktree" | sed 's#[^/]*#..#g') && 105 ln -s "$dots/config.mak" "$tmp/worktree/config.mak" 106fi 107 108construct_makemanflags () { 109 if test "$1" = "-asciidoc" 110 then 111 echo USE_ASCIIDOCTOR= 112 elif test "$1" = "-asciidoctor" 113 then 114 echo USE_ASCIIDOCTOR=YesPlease 115 fi 116} 117 118from_makemanflags=$(construct_makemanflags "$from_program") && 119to_makemanflags=$(construct_makemanflags "$to_program") && 120 121from_dir=$from_oid$from_program$cut_footer && 122to_dir=$to_oid$to_program$cut_footer && 123 124# generate_render_makefile <srcdir> <dstdir> 125generate_render_makefile () { 126 find "$1" -type f | 127 while read src 128 do 129 dst=$2/${src#$1/} 130 printf 'all: %s\n' "$dst" 131 printf '%s: %s\n' "$dst" "$src" 132 printf '\t@echo >&2 " RENDER $(notdir $@)" && \\\n' 133 printf '\tmkdir -p $(dir $@) && \\\n' 134 printf '\tMANWIDTH=80 man $< >$@+ && \\\n' 135 printf '\tmv $@+ $@\n' 136 done 137} 138 139# render_tree <committish_oid> <directory_name> <makemanflags> 140render_tree () { 141 # Skip install-man entirely if we already have an installed directory. 142 # We can't rely on make here, since "install-man" unconditionally 143 # copies the files (spending effort, but also updating timestamps that 144 # we then can't rely on during the render step). We use "mv" to make 145 # sure we don't get confused by a previous run that failed partway 146 # through. 147 oid=$1 && 148 dname=$2 && 149 makemanflags=$3 && 150 if ! test -d "$tmp/installed/$dname" 151 then 152 git -C "$tmp/worktree" checkout --detach "$oid" && 153 make -j$parallel -C "$tmp/worktree" \ 154 $makemanflags \ 155 GIT_VERSION=omitted \ 156 GIT_DATE=1970-01-01 \ 157 DESTDIR="$tmp/installed/$dname+" \ 158 install-man && 159 mv "$tmp/installed/$dname+" "$tmp/installed/$dname" 160 fi && 161 162 # As with "installed" above, we skip the render if it's already been 163 # done. So using make here is primarily just about running in 164 # parallel. 165 if ! test -d "$tmp/rendered/$dname" 166 then 167 generate_render_makefile "$tmp/installed/$dname" \ 168 "$tmp/rendered/$dname+" | 169 make -j$parallel -f - && 170 mv "$tmp/rendered/$dname+" "$tmp/rendered/$dname" 171 172 if test "$cut_footer" = "-cut-footer" 173 then 174 for f in $(find "$tmp/rendered/$dname" -type f) 175 do 176 head -n -2 "$f" | sed -e '${/^$/d}' >"$f+" && 177 mv "$f+" "$f" || 178 return 1 179 done 180 fi 181 fi 182} 183 184render_tree $from_oid $from_dir $from_makemanflags && 185render_tree $to_oid $to_dir $to_makemanflags && 186git -C $tmp/rendered diff --no-index "$@" $from_dir $to_dir