aboutsummaryrefslogtreecommitdiff
path: root/wlauto/tools/extdoc.py
diff options
context:
space:
mode:
authorSergei Trofimov <sergei.trofimov@arm.com>2015-03-10 13:09:31 +0000
committerSergei Trofimov <sergei.trofimov@arm.com>2015-03-10 13:09:31 +0000
commita747ec7e4c2ea8a25bfc675f80042eb6600c7050 (patch)
tree077c0439a89a5c33b9fa1dbf9e81146ca9960d3c /wlauto/tools/extdoc.py
Initial commit of open source Workload Automation.
Diffstat (limited to 'wlauto/tools/extdoc.py')
-rw-r--r--wlauto/tools/extdoc.py134
1 files changed, 134 insertions, 0 deletions
diff --git a/wlauto/tools/extdoc.py b/wlauto/tools/extdoc.py
new file mode 100644
index 00000000..8c6592ec
--- /dev/null
+++ b/wlauto/tools/extdoc.py
@@ -0,0 +1,134 @@
+# Copyright 2014-2015 ARM Limited
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+
+"""
+This module contains utilities for generating user documentation for Workload
+Automation Extensions.
+
+"""
+import re
+import inspect
+
+
+PARAGRAPH_SEP = re.compile(r'\n\n+')
+LINE_START = re.compile(r'\n\s*')
+
+
+def get_paragraphs(text):
+ """returns a list of paragraphs contained in the text"""
+ return [LINE_START.sub(' ', p) for p in PARAGRAPH_SEP.split(text)]
+
+
+class ExtensionDocumenter(object):
+
+ @property
+ def name(self):
+ return self.ext.name
+
+ @property
+ def summary(self):
+ """Returns the summary description for this Extension, which, by
+ convention, is the first paragraph of the description."""
+ return get_paragraphs(self.description)[0]
+
+ @property
+ def description(self):
+ """
+ The description for an extension is specified in the ``description``
+ attribute, or (legacy) as a docstring for the extension's class. If
+ neither method is used in the Extension, an empty string is returned.
+
+ Description is assumed to be formed as reStructuredText. Leading and
+ trailing whitespace will be stripped away.
+
+ """
+ if hasattr(self.ext, 'description'):
+ return self.ext.description.strip()
+ elif self.ext.__class__.__doc__:
+ return self.ext.__class__.__doc__.strip()
+ else:
+ return ''
+
+ @property
+ def parameters(self):
+ return [ExtensionParameterDocumenter(p) for p in self.ext.parameters]
+
+ def __init__(self, ext):
+ self.ext = ext
+
+
+class ExtensionParameterDocumenter(object):
+
+ @property
+ def name(self):
+ return self.param.name
+
+ @property
+ def kind(self):
+ return self.param.get_type_name()
+
+ @property
+ def default(self):
+ return self.param.default
+
+ @property
+ def description(self):
+ return self.param.description
+
+ @property
+ def constraint(self):
+ constraints = []
+ if self.param.allowed_values:
+ constraints.append('value must be in {}'.format(self.param.allowed_values))
+ if self.param.constraint:
+ constraint_text = self.param.constraint.__name__
+ if constraint_text == '<lambda>':
+ constraint_text = _parse_lambda(inspect.getsource(self.param.constraint))
+ constraints.append(constraint_text)
+ return ' and '.join(constraints)
+
+ def __init__(self, param):
+ self.param = param
+
+
+# Utility functions
+
+
+def _parse_lambda(text):
+ """Parse the definition of a lambda function in to a readable string."""
+ text = text.split('lambda')[1]
+ param, rest = text.split(':')
+ param = param.strip()
+ # There are three things that could terminate a lambda: an (unparenthesized)
+ # comma, a new line and an (unmatched) close paren.
+ term_chars = [',', '\n', ')']
+ func_text = ''
+ inside_paren = 0 # an int rather than a bool to keep track of nesting
+ for c in rest:
+ if c in term_chars and not inside_paren:
+ break
+ elif c == ')': # must be inside paren
+ inside_paren -= 1
+ elif c == '(':
+ inside_paren += 1
+ func_text += c
+
+ # Rename the lambda parameter to 'value' so that the resulting
+ # "description" makes more sense.
+ func_text = re.sub(r'\b{}\b'.format(param), 'value', func_text)
+
+ return func_text
+