summaryrefslogtreecommitdiffstats
path: root/src/lib/Options.py
blob: 02815ba24c8cc848eb45476503e7c02cffe32e68 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
'''Option parsing library for utilities'''
__revision__ = '$Revision$'

import getopt, os, sys, ConfigParser
# (option, env, cfpath, default value, option desc, boolean, arg desc)
# ((option, arg desc, opt desc), env, cfpath, default, boolean)
bootstrap = {'configfile': (('-C', '<configfile>', 'Path to config file'), 
                             'BCFG2_CONF', False, '/etc/bcfg2.conf',  False)}

class OptionFailure(Exception):
    pass

class BasicOptionParser:
    '''Basic OptionParser takes input from command line arguments, environment variables, and defaults'''
    def __init__(self, name, optionspec, configfile=False, dogetopt=False):
        self.name = name
        self.dogetopt = dogetopt
        self.configfile = configfile
        self.optionspec = optionspec
        if dogetopt:
            self.shortopt = ''
            self.helpmsg = ''
            # longopts aren't yet supported
            self.longopt = []
            for option, info in optionspec.iteritems():
                (opt, argd, optd) = info[0]
                self.helpmsg += opt.ljust(3)
                if opt.count('-') == 1:
                    self.shortopt += opt[1]
                else:
                    print "unsupported option %s" % (opt)
                    continue
                if info[4]:
                    self.helpmsg += 24 * ' '
                else:
                    self.shortopt += ':'
                    self.helpmsg += "%-24s" % (argd)
                self.helpmsg += "%s\n" % (optd)

    def parse(self):
        '''Parse options'''
        ret = {}
        if self.dogetopt:
            try:
                opts, args = getopt.getopt(sys.argv[1:], self.shortopt, self.longopt)
            except getopt.GetoptError, err:
                print err
                print "%s Usage:" % (self.name)
                print self.helpmsg
                raise SystemExit, 1
            if '-h' in sys.argv:
                print "%s Usage:" % (self.name)
                print self.helpmsg
                raise SystemExit, 1
        if self.configfile:
            cf = ConfigParser.ConfigParser()
            cf.read(self.configfile)
        for key, (option, envvar, cfpath, default, boolean) in self.optionspec.iteritems():
            if self.dogetopt:
                optinfo = [opt[1] for opt in opts if opt[0] == option[0]]
                if optinfo:
                    if boolean:
                        ret[key] = True
                    else:
                        ret[key] = optinfo[0]
                    continue
            if option[0] in sys.argv:
                if boolean:
                    ret[key] = True
                else:
                    ret[key] = sys.argv[sys.argv.index(option[0]) + 1]
                continue
            if envvar and os.environ.has_key(envvar):
                ret[key] = os.environ[envvar]
                continue
            if self.configfile and cfpath:
                try:
                    value = apply(cf.get, cfpath)
                    ret[key] = value
                    continue
                except:
                    pass
            ret[key] = default
        return ret
    
class OptionParser(BasicOptionParser):
    '''OptionParser bootstraps option parsing, getting the value of the config file'''
    def __init__(self, name, ospec):
        # first find the cf file
        cfpath = BasicOptionParser('bootstrap', bootstrap).parse()['configfile']
        BasicOptionParser.__init__(self, name, ospec, cfpath, dogetopt=True)