Skip to content
Snippets Groups Projects
Commit 7981a7a1 authored by Hugo Hörnquist's avatar Hugo Hörnquist
Browse files

Setup sphinx documentation.

Documentation can now be generated to HTML through sphinx.
Some docstrings have been updated to be on the correct format.
parent 28e25d56
No related branches found
No related tags found
No related merge requests found
.cache
.yardoc
doc.rendered
.PHONY: all output check test
.PHONY: all output check test sphinx-apidoc documentation
all: output
DOC_OUTPUT = doc.rendered
output:
python -m muppet --env ~/puppet/generated-environments/test/modules/
......@@ -15,5 +17,13 @@ PYTEST_FLAGS = --cov=muppet --cov-branch --cov-report=html
test:
python -m pytest $(PYTEST_FLAGS) tests
sphinx-apidoc:
sphinx-apidoc --separate --force -o doc muppet
$(DOC_OUTPUT)/index.html: sphinx-apidoc
sphinx-build -b dirhtml doc $(DOC_OUTPUT)
documentation: $(DOC_OUTPUT)/index.html
clean:
-rm -r output
......@@ -9,6 +9,24 @@ environments.
Usage
-----
### Building the example (probably broken for you)
```bash
make clean all
```
### Running the tests
```bash
make check # Run linters
make test # Run unit tests
```
Coverage information will end up in `htmlcov/`.
### Building the documentation
```bash
make documentation
```
Documentation will end up in `doc.rendered/`.
muppet*.rst
modules.rst
# Configuration file for the Sphinx documentation builder.
#
# For the full list of built-in configuration values, see the documentation:
# https://www.sphinx-doc.org/en/master/usage/configuration.html
# from __future__ import annotations
import os
import sys
sys.path.insert(0, os.path.abspath('..'))
# -- Project information -----------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information
project = 'Muppet Strings'
copyright = '2023, Hugo Hörnquist'
author = 'Hugo Hörnquist'
# -- General configuration ---------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration
# Coverage not included, since flake8 already captures that
extensions = [
'sphinx.ext.autodoc', # Automatically extract source from pypthon files
'sphinx.ext.viewcode', # Adds source viewer to output
]
# Fancy type aliases.
# For this to work, each module has to individually run
# from __future__ import annotations
# Which will prevent type aliases from being eagerly evaluated.
autodoc_type_aliases = {
'Markup': 'muppet.data.Markup',
}
# Add type signatures in parameter list of description, instead of in
# signature. This reduces the clutter quite a bit.
autodoc_typehints = 'description'
templates_path = ['_templates']
exclude_patterns = []
# -- Options for HTML output -------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output
html_theme = 'pyramid'
html_static_path = ['_static']
.. Muppet Strings documentation master file, created by
sphinx-quickstart on Sat Jun 3 20:13:35 2023.
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
Welcome to Muppet Strings's documentation!
==========================================
.. toctree::
:maxdepth: 2
:caption: Contents:
Here is some content.
Indices and tables
==================
* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`
......@@ -8,6 +8,8 @@ Almost all of the datatypes have "bad" __repr__ implementations. This
is to allow *much* easier ocular diffs when running pytest.
"""
from __future__ import annotations
from dataclasses import dataclass
from abc import ABC, abstractmethod
from collections.abc import Sequence
......@@ -24,6 +26,9 @@ Markup: TypeAlias = Union[str,
'ID',
'Documentation',
'Indentation']
"""
Documentation of Markup.
"""
@dataclass
......
......@@ -44,7 +44,7 @@ class HTMLRenderer(Renderer):
The anchor will contain both the item, rendered as normally,
and a div with class documentation.
The suggested CSS for this is
The suggested CSS for this is::
.documentation-anchor {
display: relative;
......
"""
Pretty print a complete puppet documentation.
An `output.json`, as per produced by `./merge-json.py` should be
An ``output.json``, as per produced by ``./merge-json.py`` should be
provided as the first element. This program goes through every
definition in it, and outputs a complete index.html.
"""
......@@ -101,9 +101,10 @@ def print_var(x: str, dollar: bool = True) -> Link:
Print the given variable.
If documentation exists, then add that documentation as hoover text.
:param: x
:param x:
The variable to print
:param: dollar
:param dollar:
If there should be a dollar prefix.
"""
dol = '$' if dollar else ''
......@@ -155,9 +156,9 @@ def parse(form: Any, indent: int, context: list[str]) -> Tag:
"""
Print everything from a puppet parse tree.
:param: from
:param from:
A puppet AST.
:param: indent
:param indent:
How many levels deep in indentation the code is.
Will get multiplied by the indentation width.
"""
......
"""
[Jq(1)](https://jqlang.github.io/jq/) like expressions for python.
r"""
Jq(1) <https://jqlang.github.io/jq/> like expressions for python.
Something similar to Jq, but built on python objects.
All procedures eventually return the expecetd value, or a
......@@ -8,17 +8,19 @@ user-supplied default value.
Example
-------
lookup(i) \
::
lookup(object) \
.ref('docstring') \
.ref('tags') \
.select(Ref('tag_name') == 'summary')) \
.idx(0)
.idx(0) \
.ref('text') \
.exec()
TODO
----
- `select`
- ``select``
Selects all values from a list which matches a given expression.
This would however require us to manage multiple values at once.
"""
......@@ -26,11 +28,14 @@ TODO
from typing import Any, Union
class _Expression:
class Expression:
"""
A test expression.
::
x.find(Ref("key") == "summary")
Would focus in on the first list element which has the key "key"
with a value of "summary".
......@@ -38,31 +43,39 @@ class _Expression:
"""
def run(self, value: Any) -> bool:
"""Evaluate expression, returing true if the value matches the predicate."""
return False
class _RefEqExpr(_Expression):
class RefEqExpr(Expression):
"""
Equality expression.
Assumes that the left part is a _RefExpr and the right part is a value.
Assumes that the left part is a RefExpr and the right part is a value.
Checks that the left reference exists in the given value, and that
it's value is equal to the right one.
"""
def __init__(self, left: '_RefExpr', right: Any):
def __init__(self, left: 'RefExpr', right: Any):
self.left = left
self.right = right
def run(self, value: Any) -> bool:
"""
Evaluate the expression.
Returns true if the left hand side key is present in *value*,
and if the value under that key in *value* matches the right
hand side.
"""
if self.left.key not in value:
return False
else:
return bool(value[self.left.key] == self.right)
class _RefExpr(_Expression):
class RefExpr(Expression):
"""
A key reference expression.
......@@ -74,12 +87,12 @@ class _RefExpr(_Expression):
def __init__(self, key: str):
self.key = key
def __eq__(self, other: Any) -> '_RefEqExpr': # type: ignore
def __eq__(self, other: Any) -> 'RefEqExpr': # type: ignore
"""
Return a new expression checking equality between left and right.
Left side will be ourself, while the right side can in theory
be anything (see _RefEqExpr for details).
be anything (see RefEqExpr for details).
Typing is removed here, since the base object specifies the type as
def __eq__(self, x: Any) -> bool:
......@@ -90,9 +103,10 @@ class _RefExpr(_Expression):
there is a president.
"""
return _RefEqExpr(self, other)
return RefEqExpr(self, other)
def run(self, value: Any) -> bool:
"""Return true if our key is present in *value*."""
return self.key in value
......@@ -118,7 +132,7 @@ class _NullLookup:
"""Propagate null."""
return self
def find(self, _: _Expression) -> '_NullLookup':
def find(self, _: Expression) -> '_NullLookup':
"""Propagate null."""
return self
......@@ -162,7 +176,7 @@ class _TrueLookup:
# Index out of range
return _NullLookup()
def find(self, expr: _Expression) -> Union['_TrueLookup', '_NullLookup']:
def find(self, expr: Expression) -> Union['_TrueLookup', '_NullLookup']:
"""Find the first element in list matching expression."""
for item in self.object:
if expr.run(item):
......@@ -190,11 +204,9 @@ def lookup(base: Any) -> Lookup:
All queries should start here.
Parameters
----------
base - Can be anything which has meaningful subfields.
:param base: Can be anything which has meaningful subfields.
"""
return _TrueLookup(base)
Ref = _RefExpr
Ref = RefExpr
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment