From fb2aa9ff23082d812c3b8be4a22078070eeb94e2 Mon Sep 17 00:00:00 2001 From: Colm Talbot <colm.talbot@ligo.org> Date: Mon, 27 Feb 2023 18:24:24 +0000 Subject: [PATCH] DOCS: add links to actual code in docs --- docs/conf.py | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 65 insertions(+), 1 deletion(-) diff --git a/docs/conf.py b/docs/conf.py index dcd3e028a..1384090b8 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -16,11 +16,38 @@ # 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 importlib +import inspect import os +import subprocess import sys import bilby sys.path.insert(0, os.path.abspath('../')) + +def git_revision_hash(): + try: + return subprocess.check_output(['git', 'rev-parse', 'HEAD']).decode('ascii').strip() + except subprocess.CalledProcessError: + return "master" + + +def git_upstream_url(): + try: + url = subprocess.check_output(["git", "config", "--get", "remote.origin.url"]) + url = url.decode("ascii").strip().rstrip(".git") + if "@" in url: + url = url.split("@")[-1].replace(":", "/") + if url[:5] != "https": + url = f"https://{url}" + except subprocess.CalledProcessError: + url = "https://git.ligo.org/lscsoft/bilby" + return url + + +GITHASH = git_revision_hash() +GITURL = git_upstream_url() + # -- General configuration ------------------------------------------------ # If your documentation needs a minimal Sphinx version, state it here. @@ -38,7 +65,7 @@ extensions = [ 'sphinx.ext.autosummary', 'sphinx.ext.autosectionlabel', 'sphinx_tabs.tabs', - "sphinx.ext.viewcode", + "sphinx.ext.linkcode", ] autosummary_generate = True @@ -183,3 +210,40 @@ numpydoc_show_class_members = False # nbsphinx options nbsphinx_execute = "never" + + +def linkcode_resolve(domain, info): + """ + Adapted from https://github.com/aaugustin/websockets/blob/8e1628a14e0dd2ca98871c7500484b5d42d16b67/docs/conf.py + """ + if domain != 'py': + return None + if not info['module']: + return None + + try: + mod = importlib.import_module(info["module"]) + if "." in info["fullname"]: + objname, attrname = info["fullname"].split(".") + obj = getattr(mod, objname) + try: + # object is a method of a class + obj = getattr(obj, attrname) + except AttributeError: + # object is an attribute of a class + return None + else: + obj = getattr(mod, info["fullname"]) + + try: + file = inspect.getsourcefile(obj) + lines = inspect.getsourcelines(obj) + except TypeError: + # e.g. object is a typing.Union + return None + file = f"{project}/{''.join(file.split(f'{project}/')[1:])}" + start, end = lines[1], lines[1] + len(lines[0]) - 1 + except Exception: + return + + return f"{GITURL}/-/tree/{GITHASH}/{file}#L{start}-L{end}" -- GitLab