mirror of https://github.com/ansible/ansible.git
Add a script to update the intersphinx inventory (#66646)
* Add a script to update the intersphinx inventory files * We're about to add intersphinx inventories for separate ansible docs so we need an easy way to update them. Also, we should be updating these cache files for other upstreams occassionally as well. With a script, we can add updating them to a release process. * Now that we don't know what the version of the cache is, change the filenames to not contain versions. * Update the intersphinx cache files with the latest upstream versions Results of running: hacking/build-ansible.py update-intersphinx-cache -o docs/docsite -c docs/docsite/rst/conf.py * Add a comment to the configuration file which says how to structure the intersphinx mapping and why. * Update docs/docsite/rst/conf.py Co-Authored-By: Sandra McCann <samccann@redhat.com> Co-authored-by: Sandra McCann <samccann@redhat.com>pull/66702/head
parent
cb8ce7159d
commit
0da13469d3
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,101 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# (c) 2020, Ansible Project
|
||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
|
||||
# Make coding more python3-ish
|
||||
from __future__ import (absolute_import, division, print_function)
|
||||
__metaclass__ = type
|
||||
|
||||
|
||||
import argparse
|
||||
import importlib
|
||||
import os
|
||||
import pathlib
|
||||
import time
|
||||
import urllib.parse
|
||||
|
||||
from collections import defaultdict
|
||||
|
||||
from ansible.module_utils.common.collections import is_iterable
|
||||
from ansible.module_utils.urls import Request
|
||||
|
||||
# Pylint doesn't understand Python3 namespace modules.
|
||||
from ..commands import Command # pylint: disable=relative-beyond-top-level
|
||||
from .. import errors # pylint: disable=relative-beyond-top-level
|
||||
|
||||
|
||||
EXAMPLE_CONF = """
|
||||
A proper intersphinx_mapping entry should look like:
|
||||
intersphinx_mapping = {
|
||||
'python3': ('https://docs.python.org/3', (None, 'python3.inv'))
|
||||
}
|
||||
|
||||
See the intersphinx docs for more info:
|
||||
https://www.sphinx-doc.org/en/master/usage/extensions/intersphinx.html#confval-intersphinx_mapping
|
||||
"""
|
||||
|
||||
|
||||
class UpdateIntersphinxCache(Command):
|
||||
name = 'update-intersphinx-cache'
|
||||
|
||||
@classmethod
|
||||
def init_parser(cls, add_parser):
|
||||
parser = add_parser(cls.name, description='Update cached intersphinx mappings. This'
|
||||
' updates the cached intersphinx mappings for docs to reference'
|
||||
' documentation from other projects.')
|
||||
parser.add_argument('-o', '--output-dir', action='store',
|
||||
help='Path to directory the cached objects.inv files are stored in')
|
||||
parser.add_argument('-c', '--conf-file', action='store',
|
||||
help='Path to a sphinx config file to retrieve intersphinx config from')
|
||||
|
||||
@staticmethod
|
||||
def main(args):
|
||||
# Retrieve the intersphinx information from the sphinx config file
|
||||
conf_dir = pathlib.Path(args.conf_file).parent
|
||||
|
||||
conf_module_spec = importlib.util.spec_from_file_location('sphinxconf', args.conf_file)
|
||||
conf_module = importlib.util.module_from_spec(conf_module_spec)
|
||||
conf_module_spec.loader.exec_module(conf_module)
|
||||
intersphinx_mapping = conf_module.intersphinx_mapping
|
||||
|
||||
for intersphinx_name, inventory in intersphinx_mapping.items():
|
||||
if not is_iterable(inventory) or len(inventory) != 2:
|
||||
print('WARNING: The intersphinx entry for {0} must be'
|
||||
' a two-tuple.\n{1}'.format(intersphinx_name, EXAMPLE_CONF))
|
||||
continue
|
||||
|
||||
url = cache_file = None
|
||||
for inv_source in inventory:
|
||||
if isinstance(inv_source, str) and url is None:
|
||||
url = inv_source
|
||||
elif is_iterable(inv_source) and cache_file is None:
|
||||
if len(inv_source) != 2:
|
||||
print('WARNING: The fallback entry for {0} should be a tuple of (None,'
|
||||
' filename).\n{1}'.format(intersphinx_name, EXAMPLE_CONF))
|
||||
continue
|
||||
cache_file = inv_source[1]
|
||||
else:
|
||||
print('WARNING: The configuration for {0} should be a tuple of one url and one'
|
||||
' tuple for a fallback filename.\n{1}'.format(intersphinx_name,
|
||||
EXAMPLE_CONF))
|
||||
continue
|
||||
|
||||
if url is None or cache_file is None:
|
||||
print('WARNING: Could not figure out the url or fallback'
|
||||
' filename for {0}.\n{1}'.format(intersphinx_name, EXAMPLE_CONF))
|
||||
continue
|
||||
|
||||
url = urllib.parse.urljoin(url, 'objects.inv')
|
||||
# Resolve any relative cache files to be relative to the conf file
|
||||
cache_file = conf_dir / cache_file
|
||||
|
||||
# Retrieve the inventory and cache it
|
||||
# The jinja CDN seems to be blocking the default urllib User-Agent
|
||||
requestor = Request(headers={'User-Agent': 'Definitely Not Python ;-)'})
|
||||
with requestor.open('GET', url) as source_file:
|
||||
with open(cache_file, 'wb') as f:
|
||||
f.write(source_file.read())
|
||||
|
||||
print('Download of new cache files complete. Remember to git commit -a the changes')
|
||||
|
||||
return 0
|
Loading…
Reference in New Issue