Revision b6a99832 kamaki/cli/__init__.py

b/kamaki/cli/__init__.py
47 47
_colors = False
48 48
kloger = None
49 49

  
50
#  command auxiliary methods
51

  
52
_best_match = []
53

  
50 54

  
51 55
def _construct_command_syntax(cls):
52 56
        spec = getargspec(cls.main.im_func)
......
67 71
            cls.syntax += ' <%s ...>' % spec.varargs
68 72

  
69 73

  
70
def _get_cmd_tree_from_spec(spec, cmd_tree_list):
71
    for tree in cmd_tree_list:
72
        if tree.name == spec:
73
            return tree
74
    return None
75

  
76

  
77
_best_match = []
78

  
79

  
80 74
def _num_of_matching_terms(basic_list, attack_list):
81 75
    if not attack_list:
82 76
        return len(basic_list)
......
158 152
    return wrap
159 153

  
160 154

  
161
def get_cmd_terms():
162
    global command
163
    return [term for term in command.func_defaults[0]\
164
        if not term.startswith('-')]
165

  
166 155
cmd_spec_locations = [
167 156
    'kamaki.cli.commands',
168 157
    'kamaki.commands',
......
171 160
    '']
172 161

  
173 162

  
163
#  Generic init auxiliary functions
164

  
165

  
174 166
def _setup_logging(silent=False, debug=False, verbose=False, include=False):
175 167
    """handle logging for clients package"""
176 168

  
......
190 182
        add_handler('requests', logging.INFO, prefix='* ')
191 183
        add_handler('clients.send', logging.DEBUG, prefix='> ')
192 184
        add_handler('clients.recv', logging.DEBUG, prefix='< ')
193
        add_handler('kamaki', logging.DEBUG, prefix='DEBUG: ')
185
        add_handler('kamaki', logging.DEBUG, prefix='(debug): ')
194 186
    elif verbose:
195 187
        add_handler('requests', logging.INFO, prefix='* ')
196 188
        add_handler('clients.send', logging.INFO, prefix='> ')
197 189
        add_handler('clients.recv', logging.INFO, prefix='< ')
198
        add_handler('kamaki', logging.INFO, prefix='INFO: ')
190
        add_handler('kamaki', logging.INFO, prefix='(i): ')
199 191
    elif include:
200 192
        add_handler('clients.recv', logging.INFO)
201
    add_handler('kamaki', logging.WARNING, prefix='WARNING: ')
193
    add_handler('kamaki', logging.WARNING, prefix='(warning): ')
202 194
    global kloger
203
    kloger = logging.getLogger('kamaki.warning')
195
    kloger = logging.getLogger('kamaki')
204 196

  
205 197

  
206 198
def _init_session(arguments):
......
220 212
    _setup_logging(_silent, _debug, _verbose, _include)
221 213

  
222 214

  
223
def get_command_group(unparsed, arguments):
224
    groups = arguments['config'].get_groups()
225
    for term in unparsed:
226
        if term.startswith('-'):
227
            continue
228
        if term in groups:
229
            unparsed.remove(term)
230
            return term
231
        return None
232
    return None
233

  
234

  
235 215
def _load_spec_module(spec, arguments, module):
236 216
    spec_name = arguments['config'].get(spec, 'cli')
237 217
    if spec_name is None:
......
275 255
    print_dict(descriptions)
276 256

  
277 257

  
278
def _print_subcommands_help(cmd):
258
def _load_all_commands(cmd_tree, arguments):
259
    _config = arguments['config']
260
    for spec in [spec for spec in _config.get_groups()\
261
            if _config.get(spec, 'cli')]:
262
        try:
263
            spec_module = _load_spec_module(spec, arguments, '_commands')
264
            spec_commands = getattr(spec_module, '_commands')
265
        except AttributeError:
266
            if _debug:
267
                global kloger
268
                kloger.warning('No valid description for %s' % spec)
269
            continue
270
        for spec_tree in spec_commands:
271
            if spec_tree.name == spec:
272
                cmd_tree.add_tree(spec_tree)
273
                break
274

  
275

  
276
#  Methods to be used by CLI implementations
277

  
278

  
279
def print_subcommands_help(cmd):
279 280
    printout = {}
280 281
    for subcmd in cmd.get_subcommands():
281 282
        spec, sep, print_path = subcmd.path.partition('_')
......
285 286
        print_dict(printout)
286 287

  
287 288

  
288
def _update_parser_help(parser, cmd):
289
def update_parser_help(parser, cmd):
289 290
    global _best_match
290 291
    parser.syntax = parser.syntax.split('<')[0]
291 292
    parser.syntax += ' '.join(_best_match)
......
302 303
        parser.parser.description = cmd.help
303 304

  
304 305

  
305
def _print_error_message(cli_err):
306
def print_error_message(cli_err):
306 307
    errmsg = '%s' % cli_err
307 308
    if cli_err.importance == 1:
308 309
        errmsg = magenta(errmsg)
......
314 315
    print_list(cli_err.details)
315 316

  
316 317

  
317
def _get_best_match_from_cmd_tree(cmd_tree, unparsed):
318
    matched = [term for term in unparsed if not term.startswith('-')]
319
    while matched:
320
        try:
321
            return cmd_tree.get_command('_'.join(matched))
322
        except KeyError:
323
            matched = matched[:-1]
324
    return None
325

  
326

  
327
def _exec_cmd(instance, cmd_args, help_method):
318
def exec_cmd(instance, cmd_args, help_method):
328 319
    try:
329 320
        return instance.main(*cmd_args)
330 321
    except TypeError as err:
......
340 331
    return 1
341 332

  
342 333

  
334
def get_command_group(unparsed, arguments):
335
    groups = arguments['config'].get_groups()
336
    for term in unparsed:
337
        if term.startswith('-'):
338
            continue
339
        if term in groups:
340
            unparsed.remove(term)
341
            return term
342
        return None
343
    return None
344

  
345

  
343 346
def set_command_params(parameters):
344 347
    """Add a parameters list to a command
345 348

  
......
351 354
    command.func_defaults = tuple(def_params)
352 355

  
353 356

  
354
#def one_cmd(parser, unparsed, arguments):
355
def one_cmd(parser):
356
    group = get_command_group(list(parser.unparsed), parser.arguments)
357
    if not group:
358
        parser.parser.print_help()
359
        _groups_help(parser.arguments)
360
        exit(0)
361

  
362
    nonargs = [term for term in parser.unparsed if not term.startswith('-')]
363
    set_command_params(nonargs)
364

  
365
    global _best_match
366
    _best_match = []
367

  
368
    spec_module = _load_spec_module(group, parser.arguments, '_commands')
369

  
370
    cmd_tree = _get_cmd_tree_from_spec(group, spec_module._commands)
371

  
372
    if _best_match:
373
        cmd = cmd_tree.get_command('_'.join(_best_match))
374
    else:
375
        cmd = _get_best_match_from_cmd_tree(cmd_tree, parser.unparsed)
376
        _best_match = cmd.path.split('_')
377
    if cmd is None:
378
        if _debug or _verbose:
379
            print('Unexpected error: failed to load command')
380
        exit(1)
381

  
382
    _update_parser_help(parser, cmd)
383

  
384
    if _help or not cmd.is_command:
385
        parser.parser.print_help()
386
        _print_subcommands_help(cmd)
387
        exit(0)
388

  
389
    cls = cmd.get_class()
390
    executable = cls(parser.arguments)
391
    parser.update_arguments(executable.arguments)
392
    #parsed, unparsed = parse_known_args(parser, executable.arguments)
393
    for term in _best_match:
394
        parser.unparsed.remove(term)
395
    _exec_cmd(executable, parser.unparsed, parser.parser.print_help)
396

  
357
#  CLI Choice:
397 358

  
398
def _load_all_commands(cmd_tree, arguments):
399
    _config = arguments['config']
400
    for spec in [spec for spec in _config.get_groups()\
401
            if _config.get(spec, 'cli')]:
402
        try:
403
            spec_module = _load_spec_module(spec, arguments, '_commands')
404
            spec_commands = getattr(spec_module, '_commands')
405
        except AttributeError:
406
            if _debug:
407
                global kloger
408
                kloger.warning('No valid description for %s' % spec)
409
            continue
410
        for spec_tree in spec_commands:
411
            if spec_tree.name == spec:
412
                cmd_tree.add_tree(spec_tree)
413
                break
359
def run_one_cmd(exe_string, parser):
360
    global _history
361
    _history = History(
362
        parser.arguments['config'].get('history', 'file'))
363
    _history.add(' '.join([exe_string] + argv[1:]))
364
    from kamaki.cli import one_command
365
    one_command.run(parser, _help)
414 366

  
415 367

  
416 368
def run_shell(exe_string, parser):
......
431 383
        _init_session(parser.arguments)
432 384

  
433 385
        if parser.unparsed:
434
            _history = History(
435
                parser.arguments['config'].get('history', 'file'))
436
            _history.add(' '.join([exe] + argv[1:]))
437
            one_cmd(parser)
386
            run_one_cmd(exe, parser)
438 387
        elif _help:
439 388
            parser.parser.print_help()
440 389
            _groups_help(parser.arguments)
441 390
        else:
442 391
            run_shell(exe, parser)
443 392
    except CLIError as err:
444
        _print_error_message(err)
393
        print_error_message(err)
445 394
        if _debug:
446 395
            raise err
447 396
        exit(1)

Also available in: Unified diff