Skip to content

Commit 309a403

Browse files
jnothmanXing
authored andcommitted
DOC use :pr: rather than :issue: in what's new (scikit-learn#13701)
1 parent 67f53dc commit 309a403

4 files changed

Lines changed: 268 additions & 164 deletions

File tree

build_tools/circle/flake8_diff.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ echo '--------------------------------------------------------------------------
121121
# We need the following command to exit with 0 hence the echo in case
122122
# there is no match
123123
MODIFIED_FILES="$(git diff --name-only $COMMIT_RANGE | grep -v 'sklearn/externals' | \
124-
grep -v 'doc/sphinxext/sphinx_gallery' || echo "no_match")"
124+
grep -v 'doc/sphinxext' || echo "no_match")"
125125

126126
check_files() {
127127
files="$1"
@@ -135,7 +135,7 @@ check_files() {
135135
}
136136

137137
if [[ "$MODIFIED_FILES" == "no_match" ]]; then
138-
echo "No file outside sklearn/externals and doc/sphinxext/sphinx_gallery has been modified"
138+
echo "No file outside sklearn/externals and doc/sphinxext has been modified"
139139
else
140140

141141
check_files "$(echo "$MODIFIED_FILES" | grep -v ^examples)"

doc/conf.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -279,9 +279,8 @@ def make_carousel_thumbs(app, exception):
279279

280280
# Config for sphinx_issues
281281

282-
issues_uri = 'https://github.com/scikit-learn/scikit-learn/issues/{issue}'
282+
# we use the issues path for PRs since the issues URL will forward
283283
issues_github_path = 'scikit-learn/scikit-learn'
284-
issues_user_uri = 'https://github.com/{user}'
285284

286285

287286
def setup(app):

doc/sphinxext/sphinx_issues.py

Lines changed: 156 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,8 @@
99
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
1010
copies of the Software, and to permit persons to whom the Software is
1111
furnished to do so, subject to the following conditions:
12-
1312
The above copyright notice and this permission notice shall be included in
1413
all copies or substantial portions of the Software.
15-
1614
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1715
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1816
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
@@ -21,24 +19,24 @@
2119
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
2220
THE SOFTWARE.
2321
"""
22+
import re
2423

2524
from docutils import nodes, utils
2625
from sphinx.util.nodes import split_explicit_title
2726

28-
__version__ = '0.2.0'
29-
__author__ = 'Steven Loria'
30-
__license__ = 'MIT'
27+
__version__ = "1.2.0"
28+
__author__ = "Steven Loria"
29+
__license__ = "MIT"
3130

3231

33-
def user_role(name, rawtext, text, lineno,
34-
inliner, options=None, content=None):
32+
def user_role(name, rawtext, text, lineno, inliner, options=None, content=None):
3533
"""Sphinx role for linking to a user profile. Defaults to linking to
36-
GitHub profiles, but the profile URIS can be configured via the
34+
Github profiles, but the profile URIS can be configured via the
3735
``issues_user_uri`` config value.
38-
39-
Example: ::
40-
36+
Examples: ::
4137
:user:`sloria`
38+
Anchor text also works: ::
39+
:user:`Steven Loria <sloria>`
4240
"""
4341
options = options or {}
4442
content = content or []
@@ -50,64 +48,171 @@ def user_role(name, rawtext, text, lineno,
5048
if config.issues_user_uri:
5149
ref = config.issues_user_uri.format(user=target)
5250
else:
53-
ref = 'https://github.com/{0}'.format(target)
51+
ref = "https://github.com/{0}".format(target)
5452
if has_explicit_title:
5553
text = title
5654
else:
57-
text = '@{0}'.format(target)
55+
text = "@{0}".format(target)
5856

5957
link = nodes.reference(text=text, refuri=ref, **options)
6058
return [link], []
6159

6260

63-
def _make_issue_node(issue_no, config, options=None):
61+
def cve_role(name, rawtext, text, lineno, inliner, options=None, content=None):
62+
"""Sphinx role for linking to a CVE on https://cve.mitre.org.
63+
Examples: ::
64+
:cve:`CVE-2018-17175`
65+
"""
6466
options = options or {}
65-
if issue_no not in ('-', '0'):
66-
if config.issues_uri:
67-
ref = config.issues_uri.format(issue=issue_no)
68-
elif config.issues_github_path:
69-
ref = 'https://github.com/{0}/issues/{1}'.format(
70-
config.issues_github_path, issue_no
67+
content = content or []
68+
has_explicit_title, title, target = split_explicit_title(text)
69+
70+
target = utils.unescape(target).strip()
71+
title = utils.unescape(title).strip()
72+
ref = "https://cve.mitre.org/cgi-bin/cvename.cgi?name={0}".format(target)
73+
text = title if has_explicit_title else target
74+
link = nodes.reference(text=text, refuri=ref, **options)
75+
return [link], []
76+
77+
78+
class IssueRole(object):
79+
80+
EXTERNAL_REPO_REGEX = re.compile(r"^(\w+)/(.+)([#@])([\w]+)$")
81+
82+
def __init__(
83+
self, uri_config_option, format_kwarg, github_uri_template, format_text=None
84+
):
85+
self.uri_config_option = uri_config_option
86+
self.format_kwarg = format_kwarg
87+
self.github_uri_template = github_uri_template
88+
self.format_text = format_text or self.default_format_text
89+
90+
@staticmethod
91+
def default_format_text(issue_no):
92+
return "#{0}".format(issue_no)
93+
94+
def make_node(self, name, issue_no, config, options=None):
95+
name_map = {"pr": "pull", "issue": "issues", "commit": "commit"}
96+
options = options or {}
97+
repo_match = self.EXTERNAL_REPO_REGEX.match(issue_no)
98+
if repo_match: # External repo
99+
username, repo, symbol, issue = repo_match.groups()
100+
if name not in name_map:
101+
raise ValueError(
102+
"External repo linking not supported for :{}:".format(name)
103+
)
104+
path = name_map.get(name)
105+
ref = "https://github.com/{issues_github_path}/{path}/{n}".format(
106+
issues_github_path="{}/{}".format(username, repo), path=path, n=issue
71107
)
72-
issue_text = '#{0}'.format(issue_no)
73-
link = nodes.reference(text=issue_text, refuri=ref, **options)
74-
else:
75-
link = None
76-
return link
108+
formatted_issue = self.format_text(issue).lstrip("#")
109+
text = "{username}/{repo}{symbol}{formatted_issue}".format(**locals())
110+
link = nodes.reference(text=text, refuri=ref, **options)
111+
return link
112+
113+
if issue_no not in ("-", "0"):
114+
uri_template = getattr(config, self.uri_config_option, None)
115+
if uri_template:
116+
ref = uri_template.format(**{self.format_kwarg: issue_no})
117+
elif config.issues_github_path:
118+
ref = self.github_uri_template.format(
119+
issues_github_path=config.issues_github_path, n=issue_no
120+
)
121+
else:
122+
raise ValueError(
123+
"Neither {} nor issues_github_path "
124+
"is set".format(self.uri_config_option)
125+
)
126+
issue_text = self.format_text(issue_no)
127+
link = nodes.reference(text=issue_text, refuri=ref, **options)
128+
else:
129+
link = None
130+
return link
131+
132+
def __call__(
133+
self, name, rawtext, text, lineno, inliner, options=None, content=None
134+
):
135+
options = options or {}
136+
content = content or []
137+
issue_nos = [each.strip() for each in utils.unescape(text).split(",")]
138+
config = inliner.document.settings.env.app.config
139+
ret = []
140+
for i, issue_no in enumerate(issue_nos):
141+
node = self.make_node(name, issue_no, config, options=options)
142+
ret.append(node)
143+
if i != len(issue_nos) - 1:
144+
sep = nodes.raw(text=", ", format="html")
145+
ret.append(sep)
146+
return ret, []
147+
148+
149+
"""Sphinx role for linking to an issue. Must have
150+
`issues_uri` or `issues_github_path` configured in ``conf.py``.
151+
Examples: ::
152+
:issue:`123`
153+
:issue:`42,45`
154+
:issue:`sloria/konch#123`
155+
"""
156+
issue_role = IssueRole(
157+
uri_config_option="issues_uri",
158+
format_kwarg="issue",
159+
github_uri_template="https://github.com/{issues_github_path}/issues/{n}",
160+
)
161+
162+
"""Sphinx role for linking to a pull request. Must have
163+
`issues_pr_uri` or `issues_github_path` configured in ``conf.py``.
164+
Examples: ::
165+
:pr:`123`
166+
:pr:`42,45`
167+
:pr:`sloria/konch#43`
168+
"""
169+
pr_role = IssueRole(
170+
uri_config_option="issues_pr_uri",
171+
format_kwarg="pr",
172+
github_uri_template="https://github.com/{issues_github_path}/pull/{n}",
173+
)
77174

78175

79-
def issue_role(name, rawtext, text, lineno,
80-
inliner, options=None, content=None):
81-
"""Sphinx role for linking to an issue. Must have
82-
`issues_uri` or `issues_github_path` configured in ``conf.py``.
176+
def format_commit_text(sha):
177+
return sha[:7]
83178

84-
Examples: ::
85179

86-
:issue:`123`
87-
:issue:`42,45`
88-
"""
89-
options = options or {}
90-
content = content or []
91-
issue_nos = [each.strip() for each in utils.unescape(text).split(',')]
92-
config = inliner.document.settings.env.app.config
93-
ret = []
94-
for i, issue_no in enumerate(issue_nos):
95-
node = _make_issue_node(issue_no, config, options=options)
96-
ret.append(node)
97-
if i != len(issue_nos) - 1:
98-
sep = nodes.raw(text=', ', format='html')
99-
ret.append(sep)
100-
return ret, []
180+
"""Sphinx role for linking to a commit. Must have
181+
`issues_pr_uri` or `issues_github_path` configured in ``conf.py``.
182+
Examples: ::
183+
:commit:`123abc456def`
184+
:commit:`sloria/konch@123abc456def`
185+
"""
186+
commit_role = IssueRole(
187+
uri_config_option="issues_commit_uri",
188+
format_kwarg="commit",
189+
github_uri_template="https://github.com/{issues_github_path}/commit/{n}",
190+
format_text=format_commit_text,
191+
)
101192

102193

103194
def setup(app):
104195
# Format template for issues URI
105196
# e.g. 'https://github.com/sloria/marshmallow/issues/{issue}
106-
app.add_config_value('issues_uri', default=None, rebuild='html')
107-
# Shortcut for GitHub, e.g. 'sloria/marshmallow'
108-
app.add_config_value('issues_github_path', default=None, rebuild='html')
197+
app.add_config_value("issues_uri", default=None, rebuild="html")
198+
# Format template for PR URI
199+
# e.g. 'https://github.com/sloria/marshmallow/pull/{issue}
200+
app.add_config_value("issues_pr_uri", default=None, rebuild="html")
201+
# Format template for commit URI
202+
# e.g. 'https://github.com/sloria/marshmallow/commits/{commit}
203+
app.add_config_value("issues_commit_uri", default=None, rebuild="html")
204+
# Shortcut for Github, e.g. 'sloria/marshmallow'
205+
app.add_config_value("issues_github_path", default=None, rebuild="html")
109206
# Format template for user profile URI
110207
# e.g. 'https://github.com/{user}'
111-
app.add_config_value('issues_user_uri', default=None, rebuild='html')
112-
app.add_role('issue', issue_role)
113-
app.add_role('user', user_role)
208+
app.add_config_value("issues_user_uri", default=None, rebuild="html")
209+
app.add_role("issue", issue_role)
210+
app.add_role("pr", pr_role)
211+
app.add_role("user", user_role)
212+
app.add_role("commit", commit_role)
213+
app.add_role("cve", cve_role)
214+
return {
215+
"version": __version__,
216+
"parallel_read_safe": True,
217+
"parallel_write_safe": True,
218+
}

0 commit comments

Comments
 (0)