forked from splunk/splunk-sdk-python
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcmdopts.py
More file actions
117 lines (96 loc) · 4.11 KB
/
cmdopts.py
File metadata and controls
117 lines (96 loc) · 4.11 KB
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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# Copyright 2011-2015 Splunk, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License"): you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
"""Command line utilities shared by command line tools & unit tests."""
from os import path
from optparse import OptionParser
import sys
__all__ = [ "error", "Parser", "cmdline" ]
# Print the given message to stderr, and optionally exit
def error(message, exitcode = None):
print >> sys.stderr, "Error: %s" % message
if exitcode is not None: sys.exit(exitcode)
class record(dict):
def __getattr__(self, name):
try:
return self[name]
except KeyError:
raise AttributeError(name)
def __setattr__(self, name, value):
self[name] = value
class Parser(OptionParser):
def __init__(self, rules = None, **kwargs):
OptionParser.__init__(self, **kwargs)
self.dests = set({})
self.result = record({ 'args': [], 'kwargs': record() })
if rules is not None: self.init(rules)
def init(self, rules):
"""Initialize the parser with the given command rules."""
# Initialize the option parser
for dest in rules.keys():
rule = rules[dest]
# Assign defaults ourselves here, instead of in the option parser
# itself in order to allow for multiple calls to parse (dont want
# subsequent calls to override previous values with default vals).
if rule.has_key('default'):
self.result['kwargs'][dest] = rule['default']
flags = rule['flags']
kwargs = { 'action': rule.get('action', "store") }
# NOTE: Don't provision the parser with defaults here, per above.
for key in ['callback', 'help', 'metavar', 'type']:
if rule.has_key(key): kwargs[key] = rule[key]
self.add_option(*flags, dest=dest, **kwargs)
# Remember the dest vars that we see, so that we can merge results
self.dests.add(dest)
# Load command options from given 'config' file. Long form options may omit
# the leading "--", and if so we fix that up here.
def load(self, filepath):
argv = []
try:
file = open(filepath)
except:
error("Unable to open '%s'" % filepath, 2)
for line in file:
if line.startswith("#"): continue # Skip comment
line = line.strip()
if len(line) == 0: continue # Skip blank line
if not line.startswith("-"): line = "--" + line
argv.append(line)
self.parse(argv)
return self
def loadif(self, filepath):
"""Load the given filepath if it exists, otherwise ignore."""
if path.isfile(filepath): self.load(filepath)
return self
def loadrc(self, filename):
filepath = path.expanduser(path.join("~", "%s" % filename))
self.loadif(filepath)
return self
def parse(self, argv):
"""Parse the given argument vector."""
kwargs, args = self.parse_args(argv)
self.result['args'] += args
# Annoying that parse_args doesn't just return a dict
for dest in self.dests:
value = getattr(kwargs, dest)
if value is not None:
self.result['kwargs'][dest] = value
return self
def format_epilog(self, formatter):
return self.epilog or ""
def cmdline(argv, rules=None, config=None, **kwargs):
"""Simplified cmdopts interface that does not default any parsing rules
and that does not allow compounding calls to the parser."""
parser = Parser(rules, **kwargs)
if config is not None: parser.loadrc(config)
return parser.parse(argv).result