Skip to content

Commit

Permalink
Switch docs hosting to gh-pages (via doctr)
Browse files Browse the repository at this point in the history
Closes #68
  • Loading branch information
goerz committed Dec 15, 2019
1 parent 5f370bb commit 2080a8b
Show file tree
Hide file tree
Showing 20 changed files with 523 additions and 85 deletions.
23 changes: 20 additions & 3 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
# Config file for automatic testing at travis-ci.org
dist: xenial
language: python
env:
global:
# Doctr deploy key for qucontrol/krotov
- secure: "GMn30DUTZh2SvIvFu9HSGEZRy0y6JyOJ3wl7iM2ykV9aXbe3QkgE+rREnrPqsgcT15rj0CQLpOuCEWspiwqiEL1suokOGDjBRXoyMXHYy7WFRxP7dfFxQzuquN2rW8wS+MLJhQRRBJBoLopsRZioREelDxWUbqOCSKO9PXQA2oWl1i9XeqriXG9w5/jH74A8WeV+wL9uJ/+RPZoHjU+oCQ9Ri9ad3FYJCThqxIAFCMiKx2gMrxJlmU3kgRJulh6fyL8YK3dNV9132o5SElzVAtoe0pNNphIJx6UyqGBKctazXyPr+mlLokZw9tx6rg25bmc4XlRG46pqTP89wC8Xc7WBKxdJsYNksqgvxKZGt8vUenpDeYwvZMRbcukclHTskQbZFHJsXALhNnPe0APgrRK45aDL7++RBD8+BCjcMHQVd6qFd6UKCrs2etTXkI5uTqQtJve7Pe8ofcTcN1BQwI9IlcZYveuMX8Tn5378+Lwxqbc92OSkGPYRp+uOjKiQXDZbdCCokcqL9OGyGh9TcEgSD1BNMT8ZlGFGtQ18oXnP70hhvm0UPEgk3FIRWFX2VRIeWlZX4UntUDiaIo65C9GSIO2lEqZL23SPm8z/vk5Jh20JFSYvRi/Llr0mORZQiZyY+b2ZaoYhQutnK3wNdA7IIhbfzxuh1wUCuxdtaBA="
matrix:
fast_finish: true
include:
Expand All @@ -9,7 +13,7 @@ matrix:
env: TOTEST="" TOXENV="run-blackcheck,run-isortcheck" TRAVISCMD=""
- name: Docs
python: 3.7
env: TOTEST="" TOXENV=docs TRAVISCMD=""
env: DOCS="true"
addons:
apt_packages:
- pandoc
Expand Down Expand Up @@ -58,13 +62,26 @@ matrix:
before_install:
- sudo apt-get -y install liblapack-dev libblas-dev gfortran
install:
- export PATH=/tmp/texlive/bin/x86_64-linux:$PATH
- travis_wait source .travis/texlive/texlive_install.sh
- pip install tox
- pip install codecov
- pip install --upgrade cython
- pip freeze
- printenv
cache:
directories:
- /tmp/texlive
- $HOME/.texlive
script:
- set -e
- if [[ "${TOXENV}" == "py38dev-test" ]]; then travis_wait 40 tox -c tox-pyenv.ini -e py38dev-runcmd -- python --version; fi
- $TRAVISCMD tox -c tox-pyenv.ini -e $TOXENV -- $TOTEST
- |
if [[ "${DOCS}" == "true" ]]; then
source .travis/docs.sh
else
$TRAVISCMD tox -c tox-pyenv.ini -e $TOXENV -- $TOTEST
fi
- echo "DONE"
after_success:
- codecov
- if [[ "${DOCS}" != "true" ]]; then codecov; fi
30 changes: 30 additions & 0 deletions .travis/docs.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
echo "# DOCTR - deploy documentation"
echo "## Generate main html documentation"
tox -c tox-pyenv.ini -e docs
if [[ -z "$TRAVIS_TAG" ]]; then
echo "Deploying as BRANCH $TRAVIS_BRANCH"
else
echo "Deploying as TAG $TRAVIS_TAG"
echo "## Generate documentation downloads"
mkdir docs/_build/download
echo "### [htmlzip]"
tox -c tox-pyenv.ini -e docs -- -b html _build_htmlzip
cd docs || exit
mv _build_htmlzip krotov.html
zip -r krotov.html.zip ./krotov.html
cd ../ || exit
mv docs/krotov.html.zip docs/_build/download
fi
# deploy with doctr
echo "## pip install doctr"
python -m pip install doctr
echo "## doctr deploy"
if [[ -z "$TRAVIS_TAG" ]]; then
DEPLOY_DIR="$TRAVIS_BRANCH"
else
DEPLOY_DIR="$TRAVIS_TAG"
fi
python -m doctr deploy --key-path docs/doctr_deploy_key.enc \
--command="git show $TRAVIS_COMMIT:.travis/docs_post_process.py > post_process.py && git show $TRAVIS_COMMIT:.travis/versions.py > versions.py && python post_process.py" \
--built-docs docs/_build --no-require-master --build-tags "$DEPLOY_DIR"
echo "# DOCTR - DONE"
54 changes: 54 additions & 0 deletions .travis/docs_post_process.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#!/usr/bin/env python
import os
import subprocess
from pathlib import Path

from versions import get_versions_data, write_versions_json


INDEX_HTML = r'''<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Refresh" content="0; url={default_branch}" />
</head>
<body>
<p>Got to <a href="{default_branch}">default documentation</a>.</p>
</body>
</html>
'''


def write_index_html(default_branch):
"""Write an index.html that redirects to the DEFAULT_BRANCH."""
with open("index.html", "w") as out_fh:
out_fh.write(INDEX_HTML.format(default_branch=default_branch))
subprocess.run(['git', 'add', 'index.html'], check=True)


def find_downloads(folder):
"""Find files in the 'download' subfolder of the given `folder`."""
downloads = []
for filename in Path(folder).glob(r'download/*'):
label = "".join(filename.suffixes).replace('.', '').lower()
if len(label) > 0:
downloads.append((label, str(filename)))
return downloads


def main():
"""Main function."""
print("Post-processing documentation on gh-pages")
print("Gather versions info")
versions_data = get_versions_data(find_downloads=find_downloads)
latest_release = versions_data['latest_release']
if latest_release is None:
latest_release = 'master'
print("Write index.html")
write_index_html(latest_release)
print("Write versions.json")
write_versions_json(versions_data, outfile='versions.json')
print("DONE post-processing")


if __name__ == "__main__":
main()
10 changes: 10 additions & 0 deletions .travis/texlive/texlive.profile
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
selected_scheme scheme-basic
TEXDIR /tmp/texlive
TEXMFCONFIG ~/.texlive/texmf-config
TEXMFHOME ~/texmf
TEXMFLOCAL /tmp/texlive/texmf-local
TEXMFSYSCONFIG /tmp/texlive/texmf-config
TEXMFSYSVAR /tmp/texlive/texmf-var
TEXMFVAR ~/.texlive/texmf-var
option_doc 0
option_src 0
32 changes: 32 additions & 0 deletions .travis/texlive/texlive_install.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#!/usr/bin/env sh

# Originally from https://github.com/latex3/latex3

# This script is used for building LaTeX files using Travis
# A minimal current TL is installed adding only the packages that are
# required

# See if there is a cached version of TL available
if ! command -v texlua > /dev/null; then
# Obtain TeX Live
wget http://mirror.ctan.org/systems/texlive/tlnet/install-tl-unx.tar.gz
tar -xzf install-tl-unx.tar.gz
cd install-tl-20*

# Install a minimal system
./install-tl --profile=../.travis/texlive/texlive.profile

cd ..
fi

# Just including texlua so the cache check above works
tlmgr install luatex

# We specify the directory in which it is located texlive_packages
tlmgr install $(sed 's/\s*#.*//;/^\s*$/d' .travis/texlive/texlive_packages)

# Keep no backups (not required, simply makes cache bigger)
tlmgr option -- autobackup 0

# Update the TL install but add nothing new
tlmgr update --self --all --no-auto-install
19 changes: 19 additions & 0 deletions .travis/texlive/texlive_packages
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# In the case you have to install LaTeX packages manually, you can check
# https://www.ctan.org/pkg/some-package to see in which TeX Live package it is contained,
# or use tlmgr info some-package

# Base tools to compile
texliveonfly latexmk

# Collections
collection-langeuropean
collection-fontsrecommended

# LuaTeX
luaotfload

# texliveonfly does not detect the following packages automatically
minted fvextra upquote lineno xstring framed caption

# project-specific
cmap fncychap titlesec tabulary varwidth fancyvrb float wrapfig parskip capt-of needspace
162 changes: 162 additions & 0 deletions .travis/versions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
"""Utilities for generating versions.json."""
import json
import subprocess
from pathlib import Path

from pkg_resources import parse_version
from pkg_resources.extern.packaging.version import LegacyVersion


def get_stable(versions):
"""Select the latest stable release from `versions`.
If there is no stable version, return None.
"""
try:
return sorted(
[v for v in versions if not parse_version(v).is_prerelease],
key=parse_version,
)[-1]
except IndexError:
return None


def _clear_broken_symlinks():
"""Clear all broken symlinks in the current directory."""
for name in Path().iterdir():
if name.is_symlink():
try:
name.resolve(strict=True)
except FileNotFoundError:
print("Remove broken symlink %s" % name)
subprocess.run(['git', 'rm', name], check=True)


def write_versions_json(versions_data, outfile):
"""Write the versions data to a json file.
This json file will be processed by the javascript that generates the
version-selector.
"""
with open(outfile, 'w') as out_fh:
json.dump(versions_data, out_fh)
print(json.dumps(versions_data, indent=2))
subprocess.run(['git', 'add', outfile], check=True)


def _is_unreleased(folder):
"""Default `is_unreleased` function.
The following are considered "unreleased":
* Anything that doesn't look like a proper version according to PEP440.
Proper versions are e.g. "1.0.0", "v1.0.0", "1.0.0.post1". Specifically,
any branch names like "master", "develop" are considered unreleased.
* Anything that PEP440 considers a pre-release, e.g. "1.0.0-dev", "1.0-rc1"
* Anything that includes a "local version identifier" according to PEP440,
e.g. "1.0.0+dev"
"""
version = parse_version(folder)
if isinstance(version, LegacyVersion):
return True
if version.is_prerelease:
return True
if version.local is not None:
return True
return False


def _find_latest_release(folders):
try:
return sorted(folders, key=parse_version)[-1]
except IndexError:
return None


def _find_downloads(folder):
return []


def get_versions_data(
hidden=None,
is_unreleased=None,
find_latest_release=None,
sort_key=None,
labels=None,
suffix_latest_release=' (latest release)',
suffix_unreleased=' (dev)',
find_downloads=None,
):
"""Get the versions data, to be serialized to json."""
if hidden is None:
hidden = []
if is_unreleased is None:
is_unreleased = _is_unreleased
if find_latest_release is None:
find_latest_release = _find_latest_release
if find_downloads is None:
find_downloads = _find_downloads
if sort_key is None:
sort_key = parse_version
if labels is None:
labels = {}
folders = sorted(
[
str(f)
for f in Path().iterdir()
if (
f.is_dir()
and not f.is_symlink()
and not str(f).startswith('.')
and not str(f).startswith('_')
)
],
key=sort_key,
)
labels = {folder: labels.get(folder, str(folder)) for folder in folders}
versions = []
unreleased = []
for folder in folders:
if folder not in hidden:
versions.append(folder)
if is_unreleased(folder):
unreleased.append(folder)
labels[folder] += suffix_unreleased
latest_release = find_latest_release(
[f for f in versions if f not in unreleased]
)
outdated = []
if latest_release is not None:
labels[latest_release] += suffix_latest_release
outdated = [
folder
for folder in versions
if (folder != latest_release and folder not in unreleased)
]
versions_data = {
# list of *all* folders
'folders': folders,
#
# folder => labels for every folder in "Versions"
'labels': labels,
#
# list folders that appear in "Versions"
'versions': versions,
#
# list of folders that do not appear in "Versions"
'hidden': hidden,
#
# list of folders that should warn & point to latest release
'outdated': outdated,
#
# list of dev-folders that should warn & point to latest release
'unreleased': unreleased,
#
# the latest stable release folder
'latest_release': latest_release,
#
# folder => list of (label, file)
'downloads': {folder: find_downloads(folder) for folder in folders},
}

return versions_data
17 changes: 17 additions & 0 deletions CONTRIBUTING.rst
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,23 @@ to generate the documentation locally.
.. _BibTeX: https://sphinxcontrib-bibtex.readthedocs.io/en/latest/
.. _Matplotlib Sphinx cheat sheet: https://matplotlib.org/sampledoc/cheatsheet.html


Deploy the documentation
------------------------

The documentation is automatically deployed to
https://qucontrol.github.io/krotov/ (the gh-pages_ associated with the
:mod:`krotov` package's Github repository) every time commits are pushed to
Github. This is done via the Travis continuous integration service and Doctr_.
The documentation for all versions of :mod:`krotov` is visible on the
`gh-pages` git branch. Any changes that are committed and pushed from this
branch will be deployed to the online documentation. Do not routinely perform
manual edits on the `gh-pages` branch! Let Doctr_ do its job of automatically
deploying documentation instead.

.. _Doctr: https://drdoctr.github.io
.. _gh-pages: https://pages.github.com

.. _ContributeExamples:

Contribute Examples
Expand Down

0 comments on commit 2080a8b

Please sign in to comment.