Commit 97659673 authored by Stavros Sachtouris's avatar Stavros Sachtouris
Browse files

Modify module methods in kamaki.cli classes

Refs #9

Renamed to comply with pep8:
kamaki.cli.config.Config: _cloud_name --> cloud_name
kamaki.cli.shell: _init_shell --> init_shell

Merged with caller methods because they where used only once:
kamaki.cli: _construct_command_syntax, _num_of_matching_terms
kamaki.cli.utils: _parse_with_regex
kamaki.cli.one_cmd: _get_cmd_tree_from_spec, _get_best_match_from_cmd_tree

Remove now unused method _num_of_matching_terms
parent a5acf923
......@@ -64,42 +64,25 @@ def _arg2syntax(arg):
'_', ' ')
def _construct_command_syntax(cls):
spec = getargspec(cls.main.im_func)
args = spec.args[1:]
n = len(args) - len(spec.defaults or ())
required = ' '.join(['<%s>' % _arg2syntax(x) for x in args[:n]])
optional = ' '.join(['[%s]' % _arg2syntax(x) for x in args[n:]])
cls.syntax = ' '.join([required, optional])
if spec.varargs:
cls.syntax += ' <%s ...>' % spec.varargs
def _num_of_matching_terms(basic_list, attack_list):
if not attack_list:
return len(basic_list)
matching_terms = 0
for i, term in enumerate(basic_list):
try:
if term != attack_list[i]:
break
except IndexError:
break
matching_terms += 1
return matching_terms
def _update_best_match(name_terms, prefix=[]):
global _best_match
if prefix:
pref_list = prefix if isinstance(prefix, list) else prefix.split('_')
else:
pref_list = []
_best_match, pref_list = [], []
num_of_matching_terms = _num_of_matching_terms(name_terms, pref_list)
global _best_match
if not prefix:
_best_match = []
if pref_list:
num_of_matching_terms = 0
for i, term in enumerate(name_terms):
try:
if term == pref_list[i]:
num_of_matching_terms += 1
else:
break
except IndexError:
break
else:
num_of_matching_terms = len(name_terms)
if num_of_matching_terms and len(_best_match) <= num_of_matching_terms:
if len(_best_match) < num_of_matching_terms:
......@@ -152,7 +135,15 @@ def command(cmd_tree, prefix='', descedants_depth=1):
except AttributeError:
raise CLICmdSpecError(
'No commend in %s (acts as cmd description)' % cls.__name__)
_construct_command_syntax(cls)
# Build command syntax help
spec = getargspec(cls.main.im_func)
args = spec.args[1:]
n = len(args) - len(spec.defaults or ())
required = ' '.join(['<%s>' % _arg2syntax(x) for x in args[:n]])
optional = ' '.join(['[%s]' % _arg2syntax(x) for x in args[n:]])
cls.syntax = ' '.join([required, optional])
if spec.varargs:
cls.syntax += ' <%s ...>' % spec.varargs
cmd_tree.add_command(
cls_name, cls.description, cls, cls.long_description)
......@@ -545,7 +536,6 @@ def main(func):
def run_shell(exe, parser):
parser.arguments['help'].value = False
cloud = _init_session(parser.arguments)
from shell import _init_shell
global kloger
_cnf = parser.arguments['config']
auth_base = init_cached_authenticator(_cnf, cloud, kloger)
......@@ -554,7 +544,8 @@ def run_shell(exe, parser):
auth_base.user_term('name'), auth_base.user_term('id'))
except Exception:
username, userid = '', ''
shell = _init_shell(exe, parser, username, userid)
from kamaki.cli.shell import init_shell
shell = init_shell(exe, parser, username, userid)
_load_all_commands(shell.cmd_tree, parser.arguments)
shell.run(auth_base, cloud, parser)
......
......@@ -132,14 +132,14 @@ class Config(RawConfigParser):
self.read(self.path)
for section in self.sections():
r = self._cloud_name(section)
r = self.cloud_name(section)
if r:
for k, v in self.items(section):
self.set_cloud(r, k, v)
self.remove_section(section)
@staticmethod
def _cloud_name(full_section_name):
def cloud_name(full_section_name):
if not full_section_name.startswith(CLOUD_PREFIX + ' '):
return None
matcher = match(CLOUD_PREFIX + ' "([~@#$.:\-\w]+)"', full_section_name)
......@@ -369,7 +369,7 @@ class Config(RawConfigParser):
"""
prefix = CLOUD_PREFIX + '.'
if section.startswith(prefix):
cloud = self._cloud_name(
cloud = self.cloud_name(
CLOUD_PREFIX + ' "' + section[len(prefix):] + '"')
return self.set_cloud(cloud, option, value)
if section not in RawConfigParser.sections(self):
......
......@@ -121,8 +121,8 @@ class Config(TestCase):
c_remove_section_num, gen_call = 0, [call('a'), call('b')]
for path, with_defaults in product((None, '/a/path'), (True, False)):
with patch(
'kamaki.cli.config.Config._cloud_name',
return_value=_2value_gen.next()) as _cloud_name:
'kamaki.cli.config.Config.cloud_name',
return_value=_2value_gen.next()) as cloud_name:
cnf = Config(path=path, with_defaults=with_defaults)
self.assertTrue(isinstance(cnf, RawConfigParser))
cpath = path or os.environ.get(CONFIG_ENV, CONFIG_PATH)
......@@ -137,7 +137,7 @@ class Config(TestCase):
self.assertEqual(len(c_sections.mock_calls), c_sections_num)
self.assertEqual(c_sections.mock_calls[-1], call())
self.assertEqual(_cloud_name.mock_calls, gen_call)
self.assertEqual(cloud_name.mock_calls, gen_call)
r = _2value_gen.next()
if r:
......@@ -154,10 +154,10 @@ class Config(TestCase):
self.assertEqual(
len(c_remove_section.mock_calls), c_remove_section_num)
def test__cloud_name(self):
def test_cloud_name(self):
from kamaki.cli.config import (
Config, CLOUD_PREFIX, InvalidCloudNameError)
cn = Config._cloud_name
cn = Config.cloud_name
self.assertEqual(cn('non%s name' % CLOUD_PREFIX), None)
for invalid in ('"!@#$%^&())_"', '"a b c"', u'"\xce\xcd"', 'naked'):
self.assertRaises(
......@@ -385,15 +385,15 @@ class Config(TestCase):
_cnf = Config(path=self.f.name)
with patch(
'kamaki.cli.config.Config._cloud_name',
return_value='cn') as _cloud_name:
'kamaki.cli.config.Config.cloud_name',
return_value='cn') as cloud_name:
with patch(
'kamaki.cli.config.Config.set_cloud',
return_value='sc') as set_cloud:
self.assertEqual(
'sc', _cnf.set('%s.sec' % CLOUD_PREFIX, 'opt', 'val'))
self.assertEqual(
_cloud_name.mock_calls[-1],
cloud_name.mock_calls[-1],
call('%s "sec"' % CLOUD_PREFIX))
self.assertEqual(
set_cloud.mock_calls[-1], call('cn', 'opt', 'val'))
......
......@@ -38,23 +38,6 @@ from kamaki.cli import (
from kamaki.cli.errors import CLIUnknownCommand
def _get_cmd_tree_from_spec(spec, cmd_tree_list):
for tree in cmd_tree_list:
if tree.name == spec:
return tree
raise CLIUnknownCommand('Unknown command: %s' % spec)
def _get_best_match_from_cmd_tree(cmd_tree, unparsed):
matched = [term for term in unparsed if not term.startswith('-')]
while matched:
try:
return cmd_tree.get_command('_'.join(matched))
except KeyError:
matched = matched[:-1]
return None
def run(cloud, parser):
group = get_command_group(list(parser.unparsed), parser.arguments)
if not group:
......@@ -79,13 +62,24 @@ def run(cloud, parser):
'Make sure %s is a valid command group' % group,
'Refer to kamaki documentation for setting custom command',
'groups or overide existing ones'])
cmd_tree = _get_cmd_tree_from_spec(group, spec_module.namespaces)
# Get command tree from group
try:
cmd_tree = [t for t in spec_module.namespaces if t.name == group][0]
except IndexError:
raise CLIUnknownCommand('Unknown command group: %s' % group)
cmd = None
if _best_match:
cmd = cmd_tree.get_command('_'.join(_best_match))
else:
cmd = _get_best_match_from_cmd_tree(cmd_tree, parser.unparsed)
_best_match = cmd.path.split('_')
match = [term for term in parser.unparsed if not term.startswith('-')]
while match:
try:
cmd = cmd_tree.get_command('_'.join(match))
_best_match = cmd.path.split('_')
break
except KeyError:
match = match[:-1]
if cmd is None:
kloger.info('Unexpected error: failed to load command (-d for more)')
exit(1)
......
......@@ -46,7 +46,7 @@ from kamaki.cli.logger import add_file_logger
log = add_file_logger(__name__)
def _init_shell(exe_string, parser, username='', userid=''):
def init_shell(exe_string, parser, username='', userid=''):
parser.arguments.pop('version', None)
shell = Shell()
shell.set_prompt(exe_string)
......
......@@ -338,11 +338,6 @@ def list2file(l, f, depth=1):
# Split input auxiliary
def _parse_with_regex(line, regex):
re_parser = regex_compile(regex)
return (re_parser.split(line), re_parser.findall(line))
def _get_from_parsed(parsed_str):
try:
parsed_str = parsed_str.strip()
......@@ -354,25 +349,24 @@ def _get_from_parsed(parsed_str):
def split_input(line):
if not line:
return []
reg_expr = '\'.*?\'|".*?"|^[\S]*$'
(trivial_parts, interesting_parts) = _parse_with_regex(line, reg_expr)
assert(len(trivial_parts) == 1 + len(interesting_parts))
terms = []
for i, tpart in enumerate(trivial_parts):
part = _get_from_parsed(tpart)
if part:
terms += part
try:
part = _get_from_parsed(interesting_parts[i])
except IndexError:
break
if part:
if tpart and not tpart[-1].endswith(' '):
terms[-1] += ' '.join(part)
else:
if line:
rprs = regex_compile('\'.*?\'|".*?"|^[\S]*$')
trivial_parts, interesting_parts = rprs.split(line), rprs.findall(line)
assert(len(trivial_parts) == 1 + len(interesting_parts))
for i, tpart in enumerate(trivial_parts):
part = _get_from_parsed(tpart)
if part:
terms += part
try:
part = _get_from_parsed(interesting_parts[i])
except IndexError:
break
if part:
if tpart and not tpart[-1].endswith(' '):
terms[-1] += ' '.join(part)
else:
terms += part
return terms
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment