Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package python-sphinx-issues for
openSUSE:Factory checked in at 2022-04-21 15:42:42
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-sphinx-issues (Old)
and /work/SRC/openSUSE:Factory/.python-sphinx-issues.new.1538 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-sphinx-issues"
Thu Apr 21 15:42:42 2022 rev:7 rq:971334 version:3.0.1
Changes:
--------
---
/work/SRC/openSUSE:Factory/python-sphinx-issues/python-sphinx-issues.changes
2020-03-27 00:23:03.488188745 +0100
+++
/work/SRC/openSUSE:Factory/.python-sphinx-issues.new.1538/python-sphinx-issues.changes
2022-04-21 15:49:00.336338472 +0200
@@ -1,0 +2,19 @@
+Wed Apr 20 11:24:07 UTC 2022 - [email protected]
+
+- version update to 3.0.1
+ 3.0.1 (2022-01-11)
+ * Fix regression from 3.0.0: exception: 'in <string>' requires string as
left operand, not type.
+ 3.0.0 (2022-01-10)
+ * The :commit: role now outputs with an @ prefix.
+ * Add configuration options for changing prefixes.
+ * Allow {group} to be specified within issues_uri, issues_pr_uri,
issues_commit_uri, and
+ 2.0.0 (2022-01-01)
+ * Drop support for Python 2.7 and 3.5.
+ * Test against Python 3.8 to 3.10.
+ * Add :cwe: role for linking to CVEs on https://cwe.mitre.org. Thanks
@hugovk for the PR.
+ * Add support for custom urls and separators Issue #93
+ * Allow custom titles for all roles Issue #116
+ * Added setting issues_default_group_project as future replacement of
issues_github_path,
+ to reflect the now to universal nature of the extension
+
+-------------------------------------------------------------------
Old:
----
1.2.0.tar.gz
New:
----
3.0.1.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-sphinx-issues.spec ++++++
--- /var/tmp/diff_new_pack.ly96di/_old 2022-04-21 15:49:00.736338899 +0200
+++ /var/tmp/diff_new_pack.ly96di/_new 2022-04-21 15:49:00.740338904 +0200
@@ -1,7 +1,7 @@
#
# spec file for package python-sphinx-issues
#
-# Copyright (c) 2020 SUSE LLC
+# Copyright (c) 2022 SUSE LLC
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@@ -19,7 +19,7 @@
%{?!python_module:%define python_module() python-%{**} python3-%{**}}
%bcond_without python2
Name: python-sphinx-issues
-Version: 1.2.0
+Version: 3.0.1
Release: 0
Summary: A Sphinx extension for linking to a project's issue tracker
License: MIT
@@ -53,7 +53,7 @@
%python_expand %fdupes %{buildroot}%{$python_sitelib}
%check
-%pytest test_sphinx_issues.py
+%pytest
%files %{python_files}
%doc README.rst
++++++ 1.2.0.tar.gz -> 3.0.1.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/sphinx-issues-1.2.0/.github/workflows/lint.yml
new/sphinx-issues-3.0.1/.github/workflows/lint.yml
--- old/sphinx-issues-1.2.0/.github/workflows/lint.yml 1970-01-01
01:00:00.000000000 +0100
+++ new/sphinx-issues-3.0.1/.github/workflows/lint.yml 2022-01-11
17:41:14.000000000 +0100
@@ -0,0 +1,12 @@
+name: Lint
+
+on: [push, pull_request, workflow_dispatch]
+
+jobs:
+ lint:
+ runs-on: ubuntu-latest
+
+ steps:
+ - uses: actions/checkout@v2
+ - uses: actions/setup-python@v2
+ - uses: pre-commit/[email protected]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/sphinx-issues-1.2.0/.github/workflows/test.yml
new/sphinx-issues-3.0.1/.github/workflows/test.yml
--- old/sphinx-issues-1.2.0/.github/workflows/test.yml 1970-01-01
01:00:00.000000000 +0100
+++ new/sphinx-issues-3.0.1/.github/workflows/test.yml 2022-01-11
17:41:14.000000000 +0100
@@ -0,0 +1,34 @@
+name: Test
+
+on: [push, pull_request, workflow_dispatch]
+
+env:
+ FORCE_COLOR: 1
+
+jobs:
+ test:
+ runs-on: ubuntu-latest
+ strategy:
+ fail-fast: false
+ matrix:
+ python-version: ["3.6", "3.10"]
+
+ steps:
+ - uses: actions/checkout@v2
+
+ - name: Set up Python ${{ matrix.python-version }}
+ uses: actions/setup-python@v2
+ with:
+ python-version: ${{ matrix.python-version }}
+ cache: pip
+ cache-dependency-path: "setup.py"
+
+ - name: Install dependencies
+ run: |
+ python -m pip install -U pip
+ python -m pip install -U wheel
+ python -m pip install -U tox
+
+ - name: Tox tests
+ run: |
+ tox -e py
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/sphinx-issues-1.2.0/.pre-commit-config.yaml
new/sphinx-issues-3.0.1/.pre-commit-config.yaml
--- old/sphinx-issues-1.2.0/.pre-commit-config.yaml 2018-12-26
17:05:00.000000000 +0100
+++ new/sphinx-issues-3.0.1/.pre-commit-config.yaml 2022-01-11
17:41:14.000000000 +0100
@@ -1,15 +1,20 @@
repos:
-- repo: https://github.com/ambv/black
- rev: 18.9b0
+- repo: https://github.com/asottile/pyupgrade
+ rev: v2.11.0
+ hooks:
+ - id: pyupgrade
+ args: [--py36-plus]
+- repo: https://github.com/python/black
+ rev: 20.8b1
hooks:
- id: black
- language_version: python3.6
-- repo: https://github.com/pre-commit/pre-commit-hooks
- rev: v2.0.0
+- repo: https://gitlab.com/pycqa/flake8
+ rev: 3.9.0
hooks:
- id: flake8
+ additional_dependencies: [flake8-bugbear==21.4.3]
- repo: https://github.com/asottile/blacken-docs
- rev: v0.3.0
+ rev: v1.10.0
hooks:
- id: blacken-docs
- additional_dependencies: [black==18.9b0]
+ additional_dependencies: [black==20.8b1]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/sphinx-issues-1.2.0/.travis.yml
new/sphinx-issues-3.0.1/.travis.yml
--- old/sphinx-issues-1.2.0/.travis.yml 2018-12-26 17:05:00.000000000 +0100
+++ new/sphinx-issues-3.0.1/.travis.yml 1970-01-01 01:00:00.000000000 +0100
@@ -1,29 +0,0 @@
-language: python
-sudo: false
-cache: pip
-install: travis_retry pip install -U tox
-script: tox
-jobs:
- fast_finish: true
-
- include:
- - { python: '3.6', env: TOXENV=lint }
- - { python: '2.7', env: TOXENV=py27 }
- - { python: '3.5', env: TOXENV=py35 }
- - { python: '3.6', env: TOXENV=py36 }
- - { python: '3.7', env: TOXENV=py37, dist: xenial, sudo: true }
-
- - stage: PyPI Release
- if: tag IS present
- python: "3.6"
- env: []
- install: skip
- script: skip
- deploy:
- provider: pypi
- user: sloria
- on:
- tags: true
- distributions: sdist bdist_wheel
- password:
- secure:
D0c2PYyI06+N5/inLaPHkEaM/GVgKVPCBDm2asmQvCTs14ory9KK17cnS+tOmrTNyMzw2tYSvD1Ar5a7MQAfcJ+p2bOnr/UCLqzt98H2LlE/2NJdzQtI3FtNCkhRVx20LK85G8ZWaHCecGIkgGmbIDZ56u1Aj+G16z0PqEz5i7s=
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/sphinx-issues-1.2.0/LICENSE
new/sphinx-issues-3.0.1/LICENSE
--- old/sphinx-issues-1.2.0/LICENSE 2018-12-26 17:05:00.000000000 +0100
+++ new/sphinx-issues-3.0.1/LICENSE 2022-01-11 17:41:14.000000000 +0100
@@ -1,4 +1,4 @@
-Copyright 2018 Steven Loria
+Copyright 2022 Steven Loria
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/sphinx-issues-1.2.0/README.rst
new/sphinx-issues-3.0.1/README.rst
--- old/sphinx-issues-1.2.0/README.rst 2018-12-26 17:05:00.000000000 +0100
+++ new/sphinx-issues-3.0.1/README.rst 2022-01-11 17:41:14.000000000 +0100
@@ -2,8 +2,17 @@
sphinx-issues
=============
-.. image:: https://travis-ci.org/sloria/sphinx-issues.svg?branch=master
- :target: https://travis-ci.org/sloria/sphinx-issues
+.. image:: https://badgen.net/pypi/v/sphinx-issues
+ :alt: pypi badge
+ :target: https://pypi.org/project/sphinx-issues/
+
+.. image::
https://github.com/OpenASL/HowSignBot/workflows/.github/workflows/test.yml/badge.svg
+ :alt: github actions status
+ :target: .github/workflows/test.yml
+
+.. image:: https://badgen.net/badge/code%20style/black/000
+ :target: https://github.com/ambv/black
+ :alt: Code style: Black
A Sphinx extension for linking to your project's issue tracker. Includes roles
for linking to issues, pull requests, user profiles, with built-in support for
GitHub (though this works with other services).
@@ -20,7 +29,11 @@
pip install sphinx-issues
-Add ``sphinx_issues`` to ``extensions`` in your ``conf.py``. If your project
is on GitHub, add the ``issues_github_path`` config variable. Otherwise, use
``issues_uri`` and ``issues_pr_uri``.
+Add ``sphinx_issues`` to ``extensions`` in your ``conf.py``.
+
+The extension has default values for GitHub projects.
+Simply set the add the ``issues_default_group_project`` config variable and
you are good
+to go:
.. code-block:: python
@@ -32,16 +45,47 @@
"sphinx_issues"
]
- # Github repo
+ # Path to GitHub repo {group}/{project} (note that `group` is the GitHub
user or organization)
issues_github_path = "sloria/marshmallow"
- # equivalent to
- issues_uri = "https://github.com/sloria/marshmallow/issues/{issue}"
- issues_pr_uri = "https://github.com/sloria/marshmallow/pull/{pr}"
- issues_commit_uri = "https://github.com/sloria/marshmallow/commit/{commit}"
+ # which is the equivalent to:
+ issues_uri = "https://github.com/{group}/{project}/issues/{issue}"
+ issues_prefix = "#"
+ issues_pr_uri = "https://github.com/{group}/{project}/pull/{pr}"
+ issues_pr_prefix = "#"
+ issues_commit_uri = "https://github.com/{group}/{project}/commit/{commit}"
+ issues_commit_prefix = "@"
+ issues_user_uri = "https://github.com/{user}"
+ issues_user_prefix = "@"
+
+The extension is very configurable and can be used with any kind of
+issue tracker. Here is how you could configure it for use
+with a custom hosed GitLab instance:
+
+.. code-block:: python
+
+ # docs/conf.py
+
+ # ...
+ extensions = [
+ # ...
+ "sphinx_issues"
+ ]
+
+ # Default repo {group}/{project} of gitlab project
+ issues_default_group_project = "myteam/super_great_project"
+ issues_uri =
"https://gitlab.company.com/{group}/{project}/-/issues/{issue}"
+ issues_prefix = "#"
+ issues_pr_uri =
"https://gitlab.company.com/{group}/{project}/-/merge_requests/{pr}"
+ issues_pr_prefix = "!"
+ issues_commit_uri =
"https://gitlab.company.com/{group}/{project}/-/commit/{commit}"
+ issues_commit_prefix = "@"
+ issues_user_uri = "https://gitlab.company.com/{user}"
+ issues_user_prefix = "@"
-Usage
-*****
+
+Usage inside the documentation
+******************************
Use the ``:issue:`` and ``:pr:`` roles in your docs like so:
@@ -56,7 +100,20 @@
See PR :pr:`58`
-Use the ``:user:`` role in your docs to link to user profiles (Github by
default, but can be configured via the ``issues_user_uri`` config variable).
+Use the ``:user:`` role in your docs to link to user profiles (GitHub by
default, but can be configured via the ``issues_user_uri`` config variable).
+
+
+Use the ``:commit:`` role to link to commits.
+
+.. code-block:: rst
+
+ Fixed in :commit:`6bb9124d5e9dbb2f7b52864c3d8af7feb1b69403`.
+
+Use the ``:cve:`` role to link to CVEs on https://cve.mitre.org.
+
+.. code-block:: rst
+
+ :cve:`CVE-2018-17175` - Addresses possible vulnerability when...
.. code-block:: rst
@@ -68,23 +125,24 @@
This change is due to :user:`Andreas Mueller <amueller>`.
+The syntax ``:role:`My custom title <target>``` works for all roles of this
extension.
-Use the ``:commit:`` role to link to commits.
+It can be also used in combination with a list:
.. code-block:: rst
- Fixed in :commit:`6bb9124d5e9dbb2f7b52864c3d8af7feb1b69403`.
+ Fix bad bug :issue:`123, (Duplicate) <199>`
-Use the ``:cve:`` role to link to CVEs on https://cve.mitre.org.
+Use the ``:cwe:`` role to link to CWEs on https://cwe.mitre.org.
.. code-block:: rst
- :cve:`CVE-2018-17175` - Addresses possible vulnerability when...
+ :cwe:`CWE-787` - The software writes data past the end, or...
Credits
*******
-Credit goes to Jeff Forcier for his work on the `releases
<https://github.com/bitprophet/releases>`_ extension, which is a full-featured
solution for generating changelogs. I just needed a quick way to reference
Github issues in my docs, so I yoinked the bits that I needed.
+Credit goes to Jeff Forcier for his work on the `releases
<https://github.com/bitprophet/releases>`_ extension, which is a full-featured
solution for generating changelogs. I just needed a quick way to reference
GitHub issues in my docs, so I yoinked the bits that I needed.
License
*******
@@ -95,6 +153,29 @@
Changelog
*********
+3.0.1 (2022-01-11)
+------------------
+
+- Fix regression from 3.0.0: `exception: 'in <string>' requires string as left
operand, not type`.
+
+3.0.0 (2022-01-10)
+------------------
+
+- The `:commit:` role now outputs with an `@` prefix.
+- Add configuration options for changing prefixes.
+- Allow `{group}` to be specified within `issues_uri`, `issues_pr_uri`,
`issues_commit_uri`, and
+
+2.0.0 (2022-01-01)
+------------------
+
+- Drop support for Python 2.7 and 3.5.
+- Test against Python 3.8 to 3.10.
+- Add ``:cwe:`` role for linking to CVEs on https://cwe.mitre.org.
+ Thanks @hugovk for the PR.
+- Add support for custom urls and separators `Issue #93
<https://github.com/sloria/sphinx-issues/issues/93>`_
+- Allow custom titles for all roles `Issue #116
<https://github.com/sloria/sphinx-issues/issues/116>`_
+- Added setting `issues_default_group_project` as future replacement of
`issues_github_path`, to reflect the now to universal nature of the extension
+
1.2.0 (2018-12-26)
------------------
@@ -132,7 +213,7 @@
0.2.0 (2014-12-22)
------------------
-- Add ``:user:`` role for linking to Github user profiles.
+- Add ``:user:`` role for linking to GitHub user profiles.
0.1.0 (2014-12-21)
------------------
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/sphinx-issues-1.2.0/setup.cfg
new/sphinx-issues-3.0.1/setup.cfg
--- old/sphinx-issues-1.2.0/setup.cfg 2018-12-26 17:05:00.000000000 +0100
+++ new/sphinx-issues-3.0.1/setup.cfg 2022-01-11 17:41:14.000000000 +0100
@@ -1,13 +1,9 @@
[metadata]
# This includes the license file in the wheel.
-license_file = LICENSE
-
-[bdist_wheel]
-universal = 1
+license_files = LICENSE
[flake8]
-ignore = E203, E266, E501, W503, E302, W504
-max-line-length = 100
+ignore = E203, E266, E501, W503
+max-line-length = 90
max-complexity = 18
select = B,C,E,F,W,T4,B9
-exclude = .git,.ropeproject,.tox,build,env,venv,__pycache__
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/sphinx-issues-1.2.0/setup.py
new/sphinx-issues-3.0.1/setup.py
--- old/sphinx-issues-1.2.0/setup.py 2018-12-26 17:05:00.000000000 +0100
+++ new/sphinx-issues-3.0.1/setup.py 2022-01-11 17:41:14.000000000 +0100
@@ -1,14 +1,13 @@
-# -*- coding: utf-8 -*-
import re
from setuptools import setup
INSTALL_REQUIRES = ["sphinx"]
EXTRAS_REQUIRE = {
- "tests": ["pytest", 'mock; python_version < "3.0"'],
+ "tests": ["pytest>=6.2.0"],
"lint": [
- "flake8==3.6.0",
- 'flake8-bugbear==18.8.0; python_version >= "3.5"',
- "pre-commit==1.13.0",
+ "flake8==3.9.2",
+ "flake8-bugbear==20.11.1",
+ "pre-commit~=2.7",
],
}
EXTRAS_REQUIRE["dev"] = EXTRAS_REQUIRE["tests"] + EXTRAS_REQUIRE["lint"] +
["tox"]
@@ -19,7 +18,7 @@
Raises RuntimeError if not found.
"""
version = ""
- with open(fname, "r") as fp:
+ with open(fname) as fp:
reg = re.compile(r'__version__ = [\'"]([^\'"]*)[\'"]')
for line in fp:
m = reg.match(line)
@@ -40,7 +39,7 @@
setup(
name="sphinx-issues",
version=find_version("sphinx_issues.py"),
- description="A Sphinx extension for linking to your project's " "issue
tracker",
+ description="A Sphinx extension for linking to your project's issue
tracker",
long_description=read("README.rst"),
install_requires=INSTALL_REQUIRES,
extras_require=EXTRAS_REQUIRE,
@@ -49,15 +48,16 @@
url="https://github.com/sloria/sphinx-issues",
license="MIT",
keywords="sphinx issues github",
+ python_requires=">=3.6",
classifiers=[
"Intended Audience :: Developers",
"License :: OSI Approved :: MIT License",
- "Programming Language :: Python :: 2",
- "Programming Language :: Python :: 2.7",
"Programming Language :: Python :: 3",
- "Programming Language :: Python :: 3.5",
"Programming Language :: Python :: 3.6",
"Programming Language :: Python :: 3.7",
+ "Programming Language :: Python :: 3.8",
+ "Programming Language :: Python :: 3.9",
+ "Programming Language :: Python :: 3.10",
"Topic :: Software Development :: Documentation",
],
py_modules=["sphinx_issues"],
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/sphinx-issues-1.2.0/sphinx_issues.py
new/sphinx-issues-3.0.1/sphinx_issues.py
--- old/sphinx-issues-1.2.0/sphinx_issues.py 2018-12-26 17:05:00.000000000
+0100
+++ new/sphinx-issues-3.0.1/sphinx_issues.py 2022-01-11 17:41:14.000000000
+0100
@@ -1,27 +1,23 @@
-# -*- coding: utf-8 -*-
"""A Sphinx extension for linking to your project's issue tracker."""
import re
+from typing import Callable, Optional, Tuple
from docutils import nodes, utils
+from sphinx.config import Config
from sphinx.util.nodes import split_explicit_title
-__version__ = "1.2.0"
+__version__ = "3.0.1"
__author__ = "Steven Loria"
__license__ = "MIT"
-def user_role(name, rawtext, text, lineno, inliner, options=None,
content=None):
- """Sphinx role for linking to a user profile. Defaults to linking to
- Github profiles, but the profile URIS can be configured via the
- ``issues_user_uri`` config value.
+def cve_role(name, rawtext, text, lineno, inliner, options=None, content=None):
+ """Sphinx role for linking to a CVE on https://cve.mitre.org.
Examples: ::
- :user:`sloria`
-
- Anchor text also works: ::
+ :cve:`CVE-2018-17175`
- :user:`Steven Loria <sloria>`
"""
options = options or {}
content = content or []
@@ -29,26 +25,154 @@
target = utils.unescape(target).strip()
title = utils.unescape(title).strip()
- config = inliner.document.settings.env.app.config
- if config.issues_user_uri:
- ref = config.issues_user_uri.format(user=target)
- else:
- ref = "https://github.com/{0}".format(target)
- if has_explicit_title:
- text = title
- else:
- text = "@{0}".format(target)
-
+ ref = f"https://cve.mitre.org/cgi-bin/cvename.cgi?name={target}"
+ text = title if has_explicit_title else target
link = nodes.reference(text=text, refuri=ref, **options)
return [link], []
-def cve_role(name, rawtext, text, lineno, inliner, options=None, content=None):
- """Sphinx role for linking to a CVE on https://cve.mitre.org.
+GITHUB_USER_RE = re.compile("^https://github.com/([^/]+)/([^/]+)/.*")
+
+
+def _get_default_group_and_project(
+ config: Config, uri_config_option: str
+) -> Optional[Tuple[str, str]]:
+ """
+ Get the default group/project or None if not set
+ """
+ old_config = getattr(config, "issues_github_path", None)
+ new_config = getattr(config, "issues_default_group_project", None)
+
+ if old_config and new_config:
+ raise ValueError(
+ "Both 'issues_github_path' and 'issues_default_group_project' are
set, even"
+ " though they define the same setting. "
+ "Please only define one of these."
+ )
+ group_and_project = new_config or old_config
+
+ if group_and_project:
+ assert isinstance(group_and_project, str)
+ try:
+ group, project = group_and_project.split("/", maxsplit=1)
+ return group, project
+ except ValueError as e:
+ raise ValueError(
+ "`issues_github_path` or `issues_default_group_project` needs
to "
+ "define a value in the form of `<group or user>/<project>` "
+ f"but `{config}` was given."
+ ) from e
+
+ # If group and project was not set, we need to look for it within the
github url
+ # for backward compatibility
+ if not group_and_project:
+ uri = getattr(config, uri_config_option)
+ if uri:
+ match = GITHUB_USER_RE.match(uri)
+ if match:
+ return match.groups()[0], match.groups()[1]
+
+ return None
+
+
+def _get_placeholder(uri_config_option: str) -> str:
+ """
+ Get the placeholder from the uri_config_option
+ """
+ try:
+ # i.e. issues_pr_uri -> pr
+ return uri_config_option[:-4].split("_", maxsplit=1)[1]
+ except IndexError:
+ # issues_uri -> issue
+ return uri_config_option[:-5]
+
+
+def _get_uri_template(
+ config: Config,
+ uri_config_option: str,
+) -> str:
+ """
+ Get a URL format template that can be filled with user information based
+ on the given configuration
+
+ The result always contains the following placeholder
+ - n (the issue number, user, pull request, etc...)
+
+ The result can contain the following other placeholders
+ - group (same as user in github)
+ - project
+
+ Examples for possible results:
+
+ - "https://github.com/{group}/{project}/issues/{n}"
+
+ - "https://gitlab.company.com/{group}/{project}/{n}"
+
+ -
"https://fancy.issuetrack.com?group={group}&project={project}&issue={n}"
+
+ Raises:
+ - ValueError if the given uri contains an invalid placeholder
+ """
+ format_string = str(getattr(config, uri_config_option))
+ placeholder = _get_placeholder(uri_config_option)
+
+ result = format_string.replace(f"{{{placeholder}}}", "{n}")
+
+ try:
+ result.format(project="", group="", n="")
+ except (NameError, KeyError) as e:
+ raise ValueError(
+ f"The `{uri_config_option}` option contains invalid placeholders. "
+ f"Only {{group}}, {{projects}} and {{{placeholder}}} are allowed."
+ f'Invalid format string: "{format_string}".'
+ ) from e
+ return result
+
+
+def _get_uri(
+ uri_config_option: str,
+ config: Config,
+ number: str,
+ group_and_project: Optional[Tuple[str, str]] = None,
+) -> str:
+ """
+ Get a URI based on the given configuration and do some sanity checking
+ """
+ format_string = _get_uri_template(config, uri_config_option)
+
+ url_vars = {"n": number}
+
+ config_group_and_project = _get_default_group_and_project(config,
uri_config_option)
+ if group_and_project:
+ # Group and Project defined by call
+ if config_group_and_project:
+ to_replace = "/".join(config_group_and_project)
+ if to_replace in format_string:
+ # Backward compatibility, replace default group/project
+ # with {group}/{project}
+ format_string = format_string.replace(to_replace,
"{group}/{project}")
+ (url_vars["group"], url_vars["project"]) = group_and_project
+ elif config_group_and_project:
+ # If not defined by call use the default if given
+ (url_vars["group"], url_vars["project"]) = config_group_and_project
+
+ try:
+ return format_string.format(**url_vars)
+ except (NameError, KeyError) as e:
+ # The format string was checked before, that it contains no additional
not
+ # supported placeholders. So this occur
+ raise ValueError(
+ f"The `{uri_config_option}` format `{format_string}` requires a "
+ f"group/project to be defined in `issues_default_group_project`."
+ ) from e
+
+
+def cwe_role(name, rawtext, text, lineno, inliner, options=None, content=None):
+ """Sphinx role for linking to a CWE on https://cwe.mitre.org.
Examples: ::
- :cve:`CVE-2018-17175`
+ :cwe:`CWE-787`
"""
options = options or {}
@@ -57,65 +181,80 @@
target = utils.unescape(target).strip()
title = utils.unescape(title).strip()
- ref = "https://cve.mitre.org/cgi-bin/cvename.cgi?name={0}".format(target)
+ number = target[4:]
+ ref = f"https://cwe.mitre.org/data/definitions/{number}.html"
text = title if has_explicit_title else target
link = nodes.reference(text=text, refuri=ref, **options)
return [link], []
-class IssueRole(object):
+class IssueRole:
+ # Symbols used to separate and issue/pull request/merge request etc
+ # i.e
+ # - group/project#2323 for issues
+ # - group/project!1234 for merge requests (in gitlab)
+ # - group/project@adbc1234 for commits
+ ELEMENT_SEPARATORS = "#@!"
- EXTERNAL_REPO_REGEX = re.compile(r"^(\w+)/(.+)([#@])([\w]+)$")
+ EXTERNAL_REPO_REGEX =
re.compile(rf"^(\w+)/(.+)([{ELEMENT_SEPARATORS}])([\w]+)$")
def __init__(
- self, uri_config_option, format_kwarg, github_uri_template,
format_text=None
+ self,
+ config_prefix: str,
+ pre_format_text: Callable[[Config, str], str] = None,
):
- self.uri_config_option = uri_config_option
- self.format_kwarg = format_kwarg
- self.github_uri_template = github_uri_template
- self.format_text = format_text or self.default_format_text
+ self.uri_config = f"{config_prefix}_uri"
+ self.separator_config = f"{config_prefix}_prefix"
+ self.pre_format_text = pre_format_text or self.default_pre_format_text
@staticmethod
- def default_format_text(issue_no):
- return "#{0}".format(issue_no)
+ def default_pre_format_text(config: Config, text: str) -> str:
+ return text
+
+ def format_text(self, config: Config, issue_no: str) -> str:
+ """
+ Add supported separator in front of the issue or raise an error if
invalid
+ separator is given
+ """
+ separator = getattr(config, self.separator_config)
+ if separator not in self.ELEMENT_SEPARATORS:
+ raise ValueError(
+ f"Option {self.separator_config} has to be one of "
+ f"{', '.join(self.ELEMENT_SEPARATORS)}."
+ )
+ text = self.pre_format_text(config,
issue_no.lstrip(self.ELEMENT_SEPARATORS))
+ return f"{separator}{text}"
+
+ def make_node(self, name: str, issue_no: str, config: Config,
options=None):
+ if issue_no in ("-", "0"):
+ return None
- def make_node(self, name, issue_no, config, options=None):
- name_map = {"pr": "pull", "issue": "issues", "commit": "commit"}
options = options or {}
+
+ has_explicit_title, title, target = split_explicit_title(issue_no)
+
+ if has_explicit_title:
+ issue_no = str(target)
+
repo_match = self.EXTERNAL_REPO_REGEX.match(issue_no)
- if repo_match: # External repo
- username, repo, symbol, issue = repo_match.groups()
- if name not in name_map:
- raise ValueError(
- "External repo linking not supported for :{}:".format(name)
- )
- path = name_map.get(name)
- ref = "https://github.com/{issues_github_path}/{path}/{n}".format(
- issues_github_path="{}/{}".format(username, repo), path=path,
n=issue
+
+ if repo_match:
+ # External repo
+ group, project, original_separator, issue_no = repo_match.groups()
+ text = f"{group}/{project}{self.format_text(config, issue_no)}"
+ ref = _get_uri(
+ self.uri_config,
+ config,
+ issue_no,
+ (group, project),
)
- formatted_issue = self.format_text(issue).lstrip("#")
- text =
"{username}/{repo}{symbol}{formatted_issue}".format(**locals())
- link = nodes.reference(text=text, refuri=ref, **options)
- return link
-
- if issue_no not in ("-", "0"):
- uri_template = getattr(config, self.uri_config_option, None)
- if uri_template:
- ref = uri_template.format(**{self.format_kwarg: issue_no})
- elif config.issues_github_path:
- ref = self.github_uri_template.format(
- issues_github_path=config.issues_github_path, n=issue_no
- )
- else:
- raise ValueError(
- "Neither {} nor issues_github_path "
- "is set".format(self.uri_config_option)
- )
- issue_text = self.format_text(issue_no)
- link = nodes.reference(text=issue_text, refuri=ref, **options)
else:
- link = None
- return link
+ text = self.format_text(config, issue_no)
+ ref = _get_uri(self.uri_config, config, issue_no)
+ if has_explicit_title:
+ return nodes.reference(text=title, refuri=ref, **options)
+ else:
+ return nodes.reference(text=text, refuri=ref, **options)
def __call__(
self, name, rawtext, text, lineno, inliner, options=None, content=None
@@ -135,70 +274,115 @@
"""Sphinx role for linking to an issue. Must have
-`issues_uri` or `issues_github_path` configured in ``conf.py``.
+`issues_uri` or `issues_default_group_project` configured in ``conf.py``.
Examples: ::
:issue:`123`
:issue:`42,45`
:issue:`sloria/konch#123`
"""
issue_role = IssueRole(
- uri_config_option="issues_uri",
- format_kwarg="issue",
- github_uri_template="https://github.com/{issues_github_path}/issues/{n}",
+ config_prefix="issues",
)
"""Sphinx role for linking to a pull request. Must have
-`issues_pr_uri` or `issues_github_path` configured in ``conf.py``.
+`issues_pr_uri` or `issues_default_group_project` configured in ``conf.py``.
Examples: ::
:pr:`123`
:pr:`42,45`
:pr:`sloria/konch#43`
"""
pr_role = IssueRole(
- uri_config_option="issues_pr_uri",
- format_kwarg="pr",
- github_uri_template="https://github.com/{issues_github_path}/pull/{n}",
+ config_prefix="issues_pr",
)
-def format_commit_text(sha):
+def format_commit_text(config, sha):
return sha[:7]
"""Sphinx role for linking to a commit. Must have
-`issues_pr_uri` or `issues_github_path` configured in ``conf.py``.
+`issues_commit_uri` or `issues_default_group_project` configured in
``conf.py``.
Examples: ::
:commit:`123abc456def`
:commit:`sloria/konch@123abc456def`
"""
commit_role = IssueRole(
- uri_config_option="issues_commit_uri",
- format_kwarg="commit",
- github_uri_template="https://github.com/{issues_github_path}/commit/{n}",
- format_text=format_commit_text,
+ config_prefix="issues_commit",
+ pre_format_text=format_commit_text,
)
+"""Sphinx role for linking to a user profile. Defaults to linking to
+GitHub profiles, but the profile URIS can be configured via the
+``issues_user_uri`` config value.
+
+Examples: ::
+
+ :user:`sloria`
+
+Anchor text also works: ::
+
+ :user:`Steven Loria <sloria>`
+"""
+user_role = IssueRole(config_prefix="issues_user")
+
def setup(app):
# Format template for issues URI
# e.g. 'https://github.com/sloria/marshmallow/issues/{issue}
- app.add_config_value("issues_uri", default=None, rebuild="html")
+ app.add_config_value(
+ "issues_uri",
+ default="https://github.com/{group}/{project}/issues/{issue}",
+ rebuild="html",
+ types=[str],
+ )
+ app.add_config_value("issues_prefix", default="#", rebuild="html",
types=[str])
# Format template for PR URI
# e.g. 'https://github.com/sloria/marshmallow/pull/{issue}
- app.add_config_value("issues_pr_uri", default=None, rebuild="html")
+ app.add_config_value(
+ "issues_pr_uri",
+ default="https://github.com/{group}/{project}/pull/{pr}",
+ rebuild="html",
+ types=[str],
+ )
+ app.add_config_value("issues_pr_prefix", default="#", rebuild="html",
types=[str])
# Format template for commit URI
# e.g. 'https://github.com/sloria/marshmallow/commits/{commit}
- app.add_config_value("issues_commit_uri", default=None, rebuild="html")
- # Shortcut for Github, e.g. 'sloria/marshmallow'
- app.add_config_value("issues_github_path", default=None, rebuild="html")
+ app.add_config_value(
+ "issues_commit_uri",
+ default="https://github.com/{group}/{project}/commit/{commit}",
+ rebuild="html",
+ types=[str],
+ )
+ app.add_config_value(
+ "issues_commit_prefix", default="@", rebuild="html", types=[str]
+ )
+ # There is no seperator config as a format_text function is given
+
+ # Default User (Group)/Project eg. 'sloria/marshmallow'
+ # Called github as the package was working with github only before
+ app.add_config_value(
+ "issues_github_path", default=None, rebuild="html", types=[str]
+ )
+ # Same as above but with new naming to reflect the new functionality
+ # Only on of both can be set
+ app.add_config_value(
+ "issues_default_group_project", default=None, rebuild="html",
types=[str]
+ )
# Format template for user profile URI
# e.g. 'https://github.com/{user}'
- app.add_config_value("issues_user_uri", default=None, rebuild="html")
+ app.add_config_value(
+ "issues_user_uri",
+ default="https://github.com/{user}",
+ rebuild="html",
+ types=[str],
+ )
+ app.add_config_value("issues_user_prefix", default="@", rebuild="html",
types=[str])
app.add_role("issue", issue_role)
app.add_role("pr", pr_role)
app.add_role("user", user_role)
app.add_role("commit", commit_role)
app.add_role("cve", cve_role)
+ app.add_role("cwe", cwe_role)
return {
"version": __version__,
"parallel_read_safe": True,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/sphinx-issues-1.2.0/test_sphinx_issues.py
new/sphinx-issues-3.0.1/test_sphinx_issues.py
--- old/sphinx-issues-1.2.0/test_sphinx_issues.py 2018-12-26
17:05:00.000000000 +0100
+++ new/sphinx-issues-3.0.1/test_sphinx_issues.py 1970-01-01
01:00:00.000000000 +0100
@@ -1,142 +0,0 @@
-# -*- coding: utf-8 -*-
-from tempfile import mkdtemp
-from shutil import rmtree
-
-try:
- from unittest.mock import Mock
-except ImportError:
- from mock import Mock
-
-from sphinx.application import Sphinx
-from sphinx_issues import (
- issue_role,
- user_role,
- pr_role,
- cve_role,
- commit_role,
- setup as issues_setup,
-)
-
-import pytest
-
-
[email protected]_fixture(
- params=[
- # Parametrize config
- {"issues_github_path": "marshmallow-code/marshmallow"},
- {
- "issues_uri":
"https://github.com/marshmallow-code/marshmallow/issues/{issue}",
- "issues_pr_uri":
"https://github.com/marshmallow-code/marshmallow/pull/{pr}",
- "issues_commit_uri":
"https://github.com/marshmallow-code/marshmallow/commit/{commit}",
- },
- ]
-)
-def app(request):
- src, doctree, confdir, outdir = [mkdtemp() for _ in range(4)]
- Sphinx._log = lambda self, message, wfile, nonl=False: None
- app = Sphinx(
- srcdir=src, confdir=None, outdir=outdir, doctreedir=doctree,
buildername="html"
- )
- issues_setup(app)
- # Stitch together as the sphinx app init() usually does w/ real conf files
- app.config._raw_config = request.param
- try:
- app.config.init_values()
- except TypeError:
- app.config.init_values(lambda x: x)
- yield app
- [rmtree(x) for x in (src, doctree, confdir, outdir)]
-
-
[email protected]()
-def inliner(app):
- return Mock(document=Mock(settings=Mock(env=Mock(app=app))))
-
-
[email protected](
- ("role", "role_name", "text", "expected_text", "expected_url"),
- [
- (
- issue_role,
- "issue",
- "42",
- "#42",
- "https://github.com/marshmallow-code/marshmallow/issues/42",
- ),
- (
- pr_role,
- "pr",
- "42",
- "#42",
- "https://github.com/marshmallow-code/marshmallow/pull/42",
- ),
- (user_role, "user", "sloria", "@sloria", "https://github.com/sloria"),
- (
- user_role,
- "user",
- "Steven Loria <sloria>",
- "Steven Loria",
- "https://github.com/sloria",
- ),
- (
- cve_role,
- "cve",
- "CVE-2018-17175",
- "CVE-2018-17175",
- "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-17175",
- ),
- (
- commit_role,
- "commit",
- "123abc456def",
- "123abc4",
-
"https://github.com/marshmallow-code/marshmallow/commit/123abc456def",
- ),
- # External issue
- (
- issue_role,
- "issue",
- "sloria/webargs#42",
- "sloria/webargs#42",
- "https://github.com/sloria/webargs/issues/42",
- ),
- # External PR
- (
- pr_role,
- "pr",
- "sloria/webargs#42",
- "sloria/webargs#42",
- "https://github.com/sloria/webargs/pull/42",
- ),
- # External commit
- (
- commit_role,
- "commit",
- "sloria/webargs@abc123def456",
- "sloria/webargs@abc123d",
- "https://github.com/sloria/webargs/commit/abc123def456",
- ),
- ],
-)
-def test_roles(inliner, role, role_name, text, expected_text, expected_url):
- result = role(role_name, rawtext="", text=text, lineno=None,
inliner=inliner)
- link = result[0][0]
- assert link.astext() == expected_text
- assert link.attributes["refuri"] == expected_url
-
-
-def test_issue_role_multiple(inliner):
- result = issue_role(
- name=None, rawtext="", text="42,43", inliner=inliner, lineno=None
- )
- link1 = result[0][0]
- assert link1.astext() == "#42"
- issue_url = "https://github.com/marshmallow-code/marshmallow/issues/"
- assert link1.attributes["refuri"] == issue_url + "42"
-
- sep = result[0][1]
- assert sep.astext() == ", "
-
- link2 = result[0][2]
- assert link2.astext() == "#43"
- assert link2.attributes["refuri"] == issue_url + "43"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/sphinx-issues-1.2.0/tests/source/conf.py
new/sphinx-issues-3.0.1/tests/source/conf.py
--- old/sphinx-issues-1.2.0/tests/source/conf.py 1970-01-01
01:00:00.000000000 +0100
+++ new/sphinx-issues-3.0.1/tests/source/conf.py 2022-01-11
17:41:14.000000000 +0100
@@ -0,0 +1,64 @@
+# Configuration file for the Sphinx documentation builder.
+#
+# This file only contains a selection of the most common options. For a full
+# list see the documentation:
+# https://www.sphinx-doc.org/en/master/usage/configuration.html
+
+# -- Path setup --------------------------------------------------------------
+
+# If extensions (or modules to document with autodoc) are in another directory,
+# add these directories to sys.path here. If the directory is relative to the
+# documentation root, use os.path.abspath to make it absolute, like shown here.
+#
+# import os
+# import sys
+# sys.path.insert(0, os.path.abspath('.'))
+
+
+# -- Project information -----------------------------------------------------
+
+project = "sphinx-issues"
+copyright = "2022, foobar"
+author = "foobar"
+
+
+# -- General configuration ---------------------------------------------------
+
+# Add any Sphinx extension module names here, as strings. They can be
+# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
+# ones.
+extensions = ["sphinx_issues"]
+
+# Add any paths that contain templates here, relative to this directory.
+templates_path = ["_templates"]
+
+# List of patterns, relative to source directory, that match files and
+# directories to ignore when looking for source files.
+# This pattern also affects html_static_path and html_extra_path.
+exclude_patterns = []
+
+
+# -- Options for HTML output -------------------------------------------------
+
+# The theme to use for HTML and HTML Help pages. See the documentation for
+# a list of builtin themes.
+#
+html_theme = "alabaster"
+
+# Add any paths that contain custom static files (such as style sheets) here,
+# relative to this directory. They are copied after the builtin static files,
+# so a file named "default.css" will overwrite the builtin "default.css".
+html_static_path = ["_static"]
+
+#
+suppress_warnings = ["app.add_node"]
+
+issues_uri = "https://gitlab.company.com/{group}/{project}/-/issues/{issue}"
+issues_prefix = "#"
+issues_pr_uri =
"https://gitlab.company.com/{group}/{project}/-/merge_requests/{pr}"
+issues_pr_prefix = "!"
+issues_commit_uri =
"https://gitlab.company.com/{group}/{project}/-/commit/{commit}"
+issues_commit_prefix = "@"
+issues_user_uri = "https://gitlab.company.com/{user}"
+issues_user_prefix = "@"
+issues_default_group_project = "myteam/super_great_project"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/sphinx-issues-1.2.0/tests/source/examples.rst
new/sphinx-issues-3.0.1/tests/source/examples.rst
--- old/sphinx-issues-1.2.0/tests/source/examples.rst 1970-01-01
01:00:00.000000000 +0100
+++ new/sphinx-issues-3.0.1/tests/source/examples.rst 2022-01-11
17:41:14.000000000 +0100
@@ -0,0 +1,7 @@
+Examples:
+
+ - See issues :issue:`12,13`
+
+ - See other issues :issue:`sloria/konch#45,46`.
+
+ - See PR :pr:`58`, thanks :user:`kound`
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/sphinx-issues-1.2.0/tests/source/index.rst
new/sphinx-issues-3.0.1/tests/source/index.rst
--- old/sphinx-issues-1.2.0/tests/source/index.rst 1970-01-01
01:00:00.000000000 +0100
+++ new/sphinx-issues-3.0.1/tests/source/index.rst 2022-01-11
17:41:14.000000000 +0100
@@ -0,0 +1,7 @@
+
+Welcome to sphinx-issues's documentation!
+=========================================
+
+
+.. include:: examples.rst
+.. include:: ../README.rst
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/sphinx-issues-1.2.0/tests/test_sphinx_issues.py
new/sphinx-issues-3.0.1/tests/test_sphinx_issues.py
--- old/sphinx-issues-1.2.0/tests/test_sphinx_issues.py 1970-01-01
01:00:00.000000000 +0100
+++ new/sphinx-issues-3.0.1/tests/test_sphinx_issues.py 2022-01-11
17:41:14.000000000 +0100
@@ -0,0 +1,358 @@
+import subprocess
+import sys
+from pathlib import Path
+from shutil import rmtree
+from tempfile import mkdtemp
+from unittest.mock import Mock
+
+import pytest
+import sphinx.application
+from sphinx_issues import commit_role, cve_role, cwe_role, issue_role, pr_role
+from sphinx_issues import setup as issues_setup
+from sphinx_issues import user_role
+
+
+BASE_DIR = Path(__file__).parent.absolute()
+
+
[email protected](
+ params=[
+ # Parametrize config
+ {"issues_github_path": "marshmallow-code/marshmallow"},
+ {"issues_default_group_project": "marshmallow-code/marshmallow"},
+ {
+ "issues_uri":
"https://github.com/marshmallow-code/marshmallow/issues/{issue}",
+ "issues_pr_uri":
"https://github.com/marshmallow-code/marshmallow/pull/{pr}",
+ "issues_commit_uri":
"https://github.com/marshmallow-code/marshmallow/commit/{commit}",
+ },
+ ]
+)
+def app(request):
+ src, doctree, confdir, outdir = [mkdtemp() for _ in range(4)]
+ sphinx.application.Sphinx._log = lambda self, message, wfile, nonl=False:
None
+ app = sphinx.application.Sphinx(
+ srcdir=src, confdir=None, outdir=outdir, doctreedir=doctree,
buildername="html"
+ )
+ issues_setup(app)
+ # Stitch together as the sphinx app init() usually does w/ real conf files
+ app.config._raw_config = request.param
+ try:
+ app.config.init_values()
+ except TypeError:
+ app.config.init_values(lambda x: x)
+ yield app
+ [rmtree(x) for x in (src, doctree, confdir, outdir)]
+
+
[email protected]()
+def inliner(app):
+ return Mock(document=Mock(settings=Mock(env=Mock(app=app))))
+
+
[email protected](
+ ("role", "role_name", "text", "expected_text", "expected_url"),
+ [
+ (
+ issue_role,
+ "issue",
+ "42",
+ "#42",
+ "https://github.com/marshmallow-code/marshmallow/issues/42",
+ ),
+ (
+ issue_role,
+ "issue",
+ "Hard Issue <42>",
+ "Hard Issue",
+ "https://github.com/marshmallow-code/marshmallow/issues/42",
+ ),
+ (
+ issue_role,
+ "issue",
+ "Not my business <foo/bar#42>",
+ "Not my business",
+ "https://github.com/foo/bar/issues/42",
+ ),
+ (
+ pr_role,
+ "pr",
+ "42",
+ "#42",
+ "https://github.com/marshmallow-code/marshmallow/pull/42",
+ ),
+ (user_role, "user", "sloria", "@sloria", "https://github.com/sloria"),
+ (
+ user_role,
+ "user",
+ "Steven Loria <sloria>",
+ "Steven Loria",
+ "https://github.com/sloria",
+ ),
+ (
+ cve_role,
+ "cve",
+ "CVE-2018-17175",
+ "CVE-2018-17175",
+ "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-17175",
+ ),
+ (
+ cwe_role,
+ "cve",
+ "CWE-787",
+ "CWE-787",
+ "https://cwe.mitre.org/data/definitions/787.html",
+ ),
+ (
+ commit_role,
+ "commit",
+ "123abc456def",
+ "@123abc4",
+
"https://github.com/marshmallow-code/marshmallow/commit/123abc456def",
+ ),
+ # External issue
+ (
+ issue_role,
+ "issue",
+ "sloria/webargs#42",
+ "sloria/webargs#42",
+ "https://github.com/sloria/webargs/issues/42",
+ ),
+ # External PR
+ (
+ pr_role,
+ "pr",
+ "sloria/webargs#42",
+ "sloria/webargs#42",
+ "https://github.com/sloria/webargs/pull/42",
+ ),
+ # External commit
+ (
+ commit_role,
+ "commit",
+ "sloria/webargs@abc123def456",
+ "sloria/webargs@abc123d",
+ "https://github.com/sloria/webargs/commit/abc123def456",
+ ),
+ ],
+)
+def test_roles(inliner, role, role_name, text, expected_text, expected_url):
+ result = role(role_name, rawtext="", text=text, lineno=None,
inliner=inliner)
+ link = result[0][0]
+ assert link.astext() == expected_text
+ assert link.attributes["refuri"] == expected_url
+
+
+def test_issue_role_multiple(inliner):
+ result = issue_role(
+ name=None, rawtext="", text="a title <42>,43", inliner=inliner,
lineno=None
+ )
+ link1 = result[0][0]
+ assert link1.astext() == "a title"
+ issue_url = "https://github.com/marshmallow-code/marshmallow/issues/"
+ assert link1.attributes["refuri"] == issue_url + "42"
+
+ sep = result[0][1]
+ assert sep.astext() == ", "
+
+ link2 = result[0][2]
+ assert link2.astext() == "#43"
+ assert link2.attributes["refuri"] == issue_url + "43"
+
+
+def test_issue_role_multiple_with_external(inliner):
+ result = issue_role(
+ "issue", rawtext="", text="42,sloria/konch#43", inliner=inliner,
lineno=None
+ )
+ link1 = result[0][0]
+ assert link1.astext() == "#42"
+ issue_url = "https://github.com/marshmallow-code/marshmallow/issues/42"
+ assert link1.attributes["refuri"] == issue_url
+
+ sep = result[0][1]
+ assert sep.astext() == ", "
+
+ link2 = result[0][2]
+ assert link2.astext() == "sloria/konch#43"
+ assert link2.attributes["refuri"] ==
"https://github.com/sloria/konch/issues/43"
+
+
[email protected]
+def app_custom_uri():
+ src, doctree, confdir, outdir = [mkdtemp() for _ in range(4)]
+ sphinx.application.Sphinx._log = lambda self, message, wfile, nonl=False:
None
+ app = sphinx.application.Sphinx(
+ srcdir=src, confdir=None, outdir=outdir, doctreedir=doctree,
buildername="html"
+ )
+ issues_setup(app)
+ # Stitch together as the sphinx app init() usually does w/ real conf files
+ app.config._raw_config = {
+ "issues_default_group_project": "myteam/super_great_project",
+ "issues_uri":
"https://gitlab.company.com/{group}/{project}/-/issues/{issue}",
+ "issues_prefix": "#",
+ "issues_pr_uri":
"https://gitlab.company.com/{group}/{project}/-/merge_requests/{pr}",
+ "issues_pr_prefix": "!",
+ "issues_commit_uri":
"https://gitlab.company.com/{group}/{project}/-/commit/{commit}",
+ "issues_commit_prefix": "@",
+ "issues_user_uri": "https://gitlab.company.com/{user}",
+ "issues_user_prefix": "@",
+ }
+ try:
+ app.config.init_values()
+ except TypeError:
+ app.config.init_values(lambda x: x)
+ yield app
+ [rmtree(x) for x in (src, doctree, confdir, outdir)]
+
+
[email protected]()
+def inliner_custom_uri(app_custom_uri):
+ return Mock(document=Mock(settings=Mock(env=Mock(app=app_custom_uri))))
+
+
[email protected](
+ ("role", "role_name", "text", "expected_text", "expected_url"),
+ [
+ (
+ issue_role,
+ "issue",
+ "42",
+ "#42",
+
"https://gitlab.company.com/myteam/super_great_project/-/issues/42",
+ ),
+ (
+ issue_role,
+ "issue",
+ "Hard Issue <42>",
+ "Hard Issue",
+
"https://gitlab.company.com/myteam/super_great_project/-/issues/42",
+ ),
+ (
+ issue_role,
+ "issue",
+ "Not my business <foo/bar#42>",
+ "Not my business",
+ "https://gitlab.company.com/foo/bar/-/issues/42",
+ ),
+ (
+ pr_role,
+ "pr",
+ "42",
+ "!42",
+
"https://gitlab.company.com/myteam/super_great_project/-/merge_requests/42",
+ ),
+ (user_role, "user", "sloria", "@sloria",
"https://gitlab.company.com/sloria"),
+ (
+ user_role,
+ "user",
+ "Steven Loria <sloria>",
+ "Steven Loria",
+ "https://gitlab.company.com/sloria",
+ ),
+ (
+ commit_role,
+ "commit",
+ "123abc456def",
+ "@123abc4",
+
"https://gitlab.company.com/myteam/super_great_project/-/commit/123abc456def",
+ ),
+ # External issue
+ (
+ issue_role,
+ "issue",
+ "sloria/webargs#42",
+ "sloria/webargs#42",
+ "https://gitlab.company.com/sloria/webargs/-/issues/42",
+ ),
+ # External PR
+ (
+ pr_role,
+ "pr",
+ "sloria/webargs#42",
+ "sloria/webargs!42",
+ "https://gitlab.company.com/sloria/webargs/-/merge_requests/42",
+ ),
+ # External commit
+ (
+ commit_role,
+ "commit",
+ "sloria/webargs@abc123def456",
+ "sloria/webargs@abc123d",
+ "https://gitlab.company.com/sloria/webargs/-/commit/abc123def456",
+ ),
+ ],
+)
+def test_roles_custom_uri(
+ inliner_custom_uri, role, role_name, text, expected_text, expected_url
+):
+ result = role(
+ role_name, rawtext="", text=text, lineno=None,
inliner=inliner_custom_uri
+ )
+ link = result[0][0]
+ assert link.astext() == expected_text
+ assert link.attributes["refuri"] == expected_url
+
+
[email protected]
+def tmp_doc_build_folder(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) ->
Path:
+ """Generate a temporary source folder and chdir in it. Return the build
folder"""
+ source = tmp_path / "source"
+ build = tmp_path / "build"
+ static = source / "_static"
+ for folder in (source, build, static):
+ folder.mkdir()
+ conf_py = BASE_DIR / "source" / "conf.py"
+ examples_rst = BASE_DIR / "source" / "examples.rst"
+
+ source.joinpath("conf.py").write_bytes(conf_py.read_bytes())
+ source.joinpath("index.rst").write_bytes(examples_rst.read_bytes())
+
+ monkeypatch.chdir(source)
+ return build
+
+
+def test_sphinx_build_integration(tmp_doc_build_folder: Path):
+ """Ensure that a simulated complete sphinx run works as expected"""
+ subprocess.run(
+ [
+ Path(sys.executable).parent.joinpath("sphinx-build"),
+ "-b",
+ "html",
+ "-W", # turn warnings into errors
+ "-E", # force rebuild of environment (even if we work in tmp)
+ ".",
+ str(tmp_doc_build_folder),
+ ],
+ check=True,
+ )
+
+ created = tmp_doc_build_folder / "index.html"
+ assert created.exists() and created.is_file()
+ content = created.read_text()
+ issue_url =
"https://gitlab.company.com/myteam/super_great_project/-/issues/"
+ other_issue_url = "https://gitlab.company.com/sloria/konch/-/issues/"
+ pr_url =
"https://gitlab.company.com/myteam/super_great_project/-/merge_requests/"
+ user_url = "https://gitlab.company.com/"
+
+ # We could do something fancy like an HTML parser or regex:
+ # Instead we keep it simple
+ expected_strings = (
+ (
+ f"See issues "
+ f'<a class="reference external" href="{issue_url}12">#12</a>, '
+ f'<a class="reference external" href="{issue_url}13">#13</a>'
+ ),
+ (
+ f"See other issues "
+ f'<a class="reference external"
href="{other_issue_url}45">sloria/konch#45</a>,'
+ f' <a class="reference external" href="{issue_url}46">#46</a>'
+ ),
+ (
+ f'See PR <a class="reference external" href="{pr_url}58">!58</a>, '
+ f'thanks <a class="reference external"
href="{user_url}kound">@kound</a>'
+ ),
+ )
+ # Ensure that we do no check character wise but line wise
+ assert len(expected_strings) == 3
+
+ for expected in expected_strings:
+ assert expected in content
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/sphinx-issues-1.2.0/tox.ini
new/sphinx-issues-3.0.1/tox.ini
--- old/sphinx-issues-1.2.0/tox.ini 2018-12-26 17:05:00.000000000 +0100
+++ new/sphinx-issues-3.0.1/tox.ini 2022-01-11 17:41:14.000000000 +0100
@@ -1,13 +1,14 @@
[tox]
-envlist = lint,py27,py35,py36,py37
+envlist = lint,py36,py37,py38,py39,py310
[testenv]
extras = tests
commands = pytest {posargs}
[testenv:lint]
-extras = lint
-commands = pre-commit run --all-files --show-diff-on-failure
+deps = pre-commit~=2.7
+skip_install = true
+commands = pre-commit run --all-files
; Below tasks are for development only (not run in CI)
[testenv:watch-readme]