diff --git a/tests/cli/test_config.py b/tests/cli/test_config.py index ef58ca0..9121de3 100644 --- a/tests/cli/test_config.py +++ b/tests/cli/test_config.py @@ -60,8 +60,7 @@ def test_storage_instance_from_config(monkeypatch): assert kw == {'foo': 'bar', 'baz': 1} return 'OK' - import vdirsyncer.storage - monkeypatch.setitem(vdirsyncer.cli.utils.storage_names._storages, + monkeypatch.setitem(cli.utils.storage_names._storages, 'lol', lol) config = {'type': 'lol', 'foo': 'bar', 'baz': 1} assert cli.utils.storage_instance_from_config(config) == 'OK' @@ -75,7 +74,7 @@ def test_parse_pairs_args(): 'eins': ('zwei', 'drei', {'ha': True}, {}) } assert sorted( - cli.parse_pairs_args(['foo/foocoll', 'one', 'eins'], pairs) + cli.utils.parse_pairs_args(['foo/foocoll', 'one', 'eins'], pairs) ) == [ ('eins', set()), ('foo', {'foocoll'}), diff --git a/vdirsyncer/cli/__init__.py b/vdirsyncer/cli/__init__.py index 08db66e..cbfeaca 100644 --- a/vdirsyncer/cli/__init__.py +++ b/vdirsyncer/cli/__init__.py @@ -3,19 +3,38 @@ import functools import sys -from .tasks import discover_collections, repair_collection, sync_pair -from .utils import CliError, WorkerQueue, cli_logger, handle_cli_error, \ - load_config, parse_pairs_args from .. import __version__, log from ..doubleclick import click, ctx +cli_logger = log.get(__name__) + + +class CliError(RuntimeError): + def __init__(self, msg, problems=None): + self.msg = msg + self.problems = problems + RuntimeError.__init__(self, msg) + + def format_cli(self): + msg = self.msg.rstrip(u'.:') + if self.problems: + msg += u':' + if len(self.problems) == 1: + msg += u' {}'.format(self.problems[0]) + else: + msg += u'\n' + u'\n - '.join(self.problems) + u'\n\n' + + return msg + + def catch_errors(f): @functools.wraps(f) def inner(*a, **kw): try: f(*a, **kw) except: + from .utils import handle_cli_error handle_cli_error() sys.exit(1) @@ -41,6 +60,7 @@ def app(verbosity): ''' vdirsyncer -- synchronize calendars and contacts ''' + from .utils import load_config log.add_handler(log.stdout_handler) log.set_level(verbosity) @@ -89,6 +109,8 @@ def sync(pairs, force_delete, max_workers): `vdirsyncer sync bob/first_collection` will sync "first_collection" from the pair "bob". ''' + from .tasks import sync_pair + from .utils import parse_pairs_args, WorkerQueue general, all_pairs, all_storages = ctx.obj['config'] cli_logger.debug('Using {} maximal workers.'.format(max_workers)) @@ -114,6 +136,8 @@ def discover(pairs, max_workers): ''' Refresh collection cache for the given pairs. ''' + from .tasks import discover_collections + from .utils import WorkerQueue general, all_pairs, all_storages = ctx.obj['config'] cli_logger.debug('Using {} maximal workers.'.format(max_workers)) wq = WorkerQueue(max_workers) @@ -151,5 +175,6 @@ def repair(collection): Example: `vdirsyncer repair calendars_local/foo` repairs the `foo` collection of the `calendars_local` storage. ''' + from .tasks import repair_collection general, all_pairs, all_storages = ctx.obj['config'] repair_collection(general, all_pairs, all_storages, collection) diff --git a/vdirsyncer/cli/utils.py b/vdirsyncer/cli/utils.py index 4c92df5..c8c0a4b 100644 --- a/vdirsyncer/cli/utils.py +++ b/vdirsyncer/cli/utils.py @@ -13,7 +13,8 @@ from itertools import chain from atomicwrites import atomic_write -from .. import DOCS_HOME, PROJECT_HOME, exceptions, log +from . import cli_logger, CliError +from .. import DOCS_HOME, PROJECT_HOME, exceptions from ..doubleclick import click from ..sync import IdentConflict, StorageEmpty, SyncConflict from ..utils import expand_path, get_class_init_args @@ -58,31 +59,11 @@ storage_names = _StorageIndex() del _StorageIndex -cli_logger = log.get(__name__) - GENERAL_ALL = frozenset(['status_path', 'password_command']) GENERAL_REQUIRED = frozenset(['status_path']) SECTION_NAME_CHARS = frozenset(chain(string.ascii_letters, string.digits, '_')) -class CliError(RuntimeError): - def __init__(self, msg, problems=None): - self.msg = msg - self.problems = problems - RuntimeError.__init__(self, msg) - - def format_cli(self): - msg = self.msg.rstrip(u'.:') - if self.problems: - msg += u':' - if len(self.problems) == 1: - msg += u' {}'.format(self.problems[0]) - else: - msg += u'\n' + u'\n - '.join(self.problems) + u'\n\n' - - return msg - - class JobFailed(RuntimeError): pass