Revision a7aacf12

b/kamaki/cli/__init__.py
340 340
    global _debug
341 341
    global kloger
342 342
    descriptions = {}
343
    acceptable_groups = arguments['config'].get_groups()
344
    for cmd_group, spec in arguments['config'].get_cli_specs():
343
    acceptable_groups = arguments['config'].groups
344
    for cmd_group, spec in arguments['config'].cli_specs:
345 345
        pkg = _load_spec_module(spec, arguments, '_commands')
346 346
        if pkg:
347 347
            cmds = getattr(pkg, '_commands')
......
361 361

  
362 362
def _load_all_commands(cmd_tree, arguments):
363 363
    _cnf = arguments['config']
364
    for cmd_group, spec in _cnf.get_cli_specs():
364
    for cmd_group, spec in _cnf.cli_specs:
365 365
        try:
366 366
            spec_module = _load_spec_module(spec, arguments, '_commands')
367 367
            spec_commands = getattr(spec_module, '_commands')
......
436 436

  
437 437

  
438 438
def get_command_group(unparsed, arguments):
439
    groups = arguments['config'].get_groups()
439
    groups = arguments['config'].groups
440 440
    for term in unparsed:
441 441
        if term.startswith('-'):
442 442
            continue
b/kamaki/cli/argument/__init__.py
98 98
class ConfigArgument(Argument):
99 99
    """Manage a kamaki configuration (file)"""
100 100

  
101
    _config_file = None
101
    def __init__(self, help, parsed_name=('-c', '--config')):
102
        super(ConfigArgument, self).__init__(1, help, parsed_name, None)
103
        self.file_path = None
102 104

  
103 105
    @property
104 106
    def value(self):
105
        """A Config object"""
106
        super(self.__class__, self).value
107
        return super(self.__class__, self).value
107
        return super(ConfigArgument, self).value
108 108

  
109 109
    @value.setter
110 110
    def value(self, config_file):
111 111
        if config_file:
112 112
            self._value = Config(config_file)
113
            self._config_file = config_file
114
        elif self._config_file:
115
            self._value = Config(self._config_file)
113
            self.file_path = config_file
114
        elif self.file_path:
115
            self._value = Config(self.file_path)
116 116
        else:
117 117
            self._value = Config()
118 118

  
......
120 120
        """Get a configuration setting from the Config object"""
121 121
        return self.value.get(group, term)
122 122

  
123
    def get_groups(self):
123
    @property
124
    def groups(self):
124 125
        suffix = '_cli'
125 126
        slen = len(suffix)
126 127
        return [term[:-slen] for term in self.value.keys('global') if (
127 128
            term.endswith(suffix))]
128 129

  
129
    def get_cli_specs(self):
130
    @property
131
    def cli_specs(self):
130 132
        suffix = '_cli'
131 133
        slen = len(suffix)
132 134
        return [(k[:-slen], v) for k, v in self.value.items('global') if (
......
139 141
        return self.value.get_cloud(cloud, option)
140 142

  
141 143

  
142
_config_arg = ConfigArgument(
143
    1, 'Path to configuration file', ('-c', '--config'))
144
_config_arg = ConfigArgument('Path to config file')
144 145

  
145 146

  
146 147
class CmdLineConfigArgument(Argument):
b/kamaki/cli/argument/test.py
34 34
#from mock import patch, call
35 35
from unittest import TestCase
36 36
from StringIO import StringIO
37
from sys import stdin, stdout
37 38
#from itertools import product
38 39

  
39 40
from kamaki.cli import argument
41
from kamaki.cli.config import Config
40 42

  
41 43

  
42 44
class Argument(TestCase):
......
85 87
            del arp
86 88

  
87 89

  
90
class ConfigArgument(TestCase):
91

  
92
    #  A cloud name in config with a URL but no TOKEN
93
    SEMI_CLOUD = 'production'
94

  
95
    # A cloud name that is not configured in config
96
    INVALID_CLOUD = 'QWERTY_123456'
97

  
98
    def setUp(self):
99
        argument._config_arg = argument.ConfigArgument('Recovered Path')
100

  
101
    def test_value(self):
102
        c = argument._config_arg
103
        self.assertEqual(c.value, None)
104
        exp = '/some/random/path'
105
        c.value = exp
106
        self.assertTrue(isinstance(c.value, Config))
107
        self.assertEqual(c.file_path, exp)
108
        self.assertEqual(c.value.path, exp)
109

  
110
    def test_get(self):
111
        c = argument._config_arg
112
        c.value = None
113
        self.assertEqual(c.value.get('global', 'config_cli'), 'config')
114

  
115
    def test_groups(self):
116
        c = argument._config_arg
117
        c.value = None
118
        self.assertTrue(set(c.groups).issuperset([
119
            'image', 'config', 'history']))
120

  
121
    def test_cli_specs(self):
122
        c = argument._config_arg
123
        c.value = None
124
        self.assertTrue(set(c.cli_specs).issuperset([
125
            ('image', 'image'), ('config', 'config'), ('history', 'history')]))
126

  
127
    def test_get_global(self):
128
        c = argument._config_arg
129
        c.value = None
130
        for k, v in (
131
                ('config_cli', 'config'),
132
                ('image_cli', 'image'),
133
                ('history_cli', 'history')):
134
            self.assertEqual(c.get_global(k), v)
135

  
136
    def test_get_cloud(self):
137
        """test_get_cloud (!! hard-set SEMI/INVALID_CLOUD to run this !!)"""
138
        c = argument._config_arg
139
        c.value = None
140
        if not self.SEMI_CLOUD:
141
            stdout.write(
142
                '\n\tA cloud name set in config file with URL but no TOKEN: ')
143
            self.SEMI_CLOUD = stdin.readline()[:-1]
144
        self.assertTrue(len(c.get_cloud(self.SEMI_CLOUD, 'url')) > 0)
145
        self.assertRaises(KeyError, c.get_cloud, self.SEMI_CLOUD, 'token')
146

  
147
        if not self.INVALID_CLOUD:
148
            stdout.write('\tok\n\tA cloud name NOT in your config file: ')
149
            self.INVALID_CLOUD = stdin.readline()[:-1]
150
        self.assertRaises(KeyError, c.get_cloud, self.INVALID_CLOUD, 'url')
151

  
152

  
88 153
if __name__ == '__main__':
89 154
    from sys import argv
90 155
    from kamaki.cli.test import runTestCase
91 156
    runTestCase(Argument, 'Argument', argv[1:])
157
    runTestCase(ConfigArgument, 'ConfigArgument', argv[1:])
b/kamaki/cli/command_shell.py
310 310
        else:
311 311
            intro = self.cmd_tree.name
312 312

  
313
        acceptable = parser.arguments['config'].get_groups()
313
        acceptable = parser.arguments['config'].groups
314 314
        total = self.cmd_tree.groups.keys()
315 315
        self.cmd_tree.exclude(set(total).difference(acceptable))
316 316

  
b/kamaki/cli/config.py
352 352
        except NoSectionError:
353 353
            pass
354 354

  
355
    def remote_from_cloud(self, cloud, option):
355
    def remove_from_cloud(self, cloud, option):
356 356
        d = self.get(CLOUD_PREFIX, cloud)
357 357
        if isinstance(d, dict):
358 358
            d.pop(option)
b/kamaki/cli/test.py
35 35
from inspect import getmembers, isclass
36 36

  
37 37
from kamaki.cli.command_tree.test import Command, CommandTree
38
from kamaki.cli.argument.test import Argument
38
from kamaki.cli.argument.test import Argument, ConfigArgument
39 39

  
40 40

  
41 41
#  TestCase auxiliary methods

Also available in: Unified diff