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