#!/usr/bin/env bash #set -x # Usage: write-user-docs [TOOLS] # # This script writes/updates the user documentation. User docs come from # three places: each tool's POD (pod2rst is used to convert their POD docs # to RST), static .rst file (docs/*.rst), and most head1 sections in # docs/percona-toolkit.pod (also converted writh pod2rst; this file is needed # in .pod form because it's used to make the percona-toolkit man page). # # Run this script from any directory in the branch whose user docs you want # to build. For example, to build user docs in the 2.0 branch: # $ cd ~dev/perona-toolkit/2.0 # $ util/write-user-docs # Unlike other scripts, this one does *not* use PERCONA_TOOLKIT_BRANCH. # # After all the RST files have been written, this script runs `make html' # in config/sphinx-build/ (which has a Makefile) to build the online HTML # docs, which are saved in docs/user/html. # # If no tools are specified on the command line, then docs for bin/* are # written (plus all the extra sections). # # To rewrite all user docs from scratch: # rm -rf docs/user/* # util/write-user-docs # # Exits 0 on success, else 1 on warnings and errors. # ############################################################################ # Parsing options # ############################################################################ usage() { echo "This script writes/updates the user documentation. Usage: write-user-docs [ -h ] [ -p ] [ -t ] [TOOLS] If no option (html, pdf) specified, builds both html and pdf. -h builds docs in html -t builds docs in html with new theme -p builds pdf doc TOOLS: If no tools are specified on the command line, then docs for bin/* are written (plus all the extra sections). " exit 2 } TEMP=$(getopt hpt $*) if [ $? -ne 0 ]; then usage fi eval set -- "$TEMP" unset TEMP while true; do case "$1" in -h) MAKE_HTML="true" MAKE_THTML="false" shift continue ;; -t) MAKE_THTML="true" MAKE_HTML="false" shift continue ;; -p) MAKE_PDF="true" shift continue ;; --) shift break ;; *) echo 'Internal error!' >&2 usage ;; esac done # if both specified or none, build both if [[ "$MAKE_HTML" == "$MAKE_PDF" ]]; then MAKE_HTML="true" MAKE_PDF="true" fi # ############################################################################ # Standard startup, find the branch's root directory # ############################################################################ exit_status=0 die() { echo "$1" >&2 exit 1 } warn() { echo "$1" >&2 exit_status=1 } cwd=$PWD while [ ! -f Makefile.PL ] && [ $(pwd) != "/" ]; do cd .. done if [ ! -f Makefile.PL ]; then die "Cannot find the root directory of the Percona Toolkit branch" fi BRANCH=`pwd` cd $cwd # ############################################################################ # Paths # ############################################################################ DOCS_DIR=$BRANCH/docs RST_DIR=$DOCS_DIR/user # ############################################################################ # Subroutines # ############################################################################ fix_html () { local name="$1" perl -MFile::Basename=basename -le ' my $f = shift; my $tool = basename($f); $tool =~ s/\.html//; my $out = do { open my $fh, q{<}, $f or die "$f: $!"; local $/; <$fh> }; $out =~ s{ \Q
\E\s* \Q--\E([^<]+) \Q --$2}, $f or die "Cannot open $f for writing: $!"; print { $fh } $out; close $fh or die "Cannot close $f: $!"; ' "$RST_DIR/html/$name.html" } write_rst() { local file="$1" local tool="$(basename $1)" if [ ! -f $file ]; then warn "$file does not exist" return fi if [ -h $file ]; then local link="$(readlink $file)" echo " .. program:: ${tool} ============================ :program:\`${tool}\` ============================ NAME ==== :program:\`$(basename $file)\` is a symbolic link to ${link}. Please read documentation for ${link}. " > $RST_DIR/$tool.rst else $BRANCH/util/pod2rst-fixed.packed $file > $RST_DIR/$tool.rst if [ $? -eq 0 ]; then echo "Wrote $RST_DIR/$tool.rst" else die "Error writing $RST_DIR/$tool.rst" fi fi } # Parse the head1 sections from percona-toolkit.pod and write them as # individual .rst files, except the sections in the grep -Ev below. # For example, head1 SYSTEM REQUIREMENTS becomes system_requirements.rst. # These sections are included in index.rst. write_sections() { # Grep head1 sections from percona-toolkit.pod, except a few, and # change spaces to _ so the for..do loop doesn't treat "SYS REQS" # as two sections. sections=$(grep '^=head1' $DOCS_DIR/percona-toolkit.pod | sed -e 's/=head1 //' -e 's/ /_/g' | grep -Ev "^NAME|DESCRIPTION|TOOLS") for section in $sections; do # Put spaces back in the section's name. header=$(echo $section | sed -e 's/_/ /g') # Convert the section name to a simple filename. filename=$(echo $section | sed -e 's/,//g' -e 's/[()]//g' | tr "[:upper:]" "[:lower:]"); # Extract the section as POD. local start_line=$(grep --line-number "^=head1 $header" $DOCS_DIR/percona-toolkit.pod | cut -d':' -f1) if [ -z "$start_line" ]; then die "Cannot find $from in $DOCS_DIR/percona-toolkit.pod" fi tail -n +$start_line $DOCS_DIR/percona-toolkit.pod | awk "BEGIN { getline; print \$0 } /^=head1|=cut/ { exit } { print }" > /tmp/$filename.pod # Convert POD to RST and remove all the Perl highlight blocks. $BRANCH/util/pod2rst-fixed.packed /tmp/$filename.pod --no-fix | sed -e 's/.. highlight:: perl//g' > /tmp/$filename.tmp # Remove extra blank lines. cat -s /tmp/$filename.tmp > $RST_DIR/$filename.rst # Remove tmp files. rm /tmp/$filename.pod rm /tmp/$filename.tmp echo "Wrote $RST_DIR/$filename.rst" done } # ############################################################################ # Script starts here # ############################################################################ WRITE=${WRITE:-1} if [ $WRITE -eq 1 ]; then if [ $# -gt 0 ]; then for tool; do write_rst $tool done else for tool in `ls $BRANCH/bin/*`; do write_rst $tool done fi # Parse and write certain parts of percona-toolkit.pod. write_sections # Copy all static .rst files, like index.rst. cp $DOCS_DIR/*.rst $RST_DIR/ echo "Copied $DOCS_DIR/*.rst to $RST_DIR" fi BUILD=${BUILD:-1} if [ $BUILD -eq 1 ]; then cd $BRANCH/config/sphinx-build if [ "${MAKE_HTML}" = "true" ]; then make html fi if [ "${MAKE_PDF}" = "true" ]; then make latexpdf fi if [ "${MAKE_THTML}" = "true" ]; then make thtml fi exit_status=$(( exit_status | $? )) fi if [ $# -gt 0 ]; then for tool; do name="$(basename $tool)" fix_html $name done else for tool in `ls $BRANCH/bin/*`; do name="$(basename $tool)" fix_html $name done fi exit $exit_status