summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWill Thames <will.thames@xvt.com.au>2017-09-11 15:19:50 +1000
committerToshio Kuratomi <a.badger@gmail.com>2017-09-11 14:33:29 -0700
commit1586274fe5512075bb49c237b0d10cb256761d5a (patch)
tree06c755a2b072f4458f7a327d82567242af9db008
parentcc995a2477665d3675cecc86046573c80c1cbccb (diff)
downloadansible-1586274fe5512075bb49c237b0d10cb256761d5a.tar.gz
Use JSON returns values to create RETURN docs
After running hacking/test-module to generate some output, the JSON output can be fed into the return skeletion generator to create an excellent starting point for RETURN docs (cherry picked from commit 5e978b0f2b1008b6fefbe3da7df3192a49acc4ad)
-rwxr-xr-xhacking/return_skeleton_generator.py96
1 files changed, 96 insertions, 0 deletions
diff --git a/hacking/return_skeleton_generator.py b/hacking/return_skeleton_generator.py
new file mode 100755
index 0000000000..05c791bf24
--- /dev/null
+++ b/hacking/return_skeleton_generator.py
@@ -0,0 +1,96 @@
+#!/usr/bin/env python
+
+# (c) 2017, Will Thames <will@thames.id.au>
+#
+# This file is part of Ansible
+#
+# Ansible is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Ansible is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
+
+# return_skeleton_generator.py takes JSON output from a module and
+# and creates a starting point for the RETURNS section of a module.
+# This can be provided as stdin or a file argument
+#
+# The easiest way to obtain the JSON output is to use hacking/test-module
+#
+# You will likely want to adjust this to remove sensitive data or
+# ensure the `returns` value is correct, and to write a useful description
+
+from __future__ import print_function
+from collections import OrderedDict
+import json
+import sys
+import yaml
+
+
+# Allow OrderedDicts to be used when dumping YAML
+# https://stackoverflow.com/a/16782282/3538079
+def represent_ordereddict(dumper, data):
+ value = []
+
+ for item_key, item_value in data.items():
+ node_key = dumper.represent_data(item_key)
+ node_value = dumper.represent_data(item_value)
+
+ value.append((node_key, node_value))
+
+ return yaml.nodes.MappingNode(u'tag:yaml.org,2002:map', value)
+
+
+def get_return_data(key, value):
+ # The OrderedDict here is so that, for complex objects, the
+ # summary data is at the top before the contains information
+ returns_info = {key: OrderedDict()}
+ returns_info[key]['description'] = "FIXME *** add description for %s" % key
+ returns_info[key]['returned'] = "always"
+ if isinstance(value, dict):
+ returns_info[key]['type'] = 'complex'
+ returns_info[key]['contains'] = get_all_items(value)
+ elif isinstance(value, list) and value and isinstance(value[0], dict):
+ returns_info[key]['type'] = 'complex'
+ returns_info[key]['contains'] = get_all_items(value[0])
+ else:
+ returns_info[key]['type'] = type(value).__name__
+ returns_info[key]['sample'] = value
+ # override python unicode type to set to string for docs
+ if returns_info[key]['type'] == 'unicode':
+ returns_info[key]['type'] = 'string'
+ return returns_info
+
+
+def get_all_items(data):
+ items = sorted([get_return_data(key, value) for key, value in data.items()])
+ result = OrderedDict()
+ for item in items:
+ key, value = item.items()[0]
+ result[key] = value
+ return result
+
+
+def main(args):
+ yaml.representer.SafeRepresenter.add_representer(OrderedDict, represent_ordereddict)
+
+ if args:
+ src = open(args[0])
+ else:
+ src = sys.stdin
+
+ data = json.load(src, strict=False)
+ docs = get_all_items(data)
+ if 'invocation' in docs:
+ del(docs['invocation'])
+ print(yaml.safe_dump(docs, default_flow_style=False))
+
+
+if __name__ == '__main__':
+ main(sys.argv[1:])