From 69aa3b419c300639ac3ee6c4e0d7f451f1576e90 Mon Sep 17 00:00:00 2001 From: Remco de Boer <29308176+redeboer@users.noreply.github.com> Date: Fri, 6 Oct 2023 15:45:32 +0200 Subject: [PATCH] DOC: host API documentation for `repoma` module (#193) * DOC: add link to `.pre-commit-hooks.yaml` * DX: recommend MyST VSCode extension * DX: visualize module dependencies with `pydeps` Install graphviz with `conda install graphviz` and run `tox -e pydeps` --- .cspell.json | 2 + .github/workflows/ci.yml | 8 ++ .gitpod.yml | 2 + .vscode/extensions.json | 2 + .vscode/settings.json | 1 + README.md | 9 +- docs/.gitignore | 1 + docs/_static/.gitignore | 1 + docs/_static/favicon.ico | Bin 0 -> 15406 bytes docs/_templates/module.rst_t | 12 +++ docs/_templates/package.rst_t | 49 ++++++++++ docs/_templates/toc.rst_t | 7 ++ docs/conf.py | 129 +++++++++++++++++++++++++++ docs/index.md | 50 +++++++++++ pyproject.toml | 7 ++ setup.cfg | 8 ++ src/repoma/__init__.py | 4 +- src/repoma/check_dev_files/vscode.py | 4 + src/repoma/pin_nb_requirements.py | 2 +- src/repoma/utilities/precommit.py | 9 +- src/repoma/utilities/project_info.py | 2 +- tox.ini | 98 +++++++++++++++++++- 22 files changed, 394 insertions(+), 13 deletions(-) create mode 100644 docs/.gitignore create mode 100644 docs/_static/.gitignore create mode 100644 docs/_static/favicon.ico create mode 100644 docs/_templates/module.rst_t create mode 100644 docs/_templates/package.rst_t create mode 100644 docs/_templates/toc.rst_t create mode 100644 docs/conf.py create mode 100644 docs/index.md diff --git a/.cspell.json b/.cspell.json index de8b553b..808adae3 100644 --- a/.cspell.json +++ b/.cspell.json @@ -64,6 +64,7 @@ "pytest", "PYTHONHASHSEED", "repoma", + "toctree", "Zenodo" ], "ignoreWords": [ @@ -81,6 +82,7 @@ "indentless", "jsonschema", "linkcheck", + "maxdepth", "maxsplit", "nargs", "nbcell", diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 12785895..406eaf2b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -26,6 +26,14 @@ on: type: string jobs: + doc: + uses: ComPWA/actions/.github/workflows/ci-docs.yml@v1 + permissions: + pages: write + id-token: write + with: + gh-pages: true + specific-pip-packages: ${{ inputs.specific-pip-packages }} pytest: uses: ComPWA/actions/.github/workflows/pytest.yml@v1 with: diff --git a/.gitpod.yml b/.gitpod.yml index f92255f1..c3e87fa6 100644 --- a/.gitpod.yml +++ b/.gitpod.yml @@ -18,6 +18,7 @@ vscode: - eamodio.gitlens - editorconfig.editorconfig - esbenp.prettier-vscode + - executablebookproject.myst-highlight - garaioag.garaio-vscode-unwanted-recommendations - github.vscode-github-actions - github.vscode-pull-request-github @@ -25,6 +26,7 @@ vscode: - ms-python.mypy-type-checker - ms-python.python - ms-python.vscode-pylance + - ms-vscode.live-server - ms-vsliveshare.vsliveshare - redhat.vscode-yaml - ryanluker.vscode-coverage-gutters diff --git a/.vscode/extensions.json b/.vscode/extensions.json index 0ec4f1f6..bdeb608f 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -5,6 +5,7 @@ "eamodio.gitlens", "editorconfig.editorconfig", "esbenp.prettier-vscode", + "executablebookproject.myst-highlight", "garaioag.garaio-vscode-unwanted-recommendations", "github.vscode-github-actions", "github.vscode-pull-request-github", @@ -12,6 +13,7 @@ "ms-python.mypy-type-checker", "ms-python.python", "ms-python.vscode-pylance", + "ms-vscode.live-server", "ms-vsliveshare.vsliveshare", "redhat.vscode-yaml", "ryanluker.vscode-coverage-gutters", diff --git a/.vscode/settings.json b/.vscode/settings.json index 1f4e9ca5..96590612 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -40,6 +40,7 @@ }, "git.rebaseWhenSync": true, "github-actions.workflows.pinned.workflows": [".github/workflows/ci.yml"], + "livePreview.defaultPreviewPath": "docs/_build/html", "mypy-type-checker.args": ["--config-file=${workspaceFolder}/pyproject.toml"], "mypy-type-checker.importStrategy": "fromEnvironment", "python.analysis.autoImportCompletions": false, diff --git a/README.md b/README.md index 053eabb6..5a6e6fcb 100644 --- a/README.md +++ b/README.md @@ -31,5 +31,10 @@ repos: - id: set-nb-cells ``` -then run `pre-commit autoupdate`. This example lists all available hooks (listed here as -`id`s) ― you can remove some of them. +then run + +```shell +pre-commit autoupdate --repo=https://github.com/ComPWA/repo-maintenance +``` + +This example lists [all available hooks](./.pre-commit-hooks.yaml) (listed here as `id`s) ― you can remove some of them. diff --git a/docs/.gitignore b/docs/.gitignore new file mode 100644 index 00000000..8c6492ca --- /dev/null +++ b/docs/.gitignore @@ -0,0 +1 @@ +api/ diff --git a/docs/_static/.gitignore b/docs/_static/.gitignore new file mode 100644 index 00000000..d81524ab --- /dev/null +++ b/docs/_static/.gitignore @@ -0,0 +1 @@ +logo.svg diff --git a/docs/_static/favicon.ico b/docs/_static/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..bfd192b144b49bcbb114ed95dbeef69b31339e23 GIT binary patch literal 15406 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 None: + if os.path.exists(output_path): + return + online_content = requests.get(url, allow_redirects=True, timeout=10) + with open(output_path, "wb") as stream: + stream.write(online_content.content) + + +def generate_api(package: str) -> None: + shutil.rmtree("api", ignore_errors=True) + subprocess.call( + " ".join( + [ + "sphinx-apidoc", + f"../src/{package}/", + f"../src/{package}/version.py", + "-o api/", + "--force", + "--no-toc", + "--templatedir _templates", + "--separate", + ] + ), + shell=True, # noqa: S602 + ) + + +def get_html_logo_path() -> Optional[str]: + logo_path = "_static/logo.svg" + os.makedirs(os.path.dirname(logo_path), exist_ok=True) + with contextlib.suppress(requests.exceptions.ConnectionError): + fetch_logo( + url="https://raw.githubusercontent.com/ComPWA/ComPWA/04e5199/doc/images/logo.svg", + output_path=logo_path, + ) + if os.path.exists(logo_path): + return logo_path + return None + + +def get_version(package_name: str) -> str: + v = get_package_version(package_name) + return ".".join(v.split(".")[:3]) + + +REPO_NAME = "repo-maintenance" +PACKAGE_NAME = "repoma" +generate_api(PACKAGE_NAME) + +author = "Common Partial Wave Analysis" +autodoc_member_order = "bysource" +autosectionlabel_prefix_document = True +autodoc_typehints_format = "short" +copybutton_prompt_is_regexp = True +copybutton_prompt_text = r">>> |\.\.\. " # doctest +copyright = "2023, Common Partial Wave Analysis" # noqa: A001 +default_role = "py:obj" +extensions = [ + "myst_parser", + "sphinx.ext.autodoc", + "sphinx.ext.autosectionlabel", + "sphinx.ext.doctest", + "sphinx.ext.intersphinx", + "sphinx.ext.napoleon", + "sphinx.ext.viewcode", + "sphinx_copybutton", +] +html_copy_source = True # needed for download notebook button +html_favicon = "_static/favicon.ico" +html_last_updated_fmt = "%-d %B %Y" +html_logo = get_html_logo_path() +html_show_copyright = False +html_show_sourcelink = False +html_show_sphinx = False +html_sourcelink_suffix = "" +html_static_path = ["_static"] +html_theme = "sphinx_book_theme" +html_theme_options = { + "logo": {"text": REPO_NAME}, + "repository_url": f"https://github.com/ComPWA/{REPO_NAME}", + "repository_branch": "main", + "path_to_docs": "docs", + "use_repository_button": True, + "show_navbar_depth": 2, + "show_toc_level": 2, +} +html_title = REPO_NAME +intersphinx_mapping = { + "attrs": ("https://www.attrs.org/en/stable", None), + "nbformat": ("https://nbformat.readthedocs.io/en/stable", None), + "python": ("https://docs.python.org/3", None), + "tomlkit": ("https://tomlkit.readthedocs.io/en/stable", None), +} +myst_enable_extensions = [ + "colon_fence", +] +nitpick_ignore = [ + ("py:class", "repoma.utilities.precommit.T"), + ("py:class", "tomlkit.container.Container"), +] +nitpick_ignore_regex = [ + (r"py:.*", r"ruamel\.yaml\..*"), +] +nitpicky = True +primary_domain = "py" +project = REPO_NAME +release = get_version(REPO_NAME) +version = get_version(REPO_NAME) diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 00000000..0303c71c --- /dev/null +++ b/docs/index.md @@ -0,0 +1,50 @@ +# ComPWA repo maintenance! + +:::{title} Welcome +::: + +This package standardizes and synchronizes the developer environment of repositories by the [ComPWA organization](https://github.com/ComPWA). The maintenance is performed through [pre-commit](https://pre-commit.com) with the use of a number of pre-commit hooks as defined by [`.pre-commit-hooks.yaml`](../.pre-commit-hooks.yaml). The {mod}`check-dev-files <.check_dev_files>` in particular can be used as a **cookie cutter** for new repositories. + +## Usage + +Add a [`.pre-commit-config.yaml`](https://pre-commit.com/index.html#adding-pre-commit-plugins-to-your-project) file to your repository and list which hooks you want to use: + +```yaml +repos: + - repo: https://github.com/ComPWA/repo-maintenance + rev: "" + hooks: + - id: check-dev-files + args: + - --repo-name="short name for your repository" + - id: colab-toc-visible + - id: fix-nbformat-version + - id: format-setup-cfg + - id: pin-nb-requirements + - id: set-nb-cells +``` + +and install and activate [`pre-commit`](https://pre-commit.com/#install) as follows: + +```shell +pip install pre-commit +pre-commit autoupdate --repo=https://github.com/ComPWA/repo-maintenance +pre-commit install +``` + +The `repo-maintenance` repository provides the following hooks: + +- {mod}`check-dev-files <.check_dev_files>` +- {mod}`colab-toc-visible <.colab_toc_visible>` +- {mod}`fix-nbformat-version <.fix_nbformat_version>` +- {mod}`format-setup-cfg <.format_setup_cfg>` +- {mod}`pin-nb-requirements <.pin_nb_requirements>` +- {mod}`set-nb-cells <.set_nb_cells>` + +```{toctree} +:hidden: +API +Changelog +Upcoming features +Help developing +``` diff --git a/pyproject.toml b/pyproject.toml index 09a5aac4..53129a8c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -179,6 +179,13 @@ task-tags = ["cspell"] known-first-party = ["repoma"] [tool.ruff.per-file-ignores] +"docs/*" = [ + "E402", + "INP001", + "S101", + "S113", + "T201", +] "setup.py" = ["D100"] "tests/*" = [ "D", diff --git a/setup.cfg b/setup.cfg index 3ec67a1c..dc024360 100644 --- a/setup.cfg +++ b/setup.cfg @@ -46,6 +46,11 @@ package_dir = =src [options.extras_require] +doc = + myst-parser + Sphinx + sphinx-book-theme + sphinx-copybutton test = pytest pytest-cov @@ -55,6 +60,7 @@ format = mypy = mypy types-PyYAML + types-requests types-setuptools types-toml lint = @@ -67,9 +73,11 @@ sty = %(test)s # for pytest type hints pre-commit >=1.4.0 dev = + %(doc)s %(sty)s %(test)s labels + sphinx-autobuild tox >=1.9 # for skip_install, use_develop [options.entry_points] diff --git a/src/repoma/__init__.py b/src/repoma/__init__.py index 8f5d896e..f6322233 100644 --- a/src/repoma/__init__.py +++ b/src/repoma/__init__.py @@ -1,5 +1,5 @@ """Bundled developer configurations and tools for ComPWA repositories. -This package contains `pre-commit ` hooks that the -`ComPWA repositories ` have in common. +This package contains `pre-commit `_ hooks that the +`ComPWA repositories `_ have in common. """ diff --git a/src/repoma/check_dev_files/vscode.py b/src/repoma/check_dev_files/vscode.py index af3bf340..07f9f974 100644 --- a/src/repoma/check_dev_files/vscode.py +++ b/src/repoma/check_dev_files/vscode.py @@ -86,6 +86,10 @@ def _update_doc_settings() -> None: } executor = Executor() executor(vscode.set_setting, settings) + executor( + vscode.add_extension_recommendation, + "executablebookproject.myst-highlight", # cspell:ignore executablebookproject + ) executor(vscode.add_extension_recommendation, "ms-vscode.live-server") executor.finalize() diff --git a/src/repoma/pin_nb_requirements.py b/src/repoma/pin_nb_requirements.py index e0fcee27..88880838 100644 --- a/src/repoma/pin_nb_requirements.py +++ b/src/repoma/pin_nb_requirements.py @@ -1,6 +1,6 @@ """Enforce adding a pip install statement in the notebook. -In the `compwa-org repo _`, notebooks +In the `compwa-org repo `_, notebooks should specify which package versions should be used to run the notebook. This hook checks whether a notebook has such install statements and whether they comply with the expected formatting. diff --git a/src/repoma/utilities/precommit.py b/src/repoma/utilities/precommit.py index 3d4cbe3f..5157130e 100644 --- a/src/repoma/utilities/precommit.py +++ b/src/repoma/utilities/precommit.py @@ -140,9 +140,8 @@ def remove_rev(config: CommentedMap) -> dict: def update_precommit_hook(repo_url: str, expected_hook: CommentedMap) -> None: """Update the pre-commit hook definition of a specific pre-commit repo. - Just like :func:`update_precommit_repo`, this function updates the - :code:`.pre-commit-config.yaml` file, but does this only for a specific hook - definition *within* a pre-commit repository definition. + This function updates the :code:`.pre-commit-config.yaml` file, but does this only + for a specific hook definition *within* a pre-commit repository definition. """ if not CONFIG_PATH.precommit.exists(): return @@ -269,7 +268,7 @@ def get_repo_index(self, search_pattern: str) -> Optional[int]: return None -_T = TypeVar("_T", Hook, PrecommitCi, PrecommitConfig, Repo) +T = TypeVar("T", Hook, PrecommitCi, PrecommitConfig, Repo) def asdict(inst: Any) -> dict: @@ -280,7 +279,7 @@ def asdict(inst: Any) -> dict: ) -def fromdict(definition: dict, typ: Type[_T]) -> _T: +def fromdict(definition: dict, typ: Type[T]) -> T: if typ in {Hook, PrecommitCi}: return typ(**definition) # type: ignore[return-value] if typ is Repo: diff --git a/src/repoma/utilities/project_info.py b/src/repoma/utilities/project_info.py index 3f10e980..e26f73a7 100644 --- a/src/repoma/utilities/project_info.py +++ b/src/repoma/utilities/project_info.py @@ -90,7 +90,7 @@ def _extract_python_versions(classifiers: List[str]) -> Optional[List[str]]: def get_pypi_name(pyproject: Optional[TOMLDocument] = None) -> str: - """Extract package name for PyPI from `setup.cfg`. + """Extract package name for PyPI from :file:`setup.cfg`. >>> get_pypi_name() 'repo-maintenance' diff --git a/tox.ini b/tox.ini index b8885ce2..6878d77f 100644 --- a/tox.ini +++ b/tox.ini @@ -1,7 +1,8 @@ [tox] envlist = - py, - sty, + doc + py + sty passenv = PYTHONPATH skip_install = True skip_missing_interpreters = True @@ -27,6 +28,99 @@ commands = description = Compute test coverage +[testenv:doc] +allowlist_externals = + sphinx-build +commands = + sphinx-build \ + --keep-going \ + -TW \ + -b html \ + docs/ docs/_build/html +description = + Build documentation and API through Sphinx +passenv = * +setenv = + FORCE_COLOR = yes + +[testenv:doclive] +allowlist_externals = + sphinx-autobuild +commands = + sphinx-autobuild \ + --open-browser \ + --re-ignore .*/.ipynb_checkpoints/.* \ + --re-ignore .*/__pycache__/.* \ + --re-ignore .*\.gitignore \ + --re-ignore .*\.tmp \ + --re-ignore docs/.*\.csv \ + --re-ignore docs/.*\.gif \ + --re-ignore docs/.*\.gv \ + --re-ignore docs/.*\.inv \ + --re-ignore docs/.*\.json \ + --re-ignore docs/.*\.pickle \ + --re-ignore docs/.*\.png \ + --re-ignore docs/.*\.svg \ + --re-ignore docs/.*\.yaml \ + --re-ignore docs/.*\.yml \ + --re-ignore docs/_build/.* \ + --re-ignore docs/_images/.* \ + --re-ignore docs/api/.* \ + --watch docs \ + --watch src \ + docs/ docs/_build/html +description = + Set up a server to directly preview changes to the HTML pages +passenv = * +setenv = + FORCE_COLOR = yes + + +[testenv:docnb] +allowlist_externals = + sphinx-build +commands = + sphinx-build \ + --keep-going \ + -TW \ + -b html \ + docs/ docs/_build/html +description = + Build documentation through Sphinx WITH output of Jupyter notebooks +passenv = * +setenv = + EXECUTE_NB = yes + FORCE_COLOR = yes + PYTHONHASHSEED = 0 + +[testenv:linkcheck] +allowlist_externals = + sphinx-build +commands = + sphinx-build \ + -T \ + -b linkcheck \ + docs/ docs/_build/linkcheck +description = + Check external links in the documentation (requires internet connection) +passenv = * +setenv = + FORCE_COLOR = yes + +[testenv:pydeps] +changedir = src +commands = + pydeps repoma \ + -o module_structure.svg \ + --exclude *._* \ + --max-bacon=1 \ + --noshow +deps = + pydeps +description = + Visualize module dependencies +passenv = * + [testenv:sty] allowlist_externals = mypy