forked from espressif/esp-adf
-
Notifications
You must be signed in to change notification settings - Fork 0
/
link-roles.py
150 lines (117 loc) · 6.21 KB
/
link-roles.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
# based on http://protips.readthedocs.io/link-roles.html
from __future__ import print_function
from __future__ import unicode_literals
import re
import os
import subprocess
from collections import namedtuple
from docutils import nodes
from local_util import run_cmd_get_output
from sphinx.util import logging
# Creates a dict of all submodules with the format {submodule_path : (url relative to git root), commit)}
def get_submodules():
git_root = subprocess.check_output(['git', 'rev-parse', '--show-toplevel']).strip().decode('utf-8')
gitmodules_file = os.path.join(git_root, '.gitmodules')
submodules = subprocess.check_output(['git', 'submodule', 'status'], cwd=git_root).strip().decode('utf-8').split('\n')
if submodules[0] == '':
return {}
submodule_dict = {}
Submodule = namedtuple('Submodule', 'url rev')
for sub in submodules:
sub_info = sub.lstrip().split(' ')
# Get short hash, 7 digits
rev = sub_info[0].lstrip('-')[0:7]
path = sub_info[1].lstrip('./')
config_key_arg = 'submodule.{}.url'.format(path)
rel_url = subprocess.check_output(['git', 'config', '--file', gitmodules_file, '--get', config_key_arg]).decode('utf-8').lstrip('./').rstrip('\n')
submodule_dict[path] = Submodule(rel_url, rev)
return submodule_dict
def get_github_rev():
path = run_cmd_get_output('git rev-parse --short HEAD')
tag = run_cmd_get_output('git describe --exact-match')
print('Git commit ID: ', path)
if len(tag):
print('Git tag: ', tag)
path = tag
return path
def setup(app):
rev = get_github_rev()
submods = get_submodules()
# links to files or folders on the GitHub
app.add_role('adf', github_link('tree', rev, submods, '/', app.config))
app.add_role('adf_file', github_link('blob', rev, submods, '/', app.config))
app.add_role('adf_raw', github_link('raw', rev, submods, '/', app.config))
app.add_role('component', github_link('tree', rev, submods, '/components/', app.config))
app.add_role('component_file', github_link('blob', rev, submods, '/components/', app.config))
app.add_role('component_raw', github_link('raw', rev, submods, '/components/', app.config))
app.add_role('example', github_link('tree', rev, submods, '/examples/', app.config))
app.add_role('example_file', github_link('blob', rev, submods, '/examples/', app.config))
app.add_role('example_raw', github_link('raw', rev, submods, '/examples/', app.config))
# link to the current documentation file in specific language version
on_rtd = os.environ.get('READTHEDOCS', None) == 'True'
if on_rtd:
# provide RTD specific commit identification to be included in the link
tag_rev = 'latest'
if (run_cmd_get_output('git rev-parse --short HEAD') != rev):
tag_rev = rev
else:
# if not on the RTD then provide generic identification
tag_rev = run_cmd_get_output('git describe --always')
app.add_role('link_to_translation', crosslink('%s../../%s/{}/%s.html'.format(tag_rev)))
def url_join(*url_parts):
""" Make a URL out of multiple components, assume first part is the https:// part and
anything else is a path component """
result = "/".join(url_parts)
result = re.sub(r"([^:])//+", r"\1/", result) # remove any // that isn't in the https:// part
return result
def github_link(link_type, adf_rev, submods, root_path, app_config):
def role(name, rawtext, text, lineno, inliner, options={}, content=[]):
logger = logging.getLogger(__name__)
ADF_REPO = "espressif/esp-adf"
BASE_URL = "https://github.com"
def warning(msg):
logger.warning(msg, location=(inliner.document.settings.env.docname, lineno))
# Redirects to submodule repo if path is a submodule, else default to IDF repo
def redirect_submodule(path, submods, rev):
for key, value in submods.items():
# Add path separator to end of submodule path to ensure we are matching a directory
if path.lstrip('/').startswith(os.path.join(key, '')):
# Remove domain
url = value.url.split('.com')[-1]
return url, value.rev, re.sub('^/{}/'.format(key), '', path)
return ADF_REPO, rev, path
m = re.search('(.*)\s*<(.*)>', text) # noqa: W605 - regular expression
if m:
link_text = m.group(1)
link = m.group(2)
else:
link_text = text
link = text
rel_path = root_path + link
abs_path = os.path.join(os.getenv('ADF_PATH', ''), rel_path.lstrip('/'))
repo_url, repo_rev, rel_path = redirect_submodule(rel_path, submods, adf_rev)
url = url_join(BASE_URL, repo_url, link_type, repo_rev, rel_path)
if 'READTHEDOCS' not in os.environ:
# only check links when building locally
is_dir = (link_type == 'tree')
if not os.path.exists(abs_path):
warning('ADF path %s does not appear to exist (absolute path %s)' % (rel_path, abs_path))
elif is_dir and not os.path.isdir(abs_path):
# note these "wrong type" warnings are not strictly needed as GitHub will apply a redirect,
# but the may become important in the future (plus make for cleaner links)
warning('ADF path %s is not a directory but role :%s: is for linking to a directory, try :%s_file:' % (rel_path, name, name))
elif not is_dir and os.path.isdir(abs_path):
warning('ADF path %s is a directory but role :%s: is for linking to a file' % (rel_path, name))
node = nodes.reference(rawtext, link_text, refuri=url, **options)
return [node], []
return role
def crosslink(pattern):
def role(name, rawtext, text, lineno, inliner, options={}, content=[]):
(language, link_text) = text.split(':')
docname = inliner.document.settings.env.docname
doc_path = inliner.document.settings.env.doc2path(docname, None, None)
return_path = '../' * doc_path.count('/')
url = pattern % (return_path, language, docname)
node = nodes.reference(rawtext, link_text, refuri=url, **options)
return [node], []
return role