Skip to content

Commit

Permalink
feat: add basic sphinx docs (#1711)
Browse files Browse the repository at this point in the history
Adds a Sphinx documentation project and some basic documentation. The
purpose is to allow automatic generation of certain reference
documentation that would otherwise need to be manually generated for
juju.is.

This includes using the Starcraft standard `starbase` sphinx docs, A
command documentation generator from rockcraft, and additions to some
pydantic models to copy documentation out of what's on juju.is.

Fixes #1692
  • Loading branch information
lengau authored Jul 2, 2024
1 parent e216376 commit b48ef73
Show file tree
Hide file tree
Showing 25 changed files with 1,080 additions and 63 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@ instance/

# Sphinx documentation
docs/_build/
# Auto-generated command reference
/docs/reference/commands/
/docs/reference/_autosummary/

# PyBuilder
target/
Expand Down
29 changes: 29 additions & 0 deletions .readthedocs.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# .readthedocs.yaml
# Read the Docs configuration file
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
---
# Required
version: 2

build:
os: ubuntu-24.04
tools:
python: "3.10"
jobs:
post_checkout:
- git fetch --tags --depth 1 # Also fetch tags
- git describe --always # Useful for debugging

# Build documentation in the docs/ directory with Sphinx
sphinx:
configuration: docs/conf.py
builder: dirhtml
fail_on_warning: false

# Optionally set the version of Python
# and requirements required to build your docs
python:
install:
- requirements: requirements-dev.txt
- method: pip
path: .[docs]
23 changes: 12 additions & 11 deletions charmcraft/application/commands/store.py
Original file line number Diff line number Diff line change
Expand Up @@ -1066,7 +1066,7 @@ class StatusCommand(CharmcraftCommand):
into a channel. This command shows the various channels for a charm
and whether there is a charm released.
For example:
For example::
$ charmcraft status
Track Base Channel Version Revision
Expand Down Expand Up @@ -1651,16 +1651,17 @@ class FetchLibs(CharmcraftCommand):
For each library in the top-level `charm-libs` key, fetch the latest library
version matching those requirements.
For example:
charm-libs:
# Fetch lib with API version 0.
# If `fetch-libs` is run and a newer minor version is available,
# it will be fetched from the store.
- lib: postgresql.postgres_client
version: "0"
# Always fetch precisely version 0.57.
- lib: mysql.client
version: "0.57"
For example::
charm-libs:
# Fetch lib with API version 0.
# If `fetch-libs` is run and a newer minor version is available,
# it will be fetched from the store.
- lib: postgresql.postgres_client
version: "0"
# Always fetch precisely version 0.57.
- lib: mysql.client
version: "0.57"
"""
)
format_option = True
Expand Down
20 changes: 10 additions & 10 deletions charmcraft/format.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,19 +72,19 @@ def printable_field_location_split(location: str) -> tuple[str, str]:
def format_pydantic_errors(errors, *, file_name: str = const.CHARMCRAFT_FILENAME) -> str:
"""Format errors.
Example 1: Single error.
Example 1: Single error::
Bad charmcraft.yaml content:
- field: <some field>
reason: <some reason>
Bad charmcraft.yaml content:
- field: <some field>
reason: <some reason>
Example 2: Multiple errors.
Example 2: Multiple errors::
Bad charmcraft.yaml content:
- field: <some field>
reason: <some reason>
- field: <some field 2>
reason: <some reason 2>
Bad charmcraft.yaml content:
- field: <some field>
reason: <some reason>
- field: <some field 2>
reason: <some reason 2>
"""
combined = [f"Bad {file_name} content:"]
for error in errors:
Expand Down
6 changes: 3 additions & 3 deletions charmcraft/instrum.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,12 +104,12 @@ class Timer:
It can work as a context manager that generates a measurement of the block of code inside
its context, or as a decorator to get the timing of the whole decorated function.
Usage as a context manager:
Usage as a context manager::
with timer("some message", more="stuff", answer=42):
...
Usage as a decorator:
Usage as a decorator::
@timer("some message", foo="bar")
def foo(...):
Expand All @@ -118,7 +118,7 @@ def foo(...):
In both cases the message is mandatory and the extra info optional.
Also this class provides a `mark` method to sub-divide the context manager code
block. How to use it:
block. How to use it::
with timer("some message") as cm:
...
Expand Down
10 changes: 3 additions & 7 deletions charmcraft/jujuignore.py
Original file line number Diff line number Diff line change
Expand Up @@ -195,15 +195,11 @@ def _compile_from(self, patterns: typing.Iterable[str]):
def match(self, path: str, is_dir: bool) -> bool:
"""Check if the given path should be ignored.
Args:
----
path: A local path (eg /foo/bar or foo/bar) from the root directory of the project.
is_dir: Indicate whether the given path is a directory (because of special handling
:param path: A local path (eg /foo/bar or foo/bar) from the root directory of the project.
:param is_dir: Indicate whether the given path is a directory (because of special handling
from ignore files when the path ends with a '/')
Return:
------
A boolean indicating whether the ignore rules matched the given path (thus the path
:returns: A boolean indicating whether the ignore rules matched the given path (thus the path
should be ignored).
"""
Expand Down
5 changes: 3 additions & 2 deletions charmcraft/metafiles/actions.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,11 @@

import pydantic
import yaml
from craft_application import util
from craft_cli import CraftError, emit

from charmcraft import const
from charmcraft.format import format_pydantic_errors
from charmcraft.metafiles import read_yaml
from charmcraft.models.actions import JujuActions

if TYPE_CHECKING:
Expand Down Expand Up @@ -60,7 +60,8 @@ def parse_actions_yaml(charm_dir, allow_broken=False):
:raises: CraftError if actions.yaml is not valid.
"""
try:
actions = read_yaml(charm_dir / const.JUJU_ACTIONS_FILENAME)
with (charm_dir / const.JUJU_ACTIONS_FILENAME).open() as file:
actions = util.safe_yaml_load(file)
except FileNotFoundError:
return None
except OSError as exc:
Expand Down
3 changes: 2 additions & 1 deletion charmcraft/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

"""Charmcraft pydantic models."""

from . import config, metadata
from . import actions, config, metadata
from .charmcraft import Base
from .lint import CheckResult, CheckType, LintResult, ResultLevel
from .manifest import Attribute, Manifest
Expand All @@ -33,6 +33,7 @@
)

__all__ = [
"actions",
"config",
"metadata",
"Base",
Expand Down
23 changes: 22 additions & 1 deletion charmcraft/models/charmcraft.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,23 @@ class BasesConfiguration(
alias_generator=lambda s: s.replace("_", "-"),
frozen=True,
):
"""Definition of build-on/run-on combinations."""
"""Definition of build-on/run-on combinations.
Example::
bases:
- build-on:
- name: ubuntu
channel: "20.04"
architectures: [amd64, arm64]
run-on:
- name: ubuntu
channel: "20.04"
architectures: [amd64, arm64]
- name: ubuntu
channel: "22.04"
architectures: [amd64, arm64]
"""

build_on: list[Base]
run_on: list[Base]
Expand Down Expand Up @@ -110,10 +126,15 @@ class Links(ModelConfigDefaults, frozen=True):
"""Definition of `links` in metadata."""

contact: pydantic.StrictStr | list[pydantic.StrictStr] | None
"""Instructions for contacting the owner of the charm."""
documentation: pydantic.AnyHttpUrl | None
"""The URL of the documentation for this charm."""
issues: pydantic.AnyHttpUrl | list[pydantic.AnyHttpUrl] | None
"""A link to the issue tracker for this charm."""
source: pydantic.AnyHttpUrl | list[pydantic.AnyHttpUrl] | None
"""Where to find this charm's source code."""
website: pydantic.AnyHttpUrl | list[pydantic.AnyHttpUrl] | None
"""The website for this charm."""


class CharmcraftConfig(
Expand Down
Loading

0 comments on commit b48ef73

Please sign in to comment.