summaryrefslogtreecommitdiff
path: root/docs/_ext/vyos.py
diff options
context:
space:
mode:
Diffstat (limited to 'docs/_ext/vyos.py')
-rw-r--r--docs/_ext/vyos.py265
1 files changed, 230 insertions, 35 deletions
diff --git a/docs/_ext/vyos.py b/docs/_ext/vyos.py
index 4001f0fe..4a974b46 100644
--- a/docs/_ext/vyos.py
+++ b/docs/_ext/vyos.py
@@ -1,25 +1,41 @@
import re
-import io
+import json
import os
from docutils import io, nodes, utils, statemachine
-from docutils.utils.error_reporting import SafeString, ErrorString
from docutils.parsers.rst.roles import set_classes
-from docutils.parsers.rst import Directive, directives
+from docutils.parsers.rst import Directive, directives, states
+
from sphinx.util.docutils import SphinxDirective
+from testcoverage import get_working_commands
+
def setup(app):
app.add_config_value(
'vyos_phabricator_url',
- 'https://phabricator.vyos.net/', ''
+ 'https://phabricator.vyos.net/',
+ 'html'
+ )
+
+ app.add_config_value(
+ 'vyos_working_commands',
+ get_working_commands(),
+ 'html'
)
+ app.add_config_value(
+ 'vyos_coverage',
+ {
+ 'cfgcmd': [0,len(app.config.vyos_working_commands['cfgcmd'])],
+ 'opcmd': [0,len(app.config.vyos_working_commands['opcmd'])]
+ },
+ 'html'
+ )
+
app.add_role('vytask', vytask_role)
app.add_role('cfgcmd', cmd_role)
app.add_role('opcmd', cmd_role)
- print(app.config.vyos_phabricator_url)
-
app.add_node(
inlinecmd,
html=(inlinecmd.visit_span, inlinecmd.depart_span),
@@ -46,9 +62,11 @@ def setup(app):
text=(CmdHeader.visit_div, CmdHeader.depart_div)
)
app.add_node(CfgcmdList)
+ app.add_node(CfgcmdListCoverage)
app.add_directive('cfgcmdlist', CfgcmdlistDirective)
app.add_node(OpcmdList)
+ app.add_node(OpcmdListCoverage)
app.add_directive('opcmdlist', OpcmdlistDirective)
app.add_directive('cfgcmd', CfgCmdDirective)
@@ -56,15 +74,17 @@ def setup(app):
app.add_directive('cmdinclude', CfgInclude)
app.connect('doctree-resolved', process_cmd_nodes)
-
class CfgcmdList(nodes.General, nodes.Element):
pass
-
class OpcmdList(nodes.General, nodes.Element):
pass
-import json
+class CfgcmdListCoverage(nodes.General, nodes.Element):
+ pass
+
+class OpcmdListCoverage(nodes.General, nodes.Element):
+ pass
class CmdHeader(nodes.General, nodes.Element):
@@ -153,7 +173,7 @@ class inlinecmd(nodes.inline):
#self.literal_whitespace -= 1
-class CfgInclude(Directive):
+class CfgInclude(SphinxDirective):
required_arguments = 1
optional_arguments = 0
final_argument_whitespace = True
@@ -169,10 +189,15 @@ class CfgInclude(Directive):
'var8': str,
'var9': str
}
+ standard_include_path = os.path.join(os.path.dirname(states.__file__),
+ 'include')
def run(self):
### Copy from include directive docutils
"""Include a file as part of the content of this reST file."""
+ rel_filename, filename = self.env.relfn2path(self.arguments[0])
+ self.arguments[0] = filename
+ self.env.note_included(filename)
if not self.state.document.settings.file_insertion_enabled:
raise self.warning('"%s" directive disabled.' % self.name)
source = self.state_machine.input_lines.source(
@@ -199,9 +224,9 @@ class CfgInclude(Directive):
'Cannot encode input file path "%s" '
'(wrong locale?).' %
(self.name, SafeString(path)))
- except IOError:
- raise self.severe(u'Problems with "%s" directive path.' %
- (self.name))
+ except IOError as error:
+ raise self.severe(u'Problems with "%s" directive path:\n%s.' %
+ (self.name, error))
startline = self.options.get('start-line', None)
endline = self.options.get('end-line', None)
try:
@@ -275,9 +300,8 @@ class CfgInclude(Directive):
self.state,
self.state_machine)
return codeblock.run()
-
+
new_include_lines = []
-
for line in include_lines:
for i in range(10):
value = self.options.get(f'var{i}','')
@@ -285,22 +309,41 @@ class CfgInclude(Directive):
line = re.sub('\s?{{\s?var' + str(i) + '\s?}}',value,line)
else:
line = re.sub('{{\s?var' + str(i) + '\s?}}',value,line)
-
new_include_lines.append(line)
self.state_machine.insert_input(new_include_lines, path)
return []
class CfgcmdlistDirective(Directive):
+ has_content = False
+ required_arguments = 0
+ option_spec = {
+ 'show-coverage': directives.flag
+ }
def run(self):
- return [CfgcmdList('')]
+ cfglist = CfgcmdList()
+ cfglist['coverage'] = False
+ if 'show-coverage' in self.options:
+ cfglist['coverage'] = True
+ return [cfglist]
class OpcmdlistDirective(Directive):
+ has_content = False
+ required_arguments = 0
+ option_spec = {
+ 'show-coverage': directives.flag
+ }
def run(self):
- return [OpcmdList('')]
+ oplist = OpcmdList()
+ oplist['coverage'] = False
+ if 'show-coverage' in self.options:
+ oplist['coverage'] = True
+
+ return [oplist]
+
class CmdDirective(SphinxDirective):
@@ -308,7 +351,8 @@ class CmdDirective(SphinxDirective):
has_content = True
custom_class = ''
- def run(self):
+ def run(self):
+
title_list = []
content_list = []
title_text = ''
@@ -386,7 +430,134 @@ class CfgCmdDirective(CmdDirective):
custom_class = 'cfg'
-def process_cmd_node(app, cmd, fromdocname):
+def strip_cmd(cmd):
+ cmd = re.sub('set','',cmd)
+ cmd = re.sub('\s\|\s','',cmd)
+ cmd = re.sub('<\S*>','',cmd)
+ cmd = re.sub('\[\S\]','',cmd)
+ cmd = re.sub('\s+','',cmd)
+ return cmd
+
+def build_row(app, fromdocname, rowdata):
+ row = nodes.row()
+ for cell in rowdata:
+ entry = nodes.entry()
+ row += entry
+ if isinstance(cell, list):
+ for item in cell:
+ if isinstance(item, dict):
+ entry += process_cmd_node(app, item, fromdocname, '')
+ else:
+ entry += nodes.paragraph(text=item)
+ elif isinstance(cell, bool):
+ if cell:
+ entry += nodes.paragraph(text="")
+ entry['classes'] = ['coverage-ok']
+ else:
+ entry += nodes.paragraph(text="")
+ entry['classes'] = ['coverage-fail']
+ else:
+ entry += nodes.paragraph(text=cell)
+ return row
+
+
+
+def process_coverage(app, fromdocname, doccmd, xmlcmd, cli_type):
+ coverage_list = {}
+ int_docs = 0
+ int_xml = 0
+ for cmd in doccmd:
+ coverage_item = {
+ 'doccmd': None,
+ 'xmlcmd': None,
+ 'doccmd_item': None,
+ 'xmlcmd_item': None,
+ 'indocs': False,
+ 'inxml': False,
+ 'xmlfilename': None
+ }
+ coverage_item['doccmd'] = cmd['cmd']
+ coverage_item['doccmd_item'] = cmd
+ coverage_item['indocs'] = True
+ int_docs += 1
+ coverage_list[strip_cmd(cmd['cmd'])] = dict(coverage_item)
+
+ for cmd in xmlcmd:
+
+ strip = strip_cmd(cmd['cmd'])
+ if strip not in coverage_list.keys():
+ coverage_item = {
+ 'doccmd': None,
+ 'xmlcmd': None,
+ 'doccmd_item': None,
+ 'xmlcmd_item': None,
+ 'indocs': False,
+ 'inxml': False,
+ 'xmlfilename': None
+ }
+ coverage_item['xmlcmd'] = cmd['cmd']
+ coverage_item['xmlcmd_item'] = cmd
+ coverage_item['inxml'] = True
+ coverage_item['xmlfilename'] = cmd['filename']
+ int_xml += 1
+ coverage_list[strip] = dict(coverage_item)
+ else:
+ #print("===BEGIN===")
+ #print(cmd)
+ #print(coverage_list[strip])
+ #print(strip)
+ #print("===END====")
+ coverage_list[strip]['xmlcmd'] = cmd['cmd']
+ coverage_list[strip]['xmlcmd_item'] = cmd
+ coverage_list[strip]['inxml'] = True
+ coverage_list[strip]['xmlfilename'] = cmd['filename']
+ int_xml += 1
+
+
+
+
+ table = nodes.table()
+ tgroup = nodes.tgroup(cols=3)
+ table += tgroup
+
+ header = (f'{int_docs}/{len(coverage_list)} in Docs', f'{int_xml}/{len(coverage_list)} in XML', 'Command')
+ colwidths = (1, 1, 8)
+ table = nodes.table()
+ tgroup = nodes.tgroup(cols=len(header))
+ table += tgroup
+ for colwidth in colwidths:
+ tgroup += nodes.colspec(colwidth=colwidth)
+ thead = nodes.thead()
+ tgroup += thead
+ thead += build_row(app, fromdocname, header)
+ tbody = nodes.tbody()
+ tgroup += tbody
+ for entry in sorted(coverage_list):
+ body_text_list = []
+ if coverage_list[entry]['indocs']:
+ body_text_list.append(coverage_list[entry]['doccmd_item'])
+ else:
+ body_text_list.append('Not documented yet')
+
+ if coverage_list[entry]['inxml']:
+ body_text_list.append("------------------")
+ body_text_list.append(str(coverage_list[entry]['xmlfilename']) + ":")
+ body_text_list.append(coverage_list[entry]['xmlcmd'])
+ else:
+ body_text_list.append('Nothing found in XML Definitions')
+
+
+ tbody += build_row(app, fromdocname,
+ (
+ coverage_list[entry]['indocs'],
+ coverage_list[entry]['inxml'],
+ body_text_list
+ )
+ )
+
+ return table
+
+def process_cmd_node(app, cmd, fromdocname, cli_type):
para = nodes.paragraph()
newnode = nodes.reference('', '')
innernode = cmd['cmdnode']
@@ -401,21 +572,45 @@ def process_cmd_node(app, cmd, fromdocname):
def process_cmd_nodes(app, doctree, fromdocname):
- env = app.builder.env
-
- for node in doctree.traverse(CfgcmdList):
- content = []
-
- for cmd in sorted(env.vyos_cfgcmd, key=lambda i: i['cmd']):
- content.append(process_cmd_node(app, cmd, fromdocname))
- node.replace_self(content)
-
- for node in doctree.traverse(OpcmdList):
- content = []
+ try:
+ env = app.builder.env
+
+ for node in doctree.traverse(CfgcmdList):
+ content = []
+ if node.attributes['coverage']:
+ node.replace_self(
+ process_coverage(
+ app,
+ fromdocname,
+ env.vyos_cfgcmd,
+ app.config.vyos_working_commands['cfgcmd'],
+ 'cfgcmd'
+ )
+ )
+ else:
+ for cmd in sorted(env.vyos_cfgcmd, key=lambda i: i['cmd']):
+ content.append(process_cmd_node(app, cmd, fromdocname, 'cfgcmd'))
+ node.replace_self(content)
+
+ for node in doctree.traverse(OpcmdList):
+ content = []
+ if node.attributes['coverage']:
+ node.replace_self(
+ process_coverage(
+ app,
+ fromdocname,
+ env.vyos_opcmd,
+ app.config.vyos_working_commands['opcmd'],
+ 'opcmd'
+ )
+ )
+ else:
+ for cmd in sorted(env.vyos_opcmd, key=lambda i: i['cmd']):
+ content.append(process_cmd_node(app, cmd, fromdocname, 'opcmd'))
+ node.replace_self(content)
- for cmd in sorted(env.vyos_opcmd, key=lambda i: i['cmd']):
- content.append(process_cmd_node(app, cmd, fromdocname))
- node.replace_self(content)
+ except Exception as inst:
+ print(inst)
def vytask_role(name, rawtext, text, lineno, inliner, options={}, content=[]):
@@ -430,4 +625,4 @@ def vytask_role(name, rawtext, text, lineno, inliner, options={}, content=[]):
def cmd_role(name, rawtext, text, lineno, inliner, options={}, content=[]):
node = nodes.literal(text, text)
- return [node], []
+ return [node], [] \ No newline at end of file