""" @package tools.build_modules_xml @brief Builds XML metadata of GRASS modules. Runs only during compilation. (C) 2013 by the GRASS Development Team This program is free software under the GNU General Public License (>=v2). Read the file COPYING that comes with GRASS for details. @author Vaclav Petras @author Anna Petrasova """ import sys from datetime import datetime import grass.script.core as gcore import grass.script.task as gtask def escapeXML(text): """This is a duplicate of function in core/toolboxes. >>> escapeXML('<>&') '&lt;>&' """ return text.replace('<', '<').replace("&", '&').replace(">", '>') def do_doctest_gettext_workaround(): """This is a duplicate of function in core/toolboxes.""" def new_displayhook(string): """A replacement for default `sys.displayhook`""" if string is not None: sys.stdout.write("%r\n" % (string,)) def new_translator(string): """A fake gettext underscore function.""" return string sys.displayhook = new_displayhook sys.__displayhook__ = new_displayhook import __builtin__ __builtin__._ = new_translator def parse_modules(fd): """Writes metadata to xml file.""" # TODO: what about ms windows? does gtask handle this? mlist = list(gcore.get_commands()[0]) indent = 4 for m in sorted(mlist): # TODO: get rid of g.mapsets_picker.py if m == 'g.mapsets_picker.py' or m == 'g.parser': continue desc, keyw = get_module_metadata(m) fd.write('%s\n' % (' ' * indent, m)) indent += 4 fd.write('%s%s\n' % (' ' * indent, m)) fd.write( '%s%s\n' % (' ' * indent, escapeXML(desc))) fd.write('%s%s\n' % (' ' * indent, escapeXML(','.join(keyw)))) indent -= 4 fd.write('%s\n' % (' ' * indent)) def get_module_metadata(name): """ >>> get_module_metadata('g.region') ('Manages the boundary definitions for the geographic region.', ['general', 'settings']) >>> get_module_metadata('m.proj') ('Converts coordinates from one projection to another (cs2cs frontend).', ['miscellaneous', 'projection']) """ try: task = gtask.parse_interface(name) except: sys.stderr.write("Cannot parse interface for module %s. Empty strings" " will be placed instead of description and keywords." "\n" % name) return '', '' return task.get_description(full=True), \ task.get_keywords() def header(fd): fd.write('\n') fd.write('\n') fd.write( '\n' % sys.argv[0]) # g.version -r is crashing, commenting this block for now # vInfo = gcore.version() # fd.write('\n' % \ # (vInfo['version'].split('.')[0], # vInfo['revision'], # datetime.now())) fd.write('\n') def footer(fd): fd.write('\n') def doc_test(): """Tests the module using doctest :return: a number of failed tests """ import doctest do_doctest_gettext_workaround() return doctest.testmod().failed def module_test(): grass_commands = gcore.get_commands()[0] if not 'g.region' in grass_commands: print "No g.region" return 1 if not 'm.proj' in grass_commands: print "No m.proj" return 1 if not 't.rast.univar' in grass_commands: print "No t.rast.univar" return 1 print get_module_metadata('g.region') print get_module_metadata('m.proj') print get_module_metadata('t.rast.univar') def main(): fh = sys.stdout header(fh) parse_modules(fh) footer(fh) return 0 if __name__ == "__main__": if len(sys.argv) > 1: if sys.argv[1] == 'doctest': sys.exit(doc_test()) elif sys.argv[1] == 'test': sys.exit(module_test()) else: gcore.fatal('Unrecognized parameter.') sys.exit(main())