openstack-doc-tools/bin/doc-tools-check-languages
Andreas Jaeger 67d94fe198 Do not publish doctrees for translated guides
As done for RST building, do not publish doctrees for translated guides,
place them instead outside of the build directory.

Change-Id: Ia24b95f896e831cb4408112cdae6fb94c07da367
2015-11-15 14:04:18 +01:00

353 lines
12 KiB
Bash
Executable File

#!/bin/bash
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
BUILD_FAIL=0
if [ -x "$(command -v getconf)" ]; then
NUMBER_OF_CORES=$(getconf _NPROCESSORS_ONLN)
else
NUMBER_OF_CORES=2
fi
function setup_directories {
language=$1
for directory in ${DIRECTORIES["$language"]} ; do
echo " $directory"
openstack-generate-docbook -l $language -b $directory -r $DOC_DIR
done
}
function setup_language {
language=$1
echo "Setting up files for $language"
echo "======================="
echo " Directories:"
setup_directories $language
if [ -n "$POM_FILE" ] ; then
cp $POM_FILE generated/$language/pom.xml
fi
}
function build_rst {
language=$1
book=$2
# First build all the single po files
# Note that we need to run inside a venv since the venv we are run in
# uses SitePackages=True and we have to install Sphinx in the venv
# together with openstackdocstheme. With SitePackages, the global Sphinx
# is used and that will not work with a local openstackdocstheme installed.
TAG=""
# We need to extract all strings, so add all supported tags
if [ ${book} = "firstapp" ] ; then
TAG="-t libcloud -t fog -t dotnet -t openstacksdk -t pkgcloud -t shade"
fi
if [ ${book} = "install-guide" ] ; then
TAG="-t obs -t rdo -t ubuntu -t debian"
fi
tox -evenv "sphinx-build -j $NUMBER_OF_CORES -q -E -W -b gettext $TAG ${DOC_DIR}${book}/source/ \
${DOC_DIR}${book}/source/locale/"
# Merge the common-rst po file in
if [[ -e ${DOC_DIR}common-rst/source/locale/${language}/LC_MESSAGES/common-rst.po ]] ; then
msgcat --use-first -o ${DOC_DIR}${book}/source/locale/${language}/${book}.po \
${DOC_DIR}${book}/source/locale/${language}/LC_MESSAGES/${book}.po \
${DOC_DIR}common-rst/source/locale/${language}/LC_MESSAGES/common-rst.po
mv -f ${DOC_DIR}${book}/source/locale/${language}/${book}.po \
${DOC_DIR}${book}/source/locale/${language}/LC_MESSAGES/${book}.po
fi
# Now run msgmerge on all files
for f in ${DOC_DIR}${book}/source/locale/*.pot ; do
# Skip the master file
if [ $f = "${DOC_DIR}${book}/source/locale/${book}.pot" ] ; then
continue
fi
bf=$(basename $f)
# Remove .pot
bfname=${bf%.pot}
msgmerge --silent -o ${DOC_DIR}${book}/source/locale/${language}/LC_MESSAGES/${bfname}.po \
${DOC_DIR}${book}/source/locale/${language}/LC_MESSAGES/${book}.po \
${DOC_DIR}${book}/source/locale/${bf}
msgfmt ${DOC_DIR}${book}/source/locale/${language}/LC_MESSAGES/${bfname}.po \
-o ${DOC_DIR}${book}/source/locale/${language}/LC_MESSAGES/${bfname}.mo
done
# Build all books
if [ ${book} = "firstapp" ] ; then
# Firstapp has several variations, build all of them
for tag in libcloud dotnet fog openstacksdk pkgcloud shade; do
BUILD_DIR="${DOC_DIR}${book}/build-${tag}/html"
DOCTREES="${BUILD_DIR}.doctrees"
tox -evenv "sphinx-build -j $NUMBER_OF_CORES -q -E -t $tag -D language=${language} \
-d ${DOCTREES}
${DOC_DIR}${book}/source/ \
${BUILD_DIR}"
mkdir -p publish-docs/${language}/${book}-${tag}
rsync -a ${DOC_DIR}${book}/build-${tag}/html/ \
publish-docs/${language}/${book}-${tag}
done
elif [ ${book} = "install-guide" ] ; then
# Install Guide has several variations, build all of them
TAGS="obs rdo ubuntu debian"
INDEX=${DOC_DIR}${book}/source/index.rst
# For translation work, we should have only one index file,
# because our tools generate translation resources from
# only one index file.
# Therefore, this tool uses one combined index file
# while processing title and toctree for each distribution.
# Save and restore the index file
cp -f ${INDEX} ${INDEX}.save
trap "mv -f ${INDEX}.save ${INDEX}" EXIT
for tag in $TAGS; do
##
# Because Sphinx uses the first heading as title regardless of
# only directive, replace title directive with the proper title
# for each distribution to set the title explicitly.
title=$(grep -m 1 -A 5 "^.. only:: ${tag}" ${INDEX} | \
sed -n 4p | sed -e 's/^ *//g')
sed -i -e "s/\.\. title::.*/.. title:: ${title}/" ${INDEX}
##
# Sphinx builds the navigation before processing directives,
# so the conditional toctree does not work.
# We need to prepare toctree depending on distribution
# only with one toctree before exectuing sphinx-build.
# Get line number of each tag
lineno_start=$(grep -n "^Contents" ${INDEX} | sed -e 's/:.*//')
lineno_end=$(grep -n "^.. end of contents" ${INDEX} | sed -e 's/:.*//')
lineno_debian=$(grep -n "^.. only:: debian" ${INDEX} \
| tail -1 | sed -e 's/:.*//')
lineno_notdebian=$(grep -n "^.. only:: [^d]" ${INDEX} \
| tail -1 | sed -e 's/:.*//')
# Remove indent for pseudo only directive
sed -i "${lineno_start},${lineno_end} s/^ *\.\. toctree/.. toctree/" ${INDEX}
sed -i "${lineno_start},${lineno_end} s/^ */ /" ${INDEX}
# Remove unnecessary toctree for each distribution
if [[ "$tag" == "debian" ]]; then
sed -i "${lineno_notdebian},${lineno_debian}d" ${INDEX}
else
sed -i "${lineno_debian},$((${lineno_end}-1))d" ${INDEX}
sed -i "${lineno_notdebian}d" ${INDEX}
fi
# Build the guide
BUILD_DIR="${DOC_DIR}${book}/build-${tag}/html"
DOCTREES="${BUILD_DIR}.doctrees"
tox -evenv "sphinx-build -j $NUMBER_OF_CORES -q -E -t $tag \
-D language=${language}
-d ${DOCTREES}
${DOC_DIR}${book}/source/ \
${BUILD_DIR}"
mkdir -p publish-docs/${language}/${book}-${tag}
rsync -a ${DOC_DIR}${book}/build-${tag}/html/ \
publish-docs/${language}/${book}-${tag}
# Restore the index file
cp -f ${INDEX}.save ${INDEX}
# Remove Debian specific content from other guides
if [[ "$tag" != "debian" ]]; then
rm -rf publish-docs/${language}/{book}-$tag/debconf
fi
done
else
BUILD_DIR="${DOC_DIR}${book}/build/html"
DOCTREES="${BUILD_DIR}.doctrees"
tox -evenv "sphinx-build -j $NUMBER_OF_CORES -q -E -D language=${language} \
-d ${DOCTREES} \
${DOC_DIR}${book}/source/ \
${BUILD_DIR}"
mkdir -p publish-docs/${language}/${book}/
rsync -a ${DOC_DIR}${book}/build/html/ publish-docs/${language}/${book}/
fi
# Remove newly created files
git clean -f -q ${DOC_DIR}${book}/source/locale/${language}/LC_MESSAGES/*.po
git clean -f -x -q ${DOC_DIR}${book}/source/locale/${language}/LC_MESSAGES/*.mo
git clean -f -q ${DOC_DIR}${book}/source/locale/*.pot
# Revert changes to po file
git reset -q ${DOC_DIR}${book}/source/locale/${language}/LC_MESSAGES/${book}.po
git checkout -- ${DOC_DIR}${book}/source/locale/${language}/LC_MESSAGES/${book}.po
}
function test_language {
language=$1
echo
echo "Building for language $language"
echo
args=("-v")
if [[ $PURPOSE -eq "publish" ]]; then
args+=("--publish")
fi
args+=("--check-build" "-l $language")
BUILD_XML=0
for book in ${BOOKS["$language"]}; do
if [ ${SPECIAL_BOOKS[$book]+_} ] ; then
if [ ${SPECIAL_BOOKS[$book]} = "RST" ] ; then
echo "Building translated RST book $book for $language"
build_rst $language $book
if [[ $? -eq 0 ]] ; then
echo "... succeeded"
else
echo "... failed"
BUILD_FAIL=1
fi
continue
fi
fi
args+=("--only-book $book")
BUILD_XML=1
done
if [ "$BUILD_XML" -eq "1" ] ; then
setup_language $language
openstack-doc-test ${args[@]}
if [[ $? -eq 0 ]] ; then
echo "... succeeded"
else
echo "... failed"
BUILD_FAIL=1
fi
fi
}
function handle_draft_language {
language=$1
echo
echo "Moving drafts for language $language"
echo
mkdir -p publish-docs/draft/$language
for book in ${DRAFTS["$language"]}; do
case "${book}" in
config-reference)
mv publish-docs/$language/draft/$book publish-docs/draft/$language/$book
# Remove directory if it's empty and do not fail if it's non-empty
rmdir publish-docs/$language/draft || true
;;
firstapp)
for tag in libcloud dotnet fog openstacksdk pkgcloud shade; do
mv publish-docs/$language/$book-${tag} \
publish-docs/draft/$language/$book-${tag}
done
# Remove directory if it's empty and do not fail if it's non-empty
rmdir publish-docs/$language/ || true
;;
install-guide)
for tag in obs rdo ubuntu debian; do
mv publish-docs/$language/$book-${tag} \
publish-docs/draft/$language/$book-${tag}
done
# Remove directory if it's empty and do not fail if it's non-empty
rmdir publish-docs/$language/ || true
;;
*)
mv publish-docs/$language/$book publish-docs/draft/$language/$book
;;
esac
done
}
function usage {
echo "usage: $0 CONF_FILE PURPOSE LANGUAGE1 LANGUAGE2 ..."
echo
echo "CONF_FILE is the path to the configuration file."
echo
echo "PURPOSE is either 'test' or 'publish'."
echo
echo "LANGUAGE is either 'all' or 'LANG'."
echo "LANG is a language code like 'fr' or 'ja'."
}
# Declare in case it's not in the file
declare -A SPECIAL_BOOKS
declare -A DRAFTS
CONF_FILE=$1
shift
if [[ -z $CONF_FILE ]]; then
usage
exit 1
fi
if [[ ! -e $CONF_FILE ]]; then
echo "Error: the configuration file '$CONF_FILE' does not exist"
exit 1
fi
source $CONF_FILE
if [[ -z $(declare -p BOOKS 2> /dev/null | grep 'declare -A BOOKS') || \
-z $(declare -p DIRECTORIES 2> /dev/null | grep 'declare -A DIRECTORIES') || \
-z $DOC_DIR ]]; then
echo "Error: the configuration file '$CONF_FILE' is invalid"
exit 1
fi
case "$1" in
test|publish)
PURPOSE=$1
shift
;;
*)
usage
exit 1
;;
esac
for language in "$@" ; do
case "$language" in
all)
for language in "${!BOOKS[@]}"; do
test_language $language
done
# Move draft language guides
for language in "${!DRAFTS[@]}"; do
handle_draft_language $language
done
;;
*)
if [[ -n ${BOOKS[$language]} ]]; then
test_language $language
if [ ${DRAFTS["${language}"]+_} ] ; then
handle_draft_language $language
fi
else
BUILD_FAIL=1
echo "Error: language $language not handled"
fi
;;
esac
done
exit $BUILD_FAIL