diff --git a/docs/Makefile b/docs/Makefile deleted file mode 100644 index 8af9df276194169257f26c7251cc86ff049d0ad5..0000000000000000000000000000000000000000 --- a/docs/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -# Makefile for Sphinx documentation -# - -# You can set these variables from the command line. -SPHINXOPTS = -SPHINXBUILD = sphinx-build -SPHINXPROJ = GWDataFind -SOURCEDIR = . -BUILDDIR = _build - -.PHONY: help html - -# Put it first so that "make" without argument is like "make help". -help: - @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) - -# Catch-all target: route all unknown targets to Sphinx using the new -# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). -html: - @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/docs/conf.py b/docs/conf.py index 7ab859922654b4d8f37acdbdfd69cf860fd47cf5..9e29178e147e1f7b3bbb41202816d755d44bca60 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -1,44 +1,66 @@ -# # gwdatafind documentation build configuration file -import glob -import os.path +import inspect import re +import sys +from os import getenv +from pathlib import Path -from gwdatafind import __version__ as gwdatafind_version +import gwdatafind -extensions = [ - 'sphinx.ext.intersphinx', - 'sphinx.ext.napoleon', - 'sphinx_automodapi.automodapi', - 'sphinxarg.ext', -] +# -- metadata + +project = "gwdatafind" +copyright = "2018-2025, Cardiff University" +author = "Duncan Macleod" +release = gwdatafind.__version__ +version = re.split(r'[\w-]', gwdatafind.__version__)[0] -#templates_path = ['_templates'] +# -- config source_suffix = '.rst' - master_doc = 'index' -# General information about the project. -project = "gwdatafind" -copyright = "2018-2021, Cardiff University" -author = "Duncan Macleod" +default_role = 'obj' + +# -- theme + +html_theme = "furo" + +html_theme_options = { + "footer_icons": [ + { + "name": "GitLab", + "url": "https://git.ligo.org/computing/gwdatafind/client", + "class": "fa-brands fa-gitlab", + }, + ], +} -# The short X.Y version. -version = re.split(r'[\w-]', gwdatafind_version)[0] -# The full version, including alpha/beta/rc tags. -release = gwdatafind_version +# need fontawesome for the gitlab icon in the footer +html_css_files = [ + "https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.2/css/fontawesome.min.css", + "https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.2/css/solid.min.css", + "https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.2/css/brands.min.css", +] -# List of patterns, relative to source directory, that match files and -# directories to ignore when looking for source files. -# This patterns also effect to html_static_path and html_extra_path -exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] +pygments_dark_style = "monokai" -# The name of the Pygments (syntax highlighting) style to use. -pygments_style = 'monokai' +# -- extensions -# Intersphinx directory +extensions = [ + "sphinx.ext.intersphinx", + "sphinx.ext.napoleon", + "sphinx.ext.linkcode", + "sphinx_automodapi.automodapi", + "sphinx_copybutton", + "sphinxarg.ext", +] + +# automodapi +automodapi_inherited_members = False + +# intersphinx intersphinx_mapping = { "igwn-auth-utils": ( "https://igwn-auth-utils.readthedocs.io/en/stable/", @@ -62,49 +84,75 @@ intersphinx_mapping = { ), } -# The reST default role (used for this markup: `text`) to use for all -# documents. -default_role = 'obj' - -# napoleon configuration +# napoleon napoleon_use_rtype = False -# Don't inherit in automodapi -numpydoc_show_class_members = False -automodapi_inherited_members = False - -# -- 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 = 'sphinx_rtd_theme' - -# 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'] - -# Output file base name for HTML help builder. -htmlhelp_basename = 'gwdatafinddoc' - -# -- add static files---------------------------------------------------------- - -def setup_static_content(app): - curdir = os.path.abspath(os.path.dirname(__file__)) - # configure stylesheets - for sdir in html_static_path: - staticdir = os.path.join(curdir, sdir) - - # add stylesheets - for cssf in glob.glob(os.path.join(staticdir, 'css', '*.css')): - app.add_css_file(cssf[len(staticdir)+1:]) - - # add custom javascript - for jsf in glob.glob(os.path.join(staticdir, 'js', '*.js')): - app.add_js_file(jsf[len(staticdir)+1:]) - -# -- setup -------------------------------------------------------------------- -def setup(app): - setup_static_content(app) +# -- linkcode + +def _project_git_ref(version, prefix="v"): + """Returns the git reference for the given full release version. + """ + # handle builds in CI + if getenv("GITLAB_CI"): + return getenv("CI_COMMIT_REF") + if getenv("GITHUB_ACTIONS"): + return getenv("GITHUB_SHA") + # otherwise use the project metadata + _setuptools_scm_version_regex = re.compile( + r"\+g(\w+)(?:\Z|\.)", + ) + if match := _setuptools_scm_version_regex.search(version): + return match.groups()[0] + return f"{prefix}{version}" + + +PROJECT_GIT_REF = _project_git_ref(release, prefix="") +PROJECT_PATH = Path(gwdatafind.__file__).parent +PROJECT_URL = getenv( + "CI_PROJECT_URL", + "https://git.ligo.org/computing/gwdatafind/client", +) +PROJECT_BLOB_URL = f"{PROJECT_URL}/blob/{PROJECT_GIT_REF}/{PROJECT_PATH.name}" + + +def linkcode_resolve(domain, info): + """Determine the URL corresponding to Python object. + """ + if domain != "py" or not info["module"]: + return None + + def find_source(module, fullname): + """Construct a source file reference for an object reference. + """ + # resolve object + obj = sys.modules[module] + for part in fullname.split("."): + obj = getattr(obj, part) + # get filename relative to project + filename = Path( + inspect.getsourcefile(obj), # type: ignore [arg-type] + ).relative_to(PROJECT_PATH).as_posix() + # get line numbers of this object + lines, lineno = inspect.findsource(obj) + if lineno: + start = lineno + 1 # 0-index + end = lineno + len(inspect.getblock(lines[lineno:])) + else: + start = end = 0 + return filename, start, end + + try: + path, start, end = find_source(info["module"], info["fullname"]) + except ( + AttributeError, # object not found + OSError, # file not found + TypeError, # source for object not found + ValueError, # file not from this project + ): + return None + + url = f"{PROJECT_BLOB_URL}/{path}" + if start: + url += f"#L{start}-L{end}" + return url diff --git a/pyproject.toml b/pyproject.toml index 1801bd37cc7dfbf705d07d05d4dcf1e6ec285023..9db2a4fd29c248adfd1e81002f10d6ccb036685d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -44,11 +44,12 @@ dynamic = [ [project.optional-dependencies] docs = [ + "furo", "numpydoc", - "sphinx >= 4.4.0", + "Sphinx >= 4.4.0", "sphinx-argparse", "sphinx_automodapi", - "sphinx_rtd_theme", + "sphinx-copybutton", ] test = [ "pytest >= 2.8.0",