From dc0ed5dd7added92df40a8a59569dfaacf5bedf2 Mon Sep 17 00:00:00 2001 From: Duncan Macleod <macleoddm@cardiff.ac.uk> Date: Mon, 13 Jan 2025 13:08:48 +0000 Subject: [PATCH 1/3] docs: use furo docs theme numerous improvements over sphinx_rtd_theme, namely automatic dark mode --- docs/Makefile | 20 ----------- docs/conf.py | 98 ++++++++++++++------------------------------------ pyproject.toml | 5 +-- 3 files changed, 30 insertions(+), 93 deletions(-) delete mode 100644 docs/Makefile diff --git a/docs/Makefile b/docs/Makefile deleted file mode 100644 index 8af9df2..0000000 --- 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 7ab8599..6335b97 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -1,44 +1,44 @@ -# # gwdatafind documentation build configuration file -import glob -import os.path import re from gwdatafind import __version__ as gwdatafind_version -extensions = [ - 'sphinx.ext.intersphinx', - 'sphinx.ext.napoleon', - 'sphinx_automodapi.automodapi', - 'sphinxarg.ext', -] +# -- metadta -#templates_path = ['_templates'] +project = "gwdatafind" +copyright = "2018-2025, Cardiff University" +author = "Duncan Macleod" +release = gwdatafind_version +version = re.split(r'[\w-]', gwdatafind_version)[0] -source_suffix = '.rst' +# -- 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' -# The short X.Y version. -version = re.split(r'[\w-]', gwdatafind_version)[0] -# The full version, including alpha/beta/rc tags. -release = gwdatafind_version +# -- theme -# 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'] +html_theme = "furo" +pygments_dark_style = "monokai" -# The name of the Pygments (syntax highlighting) style to use. -pygments_style = 'monokai' -# Intersphinx directory +# -- extensions + +extensions = [ + "sphinx.ext.intersphinx", + "sphinx.ext.napoleon", + "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 +62,5 @@ 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) diff --git a/pyproject.toml b/pyproject.toml index 1801bd3..9db2a4f 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", -- GitLab From 0c4039218570adff9d703205b9e0877f8264acb8 Mon Sep 17 00:00:00 2001 From: Duncan Macleod <macleoddm@cardiff.ac.uk> Date: Mon, 13 Jan 2025 17:32:26 +0000 Subject: [PATCH 2/3] docs: add linkcode and gitlab footer link closes #38 --- docs/conf.py | 96 +++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 91 insertions(+), 5 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index 6335b97..15f6d73 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -1,16 +1,20 @@ # gwdatafind documentation build configuration file +import inspect import re +import sys +from os import getenv +from pathlib import Path -from gwdatafind import __version__ as gwdatafind_version +import gwdatafind -# -- metadta +# -- metadata project = "gwdatafind" copyright = "2018-2025, Cardiff University" author = "Duncan Macleod" -release = gwdatafind_version -version = re.split(r'[\w-]', gwdatafind_version)[0] +release = gwdatafind.__version__ +version = re.split(r'[\w-]', gwdatafind.__version__)[0] # -- config @@ -22,14 +26,32 @@ default_role = 'obj' # -- theme html_theme = "furo" -pygments_dark_style = "monokai" +html_theme_options = { + "footer_icons": [ + { + "name": "GitLab", + "url": "https://git.ligo.org/computing/gwdatafind/client", + "class": "fa-brands fa-gitlab", + }, + ], +} + +# 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", +] + +pygments_dark_style = "monokai" # -- extensions extensions = [ "sphinx.ext.intersphinx", "sphinx.ext.napoleon", + "sphinx.ext.linkcode", "sphinx_automodapi.automodapi", "sphinx_copybutton", "sphinxarg.ext", @@ -64,3 +86,67 @@ intersphinx_mapping = { # napoleon napoleon_use_rtype = False + + +# -- linkcode + +def _project_git_ref(version, prefix="v"): + """Returns the git reference for the given full release version. + """ + _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 -- GitLab From 41b37bb1214d529e515dce95f41935bf11c7c5a4 Mon Sep 17 00:00:00 2001 From: Duncan Macleod <macleoddm@cardiff.ac.uk> Date: Wed, 15 Jan 2025 11:58:16 +0000 Subject: [PATCH 3/3] docs: improve linkcode git ref handling --- docs/conf.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/docs/conf.py b/docs/conf.py index 15f6d73..9e29178 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -93,6 +93,12 @@ napoleon_use_rtype = False 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|\.)", ) @@ -107,7 +113,7 @@ 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}" +PROJECT_BLOB_URL = f"{PROJECT_URL}/blob/{PROJECT_GIT_REF}/{PROJECT_PATH.name}" def linkcode_resolve(domain, info): -- GitLab