changeset 19:9db5f8eddb0d

Proper {{{optparse}}}-based command-line interface for master and slave.
author cmlenz
date Fri, 17 Jun 2005 11:23:22 +0000
parents 591a5a836ecc
children c668a9386194
files bitten/__init__.py bitten/master.py bitten/slave.py setup.py
diffstat 4 files changed, 73 insertions(+), 69 deletions(-) [+]
line wrap: on
line diff
--- a/bitten/__init__.py
+++ b/bitten/__init__.py
@@ -18,5 +18,7 @@
 #
 # Author: Christopher Lenz <cmlenz@gmx.de>
 
+__version__ = '0.1'
+
 class BuildError(Exception):
     pass
--- a/bitten/master.py
+++ b/bitten/master.py
@@ -18,14 +18,13 @@
 #
 # Author: Christopher Lenz <cmlenz@gmx.de>
 
-import getopt
 import logging
 import os.path
-import sys
 import time
 
 from trac.env import Environment
 
+from bitten import __version__ as VERSION
 from bitten.util import beep
 from bitten.util.xmlio import Element, parse_xml
 
@@ -36,7 +35,7 @@
 
     def __init__(self, env_path, ip, port):
         beep.Listener.__init__(self, ip, port)
-        self.profiles[BittenProfileHandler.URI] = BittenProfileHandler()
+        self.profiles[OrchestrationProfileHandler.URI] = OrchestrationProfileHandler()
 
         self.env = Environment(env_path)
         self.youngest_rev = None
@@ -56,8 +55,11 @@
         self.schedule(self.TRIGGER_INTERVAL, self.check_trigger)
 
 
-class BittenProfileHandler(beep.ProfileHandler):
-    URI = 'http://bitten.cmlenz.net/beep-profile/'
+class OrchestrationProfileHandler(beep.ProfileHandler):
+    """Handler for communication on the Bitten build orchestration profile from
+    the perspective of the build master.
+    """
+    URI = 'http://bitten.cmlenz.net/beep/orchestration'
 
     def handle_connect(self):
         self.master = self.session.listener
@@ -86,37 +88,43 @@
 
 
 if __name__ == '__main__':
-    options, args = getopt.getopt(sys.argv[1:], 'p:dvq',
-                                  ['port=', 'debug', 'verbose', 'quiet'])
+    from optparse import OptionParser
+
+    parser = OptionParser(usage='usage: %prog [options] env-path',
+                          version='%%prog %s' % VERSION)
+    parser.add_option('-p', '--port', action='store', type='int', dest='port',
+                      help='port number to use')
+    parser.add_option('-H', '--host', action='store', dest='host',
+                      help='the host name of IP address to bind to')
+    parser.add_option('--debug', action='store_const', dest='loglevel',
+                      const=logging.DEBUG, help='enable debugging output')
+    parser.add_option('-v', '--verbose', action='store_const', dest='loglevel',
+                      const=logging.INFO, help='print as much as possible')
+    parser.add_option('-q', '--quiet', action='store_const', dest='loglevel',
+                      const=logging.ERROR, help='print as little as possible')
+    parser.set_defaults(port=7633, loglevel=logging.WARNING)
+    options, args = parser.parse_args()
+    
     if len(args) < 1:
-        print>>sys.stderr, 'usage: %s [options] ENV_PATH' \
-                           % os.path.basename(sys.argv[0])
-        print>>sys.stderr
-        print>>sys.stderr, 'Valid options:'
-        print>>sys.stderr, '  -p [--port] arg\tport number to use (default: 7633)'
-        print>>sys.stderr, '  -q [--quiet]\tprint as little as possible'
-        print>>sys.stderr, '  -v [--verbose]\tprint as much as possible'
-        sys.exit(2)
+        parser.error('incorrect number of arguments')
     env_path = args[0]
 
-    port = 7633
-    loglevel = logging.WARNING
-    for opt, arg in options:
-        if opt in ('-p', '--port'):
-            try:
-                port = int(arg)
-            except ValueError:
-                print>>sys.stderr, 'Port must be an integer'
-                sys.exit(2)
-        elif opt in ('-d', '--debug'):
-            loglevel = logging.DEBUG
-        elif opt in ('-v', '--verbose'):
-            loglevel = logging.INFO
-        elif opt in ('-q', '--quiet'):
-            loglevel = logging.ERROR
-    logging.getLogger().setLevel(loglevel)
+    logging.getLogger().setLevel(options.loglevel)
+    port = options.port
+    if not (1 <= port <= 65535):
+        parser.error('port must be an integer in the range 1-65535')
 
-    master = Master(env_path, 'localhost', port)
+    host = options.host
+    if not host:
+        import socket
+        ip = socket.gethostbyname(socket.gethostname())
+        try:
+            host = socket.gethostbyaddr(ip)[0]
+        except socket.error, e:
+            logging.warning('Reverse host name lookup failed (%s)', e)
+            host = ip
+
+    master = Master(env_path, host, port)
     try:
         master.run()
     except KeyboardInterrupt:
--- a/bitten/slave.py
+++ b/bitten/slave.py
@@ -18,12 +18,12 @@
 #
 # Author: Christopher Lenz <cmlenz@gmx.de>
 
-import getopt
 import logging
 import os
 import sys
 import time
 
+from bitten import __version__ as VERSION
 from bitten.util import beep
 from bitten.util.xmlio import Element, parse_xml
 
@@ -34,21 +34,22 @@
     terminated = False
 
     def channel_started(self, channelno, profile_uri):
-        if profile_uri == BittenProfileHandler.URI:
+        if profile_uri == OrchestrationProfileHandler.URI:
             self.channelno = channelno
 
     def greeting_received(self, profiles):
-        if BittenProfileHandler.URI not in profiles:
+        if OrchestrationProfileHandler.URI not in profiles:
             logging.error('Peer does not support Bitten profile')
             raise beep.TerminateSession, 'Peer does not support Bitten profile'
-        self.channels[0].profile.send_start([BittenProfileHandler],
+        self.channels[0].profile.send_start([OrchestrationProfileHandler],
                                             handle_ok=self.channel_started)
 
 
-class BittenProfileHandler(beep.ProfileHandler):
-    """Handles communication on the Bitten profile from the client perspective.
+class OrchestrationProfileHandler(beep.ProfileHandler):
+    """Handler for communication on the Bitten build orchestration profile from
+    the perspective of the build slave.
     """
-    URI = 'http://bitten.cmlenz.net/beep-profile/'
+    URI = 'http://bitten.cmlenz.net/beep/orchestration'
 
     def handle_connect(self):
         """Register with the build master."""
@@ -71,45 +72,37 @@
                               handle_reply)
 
     def handle_msg(self, msgno, msg):
-        # TODO: Handle build initiation requests
+        # TODO: Handle build initiation requests etc
         pass
 
 
 if __name__ == '__main__':
-    options, args = getopt.getopt(sys.argv[1:], 'dvq',
-                                  ['debug', 'verbose', 'quiet'])
+    from optparse import OptionParser
+
+    parser = OptionParser(usage='usage: %prog [options] host [port]',
+                          version='%%prog %s' % VERSION)
+    parser.add_option('--debug', action='store_const', dest='loglevel',
+                      const=logging.DEBUG, help='enable debugging output')
+    parser.add_option('-v', '--verbose', action='store_const', dest='loglevel',
+                      const=logging.INFO, help='print as much as possible')
+    parser.add_option('-q', '--quiet', action='store_const', dest='loglevel',
+                      const=logging.ERROR, help='print as little as possible')
+    parser.set_defaults(loglevel=logging.WARNING)
+    options, args = parser.parse_args()
+
     if len(args) < 1:
-        print>>sys.stderr, 'Usage: %s [options] host [port]' % sys.argv[0]
-        print>>sys.stderr
-        print>>sys.stderr, 'Valid options:'
-        print>>sys.stderr, '  -d [--debug]\tenable debugging output'
-        print>>sys.stderr, '  -q [--quiet]\tprint as little as possible'
-        print>>sys.stderr, '  -v [--verbose]\tprint as much as possible'
-        sys.exit(2)
-
+        parser.error('incorrect number of arguments')
     host = args[0]
     if len(args) > 1:
         try:
             port = int(args[1])
-        except ValueError:
-            print>>sys.stderr, 'Port must be an integer'
-            sys.exit(2)
+            assert (1 <= port <= 65535), 'port number out of range'
+        except AssertionError, ValueError:
+            parser.error('port must be an integer in the range 1-65535')
     else:
         port = 7633
 
-    loglevel = logging.WARNING
-    for opt, arg in options:
-        if opt in ('-d', '--debug'):
-            loglevel = logging.DEBUG
-        elif opt in ('-v', '--verbose'):
-            loglevel = logging.INFO
-        elif opt in ('-q', '--quiet'):
-            loglevel = logging.ERROR
-    logger = logging.getLogger()
-    logger.setLevel(loglevel)
+    logging.getLogger().setLevel(options.loglevel)
 
     slave = Slave(host, port)
-    try:
-        slave.run()
-    except beep.TerminateSession, e:
-        print>>sys.stderr, 'Session terminated:', e
+    slave.run()
--- a/setup.py
+++ b/setup.py
@@ -21,9 +21,10 @@
 
 from distutils.core import setup
 
+from bitten import __version__ as VERSION
 from bitten.setuptools.testrunner import unittest
 
-setup(name='bitten', version='1.0',
-      packages=['bitten', 'bitten.distutils', 'bitten.recipe', 'bitten.util'],
+setup(name='bitten', version=VERSION,
+      packages=['bitten', 'bitten.recipe', 'bitten.setuptools', 'bitten.util'],
       author="Christopher Lenz", author_email="cmlenz@gmx.de",
       url="http://bitten.cmlenz.net/", cmdclass={'unittest': unittest})
Copyright (C) 2012-2017 Edgewall Software