2018-08-06 19:37:20 +02:00
|
|
|
#!/bin/sh
|
2018-08-21 21:23:22 +02:00
|
|
|
#
|
|
|
|
# Build two documentation trees and diff the resulting formatted output.
|
|
|
|
# Compared to a source diff, this can reveal mistakes in the formatting.
|
|
|
|
# For example:
|
|
|
|
#
|
|
|
|
# ./doc-diff origin/master HEAD
|
|
|
|
#
|
|
|
|
# would show the differences introduced by a branch based on master.
|
2018-08-06 19:37:20 +02:00
|
|
|
|
|
|
|
OPTIONS_SPEC="\
|
|
|
|
doc-diff [options] <from> <to> [-- <diff-options>]
|
2018-08-31 08:33:17 +02:00
|
|
|
doc-diff (-c|--clean)
|
2018-08-06 19:37:20 +02:00
|
|
|
--
|
2019-03-17 19:36:02 +01:00
|
|
|
j=n parallel argument to pass to make
|
|
|
|
f force rebuild; do not rely on cached results
|
|
|
|
c,clean cleanup temporary working files
|
|
|
|
from-asciidoc use asciidoc with the 'from'-commit
|
|
|
|
from-asciidoctor use asciidoctor with the 'from'-commit
|
|
|
|
asciidoc use asciidoc with both commits
|
|
|
|
to-asciidoc use asciidoc with the 'to'-commit
|
|
|
|
to-asciidoctor use asciidoctor with the 'to'-commit
|
|
|
|
asciidoctor use asciidoctor with both commits
|
2019-09-16 21:00:28 +02:00
|
|
|
cut-footer cut away footer
|
2018-08-06 19:37:20 +02:00
|
|
|
"
|
|
|
|
SUBDIRECTORY_OK=1
|
|
|
|
. "$(git --exec-path)/git-sh-setup"
|
|
|
|
|
|
|
|
parallel=
|
|
|
|
force=
|
2018-08-31 08:33:17 +02:00
|
|
|
clean=
|
2019-03-17 19:36:02 +01:00
|
|
|
from_program=
|
|
|
|
to_program=
|
2019-09-16 21:00:28 +02:00
|
|
|
cut_footer=
|
2018-08-06 19:37:20 +02:00
|
|
|
while test $# -gt 0
|
|
|
|
do
|
|
|
|
case "$1" in
|
|
|
|
-j)
|
|
|
|
parallel=$2; shift ;;
|
2018-08-31 08:33:17 +02:00
|
|
|
-c|--clean)
|
|
|
|
clean=t ;;
|
2018-08-06 19:37:20 +02:00
|
|
|
-f)
|
|
|
|
force=t ;;
|
2019-03-17 19:36:02 +01:00
|
|
|
--from-asciidoctor)
|
|
|
|
from_program=-asciidoctor ;;
|
|
|
|
--to-asciidoctor)
|
|
|
|
to_program=-asciidoctor ;;
|
|
|
|
--asciidoctor)
|
|
|
|
from_program=-asciidoctor
|
|
|
|
to_program=-asciidoctor ;;
|
|
|
|
--from-asciidoc)
|
|
|
|
from_program=-asciidoc ;;
|
|
|
|
--to-asciidoc)
|
|
|
|
to_program=-asciidoc ;;
|
|
|
|
--asciidoc)
|
|
|
|
from_program=-asciidoc
|
|
|
|
to_program=-asciidoc ;;
|
2019-09-16 21:00:28 +02:00
|
|
|
--cut-footer)
|
|
|
|
cut_footer=-cut-footer ;;
|
2018-08-06 19:37:20 +02:00
|
|
|
--)
|
|
|
|
shift; break ;;
|
|
|
|
*)
|
|
|
|
usage ;;
|
|
|
|
esac
|
|
|
|
shift
|
|
|
|
done
|
|
|
|
|
2019-02-04 21:50:37 +01:00
|
|
|
tmp="$(git rev-parse --show-toplevel)/Documentation/tmp-doc-diff" || exit 1
|
2018-08-31 08:33:17 +02:00
|
|
|
|
|
|
|
if test -n "$clean"
|
|
|
|
then
|
|
|
|
test $# -eq 0 || usage
|
|
|
|
git worktree remove --force "$tmp/worktree" 2>/dev/null
|
|
|
|
rm -rf "$tmp"
|
|
|
|
exit 0
|
|
|
|
fi
|
|
|
|
|
2018-08-06 19:37:20 +02:00
|
|
|
if test -z "$parallel"
|
|
|
|
then
|
|
|
|
parallel=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
|
|
|
|
if test $? != 0 || test -z "$parallel"
|
|
|
|
then
|
|
|
|
parallel=1
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
|
|
|
|
test $# -gt 1 || usage
|
|
|
|
from=$1; shift
|
|
|
|
to=$1; shift
|
|
|
|
|
|
|
|
from_oid=$(git rev-parse --verify "$from") || exit 1
|
|
|
|
to_oid=$(git rev-parse --verify "$to") || exit 1
|
|
|
|
|
|
|
|
if test -n "$force"
|
|
|
|
then
|
|
|
|
rm -rf "$tmp"
|
|
|
|
fi
|
|
|
|
|
|
|
|
# We'll do both builds in a single worktree, which lets "make" reuse
|
|
|
|
# results that don't differ between the two trees.
|
|
|
|
if ! test -d "$tmp/worktree"
|
|
|
|
then
|
2018-08-30 09:54:31 +02:00
|
|
|
git worktree add -f --detach "$tmp/worktree" "$from" &&
|
2018-08-06 19:37:20 +02:00
|
|
|
dots=$(echo "$tmp/worktree" | sed 's#[^/]*#..#g') &&
|
|
|
|
ln -s "$dots/config.mak" "$tmp/worktree/config.mak"
|
|
|
|
fi
|
|
|
|
|
2019-03-17 19:36:02 +01:00
|
|
|
construct_makemanflags () {
|
|
|
|
if test "$1" = "-asciidoc"
|
|
|
|
then
|
|
|
|
echo USE_ASCIIDOCTOR=
|
|
|
|
elif test "$1" = "-asciidoctor"
|
|
|
|
then
|
|
|
|
echo USE_ASCIIDOCTOR=YesPlease
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
from_makemanflags=$(construct_makemanflags "$from_program") &&
|
|
|
|
to_makemanflags=$(construct_makemanflags "$to_program") &&
|
|
|
|
|
2019-09-16 21:00:28 +02:00
|
|
|
from_dir=$from_oid$from_program$cut_footer &&
|
|
|
|
to_dir=$to_oid$to_program$cut_footer &&
|
2019-03-17 19:36:01 +01:00
|
|
|
|
2018-08-06 19:37:20 +02:00
|
|
|
# generate_render_makefile <srcdir> <dstdir>
|
|
|
|
generate_render_makefile () {
|
|
|
|
find "$1" -type f |
|
|
|
|
while read src
|
|
|
|
do
|
|
|
|
dst=$2/${src#$1/}
|
2020-02-18 22:40:09 +01:00
|
|
|
printf 'all: %s\n' "$dst"
|
2018-08-06 19:37:20 +02:00
|
|
|
printf '%s: %s\n' "$dst" "$src"
|
|
|
|
printf '\t@echo >&2 " RENDER $(notdir $@)" && \\\n'
|
|
|
|
printf '\tmkdir -p $(dir $@) && \\\n'
|
doc-diff: fix non-portable 'man' invocation
doc-diff invokes 'man' with the -l option to force "local" mode,
however, neither MacOS nor FreeBSD recognize this option. On those
platforms, if the argument to 'man' contains a slash, it is
automatically interpreted as a file specification, so a "local"-like
mode is not needed. And, it turns out, 'man' which does support -l
falls back to enabling -l automatically if it can't otherwise find a
manual entry corresponding to the argument. Since doc-diff always
passes an absolute path of the nroff source file to 'man', the -l
option kicks in anyhow, despite not being specified explicitly.
Therefore, make the invocation portable to the various platforms by
simply dropping -l.
Signed-off-by: Eric Sunshine <sunshine@sunshineco.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-08-31 08:33:16 +02:00
|
|
|
printf '\tMANWIDTH=80 man $< >$@+ && \\\n'
|
2018-08-06 19:37:20 +02:00
|
|
|
printf '\tmv $@+ $@\n'
|
|
|
|
done
|
|
|
|
}
|
|
|
|
|
2019-03-17 19:36:02 +01:00
|
|
|
# render_tree <committish_oid> <directory_name> <makemanflags>
|
2018-08-06 19:37:20 +02:00
|
|
|
render_tree () {
|
|
|
|
# Skip install-man entirely if we already have an installed directory.
|
|
|
|
# We can't rely on make here, since "install-man" unconditionally
|
|
|
|
# copies the files (spending effort, but also updating timestamps that
|
|
|
|
# we then can't rely on during the render step). We use "mv" to make
|
|
|
|
# sure we don't get confused by a previous run that failed partway
|
|
|
|
# through.
|
2019-03-17 19:36:01 +01:00
|
|
|
oid=$1 &&
|
|
|
|
dname=$2 &&
|
2019-03-17 19:36:02 +01:00
|
|
|
makemanflags=$3 &&
|
2019-03-17 19:36:01 +01:00
|
|
|
if ! test -d "$tmp/installed/$dname"
|
2018-08-06 19:37:20 +02:00
|
|
|
then
|
2019-03-17 19:36:01 +01:00
|
|
|
git -C "$tmp/worktree" checkout --detach "$oid" &&
|
2018-08-06 19:37:20 +02:00
|
|
|
make -j$parallel -C "$tmp/worktree" \
|
2019-03-17 19:36:02 +01:00
|
|
|
$makemanflags \
|
2018-08-06 19:37:20 +02:00
|
|
|
GIT_VERSION=omitted \
|
|
|
|
SOURCE_DATE_EPOCH=0 \
|
2019-03-17 19:36:01 +01:00
|
|
|
DESTDIR="$tmp/installed/$dname+" \
|
2018-08-06 19:37:20 +02:00
|
|
|
install-man &&
|
2019-03-17 19:36:01 +01:00
|
|
|
mv "$tmp/installed/$dname+" "$tmp/installed/$dname"
|
2018-08-06 19:37:20 +02:00
|
|
|
fi &&
|
|
|
|
|
|
|
|
# As with "installed" above, we skip the render if it's already been
|
|
|
|
# done. So using make here is primarily just about running in
|
|
|
|
# parallel.
|
2019-03-17 19:36:01 +01:00
|
|
|
if ! test -d "$tmp/rendered/$dname"
|
2018-08-06 19:37:20 +02:00
|
|
|
then
|
2019-03-17 19:36:01 +01:00
|
|
|
generate_render_makefile "$tmp/installed/$dname" \
|
|
|
|
"$tmp/rendered/$dname+" |
|
2018-08-06 19:37:20 +02:00
|
|
|
make -j$parallel -f - &&
|
2019-03-17 19:36:01 +01:00
|
|
|
mv "$tmp/rendered/$dname+" "$tmp/rendered/$dname"
|
doc-diff: add `--cut-header-footer`
AsciiDoc and Asciidoctor do not agree on what to write in the header and
footer of each man-page, i.e., the very first and the very last line of
*.[157]. Those differences can certainly be interesting in their own
right, but they clutter the output of `./doc-diff --from-asciidoc
--to-asciidoctor HEAD HEAD` quite a bit since the diff contains some
10-15 lines of noise per file diffed.
Teach doc-diff to cut away the first two and last two lines, i.e., the
header/footer and the empty line immediately following/preceding it.
Because Asciidoctor uses an extra empty line compared to AsciiDoc,
remove one more line at each end of the file, but only if it's empty.
An alternative approach might be to pass down `--no-header-footer`,
which both AsciiDoc and Asciidoctor understand, but it has some
drawbacks. First of all, the result doesn't build -- `xmlto` stumbles on
the resulting xml since it has multiple root elements. Second, it cuts
too much -- dropping the header loses the synopsis, which would be
interesting to diff.
Like in the previous commit, encode this option into the directory name
of the "installed" and "rendered" files. Otherwise, we wouldn't be able
to trust that what we use out of that cache actually corresponds to the
options given for this run. (We could optimize this caching a little
since this flag doesn't affect the contents of "installed" at all, but
let's punt on that.)
Signed-off-by: Martin Ågren <martin.agren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-03-17 19:36:03 +01:00
|
|
|
|
2019-09-16 21:00:28 +02:00
|
|
|
if test "$cut_footer" = "-cut-footer"
|
doc-diff: add `--cut-header-footer`
AsciiDoc and Asciidoctor do not agree on what to write in the header and
footer of each man-page, i.e., the very first and the very last line of
*.[157]. Those differences can certainly be interesting in their own
right, but they clutter the output of `./doc-diff --from-asciidoc
--to-asciidoctor HEAD HEAD` quite a bit since the diff contains some
10-15 lines of noise per file diffed.
Teach doc-diff to cut away the first two and last two lines, i.e., the
header/footer and the empty line immediately following/preceding it.
Because Asciidoctor uses an extra empty line compared to AsciiDoc,
remove one more line at each end of the file, but only if it's empty.
An alternative approach might be to pass down `--no-header-footer`,
which both AsciiDoc and Asciidoctor understand, but it has some
drawbacks. First of all, the result doesn't build -- `xmlto` stumbles on
the resulting xml since it has multiple root elements. Second, it cuts
too much -- dropping the header loses the synopsis, which would be
interesting to diff.
Like in the previous commit, encode this option into the directory name
of the "installed" and "rendered" files. Otherwise, we wouldn't be able
to trust that what we use out of that cache actually corresponds to the
options given for this run. (We could optimize this caching a little
since this flag doesn't affect the contents of "installed" at all, but
let's punt on that.)
Signed-off-by: Martin Ågren <martin.agren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-03-17 19:36:03 +01:00
|
|
|
then
|
|
|
|
for f in $(find "$tmp/rendered/$dname" -type f)
|
|
|
|
do
|
2019-09-16 21:00:28 +02:00
|
|
|
head -n -2 "$f" | sed -e '${/^$/d}' >"$f+" &&
|
doc-diff: add `--cut-header-footer`
AsciiDoc and Asciidoctor do not agree on what to write in the header and
footer of each man-page, i.e., the very first and the very last line of
*.[157]. Those differences can certainly be interesting in their own
right, but they clutter the output of `./doc-diff --from-asciidoc
--to-asciidoctor HEAD HEAD` quite a bit since the diff contains some
10-15 lines of noise per file diffed.
Teach doc-diff to cut away the first two and last two lines, i.e., the
header/footer and the empty line immediately following/preceding it.
Because Asciidoctor uses an extra empty line compared to AsciiDoc,
remove one more line at each end of the file, but only if it's empty.
An alternative approach might be to pass down `--no-header-footer`,
which both AsciiDoc and Asciidoctor understand, but it has some
drawbacks. First of all, the result doesn't build -- `xmlto` stumbles on
the resulting xml since it has multiple root elements. Second, it cuts
too much -- dropping the header loses the synopsis, which would be
interesting to diff.
Like in the previous commit, encode this option into the directory name
of the "installed" and "rendered" files. Otherwise, we wouldn't be able
to trust that what we use out of that cache actually corresponds to the
options given for this run. (We could optimize this caching a little
since this flag doesn't affect the contents of "installed" at all, but
let's punt on that.)
Signed-off-by: Martin Ågren <martin.agren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-03-17 19:36:03 +01:00
|
|
|
mv "$f+" "$f" ||
|
|
|
|
return 1
|
|
|
|
done
|
|
|
|
fi
|
2018-08-06 19:37:20 +02:00
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
2019-03-17 19:36:02 +01:00
|
|
|
render_tree $from_oid $from_dir $from_makemanflags &&
|
|
|
|
render_tree $to_oid $to_dir $to_makemanflags &&
|
2019-03-17 19:36:01 +01:00
|
|
|
git -C $tmp/rendered diff --no-index "$@" $from_dir $to_dir
|