[docs] Generate custom "Edit on GitHub" links

Some of the documentation files are generated from source '.yml' files
(for example default variable sections), some others are located
elsewhere in the monorepo (Changelog, installation documentation).

This commit implements a custom Python function that generates correct
URLs for the above set of files, used in the "Edit on GitHub" links in
the documentation.
parent 69c56883
# -*- coding: utf-8 -*-
from .func import * # pylint: disable=wildcard-import
# -*- coding: utf-8 -*-
#
# Copyright (C) 2016-2018 DebOps project https://debops.org/
from __future__ import print_function
import os
import fnmatch
import re
from subprocess import check_output
# Fix "Edit on GitHub" links in the documentation
# Jinja2 Support is only basic Jinja2 without all the good stuff from Ansible.
# So I am not gonna mess with that or try to extend it as in:
# https://stackoverflow.com/questions/36019670/
# What I am gonna do instead is just recompute source file to URL map in Python
# and job done.
def find_files(directory, pattern):
for root, dirs, files in os.walk(directory):
for basename in files:
if fnmatch.fnmatch(basename, pattern):
filename = os.path.join(root, basename)
yield filename
def get_source_file_to_url_map(start_dir='.', skip_patterns=[]):
source_file_to_url_map = {}
repo_dir_to_url_map = {}
cur_dir = os.path.abspath(start_dir)
for source_file_name in find_files('.', '*.rst'):
pagename_source_file = source_file_name.lstrip('/.')
skip = False
for skip_pattern in skip_patterns:
if re.search(skip_pattern, pagename_source_file):
skip = True
break
if skip:
continue
dir_path = os.path.dirname(source_file_name)
if len(dir_path) > 2:
dir_path = dir_path.lstrip('/.')
# Can also contain subdirs in a repo but this optimization should
# already get factor 10 in performance for git invocation.
if dir_path not in repo_dir_to_url_map:
for remote_line in check_output(['git', '-C', dir_path,
'remote', '-v']).split('\n'):
remote_item = re.split(r'\s', remote_line)
if remote_item[0] == 'origin' and remote_item[2] == '(fetch)':
base_url = remote_item[1]
if base_url.endswith('.git'):
base_url = base_url[:-4]
if '@' in base_url: # it's a git+ssh URL
base_url = base_url.replace(':', '/')
base_url = base_url.replace('[email protected]', 'https://')
repo_dir_to_url_map[dir_path] = base_url
relative_pagename = 'docs/' + pagename_source_file
if re.match(r'docs/news/changelog(?:\.rst)$',
relative_pagename, flags=re.I):
relative_pagename = 'CHANGELOG.rst'
if re.match(r'docs/user-guide/install(?:\.rst)$',
relative_pagename, flags=re.I):
relative_pagename = 'INSTALL.rst'
relative_path = re.match(
r'docs/ansible/roles/(.*)/defaults(?:\.rst)$',
relative_pagename, flags=re.I)
if relative_path:
relative_pagename = ('ansible/roles/' + relative_path.group(1)
+ '/defaults/main.yml')
pagename_source_file = re.sub(r'\.rst$', '', pagename_source_file)
source_file_to_url_map[pagename_source_file] = {
'url': repo_dir_to_url_map[dir_path],
'pagename': relative_pagename,
}
return source_file_to_url_map
{# Support for Sphinx 1.3+ page_source_suffix, but don't break old builds. #}
{% if page_source_suffix %}
{% set suffix = page_source_suffix %}
{% else %}
{% set suffix = source_suffix %}
{% endif %}
{% if meta is defined and meta is not none %}
{% set check_meta = True %}
{% else %}
{% set check_meta = False %}
{% endif %}
{% if check_meta and 'github_url' in meta %}
{% set display_github = True %}
{% endif %}
{% if check_meta and 'bitbucket_url' in meta %}
{% set display_bitbucket = True %}
{% endif %}
<div role="navigation" aria-label="breadcrumbs navigation">
<ul class="wy-breadcrumbs">
{% block breadcrumbs %}
<li><a href="{{ pathto(master_doc) }}">Docs</a> &raquo;</li>
{% for doc in parents %}
<li><a href="{{ doc.link|e }}">{{ doc.title }}</a> &raquo;</li>
{% endfor %}
<li>{{ title }}</li>
{% endblock %}
{% block breadcrumbs_aside %}
<li class="wy-breadcrumbs-aside">
{% if pagename != "search" %}
{% if display_github and pagename in source_file_to_url_map %}
{% if check_meta and 'github_url' in meta %}
<!-- User defined GitHub URL -->
<a href="{{ meta['github_url'] }}" class="fa fa-github"> Edit on GitHub</a>
{% else %}
{# Removed: github_version #}
<a href="{{ source_file_to_url_map[pagename]['url'] }}/blob/master/{{ source_file_to_url_map[pagename]['pagename'] }}" class="fa fa-github"> Edit on GitHub</a>
{% endif %}
{% elif display_bitbucket %}
{% if check_meta and 'bitbucket_url' in meta %}
<!-- User defined Bitbucket URL -->
<a href="{{ meta['bitbucket_url'] }}" class="fa fa-bitbucket"> Edit on Bitbucket</a>
{% else %}
<a href="https://bitbucket.org/{{ bitbucket_user }}/{{ bitbucket_repo }}/src/{{ bitbucket_version}}{{ conf_py_path }}{{ pagename }}{{ suffix }}" class="fa fa-bitbucket"> Edit on Bitbucket</a>
{% endif %}
{% elif show_source and source_url_prefix %}
<a href="{{ source_url_prefix }}{{ pagename }}{{ suffix }}">View page source</a>
{% elif show_source and has_source and sourcename %}
<a href="{{ pathto('_sources/' + sourcename, true)|e }}" rel="nofollow"> View page source</a>
{% endif %}
{% endif %}
</li>
{% endblock %}
</ul>
<hr/>
</div>
......@@ -24,6 +24,7 @@ from docutils.utils import get_source_line
sys.path.insert(0, os.path.abspath('_lib'))
import yaml2rst # noqa
import edit_url # noqa
rst_ansible_roles = 'ansible/roles/'
yml_ansible_roles = '../ansible/roles/'
......@@ -48,6 +49,21 @@ def _warn_node(self, msg, node, **kwargs):
sphinx.environment.BuildEnvironment.warn_node = _warn_node
git_commit_id = os.popen('git rev-parse --short HEAD').read().strip()
html_context = {
'display_github': True, # # Add 'Edit on Github' link
'github_user': 'debops',
'github_repo': 'debops',
'github_version': 'master',
'conf_py_path': '/docs/',
'commit': git_commit_id,
'source_file_to_url_map': edit_url.get_source_file_to_url_map(
start_dir=os.path.dirname(__file__),
skip_patterns=[]
)
}
# -- General configuration ------------------------------------------------
# If your documentation needs a minimal Sphinx version, state it here.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment