summaryrefslogtreecommitdiffstats
path: root/source-builder/sb/reports.py
diff options
context:
space:
mode:
authorChris Johns <chrisj@rtems.org>2017-08-07 09:59:49 +1000
committerChris Johns <chrisj@rtems.org>2017-08-07 09:59:49 +1000
commit8b96e17c8abf61d97dd224b23370dc148f32fe3c (patch)
treee8eb043159d145ffbbbf9c23ef872226de5ab059 /source-builder/sb/reports.py
parent4.12: Fix SIS patch URL (diff)
downloadrtems-source-builder-8b96e17c8abf61d97dd224b23370dc148f32fe3c.tar.bz2
doc: Remove in source documentation and the asciidoc package
The RSB documentation is now in ReST format and part of the RTEMS Documentation project. See https://docs.rtems.org/. Remove support for the GPL based asciidoc tool and remove the asciidoc package from the RSB. Add the Python Markdown package and update the reporter to use Markdown for HTML generation. The resuling HTML report is a single self contained file. Closes #3047.
Diffstat (limited to '')
-rw-r--r--source-builder/sb/reports.py268
1 files changed, 180 insertions, 88 deletions
diff --git a/source-builder/sb/reports.py b/source-builder/sb/reports.py
index 5eb8bb8..3aa0952 100644
--- a/source-builder/sb/reports.py
+++ b/source-builder/sb/reports.py
@@ -24,6 +24,7 @@
from __future__ import print_function
+import base64
import copy
import datetime
import os
@@ -139,127 +140,212 @@ class formatter(object):
def post_process(self):
return self.content
-class asciidoc_formatter(formatter):
+class markdown_formatter(formatter):
def __init__(self):
- super(asciidoc_formatter, self).__init__()
+ super(markdown_formatter, self).__init__()
+ self.level_current = 1
+ self.level_path = '0.'
+ self.levels = { '0.': 0 }
+ self.cols = [20, 55]
+
+ def _heading(self, heading, level):
+ return '%s %s' % ('#' * level, heading)
+
+ def _strong(self, s):
+ return '__' + s + '__'
+
+ def _bold(self, s):
+ return '__' + s + '__'
+
+ def _italic(self, s):
+ return '_' + s + '_'
+
+ def _table_line(self):
+ l = '|'
+ for c in self.cols:
+ l += '-' * c + '|'
+ return l
+
+ def _table_row(self, cols):
+ if len(cols) != len(self.cols):
+ raise error.general('invalid table column count')
+ l = '|'
+ for c in range(0, len(cols)):
+ l += '%-*s|' % (self.cols[c], cols[c])
+ return l
+
+ def _btext(self, level, text):
+ return '> ' * (level - 1) + text
+
+ def _bline(self, level, text):
+ self.line(self._btext(level, text))
+
+ def _level(self, nest_level):
+ if nest_level > self.level_current:
+ self.level_path += '%d.' % (self.levels[self.level_path])
+ if nest_level < self.level_current:
+ self.level_path = self.level_path[:-2]
+ if self.level_path not in self.levels:
+ self.levels[self.level_path] = 0
+ self.level_current = nest_level
+ self.levels[self.level_path] += 1
+ return '%s%d.' % (self.level_path[2:], self.levels[self.level_path])
def format(self):
- return 'asciidoc'
+ return 'markdown'
def ext(self):
- return '.txt'
+ return '.md'
def introduction(self, name, now, intro_text):
- h = 'RTEMS Source Builder Report'
- self.line(h)
- self.line('=' * len(h))
- self.line(':doctype: book')
- self.line(':toc2:')
- self.line(':toclevels: 5')
- self.line(':icons:')
- self.line(':numbered:')
- self.line(':data-uri:')
- self.line('')
- self.line(_title)
- self.line(now)
+ self.line('- - -')
+ self.line(self._heading('RTEMS Source Builder Report', 1))
+ self.line(self._strong(_title))
self.line('')
- image = _make_path(self.sbpath, options.basepath, 'images', 'rtemswhitebg.jpg')
- self.line('image:%s["RTEMS",width="20%%"]' % (image))
+ self.line(self._bold('Generated: ' + now))
self.line('')
if intro_text:
self.line('%s' % ('\n'.join(intro_text)))
+ self.line('')
+ self.line('')
+ self.line('- - -')
+ self.line(self._heading('Table Of Contents', 2))
+ self.line('')
+ self.line('[TOC]')
+ self.line('')
def release_status(self, release_string):
self.line('')
- self.line("'''")
+ self.line(self._heading(_release_status_text, 2))
self.line('')
- self.line('.%s' % (_release_status_text))
self.line('*Version*: %s;;' % (release_string))
self.line('')
- self.line("'''")
- self.line('')
def git_status(self, valid, dirty, head, remotes):
self.line('')
- self.line("'''")
- self.line('')
- self.line('.%s' % (_git_status_text))
+ self.line('- - -')
+ self.line(self._heading(_git_status_text, 2))
if valid:
- self.line('*Remotes*:;;')
+ self.line(self._strong('Remotes:'))
+ self.line('')
+ rc = 1
for r in remotes:
if 'url' in remotes[r]:
text = remotes[r]['url']
else:
text = 'no URL found'
- text = '%s: %s' % (r, text)
- self.line('. %s' % (text))
- self.line('*Status*:;;')
+ self.line('%d. %s: %s' % (rc, r, text))
+ rc += 1
+ self.line('')
+ self.line(self._strong('Status:'))
+ self.line('')
if dirty:
- self.line('_Repository is dirty_')
+ self.line('> ' + self._italic('Repository is dirty'))
else:
- self.line('Clean')
- self.line('*Head*:;;')
- self.line('Commit: %s' % (head))
+ self.line('> Clean')
+ self.line('>')
+ self.line('> ' + self._bold('Head: ') + head)
else:
- self.line('_Not a valid GIT repository_')
- self.line('')
- self.line("'''")
+ self.line('> ' + self._italic('Not a valid GIT repository'))
self.line('')
def config(self, nest_level, name, _config):
- self.line('*Package*: _%s_ +' % (name))
- self.line('*Config*: %s' % (_config.file_name()))
- self.line('')
+ self._bline(nest_level, self._bold('Package:'))
+ self._bline(nest_level, '')
+ self._bline(nest_level + 1, self._table_row([self._bold('Item'),
+ self._bold('Description')]))
+ self._bline(nest_level + 1, self._table_line())
+ self._bline(nest_level + 1, self._table_row(['Package', name]))
+ self._bline(nest_level + 1, self._table_row(['Config',
+ _config.file_name()]))
def config_end(self, nest_level, name):
- self.line('')
- self.line("'''")
- self.line('')
+ self._bline(nest_level + 1, '')
def buildset_start(self, nest_level, name):
- h = '%s' % (name)
- self.line('=%s %s' % ('=' * int(nest_level), h))
+ if nest_level == 1:
+ self.line('- - -')
+ self._bline(nest_level,
+ self._heading('RTEMS Source Builder Packages', 2))
+ self._bline(nest_level,
+ self._heading('%s Build %s' % (self._level(nest_level), name), 3))
def info(self, nest_level, name, info, separated):
- end = ''
- if separated:
- self.line('*%s:*::' % (name))
- self.line('')
- else:
- self.line('*%s:* ' % (name))
- end = ' +'
- spaces = ''
- for l in info:
- self.line('%s%s%s' % (spaces, l, end))
- if separated:
- self.line('')
+ self._bline(nest_level + 1,
+ self._table_row([name, ' '.join(info)]))
def directive(self, nest_level, name, data):
- self.line('')
- self.line('*%s*:' % (name))
- self.line('--------------------------------------------')
+ self._bline(nest_level, '')
+ self._bline(nest_level, self._bold(name + ':'))
for l in data:
- self.line(l)
- self.line('--------------------------------------------')
+ self._bline(nest_level + 1, ' ' * 4 + l)
def files(self, nest_level, singular, plural, _files):
- self.line('')
- self.line('*' + plural + ':*::')
+ self._bline(nest_level, '')
+ self._bline(nest_level, self._bold(plural + ':'))
+ self._bline(nest_level, '')
if len(_files) == 0:
- self.line('No ' + plural.lower())
+ self._bline(nest_level + 1, 'No ' + plural.lower())
+ fc = 0
for name in _files:
for s in _files[name]:
- self.line('. %s' % (s[0]))
+ fc += 1
if s[1] is None:
- h = 'No checksum'
+ h = self._bold('No checksum')
else:
hash = s[1].split()
h = '%s: %s' % (hash[0], hash[1])
- self.line('+\n%s\n' % (h))
+ self._bline(nest_level,
+ '%d. [%s](%s "%s %s")<br/>' % (fc, s[0], s[0],
+ name, singular.lower()))
+ self._bline(nest_level,
+ ' <span class=checksum>%s</span>' % (h))
-class html_formatter(asciidoc_formatter):
+class html_formatter(markdown_formatter):
def __init__(self):
super(html_formatter, self).__init__()
+ self.html_header = '<!DOCTYPE html>' + os.linesep + \
+ '<html lang="en">' + os.linesep + \
+ '<head>' + os.linesep + \
+ '<title>RTEMS RSB - @BUILD@</title>' + os.linesep + \
+ '<meta http-equiv="content-type" content="text/html; charset=UTF-8" />' + os.linesep + \
+ '<meta name="created" content="@NOW@" />' + os.linesep + \
+ '<meta name="description" content="RTEMS RSB Report" />' + os.linesep + \
+ '<meta name="keywords" content="RTEMS RSB" />' + os.linesep + \
+ '<meta charset="utf-8">' + os.linesep + \
+ '<meta http-equiv="X-UA-Compatible" content="IE=edge">' + os.linesep + \
+ '<meta name="viewport" content="width=device-width, initial-scale=1">' + os.linesep + \
+ '<style type="text/css">' + os.linesep + \
+ 'body {' + os.linesep + \
+ ' font-family: arial, helvetica, serif;' + os.linesep + \
+ ' font-style: normal;' + os.linesep + \
+ ' font-weight: 400;' + os.linesep + \
+ '}' + os.linesep + \
+ 'h1, h2 { margin: 10px 5px 10px 5px; }' + os.linesep + \
+ 'h1 { font-size: 28px; }' + os.linesep + \
+ 'h2 { font-size: 22px;}' + os.linesep + \
+ 'h3 { font-size: 18px; }' + os.linesep + \
+ 'p, ol, blockquote, h3, table, pre { margin: 1px 20px 2px 7px; }' + os.linesep + \
+ 'table, th, td, pre { border: 1px solid gray; border-spacing: 0px; }' + os.linesep + \
+ 'table { width: 100%; }' + os.linesep + \
+ 'th, td { padding: 1px; }' + os.linesep + \
+ 'pre { padding: 4px; }' + os.linesep + \
+ '.checksum { font-size: 12px; }' + os.linesep + \
+ '</style>' + os.linesep + \
+ '</head>' + os.linesep + \
+ '<body>' + os.linesep
+ self.html_footer = '</body>' + os.linesep + \
+ '</html>' + os.linesep
+
+ def _logo(self):
+ logo = _make_path(self.sbpath, options.basepath, 'images', 'rtemswhitebg.jpg')
+ try:
+ with open(logo, "rb") as image:
+ b64 = base64.b64encode(image.read())
+ except:
+ raise error.general('installation error: no logo found')
+ logo = '<img alt="RTEMS Project" height="100" src="data:image/png;base64,' + b64 + '" />'
+ return logo
def format(self):
return 'html'
@@ -267,24 +353,30 @@ class html_formatter(asciidoc_formatter):
def ext(self):
return '.html'
+ def introduction(self, name, now, intro_text):
+ self.name = name
+ self.now = now
+ super(html_formatter, self).introduction(name, now, intro_text)
+
def post_process(self):
- import io
- infile = io.StringIO(self.content)
- outfile = io.StringIO()
try:
- import asciidocapi
+ import markdown
except:
- raise error.general('installation error: no asciidocapi found')
- asciidoc_py = _make_path(self.sbpath, options.basepath, 'asciidoc', 'asciidoc.py')
+ raise error.general('installation error: no markdown found')
try:
- asciidoc = asciidocapi.AsciiDocAPI(asciidoc_py)
+ out = markdown.markdown(self.content,
+ output_format = 'html5',
+ extensions = ['markdown.extensions.toc',
+ 'markdown.extensions.tables',
+ 'markdown.extensions.sane_lists',
+ 'markdown.extensions.smarty'])
except:
- raise error.general('application error: asciidocapi failed')
- asciidoc.execute(infile, outfile)
- out = outfile.getvalue()
- infile.close()
- outfile.close()
- return out
+ raise
+ raise error.general('application error: markdown failed')
+ header = self.html_header.replace('@BUILD@', self.name).replace('@NOW@', self.now)
+ footer = self.html_footer
+ logo = self._logo()
+ return header + logo + out + footer
class text_formatter(formatter):
def __init__(self):
@@ -503,8 +595,8 @@ class report:
if type(formatter) == str:
if formatter == 'text':
self.formatter = text_formatter()
- elif formatter == 'asciidoc':
- self.formatter = asciidoc_formatter()
+ elif formatter == 'markdown':
+ self.formatter = markdown_formatter()
elif formatter == 'html':
self.formatter = html_formatter()
elif formatter == 'ini':
@@ -784,9 +876,9 @@ def run(args):
try:
optargs = { '--list-bsets': 'List available build sets',
'--list-configs': 'List available configurations',
- '--format': 'Output format (text, html, asciidoc, ini, xml)',
+ '--format': 'Output format (text, html, markdown, ini, xml)',
'--output': 'File name to output the report' }
- opts = options.load(args, optargs)
+ opts = options.load(args, optargs, logfile = False)
if opts.get_arg('--output') and len(opts.params()) > 1:
raise error.general('--output can only be used with a single config')
print('RTEMS Source Builder, Reporter, %s' % (version.str()))
@@ -805,8 +897,8 @@ def run(args):
raise error.general('invalid format option: %s' % ('='.join(format_opt)))
if format_opt[1] == 'text':
pass
- elif format_opt[1] == 'asciidoc':
- formatter = asciidoc_formatter()
+ elif format_opt[1] == 'markdown':
+ formatter = markdown_formatter()
elif format_opt[1] == 'html':
formatter = html_formatter()
elif format_opt[1] == 'ini':
@@ -824,7 +916,7 @@ def run(args):
outname = output
config = build.find_config(_config, configs)
if config is None:
- raise error.general('config file not found: %s' % (inname))
+ raise error.general('config file not found: %s' % (_config))
r.create(config, outname)
del r
else: