Browse Source

Add attr-overview directive

This directive creates a bullet-point list of all the attributes
defined within a file.  The idea is to give a quick overview reference
for config file options.

There are two options to start with -- maxdepth is similar to the TOC
option and only shows certain levels of options; prefix allows to
filter down to a smaller set of options if required.

I've reworked the documentation examples as part of testing this.  The
various components are moved into separate files.  On the main page,
moved the config options into the main documentation (and use the zuul
attributes :) and pointed out that you can view the source of each
sample page to see how to generate what you see.

Change-Id: I6b0f414f50428c6e04b3aeb2a2c1f9196de80ce6
Ian Wienand 7 months ago
parent
commit
5bc7086580

+ 2
- 14
README.rst View File

@@ -1,18 +1,6 @@
1 1
 Zuul Sphinx
2 2
 ===========
3 3
 
4
-A Sphinx extension for documenting Zuul jobs.
4
+A `Sphinx <https://www.sphinx-doc.org>`__ extension for documenting
5
+`Zuul <https://zuul-ci.org>`__ jobs and configuration.
5 6
 
6
-Config options
7
---------------
8
-
9
-``zuul_role_paths``
10
-  (str list)
11
-  List of extra paths to examine for role documentation (other than
12
-  ``roles/``)
13
-
14
-``zuul_autoroles_warn_missing``
15
-  (boolean)
16
-  Default: True
17
-  Warn when a role found with ``autoroles`` does not have a
18
-  ``README.rst`` file.

+ 61
- 0
doc/source/example-attributes.rst View File

@@ -0,0 +1,61 @@
1
+Configuration Attributes
2
+------------------------
3
+
4
+.. attr:: example-attr
5
+   :required:
6
+
7
+   This is an example configuration attribute.
8
+
9
+   .. attr:: foo
10
+      :default: bar
11
+      :example: sample_value_for_example_attr
12
+      :type: str
13
+
14
+      A sub attribute.
15
+
16
+      .. value:: bar
17
+
18
+         An attribute value.
19
+
20
+      .. value:: baz
21
+
22
+         Another attribute value.
23
+
24
+      .. attr:: moo
25
+
26
+         An even further nested attribute
27
+
28
+         .. attr:: boo
29
+
30
+            And one more for good luck
31
+
32
+.. attr:: another-example-attr
33
+
34
+   And back to the top level
35
+
36
+References
37
+==========
38
+
39
+This is an attribute role: :attr:`example-attr.foo`
40
+
41
+This is an attribute value role: :value:`example-attr.foo.bar`
42
+
43
+Summaries
44
+=========
45
+
46
+All attributes
47
+^^^^^^^^^^^^^^
48
+
49
+.. attr-overview::
50
+
51
+Only one level
52
+^^^^^^^^^^^^^^
53
+
54
+.. attr-overview::
55
+   :maxdepth: 1
56
+
57
+Only example-attr.foo prefix
58
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
59
+
60
+.. attr-overview::
61
+   :prefix: example-attr.foo

+ 1
- 4
doc/source/example-jobs.rst View File

@@ -1,8 +1,5 @@
1
-Example Jobs
2
-============
3
-
4 1
 Jobs
5
-----
2
+====
6 3
 
7 4
 .. job:: example
8 5
 

+ 1
- 4
doc/source/example-roles.rst View File

@@ -1,8 +1,5 @@
1
-Example Roles
2
-=============
3
-
4 1
 Roles
5
------
2
+=====
6 3
 
7 4
 .. role:: example
8 5
 

+ 13
- 0
doc/source/example-statistics.rst View File

@@ -0,0 +1,13 @@
1
+Statistics
2
+----------
3
+
4
+.. stat:: example-stat
5
+
6
+   This is an example statistic.
7
+
8
+   .. stat:: foo
9
+      :type: counter
10
+
11
+      A sub stat.
12
+
13
+This is a statistics role: :stat:`example-stat.foo`

+ 1
- 4
doc/source/example-templates.rst View File

@@ -1,8 +1,5 @@
1
-Example Project Templates
2
-=========================
3
-
4 1
 Project Templates
5
------------------
2
+=================
6 3
 
7 4
 .. project_template:: example
8 5
 

+ 25
- 0
doc/source/example-variables.rst View File

@@ -0,0 +1,25 @@
1
+Variables
2
+---------
3
+
4
+.. var:: example-variable
5
+
6
+   This is an example variable.
7
+
8
+   .. var:: foo
9
+
10
+      This is a variable.
11
+
12
+      .. var:: bar
13
+
14
+         This is a sub key.
15
+
16
+   .. var:: items
17
+      :type: list
18
+
19
+      This variable is a list.
20
+
21
+      .. var:: baz
22
+
23
+         This is an item in a list.
24
+
25
+This is a variable role: :var:`example-variable.items.baz`

+ 0
- 71
doc/source/examples.rst View File

@@ -1,71 +0,0 @@
1
-Examples
2
-========
3
-
4
-Configuration Attributes
5
-------------------------
6
-
7
-.. attr:: example-attr
8
-   :required:
9
-
10
-   This is an example configuration attribute.
11
-
12
-   .. attr:: foo
13
-      :default: bar
14
-      :example: sample_value_for_example_attr
15
-      :type: str
16
-
17
-      A sub attribute.
18
-
19
-      .. value:: bar
20
-
21
-         An attribute value.
22
-
23
-      .. value:: baz
24
-
25
-         Another attribute value.
26
-
27
-This is an attribute role: :attr:`example-attr.foo`
28
-
29
-This is an attribute value role: :value:`example-attr.foo.bar`
30
-
31
-
32
-Job Variables
33
--------------
34
-
35
-.. var:: example-variable
36
-
37
-   This is an example variable.
38
-
39
-   .. var:: foo
40
-
41
-      This is a variable.
42
-
43
-      .. var:: bar
44
-
45
-         This is a sub key.
46
-
47
-   .. var:: items
48
-      :type: list
49
-
50
-      This variable is a list.
51
-
52
-      .. var:: baz
53
-
54
-         This is an item in a list.
55
-
56
-This is a variable role: :var:`example-variable.items.baz`
57
-
58
-
59
-Statistics
60
-----------
61
-
62
-.. stat:: example-stat
63
-
64
-   This is an example statistic.
65
-
66
-   .. stat:: foo
67
-      :type: counter
68
-
69
-      A sub stat.
70
-
71
-This is a statistics role: :stat:`example-stat.foo`

+ 38
- 2
doc/source/index.rst View File

@@ -1,16 +1,52 @@
1 1
 .. include:: ../../README.rst
2 2
 
3
+Overview
4
+--------
5
+
6
+This documentation has full examples of how to use the zuul-sphinx
7
+features.
8
+
9
+Config options
10
+--------------
11
+
12
+The following options can be set
13
+
14
+.. attr:: zuul_role_paths
15
+   :type: str list
16
+
17
+   List of extra paths to examine for role documentation (other than
18
+   ``roles/``)
19
+
20
+.. attr:: zuul_roles_warn_missing
21
+   :type: bool
22
+   :default: True
23
+
24
+    Warn when a role found with ``autoroles`` does not have a
25
+    ``README.rst`` file.
26
+
27
+
28
+Examples
29
+--------
30
+
31
+.. note::
32
+
33
+   To see the commands that produces the rendered output for this page
34
+   or any of the examples below, use the ``Show Source`` link at the
35
+   bottom of the page.
36
+
3 37
 .. toctree::
4 38
    :maxdepth: 2
5 39
 
6
-   examples
40
+   example-variables
41
+   example-attributes
7 42
    example-jobs
8 43
    example-templates
9 44
    example-roles
10 45
    example-autodoc
46
+   example-statistics
11 47
 
12 48
 Indices and tables
13
-==================
49
+------------------
14 50
 
15 51
 * :ref:`genindex`
16 52
 * :ref:`search`

+ 99
- 0
zuul_sphinx/zuul.py View File

@@ -17,7 +17,9 @@ import codecs
17 17
 import os
18 18
 
19 19
 from sphinx import addnodes
20
+from docutils import nodes
20 21
 from docutils.parsers.rst import Directive
22
+from docutils.parsers.rst import directives
21 23
 from sphinx.domains import Domain, ObjType
22 24
 from sphinx.errors import SphinxError
23 25
 from sphinx.roles import XRefRole
@@ -649,7 +651,104 @@ class ZuulDomain(Domain):
649 651
                 del self.data['objects'][fullname]
650 652
 
651 653
 
654
+######################################################################
655
+#
656
+# Attribute overview directives
657
+#
658
+
659
+# TODO(ianw)
660
+#
661
+# There are many ways this could be improved
662
+#  * fancy indentation of nested attrs in the overview
663
+#  * (related) stripping of prefixes for nesting
664
+#  * something better than a bullet list (table?)
665
+#  * add something to attributes so that they can list thier child
666
+#    attributes atuomatically.  Something like
667
+#
668
+#    .. attr:: foo
669
+#       :show_overview:
670
+#
671
+#       This is the foo option
672
+#
673
+#    and then
674
+#
675
+#       .. attr-overview::
676
+#          :maxdepth: 1
677
+#          :prefix: foo
678
+#
679
+#    gets automatically inserted for you, and then you should have a
680
+#    sensible overview of the sub-options of "foo" inside the
681
+#    top-level "foo" documentation
682
+#  * figure out if it could be added to TOC
683
+
684
+class attroverview(nodes.General, nodes.Element):
685
+    pass
686
+
687
+class AttrOverviewDirective(Directive):
688
+    option_arguments = 2
689
+    option_spec = {
690
+        'maxdepth': directives.positive_int,
691
+        'prefix': directives.unchanged
692
+    }
693
+
694
+    def run(self):
695
+        attr = attroverview('')
696
+        if 'maxdepth' in self.options:
697
+            attr._maxdepth = self.options['maxdepth']
698
+        if 'prefix' in self.options:
699
+            attr._prefix = self.options['prefix']
700
+        return [attr]
701
+
702
+
703
+def process_attr_overview(app, doctree, fromdocname):
704
+    objects = app.builder.env.domaindata['zuul']['objects']
705
+
706
+    for node in doctree.traverse(attroverview):
707
+        content = []
708
+
709
+        l = nodes.bullet_list()
710
+        content.append(l)
711
+        # The "..attr" calls have built up this dictionary, of the format
712
+        #
713
+        # {
714
+        #   attr-foo : (docname, attr),
715
+        #   attr-foo.bar : (docname, attr),
716
+        # }
717
+        #
718
+        # So, in words, we look at all items in this list that have
719
+        # our docname and the attr "type" (second argument) and build
720
+        # them into a bullet list.
721
+        for k,v in objects.items():
722
+            if v[0] == fromdocname and v[1] == 'attr':
723
+                # remove the leading "attr-" for the link name ... the
724
+                # whole thing is is the refid however.
725
+                name = k[5:]
726
+
727
+                # e.g. if we have foo.bar.baz that's considered 3
728
+                # levels
729
+                if getattr(node, '_maxdepth', None):
730
+                    maxdepth = node._maxdepth
731
+                    if len(name.split('.')) > maxdepth:
732
+                        continue
733
+
734
+                if getattr(node, '_prefix', None):
735
+                    prefix = node._prefix
736
+                    if not name.startswith(prefix.strip()):
737
+                        continue
738
+
739
+                item = nodes.list_item()
740
+                para = nodes.paragraph()
741
+                refnode = nodes.reference(name, name, internal=True, refid=k)
742
+                para.append(refnode)
743
+                item.append(para)
744
+                l.append(item)
745
+
746
+        node.replace_self(content)
747
+
748
+
652 749
 def setup(app):
653 750
     app.add_config_value('zuul_role_paths', [], 'html')
654 751
     app.add_config_value('zuul_autoroles_warn_missing', True, '')
752
+    app.add_directive('attr-overview', AttrOverviewDirective)
753
+    app.connect('doctree-resolved', process_attr_overview)
655 754
     app.add_domain(ZuulDomain)

Loading…
Cancel
Save