#!/usr/bin/env bash
# v0.1 Quick and dirty script to grab fossil's help and stuff it into a file.
# v0.2 Now I have working sed expressions, I can grab the help keywords.
# v0.3 This gets me the keywords and only the keywords.
# v0.4 Glue all relevant things together and produce an info file.
# v0.5 Working out sed/head/tail differences between GNU and BSD.
# v0.6 Replaced "head -n -1" with "sed '$d'" which does the same thing.
# v0.7 Adding help in separately for normal/auxil commands.
# v0.8 Added common options and Features. Got rid of some obvious bugs.
# v0.9 Added @bye at end.
# v0.10 Retitled Features to Fossil.
# v0.11 Added entries relevant to system-wide dir entry.
# v0.12 Reworded section introductions.
# v0.13 Added testing commands to texi output.
# v0.14 Added web commands to texi output. Note added far later.
# v0.15 Added Fossil settings.
#        Builds a correct texinfo file (finally) on OpenBSD and NetBSD.
#
# Requires fossil, tail, GNU sed and makeinfo
#

##### Header #####
# put header, then common node, finish menu, then uncommon node then finish menu
echo "Create Header"
printf "\\input texinfo
@settitle Fossil
@setfilename fossil.info
@c @author brickviking
@dircategory Development
@direntry
* Fossil: (fossil).        A distributed version control system.
@end direntry

" > fossil.texi
printf "@c Initial rendition to convert fossil help -a -v into texinfo for further
@c massaging by makeinfo. Scripts to do this automatically may come
@c later. Don't expect this to conform to GNU guidelines.

" >> fossil.texi

# Add a title page
printf "@titlepage
@title Fossil
@subtitle The Fossil Source Code Manager (fossil-scm)
@subtitle A distributed version control system
@author The fossil committers

@page
@vskip 0pt plus 1filll

@end titlepage

" >> fossil.texi

# Add @contents
printf "@contents\n

" >> fossil.texi

# Check fossil version. Only thing wrong with this is which fossil binary is picked up first.
# Older versions of fossil didn't have a version number, just a truncated commit hash.
fossil version | sed 's/This is fossil version /@set VERSION /' | cut -c1-17  >> fossil.texi

# Insert repeat of Top node for PDF. We have to hack to do this
printf "@ifnotinfo
@ifnothtml
@node Introduction
@top Introduction for Fossil - a distributed version control system

Fossil is a distributed version control system (DVCS) with built-in
forum, wiki, ticket tracker, CGI/HTTP interface, and HTTP server.
This file documents version @value{VERSION} of Fossil.

@end ifnothtml
@end ifnotinfo
" >> fossil.texi

printf "@node Top
@chapter Fossil

Fossil is a distributed version control system (DVCS) with built-in
forum, wiki, ticket tracker, CGI/HTTP interface, and HTTP server.
This file documents version @value{VERSION} of Fossil.

@c     @node menu
@menu
* Introduction::               Introduction and features listed from the website front page.
* Common commands::      These are the commands that are most likely to be used.
* Uncommon commands::    These aren't used as often, but they're still there when needed.
* Test commands::        These are definitely not recommended for production use.
* Fossil settings::      These describe fossil settings. 
* Web commands::         Available webpage help.
* Common arguments::     Arguments common to all commands.
* License::              The license agreement of the fossil project.
@end menu

You can get help for any of the available fossil commands by using:

@example
fossil help some-command
@end example

This will show you help on some-command. I've attempted to put all the available
help nodes from fossil into here, but it's vaguely possible I've missed some.

" >> fossil.texi

# Add in the Features from the front webpage
printf "@node Introduction,Common commands,Top,Top
@chapter Introduction

Fossil is a distributed version control system (DVCS) with built-in
forum, wiki, ticket tracker, CGI/HTTP interface, and HTTP server.
This file documents version @value{VERSION} of Fossil.

This is a quick breakdown of the things that you get when you run the fossil binary:

@enumerate
@item
Integrated Bug Tracking, Wiki, Forum, and Technotes
 - In addition to doing distributed version control like Git and Mercurial, Fossil also supports bug tracking, wiki, forum, and tech-notes.

@item
Built-in Web Interface
 - Fossil has a built-in and intuitive web interface that promotes project situational awareness. Type \"fossil ui\" and Fossil automatically opens a web browser to a page that shows detailed graphical history and status information on that project.

@item
Self-Contained
 -  Fossil is a single self-contained stand-alone executable. To install, simply download a precompiled binary for Linux, Mac, OpenBSD, or Windows and put it on your  \$PATH. Easy-to-compile source code is available for users on other platforms.

@item
Simple Networking
 - No custom protocols or TCP ports. Fossil uses plain old HTTP (or HTTPS or SSH) for all network communications, so it works fine from behind restrictive firewalls, including proxies. The protocol is bandwidth efficient to the point that Fossil can be used comfortably over dial-up or over the exceedingly slow Wifi on airliners.

@item
CGI/SCGI Enabled
 - No server is required, but if you want to set one up, Fossil supports four easy server configurations.

@item
Autosync
 -  Fossil supports \"autosync\" mode which helps to keep projects moving forward by reducing the amount of needless forking and merging often associated with distributed projects.

@item
Robust & Reliable
 - Fossil stores content using an enduring file format in an SQLite database so that transactions are atomic even if interrupted by a power loss or system crash. Automatic self-checks verify that all aspects of the repository are consistent prior to each commit.

@item
Free and Open-Source
 - Uses the 2-clause BSD license.
@end enumerate
" >> fossil.texi

###### Common commands
echo "List common commands"

printf "@node Common commands,Uncommon commands,Introduction,Top
@chapter Common commands

These are the more commonly used commands for the average fossil user. They're
listed by fossil when you run the command:

@example
fossil help
@end example

They are similar to commands that are available in other VCS programs such as
subversion, git or mercurial.

" >> fossil.texi

# begin menu for common keywords
printf "@menu\n" >> fossil.texi

# Slurp in Common keywords from fossil help
# WARNING: tail count is brittle
echo "Grab common keywords for menu"
for u in $(for t in $(fossil help | tail -n +11| sed '$d'); do echo "$t"; done | sort);  do echo "* ${u}::"; done >> fossil.texi

# Add end menu, add some space too
printf "@end menu

" >> fossil.texi

# Add in the actual help for common commands
# WARNING: tail count is brittle
# tail command pops off the first fourteen lines, sed commands remove the last two lines.
echo "Fossil output common help to workfile"

# I'd like if this could start at where the "Options:" is, and finish at the next
# pair of blank lines.
#printf "@table @option
#
#" >> fossil.texi

fossil help -v | tail -n +14 | sed '$d' | sed '$d' >workfile

# swap out @ with @@ so texinfo doesn't barf
echo "Doubling up the @'s"
sed -i -e 's/@/@@/g' workfile

echo "Swapping out # for @node ... \n@section ..."
# This swaps out "# keyword" with 
# @node keyword
# @section keyword
# breaks on *BSD's seds, needs gsed there

# Check the OS so we can use gsed if needed
MYOS="$(uname )"
if [[ ${MYOS} == "Linux" ]]; then
    sed -i -e 's/^##* \([a-z0-9-]\{1,\}\)/@node \1\n@section \1\n/' workfile
else
    # We'll assume we're on a BSD here, even though this won't always be true
    gsed -i -e 's/^##* \([a-z0-9-]\{1,\}\)/@node \1\n@section \1\n/' workfile
fi

# turns --switches into @option{--switches}
sed -i -e 's/--\([[:alnum:]-]\{1,\}\)/@option\{--\1\}/g' workfile
# now do the same for places where there's -f|--force
sed -i -e 's/|--\([[:alnum:]-]\{1,\}\)/|@option\{--\1\}/g' workfile
# turns -switches into @option{-switches}. Usually starts with space
sed -i -e 's/ -\([[:alnum:]-]\{1,\}\)/ @option\{-\1\}/g' workfile
# ... and adds it to the output file with some space
cat workfile >> fossil.texi

##### Uncommon commands ####
echo "List uncommon commands"
printf "
@node Uncommon commands,Test commands,Common commands,Top
@chapter Uncommon commands

These are auxiliary commands,  listed by fossil when you run the command:

@example
fossil help -x
@end example

They're not used quite as often, and are normally used in specific
circumstances, such as creating fossils suitable for hosting.

@menu
" >> fossil.texi

# Slurp in auxiliary/uncommon keywords - no need to remove last line here
echo "Grab uncommon keywords for menu"
for u in $(for t in $(fossil help -x); do echo "$t"; done | sort); do echo "* ${u}::"; done >> fossil.texi

echo "@end menu" >> fossil.texi
echo "" >> fossil.texi

# Now add all the help from "fossil help -x -v"
# WARNING: tail count is brittle
# sed comands remove the last two lines.
echo "Fossil output auxiliary help to workfile"
fossil help -x -v | tail -n +4 | sed '$d' | sed '$d' >workfile

# swap out @ with @@ so texinfo doesn't barf
echo "Doubling up the @'s"
sed -i -e 's/@/@@/g' workfile

# This swaps out "# keyword" with 
# @node keyword
# @unnumbered keyword
# breaks on *BSD's seds, needs gsed there
echo "Swapping out # for @node ... \n@unnumbered ..."

if [[ ${MYOS} == "Linux" ]]; then
    sed -i -e 's/^##* \([a-z0-9-]\{1,\}\)/@node \1\n@section \1\n/' workfile
else
    # We'll assume we're on a BSD here, even though this won't always be true
    gsed -i -e 's/^##* \([a-z0-9-]\{1,\}\)/@node \1\n@section \1\n/' workfile
fi

# turns --switches into @option{--switches}
sed -i -e 's/--\([[:alnum:]-]\{1,\}\)/@option\{--\1\}/g' workfile

# ... and adds it to the output file with a spacer line
cat workfile >> fossil.texi
echo "" >> fossil.texi

##### Now the test commands. Here be dragons. #####
echo "List test commands"
printf "@node Test commands,Fossil settings,Uncommon commands,Top
@chapter Testing commands

These are testing commands, listed by fossil when you run the command:

@example
fossil help -t
@end example

They're often used to solve specific little problems that didn't warrant a full
tool, but are useful enough to be kept around. They are most definitely not
supported, and the developers will expect to change these far more often. They
are not stable, so do not depend upon their behavior, or even their existence.

@menu\n" >> fossil.texi

# Insert test commands in here
echo "Grab test keywords for menu"
for u in $(for t in $(fossil help -t); do echo "$t"; done | sort); do echo "* ${u}::"; done >> fossil.texi

# Now end that menu (Test commands)
echo "@end menu

" >> fossil.texi

# Now add all the help from "fossil help -t -v"
# WARNING: tail count is brittle
# sed comands remove the last two lines.
echo "Fossil output test help to workfile"
fossil help -t -v | tail -n +4 | sed '$d' | sed '$d' >workfile

# swap out @ with @@ so texinfo doesn't barf
echo "Doubling up the @'s"
sed -i -e 's/@/@@/g' workfile

# This swaps out "# keyword" with 
# @node keyword
# @unnumbered keyword
# breaks on *BSD's seds, needs gsed there
echo "Swapping out # for @node ... \n@unnumbered ..."

if [[ ${MYOS} == "Linux" ]]; then
    sed -i -e 's/^##* \([a-z0-9-]\{1,\}\)/@node \1\n@section \1\n/' workfile
else
    # We'll assume we're on a BSD here, even though this won't always be true
    gsed -i -e 's/^##* \([a-z0-9-]\{1,\}\)/@node \1\n@section \1\n/' workfile
fi

# turns --switches into @option{--switches}
sed -i -e 's/--\([[:alnum:]-]\{1,\}\)/@option\{--\1\}/g' workfile

# ... and adds it to the output file with a spacer line
cat workfile >> fossil.texi
echo "" >> fossil.texi

##### Now, add in fossil settings #####
# The usual wyvern warnings.
echo "List settings"
printf "@node Fossil settings,Web commands,Test commands,Top
@chapter Fossil settings

These are help pages for settings within fossil, shown when you run:
@example
fossil help -s
@end example

@menu\n" >> fossil.texi

# Insert settings keywords in here
echo "Grab settings keywords for menu"
for u in $(for t in $(fossil help -s); do echo "$t"; done | sort); do echo "* ${u}::"; done >> fossil.texi

# and finish the menu
echo "@end menu

" >> fossil.texi
# Now add all the help from "fossil help -s -v"
# WARNING: tail count is brittle
# sed comands remove the last two lines.
echo "Fossil output test help to workfile"
fossil help -s -v | tail -n +4 | sed '$d' | sed '$d' >workfile

# swap out @ with @@ so texinfo doesn't barf
echo "Doubling up the @'s"
sed -i -e 's/@/@@/g' workfile

# This swaps out "# keyword" with 
# @node keyword
# @unnumbered keyword
# breaks on *BSD's seds, needs gsed there
echo "Swapping out # for @node ... \n@unnumbered ..."

if [[ ${MYOS} == "Linux" ]]; then
    sed -i -e 's/^##* \([a-z0-9-]\{1,\}\)/@node \1\n@section \1\n/' workfile
else
    # We'll assume we're on a BSD here, even though this won't always be true
    gsed -i -e 's/^##* \([a-z0-9-]\{1,\}\)/@node \1\n@section \1\n/' workfile
fi

# This has to be done before swapping --switches because the next command
# adds @option(--switches} and hence reuses the {}.
echo "Swapping out {} for @{ @}"
# swaps out {} for @{ @}
if [[ ${MYOS} == "Linux" ]]; then
    sed -i -e 's/{/@{/g' -e 's/}/@}/g' workfile
else
    gsed -i -e 's/{/@{/g' -e 's/}/@}/g' workfile
fi

# turns --switches into @option{--switches}
sed -i -e 's/--\([[:alnum:]-]\{1,\}\)/@option\{--\1\}/g' workfile

# ... and adds it to the output file with a spacer line
cat workfile >> fossil.texi
echo "" >> fossil.texi

# Now the webpage content. Here be wild wild web pages.
echo "List web commands"
printf "@node Web commands,Common arguments,Fossil settings,Top
@chapter Web commands

These are help pages for the internal web pages, listed by fossil when you run the command:

@example
fossil help -w
@end example

All of these can be provided to the URL line on the browser address input like the
example below, that starts from the final / (in this case, /timeline?ms=glob):

@example
https://fossil.example.com/fossil/timeline?ms=glob
@end example

@menu\n" >> fossil.texi

# Insert webpage keywords in here
echo "Grab web keywords for menu"
for u in $(for t in $(fossil help -w); do echo "$t"; done | sort); do echo "* ${u}::"; done >> fossil.texi


# Now end that menu (Webpages)
echo "@end menu

" >> fossil.texi

# Now add all the help from "fossil help -w -v"
# WARNING: tail count is brittle
# sed comands remove the last two lines.
echo "Fossil output webpage help to workfile"
fossil help -w -v | tail -n +4 | sed '$d' | sed '$d' >workfile

# swap out @ with @@ so texinfo doesn't barf
echo "Doubling up the @'s"
sed -i -e 's/@/@@/g' workfile

# This swaps out "# keyword" with 
# @node keyword
# @unnumbered keyword
# breaks on *BSD's seds, needs gsed there
echo "Swapping out # for @node ... \n@unnumbered ..."

if [[ ${MYOS} == "Linux" ]]; then
# use a different separator here, as we need to keep /_. in strings
    sed -i -e 's%^##* /\([_.a-z0-9-]\{1,\}\)%@node /\1\n@section /\1\n%' workfile
else
    # We'll assume we're on a BSD here, even though this won't always be true
    gsed -i -e 's%^##* /\([_.a-z0-9-]\{1,\}\)%@node /\1\n@section /\1\n%' workfile
fi

# This has to be done before swapping --switches because the next command
# adds @option(--switches} and hence reuses the {}.
echo "Swapping out {} for @{ @}"
# swaps out {} for @{ @}
if [[ ${MYOS} == "Linux" ]]; then
    sed -i -e 's/{/@{/g' -e 's/}/@}/g' workfile
else
    gsed -i -e 's/{/@{/g' -e 's/}/@}/g' workfile
fi

echo "Swapping out --switches for @option{--switches}"
# turns --switches into @option{--switches}
if [[ ${MYOS} == "Linux" ]]; then
    sed -i -e 's/--\([[:alnum:]-]\{1,\}\)/@option\{--\1\}/g' workfile
else
    gsed -i -e 's/--\([[:alnum:]-]\{1,\}\)/@option\{--\1\}/g' workfile
fi

# ... and adds it to the output file with a spacer line
cat workfile >> fossil.texi
echo "" >> fossil.texi

# Add in common args
echo "List common args"
echo "@node Common arguments,License,Web commands,Top
@chapter Common arguments

These are commandline arguments that are common to all fossil commands.

" >> fossil.texi

# Slurp in auxiliary/uncommon keywords
echo "Grab common args text"
# At the moment, this doesn't do lines, and also requires GNU sed
if [[ ${MYOS} == "Linux" ]]; then
    fossil help -o | sed -e '2,$s/^  /\n/' -e '2,$s/--\([[:alnum:]-]\{1,\}\)/@option\{--\1\}/g' >> fossil.texi
else
    fossil help -o | gsed -e '2,$s/^  /\n/' -e '2,$s/--\([[:alnum:]-]\{1,\}\)/@option\{--\1\}/g' >> fossil.texi
fi
# stray stuff that didn't work
# sed -e '/--/s/--\(.*\s+\)/@item --\1 /' >> fossil.texi
echo "" >> fossil.texi

# Add in licence. Look for it in two places, just in case we're in tools/ when
# we call this program.
if [[ -f COPYRIGHT-BSD2.txt ]]; then
  HERE="COPYRIGHT-BSD2.txt"
elif [[ -f ../COPYRIGHT-BSD2.txt ]]; then
  HERE="../COPYRIGHT-BSD2.txt"
else
	echo "Where's COPYRIGHT-BSD2.txt?"
fi
# TODO: This should fail if we couldn't find COPYRIGHT-BSD2.txt
printf "
@node License,,Common arguments,Top
@chapter License agreement

@include ${HERE}

" >> fossil.texi

# Every good thing has to end
echo "@bye" >> fossil.texi

# and now we make the final info file - commented out for now
# makeinfo fossil.texi

echo "Done ... for now. Please check fossil.texi file over for inconsistencies, and fill in descriptions."
echo "Once everything's good, you can run your system's makeinfo command to turn"
echo "your .texi file into a .info file to install where you need."
