Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Generate and upload docs for hackage packages
#!/bin/bash
# Options / Usage
# put this script in the same directory as your *.cabal file
# it will use the first line of "cabal info ." to determine the package name
# custom options for "cabal haddock" (cabal haddock --help,
# http://www.haskell.org/haddock/doc/html/invoking.html)
CUSTOM_OPTIONS=(--haddock-options='-q aliased')
# hackage server to upload to (and to search uploaded versions for)
HACKAGESERVER=hackage.haskell.org
# whether to use cabal install (1) or copy docs directly from cabal haddock (0)
# some user had troubles installing their package (or dependencies)
CABAL_INSTALL=1
# put your credentials into ~/.netrc: (see man netrc)
# machine $HACKAGESERVER
# login $USERNAME
# password $PASSWORD
# nothing to configure below this line
# How it works
#
# It tries to find your package on the given hackage server, and
# uploads the generated -doc.tar.gz.
# It first tries the released version, then the candidate.
#
# To generate the docs it uses "cabal install" to install into a temporary directory,
# with a temporary ghc package db in it.
set -e
status_code() {
local code=$(curl "http://${HACKAGESERVER}$1" --silent -o /dev/null --write-out %{http_code})
echo "http://${HACKAGESERVER}$1 $code" >&2
echo $code
}
self=$(readlink -f "$0")
base=$(dirname "${self}")
cd "${base}"
tmpdir=$(mktemp --tmpdir -d doc-package-XXXXXXX)
trap 'rm -rf "${tmpdir}"' EXIT
name=$(cabal info . 2>/dev/null | awk '{print $2;exit}')
plain_name="${name%-*}" # strip version number (must not contain a '-', the name itself can)
if [ "200" = "$(status_code /package/${name})" ]; then
echo "Found released version ${name}"
targeturl="/package/${name}/docs"
elif [ "200" = "$(status_code /package/${name}/candidate)" ]; then
echo "Found candidate version ${name}"
targeturl="/package/${name}/candidate/docs"
else
echo "Found no uploaded version"
targeturl=""
fi
prefix="${tmpdir}/prefix"
docdir="${prefix}/share/doc/${name}"
if [ "${CABAL_INSTALL}" = 1 ]; then
# after cabal install:
htmldir="${docdir}/html"
else
# without cabal install:
htmldir="${tmpdir}/dist/doc/html/${plain_name}"
fi
packagedb="${tmpdir}/package.conf.d"
mkdir -p "${packagedb}"
pkgdocdir="${tmpdir}/${name}-docs"
pkgdocarchive="${tmpdir}/${name}-doc.tar.gz"
cabal configure \
--builddir="${tmpdir}/dist" \
--disable-optimization --ghc-option -O0 \
--docdir="${docdir}" \
--prefix="${prefix}"
# need separate haddock step, as install doesn't forward --builddir to haddock with
# cabal install --enable-documentation
# otherwise configure+haddock could be merged into install
# (prefix cabal haddock options with --haddock- for cabal install)
cabal haddock \
--builddir="${tmpdir}/dist" \
--html-location='/package/$pkg-$version/docs' \
--haddock-option='--built-in-themes' \
--hoogle --html \
"${CUSTOM_OPTIONS[@]}" \
--contents-location='/package/$pkg-$version' \
--hyperlink-source
if [ "${CABAL_INSTALL}" = 1 ]; then
cabal install \
--builddir="${tmpdir}/dist" \
--docdir="${docdir}" \
--prefix="${prefix}" \
--ghc-pkg-option --no-user-package-conf \
--ghc-pkg-option --package-db="${packagedb}"
fi
cp -ar "${htmldir}" "${pkgdocdir}"
(cd "$(dirname ${pkgdocdir})"; tar --format=ustar -caf "${pkgdocarchive}" "$(basename ${pkgdocdir})")
mkdir -p dist/
echo "Copying $(basename ${pkgdocdir}) to dist/"
cp -ar "${pkgdocarchive}" dist/
if [ "${targeturl}" != "" ]; then
echo -n "Upload to http://${HACKAGESERVER}${targeturl} (y/N)? "
read ack
if [ "${ack}" = "y" -o "${ack}" = "Y" ]; then
echo "Uploading..."
curl \
-X PUT \
-H "Content-Type: application/x-tar" \
-H "Content-Encoding: gzip" \
--data-binary @"${pkgdocarchive}" \
--digest --netrc \
"http://${HACKAGESERVER}${targeturl}"
else
echo "Not uploading."
fi
fi
echo Done.
@schell

This comment has been minimized.

Copy link

schell commented Dec 11, 2013

What about somehow integrating this process into cabal?

@schell

This comment has been minimized.

Copy link

schell commented Dec 11, 2013

I'm getting this error:

<command-line>:0:2: lexical error at character '\n'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.