diff --git a/.github/workflows/automatic-doc-checks.yml b/.github/workflows/automatic-doc-checks.yml new file mode 100644 index 0000000..11576b9 --- /dev/null +++ b/.github/workflows/automatic-doc-checks.yml @@ -0,0 +1,49 @@ +name: Main Documentation Checks + +on: + - push + - pull_request + - workflow_dispatch + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + docchecks: + name: Run documentation checks + runs-on: ubuntu-latest + outputs: + result_spelling: ${{ steps.spellcheck-step.outcome }} + result_woke: ${{ steps.woke-step.outcome }} + result_links: ${{ steps.linkcheck-step.outcome }} + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + submodules: recursive + + - name: Remove upstream unused files + run: | + rm -f docs/sphinx-docs-starter-pack/doc-cheat-sheet* + + - name: Spell Check + id: spellcheck-step + if: success() || failure() + uses: canonical/documentation-workflows/spellcheck@main + with: + working-directory: "docs" + + - name: Inclusive Language Check + id: woke-step + if: success() || failure() + uses: canonical/documentation-workflows/inclusive-language@main + with: + working-directory: "docs" + + - name: Link Check + id: linkcheck-step + if: success() || failure() + uses: canonical/documentation-workflows/linkcheck@main + with: + working-directory: "docs" diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml index cdbc402..007dda4 100644 --- a/.github/workflows/docs.yaml +++ b/.github/workflows/docs.yaml @@ -20,6 +20,7 @@ jobs: uses: actions/checkout@v4 with: fetch-depth: 0 + submodules: recursive - name: Setup Python uses: actions/setup-python@v4 with: diff --git a/.gitignore b/.gitignore index 4cb5044..addb87e 100644 --- a/.gitignore +++ b/.gitignore @@ -70,6 +70,11 @@ instance/ # Sphinx documentation docs/_build/ +docs/.sphinx/venv/ +docs/.sphinx/warnings.txt +docs/.sphinx/.wordlist.dic +docs/.sphinx/.doctrees/ +docs/sphinx-docs-starter-pack/* # PyBuilder target/ diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..8f787a4 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "docs/sphinx-docs-starter-pack"] + path = docs/sphinx-docs-starter-pack + url = https://github.com/canonical/sphinx-docs-starter-pack.git diff --git a/.readthedocs.yml b/.readthedocs.yml index fb58117..e17cb0d 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -5,23 +5,29 @@ # Required version: 2 +submodules: + include: + - docs/sphinx-docs-starter-pack + +# Set the version of Python and other tools you might need +build: + os: ubuntu-22.04 + tools: + python: "3.11" + # Build documentation in the docs/ directory with Sphinx sphinx: + builder: dirhtml configuration: docs/conf.py + fail_on_warning: true -# Optionally build your docs in additional formats such as PDF +# If using Sphinx, optionally build your docs in additional formats such as PDF formats: - pdf - - epub - -build: - os: ubuntu-22.04 - tools: - python: "3" +# Optionally declare the Python requirements required to build your docs python: install: + - requirements: docs/.sphinx/requirements.txt - method: pip path: . - extra_requirements: - - docs diff --git a/docs/.custom_wordlist.txt b/docs/.custom_wordlist.txt new file mode 100644 index 0000000..2ca7f84 --- /dev/null +++ b/docs/.custom_wordlist.txt @@ -0,0 +1,17 @@ +Changelog +cli +datetime +http +https +io +initialization +initialized +NotLoggedIn +keyring +StoreClient +snapcraft +SSO +ubuntu +unregistering +url +whoami \ No newline at end of file diff --git a/docs/.sphinx/requirements.txt b/docs/.sphinx/requirements.txt new file mode 100644 index 0000000..bf1c358 --- /dev/null +++ b/docs/.sphinx/requirements.txt @@ -0,0 +1,14 @@ +furo==2023.9.10 +lxd-sphinx-extensions==0.0.14 +myst-parser==2.0.0 +pyspelling==2.9 +sphinx==7.2.6 +sphinx-autobuild==2021.3.14 +sphinxcontrib-jquery==4.1 +sphinx-copybutton==0.5.2 +sphinx-design==0.5.0 +sphinxext-opengraph==0.8.2 +sphinx-lint==0.6.8 +sphinx-notfound-page==1.0.0 +sphinx-reredirects==0.1.2 +sphinx-tabs==3.4.1 \ No newline at end of file diff --git a/docs/.wordlist.txt b/docs/.wordlist.txt new file mode 120000 index 0000000..f20c7c8 --- /dev/null +++ b/docs/.wordlist.txt @@ -0,0 +1 @@ +sphinx-docs-starter-pack/.wordlist.txt \ No newline at end of file diff --git a/docs/Makefile b/docs/Makefile new file mode 100644 index 0000000..74b5b4e --- /dev/null +++ b/docs/Makefile @@ -0,0 +1,130 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line, and also +# from the environment for the first two. +SPHINXOPTS ?= -c . -d .sphinx/.doctrees +SPHINXBUILD ?= sphinx-build +SPHINXDIR = .sphinx +SOURCEDIR = . +BUILDDIR = _build +VENVDIR = $(SPHINXDIR)/venv +VENV = $(VENVDIR)/bin/activate + + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help + +# Explicit target avoids fall-through to the "Makefile" target. +$(SPHINXDIR)/requirements.txt: + test -f $(SPHINXDIR)/requirements.txt + +# If requirements are updated, venv should be rebuilt and timestamped. +$(VENVDIR): $(SPHINXDIR)/requirements.txt + @echo "... setting up virtualenv" + python3 -m venv $(VENVDIR) + . $(VENV); pip install --require-virtualenv \ + --upgrade -r $(SPHINXDIR)/requirements.txt \ + --log $(VENVDIR)/pip_install.log + @test ! -f $(VENVDIR)/pip_list.txt || \ + mv $(VENVDIR)/pip_list.txt $(VENVDIR)/pip_list.txt.bak + @. $(VENV); pip list --local --format=freeze > $(VENVDIR)/pip_list.txt + @echo "\n" \ + "--------------------------------------------------------------- \n" \ + "* watch, build and serve the documentation: make run \n" \ + "* only build: make html \n" \ + "* only serve: make serve \n" \ + "* clean built doc files: make clean-doc \n" \ + "* clean full environment: make clean \n" \ + "* check spelling: make spelling \n" \ + "* check inclusive language: make woke \n" \ + "* other possible targets: make \n" \ + "--------------------------------------------------------------- \n" + @touch $(VENVDIR) + + +woke-install: + @type woke >/dev/null 2>&1 || \ + { echo "Installing \"woke\" snap... \n"; sudo snap install woke; } + +.PHONY: woke-install + + +install: $(VENVDIR) woke-install + +.PHONY: install + + +run: install + . $(VENV); sphinx-autobuild -b dirhtml "$(SOURCEDIR)" "$(BUILDDIR)" \ + $(SPHINXOPTS) + +.PHONY: run + +# Doesn't depend on $(BUILDDIR) to rebuild properly at every run. +html: install + . $(VENV); $(SPHINXBUILD) -b dirhtml "$(SOURCEDIR)" "$(BUILDDIR)" \ + -w .sphinx/warnings.txt $(SPHINXOPTS) + +.PHONY: html + + +epub: install + . $(VENV); $(SPHINXBUILD) -b epub "$(SOURCEDIR)" "$(BUILDDIR)" \ + -w .sphinx/warnings.txt $(SPHINXOPTS) + +.PHONY: epub + + +serve: html + cd "$(BUILDDIR)"; python3 -m http.server 8000 + +.PHONY: serve + + +clean: clean-doc + @test ! -e "$(VENVDIR)" -o \ + -d "$(VENVDIR)" -a "$(abspath $(VENVDIR))" != "$(VENVDIR)" + rm -rf $(VENVDIR) + rm -rf .sphinx/.doctrees + +.PHONY: clean + + +clean-doc: + git clean -fx "$(BUILDDIR)" + +.PHONY: clean-doc + + +spelling: html + . $(VENV) ; python3 -m pyspelling -c sphinx-docs-starter-pack/.sphinx/spellingcheck.yaml + +.PHONY: spelling + + +linkcheck: install + . $(VENV) ; $(SPHINXBUILD) -b linkcheck "$(SOURCEDIR)" "$(BUILDDIR)" \ + $(SPHINXOPTS) + +.PHONY: linkcheck + + +woke: woke-install + woke *.rst **/*.rst \ + --exit-1-on-failure \ + -c https://github.com/canonical/Inclusive-naming/raw/main/config.yml + +.PHONY: woke + + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + . $(VENV); \ + $(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: Makefile \ No newline at end of file diff --git a/docs/conf.py b/docs/conf.py index f35f5b6..3a869c2 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -1,62 +1,127 @@ +import sys + +sys.path.append("./") +from custom_conf import * + # Configuration file for the Sphinx documentation builder. +# You should not do any modifications to this file. Put your custom +# configuration into the custom_conf.py file. +# If you need to change this file, contribute the changes upstream. # # For the full list of built-in configuration values, see the documentation: # https://www.sphinx-doc.org/en/master/usage/configuration.html -# -- Project information ----------------------------------------------------- -# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information - -project = "craft-store" -copyright = "2023, Canonical" -author = "Canonical" - -# region General configuration -# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration +############################################################ +### Extensions +############################################################ extensions = [ - "sphinx.ext.intersphinx", - "sphinx.ext.viewcode", - "sphinx.ext.coverage", - "sphinx.ext.doctest", "sphinx_design", + "sphinx_tabs.tabs", + "sphinx_reredirects", + "youtube-links", + "related-links", + "custom-rst-roles", + "terminal-output", "sphinx_copybutton", - "sphinx-pydantic", - "sphinx_toolbox", - "sphinx_toolbox.more_autodoc", - "sphinx.ext.autodoc", # Must be loaded after more_autodoc + "sphinxext.opengraph", + "myst_parser", + "sphinxcontrib.jquery", + "notfound.extension", ] +extensions.extend(custom_extensions) -templates_path = ["_templates"] -exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"] +### Configuration for extensions -show_authors = False +# Additional MyST syntax +myst_enable_extensions = ["substitution", "deflist"] -# endregion -# region Options for HTML output -# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output +# Used for related links +if "discourse" in html_context: + html_context["discourse_prefix"] = html_context["discourse"] + "/t/" -html_theme = "furo" -html_static_path = ["_static"] -html_css_files = [ - "css/custom.css", +# The default for notfound_urls_prefix usually works, but not for +# documentation on documentation.ubuntu.com +if slug: + notfound_urls_prefix = "/" + slug + "/en/latest/" + +notfound_context = { + "title": "Page not found", + "body": "

Page not found

\n\n

Sorry, but the documentation page that you are looking for was not found.

\n

Documentation changes over time, and pages are moved around. We try to redirect you to the updated content where possible, but unfortunately, that didn't work this time (maybe because the content you were looking for does not exist in this version of the documentation).

\n

You can try to use the navigation to locate the content you're looking for, or search for a similar page.

\n", +} + +# Default image for OGP (to prevent font errors, see +# https://github.com/canonical/sphinx-docs-starter-pack/pull/54 ) +if not "ogp_image" in locals(): + ogp_image = "https://assets.ubuntu.com/v1/253da317-image-document-ubuntudocs.svg" + +############################################################ +### General configuration +############################################################ + +exclude_patterns = [ + "_build", + "Thumbs.db", + ".DS_Store", + ".sphinx", ] +exclude_patterns.extend(custom_excludes) -# endregion -# region Options for extensions -# Intersphinx extension -# https://www.sphinx-doc.org/en/master/usage/extensions/intersphinx.html#configuration +rst_epilog = """ +.. include:: /reuse/links.txt +""" +if "custom_rst_epilog" in locals(): + rst_epilog = custom_rst_epilog # type: ignore[name-defined] -intersphinx_mapping = { - "python": ("https://docs.python.org/3", None), +source_suffix = { + ".rst": "restructuredtext", + ".md": "markdown", } -# Type hints configuration -set_type_checking_flag = True -typehints_fully_qualified = False -always_document_param_types = True +if not "conf_py_path" in html_context and "github_folder" in html_context: + html_context["conf_py_path"] = html_context["github_folder"] -# Github config -github_username = "canonical" -github_repository = "craft-store" +# For ignoring specific links +linkcheck_anchors_ignore_for_url = [r"https://github\.com/.*"] +linkcheck_anchors_ignore_for_url.extend(custom_linkcheck_anchors_ignore_for_url) + +############################################################ +### Styling +############################################################ + +# Find the current builder +builder = "dirhtml" +if "-b" in sys.argv: + builder = sys.argv[sys.argv.index("-b") + 1] + +# Setting templates_path for epub makes the build fail +if builder == "dirhtml" or builder == "html": + templates_path = ["sphinx-docs-starter-pack/.sphinx/_templates"] + +# Theme configuration +html_theme = "furo" +html_last_updated_fmt = "" +html_permalinks_icon = "¶" + +############################################################ +### Additional files +############################################################ + +html_static_path = ["sphinx-docs-starter-pack/.sphinx/_static"] + +html_css_files = [ + "custom.css", + "header.css", + "github_issue_links.css", + "furo_colors.css", +] +html_css_files.extend(custom_html_css_files) -# endregion +html_js_files = ["header-nav.js"] +if ( + "github_issues" in html_context + and html_context["github_issues"] + and not disable_feedback_button +): + html_js_files.append("github_issue_links.js") +html_js_files.extend(custom_html_js_files) diff --git a/docs/custom_conf.py b/docs/custom_conf.py new file mode 100644 index 0000000..1f815c3 --- /dev/null +++ b/docs/custom_conf.py @@ -0,0 +1,143 @@ +import datetime +from typing import Dict, List + +# Custom configuration for the Sphinx documentation builder. +# All configuration specific to your project should be done in this file. +# +# The file is included in the common conf.py configuration file. +# You can modify any of the settings below or add any configuration that +# is not covered by the common conf.py file. +# +# For the full list of built-in configuration values, see the documentation: +# https://www.sphinx-doc.org/en/master/usage/configuration.html + +############################################################ +### Project information +############################################################ + +# Product name +project = "Craft Store" +author = "Canonical Group Ltd" + +# Uncomment if your product uses release numbers +# release = '1.0' + +# The default value uses the current year as the copyright year. +# +# For static works, it is common to provide the year of first publication. +# Another option is to give the first year and the current year +# for documentation that is often changed, e.g. 2022–2023 (note the en-dash). +# +# A way to check a GitHub repo's creation date is to obtain a classic GitHub +# token with 'repo' permissions here: https://github.com/settings/tokens +# Next, use 'curl' and 'jq' to extract the date from the GitHub API's output: +# +# curl -H 'Authorization: token ' \ +# -H 'Accept: application/vnd.github.v3.raw' \ +# https://api.github.com/repos/canonical/ | jq '.created_at' + +copyright = "2021-%s, %s" % (datetime.date.today().year, author) + +## Open Graph configuration - defines what is displayed in the website preview +# The URL of the documentation output +ogp_site_url = "https://canonical-craft-store.readthedocs-hosted.com/" +# The documentation website name (usually the same as the product name) +ogp_site_name = project +# An image or logo that is used in the preview +ogp_image = "https://assets.ubuntu.com/v1/253da317-image-document-ubuntudocs.svg" + +# Update with the favicon for your product (default is the circle of friends) +html_favicon = "sphinx-docs-starter-pack/.sphinx/_static/favicon.png" + +# (Some settings must be part of the html_context dictionary, while others +# are on root level. Don't move the settings.) +html_context = { + # Change to the link to your product website (without "https://") + "product_page": "github.com/canonical/craft-store", + # Add your product tag to ".sphinx/_static" and change the path + # here (start with "_static"), default is the circle of friends + "product_tag": "_static/tag.png", + # Change to the discourse instance you want to be able to link to + # using the :discourse: metadata at the top of a file + # (use an empty value if you don't want to link) + "discourse": "", + # Change to the GitHub info for your project + "github_url": "https://github.com/canonical/craft-store", + # Change to the branch for this version of the documentation + "github_version": "main", + # Change to the folder that contains the documentation + # (usually "/" or "/docs/") + "github_folder": "/docs/", + # Change to an empty value if your GitHub repo doesn't have issues enabled. + # This will disable the feedback button and the issue link in the footer. + "github_issues": "enabled", + # Controls the existence of Previous / Next buttons at the bottom of pages + # Valid options: none, prev, next, both + "sequential_nav": "none", +} + +# If your project is on documentation.ubuntu.com, specify the project +# slug (for example, "lxd") here. +slug = "" + +############################################################ +### Redirects +############################################################ + +# Set up redirects (https://documatt.gitlab.io/sphinx-reredirects/usage.html) +# For example: 'explanation/old-name.html': '../how-to/prettify.html', + +redirects: Dict[str, str] = {} + +############################################################ +### Link checker exceptions +############################################################ + +# Links to ignore when checking links + +linkcheck_ignore: List[str] = ["http://127.0.0.1:8000"] + +# Pages on which to ignore anchors +# (This list will be appended to linkcheck_anchors_ignore_for_url) + +custom_linkcheck_anchors_ignore_for_url: List[str] = [] + +############################################################ +### Additions to default configuration +############################################################ + +## The following settings are appended to the default configuration. +## Use them to extend the default functionality. + +# Add extensions +custom_extensions: List[str] = [ + "sphinx.ext.autodoc", +] + +# Add files or directories that should be excluded from processing. +custom_excludes: List[str] = [ + "sphinx-docs-starter-pack/*", +] + +# Add CSS files (located in .sphinx/_static/) +custom_html_css_files: List[str] = [] + +# Add JavaScript files (located in .sphinx/_static/) +custom_html_js_files: List[str] = [] + +## The following settings override the default configuration. + +# Specify a reST string that is included at the end of each file. +# If commented out, use the default (which pulls the reuse/links.txt +# file into each reST file). +# custom_rst_epilog = '' + +# By default, the documentation includes a feedback button at the top. +# You can disable it by setting the following configuration to True. +disable_feedback_button = False + +############################################################ +### Additional configuration +############################################################ + +## Add any configuration that is not covered by the common conf.py file. diff --git a/docs/reuse/links.txt b/docs/reuse/links.txt new file mode 100644 index 0000000..e69de29 diff --git a/docs/sphinx-docs-starter-pack b/docs/sphinx-docs-starter-pack new file mode 160000 index 0000000..1dfe29a --- /dev/null +++ b/docs/sphinx-docs-starter-pack @@ -0,0 +1 @@ +Subproject commit 1dfe29a1451de094931f722b1c39d23a6c7ce05e diff --git a/pyproject.toml b/pyproject.toml index ddf8e21..036be9e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -37,7 +37,7 @@ dev = [ ] lint = [ "black==23.3.0", - "pylint>=2.17.0", + "pylint>=2.17.0,<3.0.0", "pylint_fixme_info>=1.0.0", "pylint_pytest>=1.1.0", "codespell[toml]==2.2.5", @@ -49,16 +49,20 @@ types = [ "pyright==1.1.316", ] docs = [ - "furo==2023.5.20", - "sphinx>=6.2.1,<7.0", + "furo==2023.9.10", + "lxd-sphinx-extensions==0.0.14", + "myst-parser==2.0.0", + "pyspelling==2.9", + "sphinx==7.2.6", "sphinx-autobuild==2021.3.14", - "sphinx-autodoc-typehints", + "sphinxcontrib-jquery==4.1", "sphinx-copybutton==0.5.2", - "sphinx-design==0.4.1", - "sphinx-pydantic==0.1.1", - "sphinx-toolbox==3.4.0", - "sphinx-lint==0.6.7", - "sphinx-rtd-theme", + "sphinx-design==0.5.0", + "sphinxext-opengraph==0.8.2", + "sphinx-lint==0.6.8", + "sphinx-notfound-page==1.0.0", + "sphinx-reredirects==0.1.2", + "sphinx-tabs==3.4.1", "sphinx-rtd-theme", ] [build-system] @@ -153,6 +157,7 @@ exclude = [ "build", "tests", "results", + "docs/sphinx-docs-starter-pack", ] warn_unused_configs = true warn_redundant_casts = true @@ -179,6 +184,7 @@ src = ["craft_store", "tests"] extend-exclude = [ "docs", "__pycache__", + "docs/sphinx-docs-starter-pack", ] # Follow ST063 - Maintaining and updating linting specifications for updating these. select = [ # Base linting rule selections. diff --git a/tox.ini b/tox.ini index 3f8a667..88afa22 100644 --- a/tox.ini +++ b/tox.ini @@ -143,7 +143,5 @@ find = git ls-files [testenv:lint-docs] description = Lint the documentation with sphinx-lint base = docs -labels = lint -allowlist_externals = bash, xargs -commands_pre = bash -c '{[lint-docs]find} > {env_tmp_dir}/lint_docs_files' -commands = xargs --no-run-if-empty --arg-file {env_tmp_dir}/lint_docs_files sphinx-lint --max-line-length 80 --enable all {posargs} +commands = sphinx-lint --ignore docs/_build --ignore .tox --ignore .venv --ignore venv --ignore docs/sphinx-docs-starter-pack --max-line-length 80 -e all {posargs} +labels = lint \ No newline at end of file