Last active
May 18, 2024 06:27
-
-
Save nlgranger/55ff2e7ff10c280731348a16d569cb73 to your computer and use it in GitHub Desktop.
A generic implementation of linkcode_resolve for the 'sphinx.ext.viewcode' extension of sphinx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# the sphinx extension 'sphinx.ext.viewcode' links documentation to an online | |
# code repository but requires to bind the code to the url through a user | |
# specific `linkcode_resolve` function. This implementation should be fairly | |
# generic and easily adaptable. | |
# | |
# License: Public Domain, CC0 1.0 Universal (CC0 1.0) | |
import sys | |
import os | |
import subprocess | |
import inspect | |
linkcode_revision = "master" | |
try: | |
# lock to commit number | |
cmd = "git log -n1 --pretty=%H" | |
head = subprocess.check_output(cmd.split()).strip().decode('utf-8') | |
linkcode_revision = head | |
# if we are on master's HEAD, use master as reference | |
cmd = "git log --first-parent master -n1 --pretty=%H" | |
master = subprocess.check_output(cmd.split()).strip().decode('utf-8') | |
if head == master: | |
linkcode_revision = "master" | |
# if we have a tag, use tag as reference | |
cmd = "git describe --exact-match --tags " + head | |
tag = subprocess.check_output(cmd.split(" ")).strip().decode('utf-8') | |
linkcode_revision = tag | |
except subprocess.CalledProcessError: | |
pass | |
linkcode_url = "https://github.com/nlgranger/SeqTools/blob/" \ | |
+ linkcode_revision + "/{filepath}#L{linestart}-L{linestop}" | |
def linkcode_resolve(domain, info): | |
if domain != 'py' or not info['module']: | |
return None | |
modname = info['module'] | |
topmodulename = modname.split('.')[0] | |
fullname = info['fullname'] | |
submod = sys.modules.get(modname) | |
if submod is None: | |
return None | |
obj = submod | |
for part in fullname.split('.'): | |
try: | |
obj = getattr(obj, part) | |
except Exception: | |
return None | |
try: | |
modpath = pkg_resources.require(topmodulename)[0].location | |
filepath = os.path.relpath(inspect.getsourcefile(obj), modpath) | |
if filepath is None: | |
return | |
except Exception: | |
return None | |
try: | |
source, lineno = inspect.getsourcelines(obj) | |
except OSError: | |
return None | |
else: | |
linestart, linestop = lineno, lineno + len(source) - 1 | |
return linkcode_url.format( | |
filepath=filepath, linestart=linestart, linestop=linestop) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment