# 
# patch-report.sh: generate a report from a patch set
################################################################
# Copyright (C) 2001, 2002 Tom Lord
# 
# See the file "COPYING" for further information about
# the copyright and warranty status of this work.
# 

set -e 

comand_line="$*"

################################################################
# special options
# 
# Some options are special:
# 
#       --version | -V
#       --help | -h
# 
if test $# -ne 0 ; then

  for opt in "$@" ; do
    case $opt in

      --version|-V) exec larch --version
                    ;;


      --help|-h)
                printf "generate a report from a patch set\\n"
                printf "usage: patch-report [options] [--] patch-set-dir\\n"
                printf "\\n"
                printf " -V --version                  print version info\\n"
                printf " -h --help                     display help\\n"
                printf "\\n"
                printf " --diffs                       include context diffs\\n"
                printf "                                in the output\\n"
                printf "\\n"
                printf " --html                        generate html instad of outline\\n"
                printf " --title TITLE                 set the report title\\n"
                printf "\\n"
                printf " --no-intro                    skip the introduction\\n"
                printf " --link-root                   hyperlink root of the patch set dir\\n"
                printf " --omit-empty                  omit empty sections\\n"
                printf " --compact                     produce compact output (html only)\\n"
                printf " --target TARGET               specify a link target (html only)\\n"
                printf "\\n"
                printf "Generate an outline-format report from a patch set.\\n"
                printf "\\n"
                exit 0
                ;;

      *)
                ;;
    esac
  done
fi

################################################################
# Ordinary Options
# 
# 

errname=
diffs=
html=
title=
no_intro=
omit_empty=
link_root=.
compact=
fill=
target=

while test $# -ne 0 ; do

  case "$1" in 

    --silent)           shift   # ignored
                        ;;
    --quiet)            shift   # ignored
                        ;;
    --report)           shift   # ignored
                        ;;
    --verbose)          shift   # ignored
                        ;;


    --no-intro)         shift
                        no_intro=--no_intro
                        ;;
                        
    --compact)          shift
                        compact=--compact
                        fill=--fill
                        ;;
                        
    --omit-empty)       shift
                        omit_empty=--omit-empty
                        ;;
                        
    --link-root)        shift
                        if test $# -eq 0 ; then
                          printf "patch-report: --link-root requires an argument\\n"
                          printf "try --help\\n"
                        fi
                        link_root="$1"
                        shift
                        ;;

    --target)           shift
                        if test $# -eq 0 ; then
                          printf "patch-report: --target requires an argument\\n"
                          printf "try --help\\n"
                        fi
                        target="--target $1"
                        shift
                        ;;

    --title)            shift
                        if test $# -eq 0 ; then
                          printf "patch-report: --title requires an argument\\n"
                          printf "try --help\\n"
                        fi
                        title="$1"
                        shift
                        ;;

    --html)             shift
                        html=--html
                        ;;

    --diffs)            shift
                        diffs=--diffs
                        ;;

    --)                 shift
                        break
                        ;;
                        
    -*)                 printf "patch-report: unrecognized option (%s)\\n" "$1" 1>&2
                        printf "try --help\\n" 1>&2
                        exit 1
                        ;;

    *)                  break
                        ;;

  esac

done



################################################################
# Ordinary Arguments
# 

if test $# -ne 1 ; then
  printf "usage: patch-report [options] [--] dir\\n" 1>&2
  printf "try --help\\n" 1>&2
  exit 1
fi

if test $# -gt 0 ; then
  delta="$1"
  shift
else
  delta=.
fi

################################################################
# Sanity Check and Process Defaults
# 

here="`pwd`"
cd "$delta"
delta="`pwd`"

if test ! -z "$html" ; then
  diffs=
fi

################################################################
# Do It
# 

export delta
cd "$delta"

if test -z "$no_intro" ; then
  if test -z "$title" ; then
    larch heading $html "patch-report\\n"
    printf "arguments: %s\\n" "$command_line" | fold -w 60 | larch body-indent $html
    larch heading $html --sub "delta\\n"
    printf "%s\\n" "$delta" | larch body-indent $html --sub
  else
    larch heading $html "%s\\n" "$title"
  fi
fi

tmpfile=",,patch-report.$$"

rm -f "$tmpfile"

join -v 1 -o 1.1 -1 2 -2 2 "$delta/orig-files-index" "$delta/mod-files-index" \
| sort \
| $ARCH_SHELL -c 'while read file ; do if test ! -h "$delta/removed-files-archive/$file" ; then printf "%s\\n" "$file" ; fi ; done' \
> "$tmpfile"

if test -z "$omit_empty" -o "(" "" != "`head -n 1 \"$tmpfile\"`" ")" ; then
  larch heading $html --sub "removed files\\n"
  cat "$tmpfile" | larch file-list $target $html $fill --sub --root "$link_root/removed-files-archive" 
fi


rm -f "$tmpfile"

join -v 1 -o 1.1 -1 2 -2 2 "$delta/orig-files-index" "$delta/mod-files-index" \
| sort \
| $ARCH_SHELL -c 'while read file ; do 
           if test -h "$delta/removed-files-archive/$file" ; then
             printf "%s -> %s\\n" "$file" "`read-link \"$delta/removed-files-archive/$file\"`"; 
           fi ; 
         done' \
> "$tmpfile"

if test -z "$omit_empty" -o "(" "" != "`head -n 1 \"$tmpfile\"`" ")" ; then

  larch heading $html --sub "removed symbolic links\\n"
  cat "$tmpfile" | larch file-list $target $html $fill --sub --root "$link_root/removed-files-archive" 

fi


rm -f "$tmpfile"

join -v 2 -o 2.1 -1 2 -2 2 "$delta/orig-files-index" "$delta/mod-files-index" \
| sort \
| $ARCH_SHELL -c 'while read file ; do if test ! -h "$delta/new-files-archive/$file" ; then printf "%s\\n" "$file" ; fi ; done' \
> "$tmpfile"

if test -z "$omit_empty" -o "(" "" != "`head -n 1 \"$tmpfile\"`" ")" ; then
  larch heading $html --sub "added files\\n"
  cat "$tmpfile" | larch file-list $target $html $fill --sub --root "$link_root/new-files-archive" 
fi

rm -f "$tmpfile"

join -v 2 -o 2.1 -1 2 -2 2 "$delta/orig-files-index" "$delta/mod-files-index" \
| sort \
| $ARCH_SHELL -c 'while read file ; do 
           if test -h "$delta/new-files-archive/$file" ; then
             printf "%s -> %s\\n" "$file" "`read-link \"$delta/new-files-archive/$file\"`"; 
           fi ; 
         done' \
> "$tmpfile" 

if test -z "$omit_empty" -o "(" "" != "`head -n 1 \"$tmpfile\"`" ")" ; then

  larch heading $html --sub "added symbolic links\\n"
  cat "$tmpfile" | larch file-list $target $html $fill --sub 

fi

rm -f "$tmpfile"

cat "$delta/mod-files-index" \
| awk -f "$ARCH_SUBCMD_ROOT/patch-sets/compute-renamed.awk" \
      -v orig_dir_index="$delta/orig-dirs-index" \
      -v mod_dir_index="$delta/mod-dirs-index" \
      -v orig_X_index="$delta/orig-files-index" \
| cut -s -d ' ' -f 1,2 \
| sort -k 1 \
> "$tmpfile" 

if test -z "$omit_empty" -o "(" "" != "`head -n 1 \"$tmpfile\"`" ")" ; then

  larch heading $html --sub "renamed files\\n"
  cat "$tmpfile" \
  | awk 'BEGIN { none = 1; }
         { 
           none = 0;
           print $1
           print "=>" $2
           print ""
         }
         END { if (none) print "<none>" }' \
  | larch body-indent $html --sub

fi


rm -f "$tmpfile"

join -v 1 -o 1.1 -1 2 -2 2 "$delta/orig-dirs-index" "$delta/mod-dirs-index" \
| sort \
> "$tmpfile"

if test -z "$omit_empty" -o "(" "" != "`head -n 1 \"$tmpfile\"`" ")" ; then

  larch heading $html --sub "removed dirs\\n"
  cat "$tmpfile" | larch file-list $target $html $fill --sub

fi

rm -f "$tmpfile"

join -v 2 -o 2.1 -1 2 -2 2 "$delta/orig-dirs-index" "$delta/mod-dirs-index" \
| sort \
> "$tmpfile"

if test -z "$omit_empty" -o "(" "" != "`head -n 1 \"$tmpfile\"`" ")" ; then

  larch heading $html --sub "added dirs\\n"
  cat "$tmpfile" | larch file-list $target $html $fill --sub

fi


rm -f "$tmpfile"

cat "$delta/mod-dirs-index" \
| awk -f "$ARCH_SUBCMD_ROOT/patch-sets/compute-renamed.awk" \
      -v orig_dir_index="$delta/orig-dirs-index" \
      -v mod_dir_index="$delta/mod-dirs-index" \
      -v orig_X_index="$delta/orig-dirs-index" \
| cut -s -d ' ' -f 1,2 \
| sort -k 1 \
> "$tmpfile"

if test -z "$omit_empty" -o "(" "" != "`head -n 1 \"$tmpfile\"`" ")" ; then

  larch heading $html --sub "renamed dirs\\n"
  cat "$tmpfile" \
  | awk 'BEGIN { none = 1; }
         {
           none = 0;
           print $1
           print "=>" $2
           print ""
         }
         END { if (none) print "<none>" }' \
  | larch body-indent $html --sub

fi


rm -f "$tmpfile"

( cd "$delta/patches" ; \
  find . -type f | grep -E -e '\.patch$' ) \
> "$tmpfile"

if test -z "$omit_empty" -o "(" "" != "`head -n 1 \"$tmpfile\"`" ")" ; then

  if test -z "$diffs" ; then

    larch heading $html --sub "patched regular files\\n"
    cat "$tmpfile" \
    | sed -e 's/.patch$//' \
    | sort \
    | larch file-list $target $html $fill --sub --root "$link_root/patches" --suffix ".patch"
  else

    larch heading --sub "patched regular files\\n"

    cat "$tmpfile" \
    | sed -e 's/.patch$//' \
    | sort \
    | awk -v delta="patches" \
          'BEGIN { none = 1; }
           {
             none = 0;
             print "larch heading --sub --sub \"%s\\\\n\" \"" $1 "\"";
             print "cat \"" delta "/" $1 ".patch\" | larch body-indent --sub --sub";
           }
           END { if (none) print "printf \"<none>\\\\n\" | larch body-indent --sub --sub" }' \
    | $ARCH_SHELL
  fi

fi


rm -f "$tmpfile"

( cd "$delta/patches" ; \
  some= ; \
  for link_patch in `find . -type f | grep -E -e '\.link-mod$' | sort` ; do \
    some=yes ; \
    link_name="${link_patch%.link-mod}"; \
    printf "%s -> " "$link_name" ; \
    cat "$link_patch" ; \
    printf "    (was" ; \
    if test -e "$link_name.link-orig" ; then \
      printf " -> " ; \
      cat "$link_name.link-orig" | awk '{ printf("%s)\n", $0); }' ; \
    else \
      printf " regular file)\\n" ; \
    fi ; \
  done ; ) \
> "$tmpfile"

if test -z "$omit_empty" -o "(" "" != "`head -n 1 \"$tmpfile\"`" ")" ; then

  larch heading $html --sub "patched symbolic links\\n"

  if test "" != "`head -n 1 \"$tmpfile\"`" ; then
    cat "$tmpfile" | larch body-indent $html --sub
  else
    printf "<none>\\n" | larch body-indent $html --sub
  fi

fi



rm -f "$tmpfile"

( cd "$delta/patches" ; \
  find . -type f | grep -E -e '\.modified$' ) \
| sed -e 's/.modified$//' \
| sort \
> "$tmpfile"

if test -z "$omit_empty" -o "(" "" != "`head -n 1 \"$tmpfile\"`" ")" ; then

  larch heading $html --sub "patched binary files\\n"
  cat "$tmpfile" | larch file-list $target $html $fill --sub

fi

rm -f "$tmpfile"
( cd "$delta/patches" ; \
  find . -type f | grep -E -e '(\.meta-mod|/=dir-meta-mod)$' | awk '{ print "printf \"%s \" \"" $0 "\" ; cat \"" $0 "\"" }' | $ARCH_SHELL ) \
| sed -e 's/.meta-mod / /' -e 's/=dir-meta-mod / /' \
| sort -k 1 \
> "$tmpfile"

if test -z "$omit_empty" -o "(" "" != "`head -n 1 \"$tmpfile\"`" ")" ; then

  larch heading $html --sub "metadata changed\\n"
  cat "$tmpfile" | larch file-list $target $html $fill --sub

fi

rm "$tmpfile"



# tag: Tom Lord Thu Dec 13 02:30:24 2001 (patch-sets/patch-report.sh)
#
