#!/usr/bin/python3 import argparse, os, urllib.request, ast, sys from io import StringIO from string import Template parser = argparse.ArgumentParser(description='Extract ODM strings.') parser.add_argument('input', type=str, help='URL to ODM\'s config.py') parser.add_argument('template', type=str, help='Template rst to use') parser.add_argument('output', type=str, help='Where to write resulting rst file') args = parser.parse_args() url = args.input outfile = args.output tmplfile = args.template strings = [] print("Fetching %s ..." % url) res = urllib.request.urlopen(url) config_file = res.read().decode('utf-8') # config_file = open("test.py").read() options = {} args_map = {} class ArgumentParserStub(argparse.ArgumentParser): def add_argument(self, *args, **kwargs): argparse.ArgumentParser.add_argument(self, *args, **kwargs) options[args[0]] = {} args_map[args[0]] = args[1:] for name, value in kwargs.items(): options[args[0]][str(name)] = str(value) def add_mutually_exclusive_group(self): return ArgumentParserStub() # Voodoo! :) # ( parse AST, extract "def config()" function, set module to only # contain that function, execute module in current scope, # run config function) root = ast.parse(config_file) new_body = [] for stmt in root.body: # Assignments if hasattr(stmt, 'targets'): new_body.append(stmt) # Functions elif hasattr(stmt, 'name'): new_body.append(stmt) root.body = new_body exec(compile(root, filename="", mode="exec")) # Misc variables needed to get config to run __version__ = '?' class context: root_path = '' num_cores = 4 class io: def path_or_json_string_to_dict(s): return s def path_or_json_string(s): return s class log: def ODM_ERROR(s): pass config(["--project-path", "/bogus", "name"], parser=ArgumentParserStub()) for opt in options: h = options[opt].get('help') if h: h = h.replace("\n", "") h = h.replace('%(default)s', ('``' + options[opt].get('default', '') + '``').replace('````', '``')) h = h.replace("Can be one of: %(choices)s", "") h = h.replace('%(choices)s', options[opt].get('choices', '')) options[opt]['help'] = h else: options[opt]['help'] = '' print("Found %s ODM options" % len(options)) if len(options) > 0: subst = "" keys = list(options.keys()) keys.sort(key=lambda a: a.replace("-", "")) for opt in keys: subst += "``%s%s`` %s\n %s\n\n" % ( opt, "," + ",".join(args_map[opt]) if len(args_map[opt]) > 0 else "", options[opt].get('choices', options[opt].get('metavar', '')).replace('[', '').replace(']', '').replace(',', ' | ').replace('\'', ''), options[opt].get('help', '') ) with open(tmplfile) as f: tmpl = Template(f.read()) with open(outfile, "w") as f: f.write(tmpl.substitute(arguments=subst)) print("Wrote %s" % outfile) else: print("No strings found")