Greg Sheremeta has uploaded a new change for review.

Change subject: engine: create tool to scan source code for help tags
......................................................................

engine: create tool to scan source code for help tags

Created a utility script to scan the ovirt-engine source code for usages of the
Model helpTag attribute. These attributes can be mapped to a documentation URL 
in
the documentation mapping properties files, so this tool is designed to help 
find
changes in the help tags around release time.

The tool can generate a simple diff, or it can generate an entire template (that
could then be diffed with any existing mapping file).

Change-Id: I70a92fd49a00fe7c235d7bc201218a7119dfa425
Bug-Url: https://bugzilla.redhat.com/1014859
Signed-off-by: Greg Sheremeta <gsher...@redhat.com>
---
A build/doctag.py
1 file changed, 204 insertions(+), 0 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/90/21390/1

diff --git a/build/doctag.py b/build/doctag.py
new file mode 100644
index 0000000..2aecd63
--- /dev/null
+++ b/build/doctag.py
@@ -0,0 +1,204 @@
+#!/usr/bin/python
+"""
+Compare code documentation tags to documentation mapping files.
+"""
+
+
+import argparse
+import json
+import os
+import re
+import sys
+
+
+if sys.version_info[0] < 3:
+    import ConfigParser
+    sys.modules['configparser'] = ConfigParser
+
+
+import configparser
+
+
+COMMAND_DIFF = 'diff'
+COMMAND_TEMPLATE = 'template'
+FORMAT_JSON = 'json'
+FORMAT_INI = 'ini'
+DOCTAG_SECTION = 'doctags'
+
+
+__RE_SETHASHNAME = re.compile(
+    flags=re.VERBOSE,
+    pattern=r"""
+        .*
+        setHashName\(
+            "(?P<hashName>.*)"
+        \)
+        .*
+    """,
+)
+
+__RE_SETHELPTAG = re.compile(
+    flags=re.VERBOSE,
+    pattern=r"""
+        .*
+        setHelpTag\(
+            "?(?P<helpTag>.*)"?\s*,\s*"(?P<helpComment>.*)" 
+        \)
+        .*
+    """,
+)
+
+
+def loadTags(file, format):
+    if format == FORMAT_JSON:
+        with open(file, 'r') as f:
+            ret = set(json.load(f).keys())
+    elif format == FORMAT_INI:
+        config = configparser.ConfigParser()
+        config.optionxform = str
+        config.read((file,))
+        ret = set(config.options(DOCTAG_SECTION))
+    else:
+        raise RuntimeError("Invalid format '%s'" % format)
+
+    return ret
+
+
+def codeTags(sourcedir):
+    """
+    look for doc tags in the source code.
+    """
+    tags = {}
+    for parent, dnames, fnames in os.walk(sourcedir):
+        for fname in fnames:
+            filename = os.path.join(parent, fname)
+            if filename.endswith('.java') and os.path.isfile(filename):
+                prev_line = ""
+                with open(filename) as f:
+                    for line in f:
+                        m = __RE_SETHELPTAG.match(line)
+                        if m:
+                            mPrev = __RE_SETHASHNAME.match(prev_line)
+                            if mPrev:
+                                helpTag = mPrev.group("hashName")
+                            else:
+                                helpTag = m.group("helpTag")
+                            helpComment = m.group("helpComment")
+                            if helpTag in tags:
+                                if tags[helpTag] != helpComment:
+                                    sys.stderr.write("Warning: detected help 
tag with multiple uses and different comments: %s ['%s' != '%s'])\n" \
+                                                     % (helpTag, helpComment, 
tags[helpTag]));
+                            else:      
+                                tags[helpTag] = helpComment
+                        prev_line = line
+    return tags
+
+
+def produceTemplate(tags, out, format=FORMAT_JSON):
+    if format == FORMAT_JSON:
+        # python 2.4 does not support auto map
+        json.dump(
+            dict(zip(tags, [''] * len(tags))),
+            out,
+            sort_keys=True,
+            indent=4,
+        )
+    elif format == FORMAT_INI:
+        out.write("[%s]" % DOCTAG_SECTION)
+        for k in sorted(tags):
+            out.write("; %s\n%s=\n\n" % (tags[k], k))
+    else:
+        raise RuntimeError('Invalid template format')
+
+
+def produceDiff(left, right, out):
+    ret = False
+
+    if left == right:
+        ret = True
+    else:
+        out.write('The following tags are changed:\n')
+        for t in sorted(right - left):
+            out.write('+%s\n' % t)
+        for t in sorted(left - right):
+            out.write('-%s\n' % t)
+
+    return ret
+
+
+def main():
+    ret = 1
+
+    parser = argparse.ArgumentParser(
+        description=(
+            'Compare code documentation tags to documentation mapping files, '
+            'or produce template of mapping files.'
+        ),
+    )
+    parser.add_argument(
+        '--sourcedir',
+        metavar='DIRECTORY',
+        dest='sourcedir',
+        default='.',
+        help='the source code directory',
+    )
+    parser.add_argument(
+        '--command',
+        metavar='COMMAND',
+        dest='command',
+        default=COMMAND_DIFF,
+        choices=[COMMAND_DIFF, COMMAND_TEMPLATE],
+        help='Command (%(choices)s)',
+    )
+    parser.add_argument(
+        '--format',
+        metavar='FORMAT',
+        dest='format',
+        default=FORMAT_JSON,
+        choices=[FORMAT_JSON, FORMAT_INI],
+        help='Format of files (%(choices)s)',
+    )
+    parser.add_argument(
+        '--load',
+        metavar='FILE',
+        dest='load',
+        default=[],
+        action='append',
+        help=(
+            'Load existing files, may be used several times to '
+            'load multiple files'
+        ),
+    )
+    args = parser.parse_args()
+
+    neededTags = codeTags(args.sourcedir)
+
+    if args.command == COMMAND_TEMPLATE:
+        produceTemplate(
+            tags=neededTags,
+            out=sys.stdout,
+            format=args.format,
+        )
+        ret = 0
+    elif args.command == COMMAND_DIFF:
+        loadedTags = set()
+        for f in args.load:
+            loadedTags |= loadTags(f, format=args.format)
+        ret = (
+            0 if produceDiff(
+                left=loadedTags,
+                right=set(neededTags.keys()),
+                out=sys.stdout,
+            ) else 1
+        )
+    else:
+        raise RuntimeError("Invalid command '%s'" % args.command)
+
+    sys.exit(ret)
+
+
+if __name__ == "__main__":
+    main()
+
+
+# vim: expandtab tabstop=4 shiftwidth=4


-- 
To view, visit http://gerrit.ovirt.org/21390
To unsubscribe, visit http://gerrit.ovirt.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I70a92fd49a00fe7c235d7bc201218a7119dfa425
Gerrit-PatchSet: 1
Gerrit-Project: ovirt-engine
Gerrit-Branch: master
Gerrit-Owner: Greg Sheremeta <gsher...@redhat.com>
_______________________________________________
Engine-patches mailing list
Engine-patches@ovirt.org
http://lists.ovirt.org/mailman/listinfo/engine-patches

Reply via email to