Statistics
| Branch: | Tag: | Revision:

root / kamaki / cli / one_command.py @ 8e3cbcfe

History | View | Annotate | Download (4.2 kB)

1
# Copyright 2012-2013 GRNET S.A. All rights reserved.
2
#
3
# Redistribution and use in source and binary forms, with or
4
# without modification, are permitted provided that the following
5
# conditions are met:
6
#
7
#   1. Redistributions of source code must retain the above
8
#      copyright notice, this list of conditions and the following
9
#      disclaimer.
10
#
11
#   2. Redistributions in binary form must reproduce the above
12
#      copyright notice, this list of conditions and the following
13
#      disclaimer in the documentation and/or other materials
14
#      provided with the distribution.
15
#
16
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
# POSSIBILITY OF SUCH DAMAGE.
28
#
29
# The views and conclusions contained in the software and
30
# documentation are those of the authors and should not be
31
# interpreted as representing official policies, either expressed
32
# or implied, of GRNET S.A.command
33

    
34
from kamaki.cli import (
35
    get_command_group, set_command_params, print_subcommands_help, exec_cmd,
36
    update_parser_help, _groups_help, _load_spec_module,
37
    init_cached_authenticator, kloger)
38
from kamaki.cli.errors import CLIUnknownCommand
39

    
40

    
41
def _get_cmd_tree_from_spec(spec, cmd_tree_list):
42
    for tree in cmd_tree_list:
43
        if tree.name == spec:
44
            return tree
45
    raise CLIUnknownCommand('Unknown command: %s' % spec)
46

    
47

    
48
def _get_best_match_from_cmd_tree(cmd_tree, unparsed):
49
    matched = [term for term in unparsed if not term.startswith('-')]
50
    while matched:
51
        try:
52
            return cmd_tree.get_command('_'.join(matched))
53
        except KeyError:
54
            matched = matched[:-1]
55
    return None
56

    
57

    
58
def run(cloud, parser, _help):
59
    group = get_command_group(list(parser.unparsed), parser.arguments)
60
    if not group:
61
        #parser.parser.print_help()
62
        parser.print_help()
63
        _groups_help(parser.arguments)
64
        exit(0)
65

    
66
    nonargs = [term for term in parser.unparsed if not term.startswith('-')]
67
    set_command_params(nonargs)
68

    
69
    global _best_match
70
    _best_match = []
71

    
72
    _cnf = parser.arguments['config']
73
    group_spec = _cnf.get('global', '%s_cli' % group)
74
    spec_module = _load_spec_module(group_spec, parser.arguments, '_commands')
75
    if spec_module is None:
76
        raise CLIUnknownCommand(
77
            'Could not find specs for %s commands' % group,
78
            details=[
79
                'Make sure %s is a valid command group' % group,
80
                'Refer to kamaki documentation for setting custom command',
81
                'groups or overide existing ones'])
82
    cmd_tree = _get_cmd_tree_from_spec(group, spec_module._commands)
83

    
84
    if _best_match:
85
        cmd = cmd_tree.get_command('_'.join(_best_match))
86
    else:
87
        cmd = _get_best_match_from_cmd_tree(cmd_tree, parser.unparsed)
88
        _best_match = cmd.path.split('_')
89
    if cmd is None:
90
        kloger.info('Unexpected error: failed to load command (-d for more)')
91
        exit(1)
92

    
93
    update_parser_help(parser, cmd)
94

    
95
    if _help or not cmd.is_command:
96
        if cmd.cmd_class:
97
            parser.required = getattr(cmd.cmd_class, 'required', None)
98
        parser.print_help()
99
        if getattr(cmd, 'long_help', False):
100
            print 'Details:\n', cmd.long_help
101
        print_subcommands_help(cmd)
102
        exit(0)
103

    
104
    cls = cmd.cmd_class
105
    auth_base = init_cached_authenticator(_cnf, cloud, kloger) if (
106
        cloud) else None
107
    executable = cls(parser.arguments, auth_base, cloud)
108
    parser.required = getattr(cls, 'required', None)
109
    parser.update_arguments(executable.arguments)
110
    for term in _best_match:
111
        parser.unparsed.remove(term)
112
    exec_cmd(executable, parser.unparsed, parser.print_help)