aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHugo Hörnquist <hugo@lysator.liu.se>2023-06-03 22:26:56 +0200
committerHugo Hörnquist <hugo@lysator.liu.se>2023-06-03 22:26:56 +0200
commit7981a7a13756bc34acf441ddf04f138571b7076c (patch)
tree51532048e4678f60f3bda35e400d729017a53527
parentIntroduce summaries for class list. (diff)
downloadmuppet-strings-7981a7a13756bc34acf441ddf04f138571b7076c.tar.gz
muppet-strings-7981a7a13756bc34acf441ddf04f138571b7076c.tar.xz
Setup sphinx documentation.
Documentation can now be generated to HTML through sphinx. Some docstrings have been updated to be on the correct format.
-rw-r--r--.gitignore1
-rw-r--r--Makefile12
-rw-r--r--README.md18
-rw-r--r--doc/.gitignore2
-rw-r--r--doc/conf.py50
-rw-r--r--doc/index.rst20
-rw-r--r--muppet/data/__init__.py5
-rw-r--r--muppet/data/html.py2
-rw-r--r--muppet/format.py11
-rw-r--r--muppet/lookup.py60
10 files changed, 150 insertions, 31 deletions
diff --git a/.gitignore b/.gitignore
index cb556ee..8012cbc 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,3 @@
.cache
.yardoc
+doc.rendered
diff --git a/Makefile b/Makefile
index 2cbbe58..a0426b1 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,9 @@
-.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
diff --git a/README.md b/README.md
index cd2ffdf..3ad4256 100644
--- a/README.md
+++ b/README.md
@@ -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/`.
diff --git a/doc/.gitignore b/doc/.gitignore
new file mode 100644
index 0000000..eebb7a8
--- /dev/null
+++ b/doc/.gitignore
@@ -0,0 +1,2 @@
+muppet*.rst
+modules.rst
diff --git a/doc/conf.py b/doc/conf.py
new file mode 100644
index 0000000..895caba
--- /dev/null
+++ b/doc/conf.py
@@ -0,0 +1,50 @@
+# 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']
diff --git a/doc/index.rst b/doc/index.rst
new file mode 100644
index 0000000..17dc708
--- /dev/null
+++ b/doc/index.rst
@@ -0,0 +1,20 @@
+.. 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`
diff --git a/muppet/data/__init__.py b/muppet/data/__init__.py
index 92dcbc2..9e685be 100644
--- a/muppet/data/__init__.py
+++ b/muppet/data/__init__.py
@@ -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
diff --git a/muppet/data/html.py b/muppet/data/html.py
index 1b155fe..67edef9 100644
--- a/muppet/data/html.py
+++ b/muppet/data/html.py
@@ -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;
diff --git a/muppet/format.py b/muppet/format.py
index e8f855e..43eaa7d 100644
--- a/muppet/format.py
+++ b/muppet/format.py
@@ -1,7 +1,7 @@
"""
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.
"""
diff --git a/muppet/lookup.py b/muppet/lookup.py
index 0abb644..d51b1af 100644
--- a/muppet/lookup.py
+++ b/muppet/lookup.py
@@ -1,5 +1,5 @@
-"""
-[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) \
- .ref('docstring') \
- .ref('tags') \
- .select(Ref('tag_name') == 'summary')) \
- .idx(0)
- .ref('text') \
- .exec()
+::
+
+ lookup(object) \
+ .ref('docstring') \
+ .ref('tags') \
+ .select(Ref('tag_name') == 'summary')) \
+ .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