pvl/args.py
author Tero Marttila <terom@paivola.fi>
Fri, 27 Dec 2013 00:35:10 +0200
changeset 28 69e1b91cd83f
parent 27 62159e5b6685
child 29 8fcb140f1ee0
permissions -rw-r--r--
pvl.args: support multiple --config's
1
ce931075b69e import pvl.args,invoke from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     1
"""
ce931075b69e import pvl.args,invoke from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     2
    CLI argument handling; common stuff: logging
ce931075b69e import pvl.args,invoke from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     3
"""
ce931075b69e import pvl.args,invoke from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     4
15
e699ed00fcf1 pvl.args: apply_file(path) and main(main)
Tero Marttila <terom@paivola.fi>
parents: 10
diff changeset
     5
import codecs
e699ed00fcf1 pvl.args: apply_file(path) and main(main)
Tero Marttila <terom@paivola.fi>
parents: 10
diff changeset
     6
import grp
1
ce931075b69e import pvl.args,invoke from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     7
import logging
15
e699ed00fcf1 pvl.args: apply_file(path) and main(main)
Tero Marttila <terom@paivola.fi>
parents: 10
diff changeset
     8
import optparse
e699ed00fcf1 pvl.args: apply_file(path) and main(main)
Tero Marttila <terom@paivola.fi>
parents: 10
diff changeset
     9
import os
e699ed00fcf1 pvl.args: apply_file(path) and main(main)
Tero Marttila <terom@paivola.fi>
parents: 10
diff changeset
    10
import pwd
e699ed00fcf1 pvl.args: apply_file(path) and main(main)
Tero Marttila <terom@paivola.fi>
parents: 10
diff changeset
    11
import sys
1
ce931075b69e import pvl.args,invoke from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    12
ce931075b69e import pvl.args,invoke from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    13
import logging; log = logging.getLogger('pvl.args')
ce931075b69e import pvl.args,invoke from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    14
9
5e9290c55d77 pvl.args: make setuid options optional
Tero Marttila <terom@paivola.fi>
parents: 1
diff changeset
    15
def parser (parser, setuid=None) :
1
ce931075b69e import pvl.args,invoke from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    16
    """
ce931075b69e import pvl.args,invoke from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    17
        Return an optparse.OptionGroup.
ce931075b69e import pvl.args,invoke from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    18
    """
ce931075b69e import pvl.args,invoke from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    19
9
5e9290c55d77 pvl.args: make setuid options optional
Tero Marttila <terom@paivola.fi>
parents: 1
diff changeset
    20
    if setuid is None :
5e9290c55d77 pvl.args: make setuid options optional
Tero Marttila <terom@paivola.fi>
parents: 1
diff changeset
    21
        # autodetect: only if we will be capable of
5e9290c55d77 pvl.args: make setuid options optional
Tero Marttila <terom@paivola.fi>
parents: 1
diff changeset
    22
        # XXX: use linux capabilities?
5e9290c55d77 pvl.args: make setuid options optional
Tero Marttila <terom@paivola.fi>
parents: 1
diff changeset
    23
        setuid = (os.geteuid() == 0)
5e9290c55d77 pvl.args: make setuid options optional
Tero Marttila <terom@paivola.fi>
parents: 1
diff changeset
    24
1
ce931075b69e import pvl.args,invoke from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    25
    general = optparse.OptionGroup(parser, "General options")
ce931075b69e import pvl.args,invoke from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    26
ce931075b69e import pvl.args,invoke from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    27
    general.add_option('-q', '--quiet',     dest='loglevel', action='store_const', const=logging.ERROR, help="Less output")
ce931075b69e import pvl.args,invoke from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    28
    general.add_option('-v', '--verbose',   dest='loglevel', action='store_const', const=logging.INFO,  help="More output")
ce931075b69e import pvl.args,invoke from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    29
    general.add_option('-D', '--debug',     dest='loglevel', action='store_const', const=logging.DEBUG, help="Even more output")
ce931075b69e import pvl.args,invoke from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    30
    general.add_option('--log-file',                                                                    help="Log to file")
ce931075b69e import pvl.args,invoke from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    31
    general.add_option('--debug-module',    action='append', metavar='MODULE', 
ce931075b69e import pvl.args,invoke from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    32
            help="Enable logging for the given logger/module name")
25
538c02bd95e0 pvl.args: new --config option, used by pvl.args.parse(...)
Tero Marttila <terom@paivola.fi>
parents: 22
diff changeset
    33
28
69e1b91cd83f pvl.args: support multiple --config's
Tero Marttila <terom@paivola.fi>
parents: 27
diff changeset
    34
    parser.add_option('-c', '--config',    metavar='PATH',      action='append',
25
538c02bd95e0 pvl.args: new --config option, used by pvl.args.parse(...)
Tero Marttila <terom@paivola.fi>
parents: 22
diff changeset
    35
            help="Read option defaults from config")
538c02bd95e0 pvl.args: new --config option, used by pvl.args.parse(...)
Tero Marttila <terom@paivola.fi>
parents: 22
diff changeset
    36
    parser.add_option('--config-encoding',  metavar='CHARSET',  default='utf-8',
538c02bd95e0 pvl.args: new --config option, used by pvl.args.parse(...)
Tero Marttila <terom@paivola.fi>
parents: 22
diff changeset
    37
            help="Unicode decoding for config file")
538c02bd95e0 pvl.args: new --config option, used by pvl.args.parse(...)
Tero Marttila <terom@paivola.fi>
parents: 22
diff changeset
    38
538c02bd95e0 pvl.args: new --config option, used by pvl.args.parse(...)
Tero Marttila <terom@paivola.fi>
parents: 22
diff changeset
    39
   
9
5e9290c55d77 pvl.args: make setuid options optional
Tero Marttila <terom@paivola.fi>
parents: 1
diff changeset
    40
    if setuid :
5e9290c55d77 pvl.args: make setuid options optional
Tero Marttila <terom@paivola.fi>
parents: 1
diff changeset
    41
        general.add_option('--uid',             help="Change uid")
5e9290c55d77 pvl.args: make setuid options optional
Tero Marttila <terom@paivola.fi>
parents: 1
diff changeset
    42
        general.add_option('--gid',             help="Change gid")
1
ce931075b69e import pvl.args,invoke from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    43
ce931075b69e import pvl.args,invoke from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    44
    # defaults
ce931075b69e import pvl.args,invoke from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    45
    parser.set_defaults(
25
538c02bd95e0 pvl.args: new --config option, used by pvl.args.parse(...)
Tero Marttila <terom@paivola.fi>
parents: 22
diff changeset
    46
        setuid              = setuid,
1
ce931075b69e import pvl.args,invoke from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    47
        logname             = parser.prog,
ce931075b69e import pvl.args,invoke from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    48
        loglevel            = logging.WARN,
ce931075b69e import pvl.args,invoke from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    49
        debug_module        = [],
28
69e1b91cd83f pvl.args: support multiple --config's
Tero Marttila <terom@paivola.fi>
parents: 27
diff changeset
    50
        config              = [],
1
ce931075b69e import pvl.args,invoke from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    51
    )
ce931075b69e import pvl.args,invoke from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    52
 
ce931075b69e import pvl.args,invoke from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    53
    return general
ce931075b69e import pvl.args,invoke from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    54
ce931075b69e import pvl.args,invoke from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    55
def options (**options) :
ce931075b69e import pvl.args,invoke from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    56
    """
ce931075b69e import pvl.args,invoke from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    57
        Synthensise options.
ce931075b69e import pvl.args,invoke from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    58
    """
ce931075b69e import pvl.args,invoke from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    59
ce931075b69e import pvl.args,invoke from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    60
    return optparse.Values(options)
ce931075b69e import pvl.args,invoke from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    61
ce931075b69e import pvl.args,invoke from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    62
def apply_setid (options, rootok=None) :
ce931075b69e import pvl.args,invoke from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    63
    """
ce931075b69e import pvl.args,invoke from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    64
        Drop privileges if running as root.
ce931075b69e import pvl.args,invoke from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    65
ce931075b69e import pvl.args,invoke from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    66
        XXX: this feature isn't very useful (import-time issues etc), but in certain cases (syslog-ng -> python),
ce931075b69e import pvl.args,invoke from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    67
        it's difficult to avoid this without some extra wrapper tool..?
ce931075b69e import pvl.args,invoke from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    68
    """
ce931075b69e import pvl.args,invoke from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    69
ce931075b69e import pvl.args,invoke from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    70
    # --uid -> pw
ce931075b69e import pvl.args,invoke from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    71
    if not options.uid :
ce931075b69e import pvl.args,invoke from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    72
        pw = None
ce931075b69e import pvl.args,invoke from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    73
    elif options.uid.isdigit() :
ce931075b69e import pvl.args,invoke from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    74
        pw = pwd.getpwuid(int(options.uid))
ce931075b69e import pvl.args,invoke from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    75
    else :
ce931075b69e import pvl.args,invoke from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    76
        pw = pwd.getpwnam(options.uid)
ce931075b69e import pvl.args,invoke from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    77
ce931075b69e import pvl.args,invoke from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    78
    # --gid -> gr
ce931075b69e import pvl.args,invoke from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    79
    if not options.gid and not pw :
ce931075b69e import pvl.args,invoke from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    80
        gr = None
ce931075b69e import pvl.args,invoke from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    81
    elif not options.gid :
ce931075b69e import pvl.args,invoke from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    82
        gr = grp.getgrgid(pw.pw_gid)
ce931075b69e import pvl.args,invoke from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    83
    elif options.gid.isdigit() :
ce931075b69e import pvl.args,invoke from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    84
        gr = grp.getgrgid(str(options.gid))
ce931075b69e import pvl.args,invoke from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    85
    else :
ce931075b69e import pvl.args,invoke from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    86
        gr = grp.getgrnam(options.gid)
ce931075b69e import pvl.args,invoke from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    87
    
ce931075b69e import pvl.args,invoke from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    88
    if gr :
ce931075b69e import pvl.args,invoke from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    89
        # XXX: secondary groups? seem to get cleared
ce931075b69e import pvl.args,invoke from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    90
        log.info("setgid: %s: %s", gr.gr_name, gr.gr_gid)
ce931075b69e import pvl.args,invoke from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    91
        os.setgid(gr.gr_gid)
ce931075b69e import pvl.args,invoke from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    92
ce931075b69e import pvl.args,invoke from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    93
    if pw :
ce931075b69e import pvl.args,invoke from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    94
        log.info("setuid: %s: %s", pw.pw_name, pw.pw_uid)
ce931075b69e import pvl.args,invoke from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    95
        os.setuid(pw.pw_uid)
ce931075b69e import pvl.args,invoke from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    96
    
ce931075b69e import pvl.args,invoke from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    97
    elif os.getuid() == 0 :
ce931075b69e import pvl.args,invoke from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    98
        if rootok :
ce931075b69e import pvl.args,invoke from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    99
            log.info("running as root")
ce931075b69e import pvl.args,invoke from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   100
        else :
ce931075b69e import pvl.args,invoke from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   101
            log.error("refusing to run as root, use --uid 0 to override")
ce931075b69e import pvl.args,invoke from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   102
            sys.exit(2)
ce931075b69e import pvl.args,invoke from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   103
22
3e93880d3a40 pvl.args: apply_file: default to no unicode..
Tero Marttila <terom@paivola.fi>
parents: 21
diff changeset
   104
def apply_file (path=None, mode='r', charset=None) :
15
e699ed00fcf1 pvl.args: apply_file(path) and main(main)
Tero Marttila <terom@paivola.fi>
parents: 10
diff changeset
   105
    """
22
3e93880d3a40 pvl.args: apply_file: default to no unicode..
Tero Marttila <terom@paivola.fi>
parents: 21
diff changeset
   106
        Open (unicode-enabled) file from path, with - using stdio.
15
e699ed00fcf1 pvl.args: apply_file(path) and main(main)
Tero Marttila <terom@paivola.fi>
parents: 10
diff changeset
   107
    """
e699ed00fcf1 pvl.args: apply_file(path) and main(main)
Tero Marttila <terom@paivola.fi>
parents: 10
diff changeset
   108
21
559a6ce73f40 pvl.args.apply_file: support -
Tero Marttila <terom@paivola.fi>
parents: 19
diff changeset
   109
    if not path or path == '-' :
15
e699ed00fcf1 pvl.args: apply_file(path) and main(main)
Tero Marttila <terom@paivola.fi>
parents: 10
diff changeset
   110
        # use stdin/out based on mode
e699ed00fcf1 pvl.args: apply_file(path) and main(main)
Tero Marttila <terom@paivola.fi>
parents: 10
diff changeset
   111
        stream, func = {
e699ed00fcf1 pvl.args: apply_file(path) and main(main)
Tero Marttila <terom@paivola.fi>
parents: 10
diff changeset
   112
            'r':    (sys.stdin, codecs.getreader),
e699ed00fcf1 pvl.args: apply_file(path) and main(main)
Tero Marttila <terom@paivola.fi>
parents: 10
diff changeset
   113
            'w':    (sys.stdout, codecs.getwriter),
e699ed00fcf1 pvl.args: apply_file(path) and main(main)
Tero Marttila <terom@paivola.fi>
parents: 10
diff changeset
   114
        }[mode[0]]
e699ed00fcf1 pvl.args: apply_file(path) and main(main)
Tero Marttila <terom@paivola.fi>
parents: 10
diff changeset
   115
22
3e93880d3a40 pvl.args: apply_file: default to no unicode..
Tero Marttila <terom@paivola.fi>
parents: 21
diff changeset
   116
        if charset :
3e93880d3a40 pvl.args: apply_file: default to no unicode..
Tero Marttila <terom@paivola.fi>
parents: 21
diff changeset
   117
            return func(charset)(stream)
3e93880d3a40 pvl.args: apply_file: default to no unicode..
Tero Marttila <terom@paivola.fi>
parents: 21
diff changeset
   118
        else :
3e93880d3a40 pvl.args: apply_file: default to no unicode..
Tero Marttila <terom@paivola.fi>
parents: 21
diff changeset
   119
            return stream
15
e699ed00fcf1 pvl.args: apply_file(path) and main(main)
Tero Marttila <terom@paivola.fi>
parents: 10
diff changeset
   120
e699ed00fcf1 pvl.args: apply_file(path) and main(main)
Tero Marttila <terom@paivola.fi>
parents: 10
diff changeset
   121
    else :
22
3e93880d3a40 pvl.args: apply_file: default to no unicode..
Tero Marttila <terom@paivola.fi>
parents: 21
diff changeset
   122
        if charset :
3e93880d3a40 pvl.args: apply_file: default to no unicode..
Tero Marttila <terom@paivola.fi>
parents: 21
diff changeset
   123
            return codecs.open(path, mode, charset)
3e93880d3a40 pvl.args: apply_file: default to no unicode..
Tero Marttila <terom@paivola.fi>
parents: 21
diff changeset
   124
        else :
3e93880d3a40 pvl.args: apply_file: default to no unicode..
Tero Marttila <terom@paivola.fi>
parents: 21
diff changeset
   125
            return open(path, mode)
15
e699ed00fcf1 pvl.args: apply_file(path) and main(main)
Tero Marttila <terom@paivola.fi>
parents: 10
diff changeset
   126
e699ed00fcf1 pvl.args: apply_file(path) and main(main)
Tero Marttila <terom@paivola.fi>
parents: 10
diff changeset
   127
def apply_files (paths, *args, **opts) :
e699ed00fcf1 pvl.args: apply_file(path) and main(main)
Tero Marttila <terom@paivola.fi>
parents: 10
diff changeset
   128
    """
e699ed00fcf1 pvl.args: apply_file(path) and main(main)
Tero Marttila <terom@paivola.fi>
parents: 10
diff changeset
   129
        Open one or more files from given paths, defaulting to stdio.
e699ed00fcf1 pvl.args: apply_file(path) and main(main)
Tero Marttila <terom@paivola.fi>
parents: 10
diff changeset
   130
    """
e699ed00fcf1 pvl.args: apply_file(path) and main(main)
Tero Marttila <terom@paivola.fi>
parents: 10
diff changeset
   131
e699ed00fcf1 pvl.args: apply_file(path) and main(main)
Tero Marttila <terom@paivola.fi>
parents: 10
diff changeset
   132
    if paths :
e699ed00fcf1 pvl.args: apply_file(path) and main(main)
Tero Marttila <terom@paivola.fi>
parents: 10
diff changeset
   133
        return [apply_file(path, *args, **opts) for path in paths]
e699ed00fcf1 pvl.args: apply_file(path) and main(main)
Tero Marttila <terom@paivola.fi>
parents: 10
diff changeset
   134
    else:
e699ed00fcf1 pvl.args: apply_file(path) and main(main)
Tero Marttila <terom@paivola.fi>
parents: 10
diff changeset
   135
        return [apply_file(None, *args, **opts)]
e699ed00fcf1 pvl.args: apply_file(path) and main(main)
Tero Marttila <terom@paivola.fi>
parents: 10
diff changeset
   136
25
538c02bd95e0 pvl.args: new --config option, used by pvl.args.parse(...)
Tero Marttila <terom@paivola.fi>
parents: 22
diff changeset
   137
import configobj
538c02bd95e0 pvl.args: new --config option, used by pvl.args.parse(...)
Tero Marttila <terom@paivola.fi>
parents: 22
diff changeset
   138
import copy
538c02bd95e0 pvl.args: new --config option, used by pvl.args.parse(...)
Tero Marttila <terom@paivola.fi>
parents: 22
diff changeset
   139
import optparse
538c02bd95e0 pvl.args: new --config option, used by pvl.args.parse(...)
Tero Marttila <terom@paivola.fi>
parents: 22
diff changeset
   140
538c02bd95e0 pvl.args: new --config option, used by pvl.args.parse(...)
Tero Marttila <terom@paivola.fi>
parents: 22
diff changeset
   141
class Options (object) :
538c02bd95e0 pvl.args: new --config option, used by pvl.args.parse(...)
Tero Marttila <terom@paivola.fi>
parents: 22
diff changeset
   142
    """
538c02bd95e0 pvl.args: new --config option, used by pvl.args.parse(...)
Tero Marttila <terom@paivola.fi>
parents: 22
diff changeset
   143
        Custom optparse.Values implementation.
538c02bd95e0 pvl.args: new --config option, used by pvl.args.parse(...)
Tero Marttila <terom@paivola.fi>
parents: 22
diff changeset
   144
538c02bd95e0 pvl.args: new --config option, used by pvl.args.parse(...)
Tero Marttila <terom@paivola.fi>
parents: 22
diff changeset
   145
        Passed to OptionParser.parse_args(), called by Option.take_action():
538c02bd95e0 pvl.args: new --config option, used by pvl.args.parse(...)
Tero Marttila <terom@paivola.fi>
parents: 22
diff changeset
   146
            setattr(values, dest, ...)
538c02bd95e0 pvl.args: new --config option, used by pvl.args.parse(...)
Tero Marttila <terom@paivola.fi>
parents: 22
diff changeset
   147
            values.ensure_value(dest, ...)
538c02bd95e0 pvl.args: new --config option, used by pvl.args.parse(...)
Tero Marttila <terom@paivola.fi>
parents: 22
diff changeset
   148
    """
538c02bd95e0 pvl.args: new --config option, used by pvl.args.parse(...)
Tero Marttila <terom@paivola.fi>
parents: 22
diff changeset
   149
28
69e1b91cd83f pvl.args: support multiple --config's
Tero Marttila <terom@paivola.fi>
parents: 27
diff changeset
   150
    def __init__ (self, parser, defaults={ }) :
69e1b91cd83f pvl.args: support multiple --config's
Tero Marttila <terom@paivola.fi>
parents: 27
diff changeset
   151
        self._parser    = parser
25
538c02bd95e0 pvl.args: new --config option, used by pvl.args.parse(...)
Tero Marttila <terom@paivola.fi>
parents: 22
diff changeset
   152
        self._defaults  = defaults
538c02bd95e0 pvl.args: new --config option, used by pvl.args.parse(...)
Tero Marttila <terom@paivola.fi>
parents: 22
diff changeset
   153
        self._options   = { }
538c02bd95e0 pvl.args: new --config option, used by pvl.args.parse(...)
Tero Marttila <terom@paivola.fi>
parents: 22
diff changeset
   154
538c02bd95e0 pvl.args: new --config option, used by pvl.args.parse(...)
Tero Marttila <terom@paivola.fi>
parents: 22
diff changeset
   155
    def __setattr__ (self, name, value) :
538c02bd95e0 pvl.args: new --config option, used by pvl.args.parse(...)
Tero Marttila <terom@paivola.fi>
parents: 22
diff changeset
   156
        if name.startswith('_') :
538c02bd95e0 pvl.args: new --config option, used by pvl.args.parse(...)
Tero Marttila <terom@paivola.fi>
parents: 22
diff changeset
   157
            self.__dict__[name] = value
538c02bd95e0 pvl.args: new --config option, used by pvl.args.parse(...)
Tero Marttila <terom@paivola.fi>
parents: 22
diff changeset
   158
        else :
538c02bd95e0 pvl.args: new --config option, used by pvl.args.parse(...)
Tero Marttila <terom@paivola.fi>
parents: 22
diff changeset
   159
            self._options[name] = value
538c02bd95e0 pvl.args: new --config option, used by pvl.args.parse(...)
Tero Marttila <terom@paivola.fi>
parents: 22
diff changeset
   160
    
538c02bd95e0 pvl.args: new --config option, used by pvl.args.parse(...)
Tero Marttila <terom@paivola.fi>
parents: 22
diff changeset
   161
    def ensure_value (self, name, default) :
538c02bd95e0 pvl.args: new --config option, used by pvl.args.parse(...)
Tero Marttila <terom@paivola.fi>
parents: 22
diff changeset
   162
        if name in self._options :
538c02bd95e0 pvl.args: new --config option, used by pvl.args.parse(...)
Tero Marttila <terom@paivola.fi>
parents: 22
diff changeset
   163
            pass
538c02bd95e0 pvl.args: new --config option, used by pvl.args.parse(...)
Tero Marttila <terom@paivola.fi>
parents: 22
diff changeset
   164
        elif name in self._defaults :
538c02bd95e0 pvl.args: new --config option, used by pvl.args.parse(...)
Tero Marttila <terom@paivola.fi>
parents: 22
diff changeset
   165
            self._options[name] = copy.copy(self._defaults[name])
538c02bd95e0 pvl.args: new --config option, used by pvl.args.parse(...)
Tero Marttila <terom@paivola.fi>
parents: 22
diff changeset
   166
        else :
538c02bd95e0 pvl.args: new --config option, used by pvl.args.parse(...)
Tero Marttila <terom@paivola.fi>
parents: 22
diff changeset
   167
            self._options[name] = default
538c02bd95e0 pvl.args: new --config option, used by pvl.args.parse(...)
Tero Marttila <terom@paivola.fi>
parents: 22
diff changeset
   168
538c02bd95e0 pvl.args: new --config option, used by pvl.args.parse(...)
Tero Marttila <terom@paivola.fi>
parents: 22
diff changeset
   169
        return self._options[name]
538c02bd95e0 pvl.args: new --config option, used by pvl.args.parse(...)
Tero Marttila <terom@paivola.fi>
parents: 22
diff changeset
   170
538c02bd95e0 pvl.args: new --config option, used by pvl.args.parse(...)
Tero Marttila <terom@paivola.fi>
parents: 22
diff changeset
   171
    def _merge (self, options) :
538c02bd95e0 pvl.args: new --config option, used by pvl.args.parse(...)
Tero Marttila <terom@paivola.fi>
parents: 22
diff changeset
   172
        """
538c02bd95e0 pvl.args: new --config option, used by pvl.args.parse(...)
Tero Marttila <terom@paivola.fi>
parents: 22
diff changeset
   173
            Merge in options from given Options.
538c02bd95e0 pvl.args: new --config option, used by pvl.args.parse(...)
Tero Marttila <terom@paivola.fi>
parents: 22
diff changeset
   174
        """
538c02bd95e0 pvl.args: new --config option, used by pvl.args.parse(...)
Tero Marttila <terom@paivola.fi>
parents: 22
diff changeset
   175
        
538c02bd95e0 pvl.args: new --config option, used by pvl.args.parse(...)
Tero Marttila <terom@paivola.fi>
parents: 22
diff changeset
   176
        # TODO: lists?
538c02bd95e0 pvl.args: new --config option, used by pvl.args.parse(...)
Tero Marttila <terom@paivola.fi>
parents: 22
diff changeset
   177
        self._options.update(options._options)
538c02bd95e0 pvl.args: new --config option, used by pvl.args.parse(...)
Tero Marttila <terom@paivola.fi>
parents: 22
diff changeset
   178
538c02bd95e0 pvl.args: new --config option, used by pvl.args.parse(...)
Tero Marttila <terom@paivola.fi>
parents: 22
diff changeset
   179
    def __getattr__ (self, name) :
538c02bd95e0 pvl.args: new --config option, used by pvl.args.parse(...)
Tero Marttila <terom@paivola.fi>
parents: 22
diff changeset
   180
        if name.startswith('_') :
538c02bd95e0 pvl.args: new --config option, used by pvl.args.parse(...)
Tero Marttila <terom@paivola.fi>
parents: 22
diff changeset
   181
            raise AttributeError(name)
538c02bd95e0 pvl.args: new --config option, used by pvl.args.parse(...)
Tero Marttila <terom@paivola.fi>
parents: 22
diff changeset
   182
538c02bd95e0 pvl.args: new --config option, used by pvl.args.parse(...)
Tero Marttila <terom@paivola.fi>
parents: 22
diff changeset
   183
        if name in self._options :
538c02bd95e0 pvl.args: new --config option, used by pvl.args.parse(...)
Tero Marttila <terom@paivola.fi>
parents: 22
diff changeset
   184
            return self._options[name]
538c02bd95e0 pvl.args: new --config option, used by pvl.args.parse(...)
Tero Marttila <terom@paivola.fi>
parents: 22
diff changeset
   185
        elif name in self._defaults :
538c02bd95e0 pvl.args: new --config option, used by pvl.args.parse(...)
Tero Marttila <terom@paivola.fi>
parents: 22
diff changeset
   186
            return self._defaults[name]
538c02bd95e0 pvl.args: new --config option, used by pvl.args.parse(...)
Tero Marttila <terom@paivola.fi>
parents: 22
diff changeset
   187
        else :
538c02bd95e0 pvl.args: new --config option, used by pvl.args.parse(...)
Tero Marttila <terom@paivola.fi>
parents: 22
diff changeset
   188
            raise AttributeError(name)
538c02bd95e0 pvl.args: new --config option, used by pvl.args.parse(...)
Tero Marttila <terom@paivola.fi>
parents: 22
diff changeset
   189
28
69e1b91cd83f pvl.args: support multiple --config's
Tero Marttila <terom@paivola.fi>
parents: 27
diff changeset
   190
    def error (self, msg) :
69e1b91cd83f pvl.args: support multiple --config's
Tero Marttila <terom@paivola.fi>
parents: 27
diff changeset
   191
        """
69e1b91cd83f pvl.args: support multiple --config's
Tero Marttila <terom@paivola.fi>
parents: 27
diff changeset
   192
            Raises an optparse error.
69e1b91cd83f pvl.args: support multiple --config's
Tero Marttila <terom@paivola.fi>
parents: 27
diff changeset
   193
        """
69e1b91cd83f pvl.args: support multiple --config's
Tero Marttila <terom@paivola.fi>
parents: 27
diff changeset
   194
69e1b91cd83f pvl.args: support multiple --config's
Tero Marttila <terom@paivola.fi>
parents: 27
diff changeset
   195
        self._parser.error(msg)
69e1b91cd83f pvl.args: support multiple --config's
Tero Marttila <terom@paivola.fi>
parents: 27
diff changeset
   196
25
538c02bd95e0 pvl.args: new --config option, used by pvl.args.parse(...)
Tero Marttila <terom@paivola.fi>
parents: 22
diff changeset
   197
def apply_config (options, parser, config, encoding=None) :
538c02bd95e0 pvl.args: new --config option, used by pvl.args.parse(...)
Tero Marttila <terom@paivola.fi>
parents: 22
diff changeset
   198
    """
538c02bd95e0 pvl.args: new --config option, used by pvl.args.parse(...)
Tero Marttila <terom@paivola.fi>
parents: 22
diff changeset
   199
        Load options from config.
538c02bd95e0 pvl.args: new --config option, used by pvl.args.parse(...)
Tero Marttila <terom@paivola.fi>
parents: 22
diff changeset
   200
    """
538c02bd95e0 pvl.args: new --config option, used by pvl.args.parse(...)
Tero Marttila <terom@paivola.fi>
parents: 22
diff changeset
   201
538c02bd95e0 pvl.args: new --config option, used by pvl.args.parse(...)
Tero Marttila <terom@paivola.fi>
parents: 22
diff changeset
   202
    import configobj
538c02bd95e0 pvl.args: new --config option, used by pvl.args.parse(...)
Tero Marttila <terom@paivola.fi>
parents: 22
diff changeset
   203
        
538c02bd95e0 pvl.args: new --config option, used by pvl.args.parse(...)
Tero Marttila <terom@paivola.fi>
parents: 22
diff changeset
   204
    config = configobj.ConfigObj(config,
538c02bd95e0 pvl.args: new --config option, used by pvl.args.parse(...)
Tero Marttila <terom@paivola.fi>
parents: 22
diff changeset
   205
            encoding        = options.config_encoding if encoding is None else encoding,
538c02bd95e0 pvl.args: new --config option, used by pvl.args.parse(...)
Tero Marttila <terom@paivola.fi>
parents: 22
diff changeset
   206
    )
28
69e1b91cd83f pvl.args: support multiple --config's
Tero Marttila <terom@paivola.fi>
parents: 27
diff changeset
   207
    config_options = Options(parser, options._defaults)
25
538c02bd95e0 pvl.args: new --config option, used by pvl.args.parse(...)
Tero Marttila <terom@paivola.fi>
parents: 22
diff changeset
   208
538c02bd95e0 pvl.args: new --config option, used by pvl.args.parse(...)
Tero Marttila <terom@paivola.fi>
parents: 22
diff changeset
   209
    # load scalars
538c02bd95e0 pvl.args: new --config option, used by pvl.args.parse(...)
Tero Marttila <terom@paivola.fi>
parents: 22
diff changeset
   210
    for scalar in config.scalars :
538c02bd95e0 pvl.args: new --config option, used by pvl.args.parse(...)
Tero Marttila <terom@paivola.fi>
parents: 22
diff changeset
   211
        # option from config
538c02bd95e0 pvl.args: new --config option, used by pvl.args.parse(...)
Tero Marttila <terom@paivola.fi>
parents: 22
diff changeset
   212
        option = parser._long_opt.get('--' + scalar)
538c02bd95e0 pvl.args: new --config option, used by pvl.args.parse(...)
Tero Marttila <terom@paivola.fi>
parents: 22
diff changeset
   213
        
538c02bd95e0 pvl.args: new --config option, used by pvl.args.parse(...)
Tero Marttila <terom@paivola.fi>
parents: 22
diff changeset
   214
        if not option :
538c02bd95e0 pvl.args: new --config option, used by pvl.args.parse(...)
Tero Marttila <terom@paivola.fi>
parents: 22
diff changeset
   215
            raise optparse.BadOptionError(scalar)
538c02bd95e0 pvl.args: new --config option, used by pvl.args.parse(...)
Tero Marttila <terom@paivola.fi>
parents: 22
diff changeset
   216
        
538c02bd95e0 pvl.args: new --config option, used by pvl.args.parse(...)
Tero Marttila <terom@paivola.fi>
parents: 22
diff changeset
   217
        # value from config
538c02bd95e0 pvl.args: new --config option, used by pvl.args.parse(...)
Tero Marttila <terom@paivola.fi>
parents: 22
diff changeset
   218
        if option.takes_value() :
538c02bd95e0 pvl.args: new --config option, used by pvl.args.parse(...)
Tero Marttila <terom@paivola.fi>
parents: 22
diff changeset
   219
            value = config[scalar]
538c02bd95e0 pvl.args: new --config option, used by pvl.args.parse(...)
Tero Marttila <terom@paivola.fi>
parents: 22
diff changeset
   220
538c02bd95e0 pvl.args: new --config option, used by pvl.args.parse(...)
Tero Marttila <terom@paivola.fi>
parents: 22
diff changeset
   221
        else :
538c02bd95e0 pvl.args: new --config option, used by pvl.args.parse(...)
Tero Marttila <terom@paivola.fi>
parents: 22
diff changeset
   222
            # ignore
538c02bd95e0 pvl.args: new --config option, used by pvl.args.parse(...)
Tero Marttila <terom@paivola.fi>
parents: 22
diff changeset
   223
            value = None
538c02bd95e0 pvl.args: new --config option, used by pvl.args.parse(...)
Tero Marttila <terom@paivola.fi>
parents: 22
diff changeset
   224
        
538c02bd95e0 pvl.args: new --config option, used by pvl.args.parse(...)
Tero Marttila <terom@paivola.fi>
parents: 22
diff changeset
   225
        # apply
538c02bd95e0 pvl.args: new --config option, used by pvl.args.parse(...)
Tero Marttila <terom@paivola.fi>
parents: 22
diff changeset
   226
        option.process(scalar, value, config_options, parser)
538c02bd95e0 pvl.args: new --config option, used by pvl.args.parse(...)
Tero Marttila <terom@paivola.fi>
parents: 22
diff changeset
   227
    
538c02bd95e0 pvl.args: new --config option, used by pvl.args.parse(...)
Tero Marttila <terom@paivola.fi>
parents: 22
diff changeset
   228
    # apply in actual options
538c02bd95e0 pvl.args: new --config option, used by pvl.args.parse(...)
Tero Marttila <terom@paivola.fi>
parents: 22
diff changeset
   229
    config_options._merge(options)
538c02bd95e0 pvl.args: new --config option, used by pvl.args.parse(...)
Tero Marttila <terom@paivola.fi>
parents: 22
diff changeset
   230
538c02bd95e0 pvl.args: new --config option, used by pvl.args.parse(...)
Tero Marttila <terom@paivola.fi>
parents: 22
diff changeset
   231
    return config_options
538c02bd95e0 pvl.args: new --config option, used by pvl.args.parse(...)
Tero Marttila <terom@paivola.fi>
parents: 22
diff changeset
   232
538c02bd95e0 pvl.args: new --config option, used by pvl.args.parse(...)
Tero Marttila <terom@paivola.fi>
parents: 22
diff changeset
   233
def parse (parser, argv) :
538c02bd95e0 pvl.args: new --config option, used by pvl.args.parse(...)
Tero Marttila <terom@paivola.fi>
parents: 22
diff changeset
   234
    """
538c02bd95e0 pvl.args: new --config option, used by pvl.args.parse(...)
Tero Marttila <terom@paivola.fi>
parents: 22
diff changeset
   235
        Parse options, args from argv.
538c02bd95e0 pvl.args: new --config option, used by pvl.args.parse(...)
Tero Marttila <terom@paivola.fi>
parents: 22
diff changeset
   236
    """
538c02bd95e0 pvl.args: new --config option, used by pvl.args.parse(...)
Tero Marttila <terom@paivola.fi>
parents: 22
diff changeset
   237
28
69e1b91cd83f pvl.args: support multiple --config's
Tero Marttila <terom@paivola.fi>
parents: 27
diff changeset
   238
    options, args = parser.parse_args(argv[1:], values=Options(parser, parser.defaults))
25
538c02bd95e0 pvl.args: new --config option, used by pvl.args.parse(...)
Tero Marttila <terom@paivola.fi>
parents: 22
diff changeset
   239
28
69e1b91cd83f pvl.args: support multiple --config's
Tero Marttila <terom@paivola.fi>
parents: 27
diff changeset
   240
    for config in options.config :
69e1b91cd83f pvl.args: support multiple --config's
Tero Marttila <terom@paivola.fi>
parents: 27
diff changeset
   241
        options = apply_config(options, parser, config)
25
538c02bd95e0 pvl.args: new --config option, used by pvl.args.parse(...)
Tero Marttila <terom@paivola.fi>
parents: 22
diff changeset
   242
    
538c02bd95e0 pvl.args: new --config option, used by pvl.args.parse(...)
Tero Marttila <terom@paivola.fi>
parents: 22
diff changeset
   243
    return options, args
538c02bd95e0 pvl.args: new --config option, used by pvl.args.parse(...)
Tero Marttila <terom@paivola.fi>
parents: 22
diff changeset
   244
1
ce931075b69e import pvl.args,invoke from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   245
def apply (options, logname=None, rootok=True) :
ce931075b69e import pvl.args,invoke from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   246
    """
ce931075b69e import pvl.args,invoke from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   247
        Apply the optparse options.
ce931075b69e import pvl.args,invoke from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   248
    """
ce931075b69e import pvl.args,invoke from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   249
ce931075b69e import pvl.args,invoke from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   250
    if logname :
ce931075b69e import pvl.args,invoke from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   251
        prefix = options.logname + ': '
ce931075b69e import pvl.args,invoke from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   252
    else :
ce931075b69e import pvl.args,invoke from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   253
        prefix = ''
ce931075b69e import pvl.args,invoke from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   254
ce931075b69e import pvl.args,invoke from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   255
    # configure
ce931075b69e import pvl.args,invoke from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   256
    logging.basicConfig(
ce931075b69e import pvl.args,invoke from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   257
        # XXX: log Class.__init__ as Class, not __init__?
19
c511078be51d pvl.args: change logging format
Tero Marttila <terom@paivola.fi>
parents: 15
diff changeset
   258
        format      = prefix + '%(levelname)8s %(name)20s.%(funcName)s: %(message)s',
1
ce931075b69e import pvl.args,invoke from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   259
        level       = options.loglevel,
ce931075b69e import pvl.args,invoke from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   260
        filename    = options.log_file,
ce931075b69e import pvl.args,invoke from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   261
    )
ce931075b69e import pvl.args,invoke from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   262
ce931075b69e import pvl.args,invoke from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   263
    # TODO: use --quiet for stdout output?
ce931075b69e import pvl.args,invoke from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   264
    options.quiet = options.loglevel > logging.WARN
ce931075b69e import pvl.args,invoke from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   265
    
25
538c02bd95e0 pvl.args: new --config option, used by pvl.args.parse(...)
Tero Marttila <terom@paivola.fi>
parents: 22
diff changeset
   266
    if options.setuid :
10
08bb817a9966 pvl.args: fix optional setuid options
Tero Marttila <terom@paivola.fi>
parents: 9
diff changeset
   267
        if options.uid or options.gid or not rootok :
08bb817a9966 pvl.args: fix optional setuid options
Tero Marttila <terom@paivola.fi>
parents: 9
diff changeset
   268
            # set uid/gid
08bb817a9966 pvl.args: fix optional setuid options
Tero Marttila <terom@paivola.fi>
parents: 9
diff changeset
   269
            apply_setid(options, rootok=rootok)
1
ce931075b69e import pvl.args,invoke from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   270
ce931075b69e import pvl.args,invoke from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   271
    # enable debugging for specific targets
ce931075b69e import pvl.args,invoke from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   272
    for logger in options.debug_module :
ce931075b69e import pvl.args,invoke from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   273
        logging.getLogger(logger).setLevel(logging.DEBUG)
ce931075b69e import pvl.args,invoke from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   274
    
15
e699ed00fcf1 pvl.args: apply_file(path) and main(main)
Tero Marttila <terom@paivola.fi>
parents: 10
diff changeset
   275
def main (main) :
e699ed00fcf1 pvl.args: apply_file(path) and main(main)
Tero Marttila <terom@paivola.fi>
parents: 10
diff changeset
   276
    """
e699ed00fcf1 pvl.args: apply_file(path) and main(main)
Tero Marttila <terom@paivola.fi>
parents: 10
diff changeset
   277
        Run given main func.
e699ed00fcf1 pvl.args: apply_file(path) and main(main)
Tero Marttila <terom@paivola.fi>
parents: 10
diff changeset
   278
    """
e699ed00fcf1 pvl.args: apply_file(path) and main(main)
Tero Marttila <terom@paivola.fi>
parents: 10
diff changeset
   279
e699ed00fcf1 pvl.args: apply_file(path) and main(main)
Tero Marttila <terom@paivola.fi>
parents: 10
diff changeset
   280
    sys.exit(main(sys.argv))