Revision fd5db045 kamaki/cli/argument.py

b/kamaki/cli/argument.py
36 36
from kamaki.cli.config import Config
37 37
from kamaki.cli.errors import CLISyntaxError
38 38

  
39

  
39 40
class Argument(object):
40 41
    """An argument that can be parsed from command line or otherwise"""
41 42

  
......
49 50
        if default is not None:
50 51
            self.default = default
51 52

  
52
    @property 
53
    @property
53 54
    def parsed_name(self):
54 55
        return getattr(self, '_parsed_name', None)
56

  
55 57
    @parsed_name.setter
56 58
    def parsed_name(self, newname):
57 59
        self._parsed_name = getattr(self, '_parsed_name', [])
......
60 62
        else:
61 63
            self._parsed_name.append(unicode(newname))
62 64

  
63
    @property 
65
    @property
64 66
    def help(self):
65 67
        return getattr(self, '_help', None)
68

  
66 69
    @help.setter
67 70
    def help(self, newhelp):
68 71
        self._help = unicode(newhelp)
69 72

  
70
    @property 
73
    @property
71 74
    def arity(self):
72 75
        return getattr(self, '_arity', None)
76

  
73 77
    @arity.setter
74 78
    def arity(self, newarity):
75 79
        newarity = int(newarity)
76 80
        assert newarity >= 0
77 81
        self._arity = newarity
78 82

  
79
    @property 
83
    @property
80 84
    def default(self):
81 85
        if not hasattr(self, '_default'):
82 86
            self._default = False if self.arity == 0 else None
83 87
        return self._default
88

  
84 89
    @default.setter
85 90
    def default(self, newdefault):
86 91
        self._default = newdefault
87 92

  
88
    @property 
93
    @property
89 94
    def value(self):
90 95
        return getattr(self, '_value', self.default)
96

  
91 97
    @value.setter
92 98
    def value(self, newvalue):
93 99
        self._value = newvalue
94 100

  
95 101
    def update_parser(self, parser, name):
96 102
        """Update an argument parser with this argument info"""
97
        action = 'store_true' if self.arity==0 else 'store'
103
        action = 'store_true' if self.arity == 0 else 'store'
98 104
        parser.add_argument(*self.parsed_name, dest=name, action=action,
99 105
            default=self.default, help=self.help)
100 106

  
......
102 108
        """Overide this method to give functionality to ur args"""
103 109
        raise NotImplementedError
104 110

  
111

  
105 112
class ConfigArgument(Argument):
106
    @property 
113
    @property
107 114
    def value(self):
108 115
        return super(self.__class__, self).value
116

  
109 117
    @value.setter
110 118
    def value(self, config_file):
111
        self._value = Config(config_file) if config_file is not None else Config()
119
        self._value = Config(config_file) if config_file else Config()
112 120

  
113 121
    def get(self, group, term):
114 122
        return self.value.get(group, term)
......
118 126

  
119 127
_config_arg = ConfigArgument(1, 'Path to configuration file', '--config')
120 128

  
129

  
121 130
class CmdLineConfigArgument(Argument):
122 131
    def __init__(self, config_arg, help='', parsed_name=None, default=None):
123 132
        super(self.__class__, self).__init__(1, help, parsed_name, default)
124 133
        self._config_arg = config_arg
125 134

  
126
    @property 
135
    @property
127 136
    def value(self):
128 137
        return super(self.__class__, self).value
138

  
129 139
    @value.setter
130 140
    def value(self, options):
131 141
        if options == self.default:
132 142
            return
133
        options = [unicode(options)] if not isinstance(options, list) else options
143
        if not isinstance(options, list):
144
            options = [unicode(options)]
134 145
        for option in options:
135 146
            keypath, sep, val = option.partition('=')
136 147
            if not sep:
137
                raise CLISyntaxError(details='Missing = between key and value: -o section.key=val')
148
                raise CLISyntaxError(
149
                    details='Missing = (usage: -o section.key=val)')
138 150
            section, sep, key = keypath.partition('.')
139 151
            if not sep:
140
                raise CLISyntaxError(details='Missing . between section and key: -o section.key=val')
141
        self._config_arg.value.override(section.strip(), key.strip(), val.strip())
152
                raise CLISyntaxError(
153
                    details='Missing . (usage: -o section.key=val)')
154
        self._config_arg.value.override(section.strip(),
155
            key.strip(),
156
            val.strip())
157

  
142 158

  
143 159
class FlagArgument(Argument):
144 160
    def __init__(self, help='', parsed_name=None, default=None):
145 161
        super(FlagArgument, self).__init__(0, help, parsed_name, default)
146 162

  
163

  
147 164
class ValueArgument(Argument):
148 165
    def __init__(self, help='', parsed_name=None, default=None):
149 166
        super(ValueArgument, self).__init__(1, help, parsed_name, default)
150 167

  
168

  
151 169
class IntArgument(ValueArgument):
152
    @property 
170
    @property
153 171
    def value(self):
154 172
        return getattr(self, '_value', self.default)
173

  
155 174
    @value.setter
156 175
    def value(self, newvalue):
157 176
        if newvalue == self.default:
......
160 179
        try:
161 180
            self._value = int(newvalue)
162 181
        except ValueError:
163
            raise CLISyntaxError('IntArgument Error', details='Value %s not an int'%newvalue)
182
            raise CLISyntaxError('IntArgument Error',
183
                details='Value %s not an int' % newvalue)
184

  
164 185

  
165 186
class VersionArgument(FlagArgument):
166
    @property 
187
    @property
167 188
    def value(self):
168 189
        return super(self.__class__, self).value
190

  
169 191
    @value.setter
170 192
    def value(self, newvalue):
171 193
        self._value = newvalue
......
174 196
    def main(self):
175 197
        if self.value:
176 198
            import kamaki
177
            print('kamaki %s'%kamaki.__version__)
199
            print('kamaki %s' % kamaki.__version__)
200

  
178 201

  
179 202
class KeyValueArgument(ValueArgument):
180 203
    def __init__(self, help='', parsed_name=None, default={}):
181
        super(KeyValueArgument,self).__init__(help, parsed_name, default)
204
        super(KeyValueArgument, self).__init__(help, parsed_name, default)
182 205

  
183
    @property 
206
    @property
184 207
    def value(self):
185 208
        return super(KeyValueArgument, self).value
186
    @value.setter 
209

  
210
    @value.setter
187 211
    def value(self, keyvalue_pairs):
188 212
        if keyvalue_pairs == self.default:
189 213
            return
......
191 215
            keyvalue_pairs = keyvalue_pairs.strip().split(',')
192 216
        self._value = self.default
193 217
        for pair in keyvalue_pairs:
194
            key,sep,val = pair.partition('=')
218
            key, sep, val = pair.partition('=')
195 219
            if not sep:
196
                raise CLISyntaxError(details='Missing "="" ( key1=val1,key2=val2 ...')
220
                raise CLISyntaxError(
221
                    details='Missing "="" (usage: key1=val1,key2=val2 ... )')
197 222
            self._value[key.strip()] = val.strip()
198 223

  
199
_arguments = dict(config = _config_arg, help = Argument(0, 'Show help message', ('-h', '--help')),
200
    debug = FlagArgument('Include debug output', ('-d', '--debug')),
201
    include = FlagArgument('Include protocol headers in the output', ('-i', '--include')),
202
    silent = FlagArgument('Do not output anything', ('-s', '--silent')),
203
    verbose = FlagArgument('More info at response', ('-v', '--verbose')),
204
    version = VersionArgument('Print current version', ('-V', '--version')),
205
    options = CmdLineConfigArgument(_config_arg, 'Override a config value', ('-o', '--options'))
224
_arguments = dict(config=_config_arg,
225
    help=Argument(0, 'Show help message', ('-h', '--help')),
226
    debug=FlagArgument('Include debug output', ('-d', '--debug')),
227
    include=FlagArgument('Include protocol headers in the output',
228
        ('-i', '--include')),
229
    silent=FlagArgument('Do not output anything', ('-s', '--silent')),
230
    verbose=FlagArgument('More info at response', ('-v', '--verbose')),
231
    version=VersionArgument('Print current version', ('-V', '--version')),
232
    options=CmdLineConfigArgument(_config_arg,
233
        'Override a config value',
234
        ('-o', '--options'))
206 235
)
207 236

  
237

  
208 238
def parse_known_args(parser, arguments=None):
209 239
    parsed, unparsed = parser.parse_known_args()
210 240
    for name, arg in arguments.items():

Also available in: Unified diff