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

set -e 

################################################################
# 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 "create or update a patch-set web\\n"
                printf "usage: patch-set-web [options] spec-file output-dir\\n"
                printf "\\n"
                printf " -V --version                  print version info\\n"
                printf " -h --help                     display help\\n"
                printf "\\n"
                printf " --silent                      no output (except odd errors)\\n"
                printf " --quiet                       brief output\\n"
                printf " --report                      default output\\n"
                printf " --verbose                     maximal output\\n"
                printf " --debug                       debugging output\\n"
                printf "\\n"
                printf " -D --dir DIR                  use project tree containing DIR\\n"
                printf " -t --title TITLE              set the page title\\n"
                printf "\\n"
                printf "Create or update web pages describing the patch sets applied\\n"
                printf "to a particular tree.  The branches included in the report are\\n"
                printf "determined by the spec file which contains entries of the form:\\n"
                printf "\\n"
                printf "        archive/version\\n"
                printf "          description of branch\\n"
                printf "\\n"
                exit 0
                ;;

      *)
                ;;
    esac
  done
fi

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

dir=.
title=

quiet=--quiet
report=--report
verbose=
silent_opt=
quiet_opt=
report_opt=
verbose_opt=
debug_opt=

while test $# -ne 0 ; do

  case "$1" in 

    --silent)   shift
                quiet=
                report=
                verbose=
                silent_opt=--silent
                quiet_opt=
                report_opt=
                verbose_opt=
                ;;

    --quiet)    shift
                quiet=--quiet
                report=
                verbose=
                silent_opt=
                quiet_opt=--quiet
                report_opt=
                verbose_opt=
                ;;

    --report)   shift
                quiet=--quiet
                report=--report
                verbose=
                silent_opt=
                quiet_opt=
                report_opt=--report
                verbose_opt=
                ;;

    --verbose)  shift
                quiet=--quiet
                report=--report
                verbose=--verbose
                silent_opt=
                quiet_opt=
                report_opt=
                verbose_opt=--verbose
                ;;

    --debug)    shift
                larch heading "patch-set-web: debugging output enabled\\n"
                set -x
                debug_opt=--debug
                ;;

    -D|--dir)           shift
                        if test $# -eq 0 ; then
                          printf "patch-set-web: -D and --dir require an argument\\n" 1>&2
                          printf "try --help\\n" 1>&2
                          exit 1
                        fi
                        dir="$1"
                        shift
                        ;;

    -t|--title)         shift
                        if test $# -eq 0 ; then
                          printf "patch-set-web: -t and --title require an argument\\n" 1>&2
                          printf "try --help\\n" 1>&2
                          exit 1
                        fi
                        title="$1"
                        shift
                        ;;

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

    *)                  break
                        ;;
  esac

done



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

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

spec_file=$1
shift
output_dir=$1
shift

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

here="`pwd`"
cd "$dir"
dir="`pwd`"
wdroot="`larch tree-root --accurate`"

cd "$here"
cd "`dirname \"$output_dir\"`"
output_dir="`pwd`/`basename \"$output_dir\"`"

cd "$here"
cd "`dirname \"$spec_file\"`"
spec_file="`pwd`/`basename \"$spec_file\"`"

if test -z "$title" ; then
  title="Patch Set Index for `basename \"$wdroot\"`"
fi



################################################################
# Greetings
# 
if test ! -z "$quiet" ; then
  larch heading "patch-set-web\\n"
  printf "arguments: %s\\n" "$command_line" | fold -w 60 | larch body-indent
  larch heading --sub "patch-set-web start time: %s\\n" "`date`"
  larch heading --sub "output dir: %s\\n" "$output_dir"
  larch heading --sub "project tree: %s\\n" "$wdroot"
fi


################################################################
# Start the Index
# 
# 

html_quote()
{
  sed -e '{
            s/&/\&amp;/g
            s/</\&lt;/g
            s/>/\&gt;/g
            s/"/\&quot;/g
          }'
}

mkdir -p "$output_dir"

cd "$output_dir"

printf "<html>\\n" > index.html
printf "<head>\\n" >> index.html
printf "<title>%s</title>\\n" "$title" >> index.html
printf "</head>\\n" >> index.html
printf "\\n" >> index.html
printf "<body text=\"#e6e6b1\"\\n" >> index.html
printf "      bgcolor=\"#560000\">\\n" >> index.html
printf "\\n" >> index.html

larch top larch heading --html "%s\n" "$title" >> index.html

larch top larch heading --html --sub "branches indexed:\n" >> index.html

cat "$spec_file" \
| html_quote \
| awk \
    '
     BEGIN {
             print "<table border bgcolor=#bebebe>"
             print "<th><font color=#000000>branch name<br>(links to branch ChangeLog)</font></th> <th><font color=#000000>description of branch</font></th>"
             in_body = 0;
             some = 0;
           }
     {
       if (match($0, "^[ \t]"))
         {
           if (!in_body)
             {
               in_body = 1;
               print "<td><font color=#000000><pre>";
             }
           print $0;
         }
       else
         {
           if (in_body)
             {
               print "</pre></font></td>";
               in_body = 0;
             }
           if (some)
             {
               print "</tr>";
             }
           some = 1;
           print "<tr><td><font color=#000000>";
           print "<a href=\"=changelogs/" $0 ".html\">" $0 "</a>";
           anchor = $0;
           sub("/", "--", anchor);
           print "<p align=right><small><a href=\"index.html#patch-index-" anchor "\">patch index</a></small>";
           print "</font></td>";
         }
     }
     END {
           if (in_body)
             {
               print "</pre></font></td>";
             }
           if (some)
             print "</tr>";
           print "</table>";
         }' \
>> index.html

larch top larch heading --html --sub "patch set indexes:\\n" >> index.html
       

for log in `cat "$spec_file" | grep -e "^[^[:space:]]"` ; do

  archive="`larch parse-package-name --arch \"$log\"`"
  version="`larch parse-package-name --non-arch \"$log\"`"

  if test ! -z "$quiet" ; then
    larch heading --sub "log: %s\\n" "$log"
  fi


  #
  # Get the patch set and build =REPORT.html
  # 
  for patch in `larch log-ls --reverse "$archive/$version"` ; do

    if test ! -z "$quiet" ; then
      larch heading --sub --sub "patch: %s\\n" "$patch"
    fi

    if ! test -e "$output_dir/$archive/$version/$patch" ; then
      mkdir -p  "$output_dir/$archive/$version"
      if ! larch get-patch "$archive/$version--$patch" "$output_dir/$archive/$version/$patch" 2> /dev/null \
      ; then
        mkdir -p "$output_dir/$archive/$version/$patch" ; \
        larch top larch heading --html "$archive/$version" > "$output_dir/$archive/$version/$patch/=REPORT.html"
        larch top larch heading --html --sub "no patch set associated with this revision" \
             >> "$output_dir/$archive/$version/$patch/=REPORT.html"
      else
        larch patch-report --title "$archive/$version--$patch" --html "$output_dir/$archive/$version/$patch" > "$output_dir/$archive/$version/$patch/=REPORT.html"
      fi
    fi

    # 
    # Get the log message, too
    # 
    larch cat-log "$archive/$version--$patch" > "$output_dir/$archive/$version/$patch/=log"

  done

  # 
  # Build the hypertext changelogs
  # 

  mkdir -p "$output_dir/=changelogs/$archive/"

  printf "<html>\\n" > "$output_dir/=changelogs/$archive/$version.html"
  printf "<head>\\n" >> "$output_dir/=changelogs/$archive/$version.html"
  printf "<title>%s</title>\\n" "ChangeLog for $archive/$version" >> "$output_dir/=changelogs/$archive/$version.html"
  printf "</head>\\n" >> "$output_dir/=changelogs/$archive/$version.html"
  printf "\\n" >> "$output_dir/=changelogs/$archive/$version.html"
  printf "<body>\\n" >> "$output_dir/=changelogs/$archive/$version.html"
  printf "\\n" >> "$output_dir/=changelogs/$archive/$version.html"

  larch top larch heading --html "ChangeLog for %s\\n" "$archive/$version" >> "$output_dir/=changelogs/$archive/$version.html"

  printf "<pre>\\n" >> "$output_dir/=changelogs/$archive/$version.html"

  larch changelog --dir "$wdroot" "$archive/$version" \
  | html_quote \
  | awk -v archive="$archive" \
        -v version="$version" \
    '
    function match_cl_ref()
    {
      return match($0, "^[ \t]*\\*[ \t]*" archivere "/" basere "(--" basere ")?--" vsnre "--" patchre "[ \t]*");
    }

    BEGIN {
            await_summary = 0;
            archivere="[-a-zA-Z0-9]+(\\.[-a-zA-Z0-9]*)*@[-a-zA-Z0-9.]*(--[-a-zA-Z0-9.]*)?";
            basere="([[:alpha:]]([[:alnum:]]*(-[[:alnum:]]+)?)*)";
            vsnre="([[:digit:]]+\\.[[:digit:]]+)";
            patchre="(base-0|patch-[0-9]+|version-0|versionfix-[0-9]+)";
          }

    match($0, "^[12][0-9]") {
                              current_patch = $0;
                              sub("^.*\t", "", current_patch);
                              gsub("[ \t]+", "", current_patch);
                              await_summary = 1;

                              print "<a name=\"" current_patch "\"></a>";
                              sub(current_patch "$", "<a href=\"../../" archive "/" version "/" current_patch "/=REPORT.html\">" current_patch "</a>", $0);
                            }

    (await_summary && match($0, "^[ \t]*Summary:")) {
                    sub("Summary:", "Summary: <a type=\"text/plain\" href=\"../../" archive "/" version "/" current_patch "/=log\"><small>(full log entry)</small></a>", $0);
                                                            await_summary = 0;
                                                         }

    match_cl_ref() {
                     ref_patch = $0;
                     sub("^[ \t]*\\*[ \t]*", "", ref_patch);
                     sub("[ \t]*$", "", ref_patch);
                     cl_loc = ref_patch;
                     cl_lvl = ref_patch;
                     sub("^" archivere "/" basere "(--" basere ")?--" vsnre "--", "", cl_lvl);
                     sub("--" cl_lvl "$", "", cl_loc);
                     $0 = "     * <a href=\"../" cl_loc ".html#" cl_lvl "\">" cl_loc "/" cl_lvl "</a>";
                   }
    { print $0; }
    ' \
  >> "$output_dir/=changelogs/$archive/$version.html"

  printf "</pre>\\n" >> "$output_dir/=changelogs/$archive/$version.html"

  printf "\\n" >> "$output_dir/=changelogs/$archive/$version.html"
  printf "</body>\\n" >> "$output_dir/=changelogs/$archive/$version.html"
  printf "\\n" >> "$output_dir/=changelogs/$archive/$version.html"


  # 
  # Build the index of patches.
  # 

  printf "<a name=\"%s\"></a>\n" "patch-index-$archive--$version" >> index.html
  printf "<table border bgcolor=#bebebe>\\n" >> index.html

  printf "\\n" >> index.html

  printf "<caption>" >> index.html
  printf "%s" "$archive/$version" | html_quote >> index.html
  printf "</caption>\\n" >> index.html

  printf "\\n" >> index.html

  printf "<tr bgcolor=\"#ffffff\">\\n" >> index.html
  printf "<td align=center colspan=3><font color=#000000>\\n" >> index.html
  printf "<pre>\\n" >> index.html

  cat "$spec_file" \
  | awk -v branch="$log" \
      '
       BEGIN { in_body = 0; }

       match($0, "^[^ \t]") {
                                    in_body = ($0 == branch);
                                  }

       match($0, "^[ \t]") { 
                                   if (in_body)
                                     print $0;
                                 }
      ' \
  | html_quote \
  >> index.html

  printf "</pre>\\n" >> index.html
  printf "</font></td>\\n" >> index.html
  printf "</tr>\\n" >> index.html

  printf "\\n" >> index.html

  printf "<tr>\\n" >> index.html
  printf "  <th><font color=#000000>patch</font></th>\\n" >> index.html
  printf "  <th><font color=#000000>author<br>(link to log entry)</font></th>\\n" >> index.html
  printf "  <th><font color=#000000>summary</font></th>\\n" >> index.html
  printf "</tr>\\n" >> index.html

  printf "\\n" >> index.html

  if test -z "`larch log-ls \"$archive/$version\"`" ; then
    printf "<tr><td colspan=3><font color=#000000><pre>                        &lt;none&gt;                        </pre></font></td></tr>\\n" >> index.html
  else
    larch log-ls --reverse --summary --creator --date "$archive/$version" \
    | html_quote \
    | awk -v root="$archive/$version" \
          -v suffix="/=REPORT.html" \
        '
         BEGIN { some = 0; in_body = 0; }
         {
           if (match($0, "^[ \t]"))
             {
               if (!in_body)
                 {
                   in_body = 1;
                   print "<td><font color=#000000><pre>";
                 }
               print $0;
             }
           else
             {
               if (in_body)
                 {
                   print "</pre></font></td>";
                   in_body = 0;
                 }
               if (some)
                 print "</tr>";
               some = 1;
               print "<tr>";
               print "<td><font color=#000000>";
               if ( "" == root suffix )
                 {
                   print "<code>" $1 "</code>";
                 }
               else
                 {
                   print "<a href=" root "/" $1 suffix "><code>" $1 "</code></a>";
                 }
               print "</font></td>";
  
               getline date;
               getline creator;
               print "<td align=\"right\"><font color=#000000>";
               print "<a type=\"type/plain\" href=" root "/" $1 "/=log>" creator "</a>";
               print "<br><small><i>" date "</i></small>";
               print "</font></td>";
            }
         }
         END {
               if (in_body)
                 print "</font></td></pre>";
               if (some)
                 print "</tr>";
             }' \
    >> index.html
  fi

  printf "</table>\\n" >> index.html
  printf "<br>\\n" >> index.html
  printf "<br>\\n" >> index.html

done

printf "\\n" >> index.html
printf "</body>\\n" >> index.html
printf "\\n" >> index.html

if test ! -z "$quiet" ; then
  larch heading --sub "patch-set-web finish time: %s\\n" "`date`"
fi

# tag: Tom Lord Wed Jan  9 02:47:02 2002 (web/patch-set-web.sh)
#
