changeset 2084:e1015a5df6f5

bridge(constructor): constructor now uses argparse instead of optparse
author Goffi <goffi@goffi.org>
date Sun, 02 Oct 2016 15:56:20 +0200
parents 7999d5299ddc
children da4097de5a95
files src/bridge/bridge_constructor/bridge_constructor.py
diffstat 1 files changed, 69 insertions(+), 69 deletions(-) [+]
line wrap: on
line diff
--- a/src/bridge/bridge_constructor/bridge_constructor.py	Sun Oct 02 15:51:42 2016 +0200
+++ b/src/bridge/bridge_constructor/bridge_constructor.py	Sun Oct 02 15:56:20 2016 +0200
@@ -1,7 +1,7 @@
 #!/usr/bin/env python2
 #-*- coding: utf-8 -*-
 
-# SAT: a jabber client
+# SàT: a XMPP client
 # Copyright (C) 2009-2016 Jérôme Poisson (goffi@goffi.org)
 
 # This program is free software: you can redistribute it and/or modify
@@ -17,36 +17,38 @@
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-#consts
-NAME = u"bridge_constructor"
-VERSION = "0.1.0"
-DEST_DIR = "generated"
-ABOUT = NAME + u""" v%s (c) Jérôme Poisson (aka Goffi) 2011
-
----
-""" + NAME + u""" Copyright (C) 2011  Jérôme Poisson (aka Goffi)
-This program comes with ABSOLUTELY NO WARRANTY;
-This is free software, and you are welcome to redistribute it
-under certain conditions.
----
-
-This script construct a SàT bridge using the given protocol
-"""
-MANAGED_PROTOCOLES = ['dbus', 'mediawiki', 'dbus-xml']
-DEFAULT_PROTOCOLE = 'dbus'
-FLAGS = ['deprecated', 'async']
-
-ENV_OVERRIDE = "SAT_BRIDGE_CONST_"  # Prefix used to override a constant
-
+from sat.core.constants import Const as C
 import sys
 import os
-from optparse import OptionParser
+import argparse
 from ConfigParser import SafeConfigParser as Parser
 from ConfigParser import NoOptionError
 import re
 from datetime import datetime
 from xml.dom import minidom
 
+#consts
+NAME = u"bridge_constructor"
+__version__ = C.APP_VERSION
+DEST_DIR_DEFAULT = "generated"
+DESCRIPTION = u"""{name} Copyright (C) 2009-2016 Jérôme Poisson (aka Goffi)
+
+This script construct a SàT bridge using the given protocol
+
+This program comes with ABSOLUTELY NO WARRANTY;
+This is free software, and you are welcome to redistribute it
+under certain conditions.
+""".format(name=NAME, version=__version__)
+# TODO: move protocoles in separate files (plugins?)
+MANAGED_PROTOCOLES = ['dbus', 'mediawiki', 'dbus-xml']
+DEFAULT_PROTOCOLE = 'dbus'
+
+# flags used method/signal declaration (not to be confused with constructor flags)
+DECLARATION_FLAGS = ['deprecated', 'async']
+
+ENV_OVERRIDE = "SAT_BRIDGE_CONST_"  # Prefix used to override a constant
+
+
 
 class ParseError(Exception):
     #Used when the signature parsing is going wrong (invalid signature ?)
@@ -57,7 +59,7 @@
 
     def __init__(self, bridge_template, options):
         self.bridge_template = bridge_template
-        self.options = options
+        self.args = options
 
     def getValues(self, name):
         """Return values of a function in a dict
@@ -96,7 +98,7 @@
         @return: List of flags (string)"""
         flags = []
         for option in self.bridge_template.options(name):
-            if option in FLAGS:
+            if option in DECLARATION_FLAGS:
                 flags.append(option)
         return flags
 
@@ -196,17 +198,19 @@
         raise NotImplementedError
 
     def finalWrite(self, filename, file_buf):
-        """Write the final generated file in DEST_DIR/filename
+        """Write the final generated file in [dest dir]/filename
+
         @param filename: name of the file to generate
-        @param file_buf: list of lines (stings) of the file"""
-        if os.path.exists(DEST_DIR) and not os.path.isdir(DEST_DIR):
+        @param file_buf: list of lines (stings) of the file
+        """
+        if os.path.exists(self.args.dest_dir) and not os.path.isdir(self.args.dest_dir):
             print ("The destination dir [%s] can't be created: a file with this name already exists !")
             sys.exit(1)
         try:
-            if not os.path.exists(DEST_DIR):
-                os.mkdir(DEST_DIR)
-            full_path = os.path.join(DEST_DIR, filename)
-            if os.path.exists(full_path) and not self.options.force:
+            if not os.path.exists(self.args.dest_dir):
+                os.mkdir(self.args.dest_dir)
+            full_path = os.path.join(self.args.dest_dir, filename)
+            if os.path.exists(full_path) and not self.args.force:
                 print ("The destination file [%s] already exists ! Use --force to overwrite it" % full_path)
             try:
                 with open(full_path, 'w') as dest_file:
@@ -373,7 +377,7 @@
                 'args': self.getArguments(function['sig_in'], name=arg_doc, default=default)}
 
             if function["type"] == "signal":
-                completion['body'] = "pass" if not self.options.debug else 'log.debug ("%s")' % section
+                completion['body'] = "pass" if not self.args.debug else 'log.debug ("%s")' % section
                 signals_part.append("""\
     @dbus.service.signal(const_INT_PREFIX+const_%(category)s_SUFFIX,
                          signature='%(sig_in)s')
@@ -386,8 +390,8 @@
 """ % completion)
 
             elif function["type"] == "method":
-                completion['debug'] = "" if not self.options.debug else 'log.debug ("%s")\n%s' % (section, 8 * ' ')
-                completion['args_result'] = self.getArguments(function['sig_in'], name=arg_doc, unicode_protect=self.options.unicode)
+                completion['debug'] = "" if not self.args.debug else 'log.debug ("%s")\n%s' % (section, 8 * ' ')
+                completion['args_result'] = self.getArguments(function['sig_in'], name=arg_doc, unicode_protect=self.args.unicode)
                 completion['async_comma'] = ', ' if async and function['sig_in'] else ''
                 completion['async_args_def'] = 'callback=None, errback=None' if async else ''
                 completion['async_args_call'] = 'callback=callback, errback=errback' if async else ''
@@ -448,7 +452,7 @@
 
             if function["type"] == "method":
                 # XXX: we can manage blocking call in the same way as async one: if callback is None the call will be blocking
-                completion['debug'] = "" if not self.options.debug else 'log.debug ("%s")\n%s' % (section, 8 * ' ')
+                completion['debug'] = "" if not self.args.debug else 'log.debug ("%s")\n%s' % (section, 8 * ' ')
                 completion['args_result'] = self.getArguments(function['sig_in'], name=arg_doc)
                 completion['async_args'] = 'callback=None, errback=None'
                 completion['async_comma'] = ', ' if function['sig_in'] else ''
@@ -472,7 +476,7 @@
         """
                     completion['async_args_result'] = '**kwargs'
                 result = "self.db_%(category)s_iface.%(name)s(%(args_result)s%(async_comma)s%(async_args_result)s)" % completion
-                completion['result'] = ("unicode(%s)" if self.options.unicode and function['sig_out'] == 's' else "%s") % result
+                completion['result'] = ("unicode(%s)" if self.args.unicode and function['sig_out'] == 's' else "%s") % result
                 methods_part.append("""\
     def %(name)s(self, %(args)s%(async_comma)s%(async_args)s):
         %(error_handler)s%(blocking_call)s%(debug)sreturn %(result)s
@@ -547,7 +551,7 @@
                 _direction = 'in' if function["type"] == 'method' else 'out'
                 arg_elt.setAttribute('direction', _direction)
                 new_elt.appendChild(arg_elt)
-                if "annotation" in self.options.flags:
+                if "annotation" in self.args.flags:
                     if arg in self.default_annotation:
                         annot_elt = doc.createElement("annotation")
                         annot_elt.setAttribute('name', "com.trolltech.QtDBus.QtTypeName.In%d" % idx)
@@ -560,7 +564,7 @@
                 arg_elt.setAttribute('type', function['sig_out'])
                 arg_elt.setAttribute('direction', 'out')
                 new_elt.appendChild(arg_elt)
-                if "annotation" in self.options.flags:
+                if "annotation" in self.args.flags:
                     if function['sig_out'] in self.default_annotation:
                         annot_elt = doc.createElement("annotation")
                         annot_elt.setAttribute('name', "com.trolltech.QtDBus.QtTypeName.Out0")
@@ -591,48 +595,44 @@
 
 class BridgeConstructor(object):
     def __init__(self):
-        self.options = None
+        self.args = None
 
-    def check_options(self):
+    def parse_args(self):
         """Check command line options"""
-        _usage = """
-        %prog [options]
-
-        %prog --help for options list
-        """
-        parser = OptionParser(usage=_usage, version=ABOUT % VERSION)
+        parser = argparse.ArgumentParser(description=DESCRIPTION, formatter_class=argparse.RawDescriptionHelpFormatter)
 
-        parser.add_option("-p", "--protocole", action="store", type="string", default=DEFAULT_PROTOCOLE,
-                          help="Generate bridge using PROTOCOLE (default: %s, possible values: [%s])" % (DEFAULT_PROTOCOLE, ", ".join(MANAGED_PROTOCOLES)))
-        parser.add_option("-s", "--side", action="store", type="string", default="core",
-                          help="Which side of the bridge do you want to make ? (default: %default, possible values: [core, frontend])")
-        parser.add_option("-t", "--template", action="store", type="string", default='bridge_template.ini',
-                          help="Use TEMPLATE to generate bridge (default: %default)")
-        parser.add_option("-f", "--force", action="store_true", default=False,
-                          help=("Force overwritting of existing files"))
-        parser.add_option("-d", "--debug", action="store_true", default=False,
-                          help=("Add debug information printing"))
-        parser.add_option("--no_unicode", action="store_false", dest="unicode", default=True,
-                          help=("Remove unicode type protection from string results"))
-        parser.add_option("--flags", action="store", type="string",
-                          help=("Constructors' specific flags, comma separated"))
+        parser.add_argument("--version", action="version", version= __version__)
+        parser.add_argument("-p", "--protocole", choices=MANAGED_PROTOCOLES, default=DEFAULT_PROTOCOLE,
+            help="generate bridge using PROTOCOLE (default: %(default)s)") # (default: %s, possible values: [%s])" % (DEFAULT_PROTOCOLE, ", ".join(MANAGED_PROTOCOLES)))
+        parser.add_argument("-s", "--side", choices=("core", "frontend"), default="core",
+            help="which side of the bridge do you want to make ?") # (default: %default, possible values: [core, frontend])")
+        parser.add_argument("-t", "--template", type=file, default='bridge_template.ini',
+            help="use TEMPLATE to generate bridge (default: %(default)s)")
+        parser.add_argument("-f", "--force", action="store_true",
+            help=("force overwritting of existing files"))
+        parser.add_argument("-d", "--debug", action="store_true",
+            help=("add debug information printing"))
+        parser.add_argument("--no-unicode", action="store_false", dest="unicode",
+            help=("remove unicode type protection from string results"))
+        parser.add_argument("--flags", nargs='+', default=[],
+            help=("constructors' specific flags"))
+        parser.add_argument("--dest-dir", default=DEST_DIR_DEFAULT,
+            help=("directory when the generated files will be written (default: %(default)s"))
 
-        (self.options, args) = parser.parse_args()
-        self.options.flags = self.options.flags.split(',') if self.options.flags else []
-        return args
+        return parser.parse_args()
 
     def go(self):
-        self.check_options()
+        args = self.parse_args()
         self.template = Parser()
         try:
-            self.template.readfp(open(self.options.template))
+            self.template.readfp(args.template)
         except IOError:
             print ("The template file doesn't exist or is not accessible")
             exit(1)
-        constructor = ConstructorFactory().create(self.template, self.options)
-        if self.options.side == "core":
+        constructor = ConstructorFactory().create(self.template, args)
+        if args.side == "core":
             constructor.generateCoreSide()
-        elif self.options.side == "frontend":
+        elif args.side == "frontend":
             constructor.generateFrontendSide()
 
 if __name__ == "__main__":