Esempio n. 1
0
	def test_update_missing(self):
		loader = ConfigLoader(run_once=True)
		fpath = os.path.join(FILE_ROOT, 'file.json')
		self.assertRaises(IOError, loader.load, fpath)
		loader.register_missing(check_file, on_load, fpath)
		loader.update()  # This line must not raise IOError
		with FSTree({'file': {'test': 1}}, root=FILE_ROOT):
			loader.update()
			self.assertEqual(loader.load(fpath), {'test': 1})
			self.assertEqual(loaded.pop_all(), [fpath])
Esempio n. 2
0
    def init(self,
             ext,
             renderer_module=None,
             run_once=False,
             logger=None,
             use_daemon_threads=True,
             shutdown_event=None,
             config_loader=None):
        '''Do actual initialization.

		__init__ function only stores the arguments and runs this function. This 
		function exists for powerline to be able to reload itself: it is easier 
		to make ``__init__`` store arguments and call overriddable ``init`` than 
		tell developers that each time they override Powerline.__init__ in 
		subclasses they must store actual arguments.
		'''
        self.ext = ext
        self.run_once = run_once
        self.logger = logger
        self.use_daemon_threads = use_daemon_threads

        if not renderer_module:
            self.renderer_module = 'powerline.renderers.' + ext
        elif '.' not in renderer_module:
            self.renderer_module = 'powerline.renderers.' + renderer_module
        elif renderer_module.startswith('.'):
            self.renderer_module = 'powerline.renderers.' + ext + renderer_module
        elif renderer_module.endswith('.'):
            self.renderer_module = renderer_module[:-1]
        else:
            self.renderer_module = renderer_module

        self.find_config_files = generate_config_finder(self.get_config_paths)

        self.cr_kwargs_lock = Lock()
        self.cr_kwargs = {}
        self.cr_callbacks = {}
        for key in ('main', 'colors', 'colorscheme', 'theme'):
            self.cr_kwargs['load_' + key] = True
            self.cr_callbacks[key] = _generate_change_callback(
                self.cr_kwargs_lock, 'load_' + key, self.cr_kwargs)

        self.shutdown_event = shutdown_event or Event()
        self.config_loader = config_loader or ConfigLoader(
            shutdown_event=self.shutdown_event, run_once=run_once)
        self.run_loader_update = False

        self.renderer_options = {}

        self.prev_common_config = None
        self.prev_ext_config = None
        self.pl = None
        self.setup_args = ()
        self.setup_kwargs = {}
        self.imported_modules = set()
Esempio n. 3
0
def get_powerline(**kwargs):
    watcher = Watcher()
    pl = TestPowerline(ext='test',
                       renderer_module='tests.lib.config_mock',
                       logger=Logger(),
                       config_loader=ConfigLoader(
                           load=load_json_config,
                           watcher=watcher,
                           run_once=kwargs.get('run_once')),
                       **kwargs)
    pl._watcher = watcher
    return pl
Esempio n. 4
0
    def __init__(self,
                 ext,
                 renderer_module=None,
                 run_once=False,
                 logger=None,
                 use_daemon_threads=True,
                 shutdown_event=None,
                 config_loader=None):
        self.ext = ext
        self.renderer_module = renderer_module or ext
        self.run_once = run_once
        self.logger = logger
        self.use_daemon_threads = use_daemon_threads

        if '.' not in self.renderer_module:
            self.renderer_module = 'powerline.renderers.' + self.renderer_module
        elif self.renderer_module[-1] == '.':
            self.renderer_module = self.renderer_module[:-1]

        config_paths = self.get_config_paths()
        self.find_config_file = lambda cfg_path: find_config_file(
            config_paths, cfg_path)

        self.cr_kwargs_lock = Lock()
        self.create_renderer_kwargs = {
            'load_main': True,
            'load_colors': True,
            'load_colorscheme': True,
            'load_theme': True,
        }
        self.shutdown_event = shutdown_event or Event()
        self.config_loader = config_loader or ConfigLoader(
            shutdown_event=self.shutdown_event)
        self.run_loader_update = False

        self.renderer_options = {}

        self.prev_common_config = None
        self.prev_ext_config = None
        self.pl = None
Esempio n. 5
0
def get_main_config(args):
	find_config_files = generate_config_finder()
	config_loader = ConfigLoader(run_once=True)
	return load_config('config', find_config_files, config_loader)
Esempio n. 6
0
def check(paths=None, debug=False, echoerr=echoerr, require_ext=None):
    '''Check configuration sanity

    :param list paths:
        Paths from which configuration should be loaded.
    :param bool debug:
        Determines whether some information useful for debugging linter should
        be output.
    :param function echoerr:
        Function that will be used to echo the error(s). Should accept four
        optional keyword parameters: ``problem`` and ``problem_mark``, and
        ``context`` and ``context_mark``.
    :param str require_ext:
        Require configuration for some extension to be present.

    :return:
        ``False`` if user configuration seems to be completely sane and ``True``
        if some problems were found.
    '''
    hadproblem = False

    register_common_names()
    search_paths = paths or get_config_paths()
    find_config_files = generate_config_finder(lambda: search_paths)

    logger = logging.getLogger('powerline-lint')
    logger.setLevel(logging.DEBUG if debug else logging.ERROR)
    logger.addHandler(logging.StreamHandler())

    ee = EchoErr(echoerr, logger)

    if require_ext:
        used_main_spec = main_spec.copy()
        try:
            used_main_spec['ext'][require_ext].required()
        except KeyError:
            used_main_spec['ext'][require_ext] = ext_spec()
    else:
        used_main_spec = main_spec

    lhadproblem = [False]
    load_json_config = generate_json_config_loader(lhadproblem)

    config_loader = ConfigLoader(run_once=True, load=load_json_config)

    lists = {
        'colorschemes': set(),
        'themes': set(),
        'exts': set(),
    }
    found_dir = {
        'themes': False,
        'colorschemes': False,
    }
    config_paths = defaultdict(lambda: defaultdict(dict))
    loaded_configs = defaultdict(lambda: defaultdict(dict))
    for d in chain(
            find_all_ext_config_files(search_paths, 'colorschemes'),
            find_all_ext_config_files(search_paths, 'themes'),
    ):
        if d['error']:
            hadproblem = True
            ee(problem=d['error'])
            continue
        if d['hadproblem']:
            hadproblem = True
        if d['ext']:
            found_dir[d['type']] = True
            lists['exts'].add(d['ext'])
            if d['name'] == '__main__':
                pass
            elif d['name'].startswith('__') or d['name'].endswith('__'):
                hadproblem = True
                ee(problem=
                   'File name is not supposed to start or end with “__”: {0}'.
                   format(d['path']))
            else:
                lists[d['type']].add(d['name'])
            config_paths[d['type']][d['ext']][d['name']] = d['path']
            loaded_configs[d['type']][d['ext']][d['name']] = d['config']
        else:
            config_paths[d['type']][d['name']] = d['path']
            loaded_configs[d['type']][d['name']] = d['config']

    for typ in ('themes', 'colorschemes'):
        if not found_dir[typ]:
            hadproblem = True
            ee(problem='Subdirectory {0} was not found in paths {1}'.format(
                typ, ', '.join(search_paths)))

    diff = set(config_paths['colorschemes']) - set(config_paths['themes'])
    if diff:
        hadproblem = True
        for ext in diff:
            typ = 'colorschemes' if ext in config_paths['themes'] else 'themes'
            if not config_paths['top_' + typ] or typ == 'themes':
                ee(problem='{0} extension {1} not present in {2}'.format(
                    ext,
                    'configuration' if (
                        ext in loaded_configs['themes'] and ext in
                        loaded_configs['colorschemes']) else 'directory',
                    typ,
                ))

    try:
        main_config = load_config('config', find_config_files, config_loader)
    except IOError:
        main_config = {}
        ee(problem='Configuration file not found: config.json')
        hadproblem = True
    except MarkedError as e:
        main_config = {}
        ee(problem=str(e))
        hadproblem = True
    else:
        if used_main_spec.match(main_config,
                                data={
                                    'configs': config_paths,
                                    'lists': lists
                                },
                                context=Context(main_config),
                                echoerr=ee)[1]:
            hadproblem = True

    import_paths = [
        os.path.expanduser(path)
        for path in main_config.get('common', {}).get('paths', [])
    ]

    try:
        colors_config = load_config('colors', find_config_files, config_loader)
    except IOError:
        colors_config = {}
        ee(problem='Configuration file not found: colors.json')
        hadproblem = True
    except MarkedError as e:
        colors_config = {}
        ee(problem=str(e))
        hadproblem = True
    else:
        if colors_spec.match(colors_config,
                             context=Context(colors_config),
                             echoerr=ee)[1]:
            hadproblem = True

    if lhadproblem[0]:
        hadproblem = True

    top_colorscheme_configs = dict(loaded_configs['top_colorschemes'])
    data = {
        'ext': None,
        'top_colorscheme_configs': top_colorscheme_configs,
        'ext_colorscheme_configs': {},
        'colors_config': colors_config
    }
    for colorscheme, config in loaded_configs['top_colorschemes'].items():
        data['colorscheme'] = colorscheme
        if top_colorscheme_spec.match(config,
                                      context=Context(config),
                                      data=data,
                                      echoerr=ee)[1]:
            hadproblem = True

    ext_colorscheme_configs = dict2(loaded_configs['colorschemes'])
    for ext, econfigs in ext_colorscheme_configs.items():
        data = {
            'ext': ext,
            'top_colorscheme_configs': top_colorscheme_configs,
            'ext_colorscheme_configs': ext_colorscheme_configs,
            'colors_config': colors_config,
        }
        for colorscheme, config in econfigs.items():
            data['colorscheme'] = colorscheme
            if ext == 'vim':
                spec = vim_colorscheme_spec
            elif ext == 'shell':
                spec = shell_colorscheme_spec
            elif ext == 'ipython':
                spec = ipython_colorscheme_spec
            else:
                spec = top_colorscheme_spec
            if spec.match(config,
                          context=Context(config),
                          data=data,
                          echoerr=ee)[1]:
                hadproblem = True

    colorscheme_configs = {}
    for ext in lists['exts']:
        colorscheme_configs[ext] = {}
        for colorscheme in lists['colorschemes']:
            econfigs = ext_colorscheme_configs[ext]
            ecconfigs = econfigs.get(colorscheme)
            mconfigs = (
                top_colorscheme_configs.get(colorscheme),
                econfigs.get('__main__'),
                ecconfigs,
            )
            if not (mconfigs[0] or mconfigs[2]):
                continue
            config = None
            for mconfig in mconfigs:
                if not mconfig:
                    continue
                if config:
                    config = mergedicts_copy(config, mconfig)
                else:
                    config = mconfig
            colorscheme_configs[ext][colorscheme] = config

    theme_configs = dict2(loaded_configs['themes'])
    top_theme_configs = dict(loaded_configs['top_themes'])
    for ext, configs in theme_configs.items():
        data = {
            'ext': ext,
            'colorscheme_configs': colorscheme_configs,
            'import_paths': import_paths,
            'main_config': main_config,
            'top_themes': top_theme_configs,
            'ext_theme_configs': configs,
            'colors_config': colors_config
        }
        for theme, config in configs.items():
            data['theme'] = theme
            if theme == '__main__':
                data['theme_type'] = 'main'
                spec = main_theme_spec
            else:
                data['theme_type'] = 'regular'
                spec = theme_spec
            if spec.match(config,
                          context=Context(config),
                          data=data,
                          echoerr=ee)[1]:
                hadproblem = True

    for top_theme, config in top_theme_configs.items():
        data = {
            'ext': None,
            'colorscheme_configs': colorscheme_configs,
            'import_paths': import_paths,
            'main_config': main_config,
            'theme_configs': theme_configs,
            'ext_theme_configs': None,
            'colors_config': colors_config
        }
        data['theme_type'] = 'top'
        data['theme'] = top_theme
        if top_theme_spec.match(config,
                                context=Context(config),
                                data=data,
                                echoerr=ee)[1]:
            hadproblem = True

    return hadproblem
Esempio n. 7
0
def check(paths=None, debug=False, echoerr=echoerr, require_ext=None):
    '''Check configuration sanity

	:param list paths:
		Paths from which configuration should be loaded.
	:param bool debug:
		Determines whether some information useful for debugging linter should 
		be output.
	:param function echoerr:
		Function that will be used to echo the error(s). Should accept four 
		optional keyword parameters: ``problem`` and ``problem_mark``, and 
		``context`` and ``context_mark``.
	:param str require_ext:
		Require configuration for some extension to be present.

	:return:
		``False`` if user configuration seems to be completely sane and ``True`` 
		if some problems were found.
	'''
    register_common_names()
    search_paths = paths or get_config_paths()
    find_config_files = generate_config_finder(lambda: search_paths)

    logger = logging.getLogger('powerline-lint')
    logger.setLevel(logging.DEBUG if debug else logging.ERROR)
    logger.addHandler(logging.StreamHandler())

    ee = EchoErr(echoerr, logger)

    if require_ext:
        used_main_spec = main_spec.copy()
        try:
            used_main_spec['ext'][require_ext].required()
        except KeyError:
            used_main_spec['ext'][require_ext] = ext_spec()
    else:
        used_main_spec = main_spec

    lhadproblem = [False]
    load_json_config = generate_json_config_loader(lhadproblem)

    config_loader = ConfigLoader(run_once=True, load=load_json_config)

    paths = {
        'themes': defaultdict(lambda: []),
        'colorschemes': defaultdict(lambda: []),
        'top_colorschemes': [],
        'top_themes': [],
    }
    lists = {
        'colorschemes': set(),
        'themes': set(),
        'exts': set(),
    }
    for path in reversed(search_paths):
        for typ in ('themes', 'colorschemes'):
            d = os.path.join(path, typ)
            if os.path.isdir(d):
                for subp in os.listdir(d):
                    extpath = os.path.join(d, subp)
                    if os.path.isdir(extpath):
                        lists['exts'].add(subp)
                        paths[typ][subp].append(extpath)
                    elif extpath.endswith('.json'):
                        name = subp[:-5]
                        if name != '__main__':
                            lists[typ].add(name)
                        paths['top_' + typ].append(extpath)
            else:
                hadproblem = True
                ee(problem=
                   'Path {0} is supposed to be a directory, but it is not'.
                   format(d))

    hadproblem = False

    configs = defaultdict(lambda: defaultdict(lambda: {}))
    for typ in ('themes', 'colorschemes'):
        for ext in paths[typ]:
            for d in paths[typ][ext]:
                for subp in os.listdir(d):
                    if subp.endswith('.json'):
                        name = subp[:-5]
                        if name != '__main__':
                            lists[typ].add(name)
                            if name.startswith('__') or name.endswith('__'):
                                hadproblem = True
                                ee(problem=
                                   'File name is not supposed to start or end with “__”: {0}'
                                   .format(os.path.join(d, subp)))
                        configs[typ][ext][name] = os.path.join(d, subp)
        for path in paths['top_' + typ]:
            name = os.path.basename(path)[:-5]
            configs['top_' + typ][name] = path

    diff = set(configs['colorschemes']) - set(configs['themes'])
    if diff:
        hadproblem = True
        for ext in diff:
            typ = 'colorschemes' if ext in configs['themes'] else 'themes'
            if not configs['top_' + typ] or typ == 'themes':
                ee(problem='{0} extension {1} not present in {2}'.format(
                    ext,
                    'configuration' if (
                        ext in paths['themes'] and ext in paths['colorschemes']
                    ) else 'directory',
                    typ,
                ))

    try:
        main_config = load_config('config', find_config_files, config_loader)
    except IOError:
        main_config = {}
        ee(problem='Configuration file not found: config.json')
        hadproblem = True
    except MarkedError as e:
        main_config = {}
        ee(problem=str(e))
        hadproblem = True
    else:
        if used_main_spec.match(main_config,
                                data={
                                    'configs': configs,
                                    'lists': lists
                                },
                                context=Context(main_config),
                                echoerr=ee)[1]:
            hadproblem = True

    import_paths = [
        os.path.expanduser(path)
        for path in main_config.get('common', {}).get('paths', [])
    ]

    try:
        colors_config = load_config('colors', find_config_files, config_loader)
    except IOError:
        colors_config = {}
        ee(problem='Configuration file not found: colors.json')
        hadproblem = True
    except MarkedError as e:
        colors_config = {}
        ee(problem=str(e))
        hadproblem = True
    else:
        if colors_spec.match(colors_config,
                             context=Context(colors_config),
                             echoerr=ee)[1]:
            hadproblem = True

    if lhadproblem[0]:
        hadproblem = True

    top_colorscheme_configs = {}
    data = {
        'ext': None,
        'top_colorscheme_configs': top_colorscheme_configs,
        'ext_colorscheme_configs': {},
        'colors_config': colors_config
    }
    for colorscheme, cfile in configs['top_colorschemes'].items():
        with open_file(cfile) as config_file_fp:
            try:
                config, lhadproblem = load(config_file_fp)
            except MarkedError as e:
                ee(problem=str(e))
                hadproblem = True
                continue
        if lhadproblem:
            hadproblem = True
        top_colorscheme_configs[colorscheme] = config
        data['colorscheme'] = colorscheme
        if top_colorscheme_spec.match(config,
                                      context=Context(config),
                                      data=data,
                                      echoerr=ee)[1]:
            hadproblem = True

    ext_colorscheme_configs = defaultdict(lambda: {})
    for ext in configs['colorschemes']:
        for colorscheme, cfile in configs['colorschemes'][ext].items():
            with open_file(cfile) as config_file_fp:
                try:
                    config, lhadproblem = load(config_file_fp)
                except MarkedError as e:
                    ee(problem=str(e))
                    hadproblem = True
                    continue
            if lhadproblem:
                hadproblem = True
            ext_colorscheme_configs[ext][colorscheme] = config

    for ext, econfigs in ext_colorscheme_configs.items():
        data = {
            'ext': ext,
            'top_colorscheme_configs': top_colorscheme_configs,
            'ext_colorscheme_configs': ext_colorscheme_configs,
            'colors_config': colors_config,
        }
        for colorscheme, config in econfigs.items():
            data['colorscheme'] = colorscheme
            if ext == 'vim':
                spec = vim_colorscheme_spec
            elif ext == 'shell':
                spec = shell_colorscheme_spec
            else:
                spec = colorscheme_spec
            if spec.match(config,
                          context=Context(config),
                          data=data,
                          echoerr=ee)[1]:
                hadproblem = True

    colorscheme_configs = {}
    for ext in lists['exts']:
        colorscheme_configs[ext] = {}
        for colorscheme in lists['colorschemes']:
            econfigs = ext_colorscheme_configs[ext]
            ecconfigs = econfigs.get(colorscheme)
            mconfigs = (
                top_colorscheme_configs.get(colorscheme),
                econfigs.get('__main__'),
                ecconfigs,
            )
            config = None
            for mconfig in mconfigs:
                if not mconfig:
                    continue
                if config:
                    config = mergedicts_copy(config, mconfig)
                else:
                    config = mconfig
            colorscheme_configs[colorscheme] = config

    theme_configs = defaultdict(lambda: {})
    for ext in configs['themes']:
        for theme, sfile in configs['themes'][ext].items():
            with open_file(sfile) as config_file_fp:
                try:
                    config, lhadproblem = load(config_file_fp)
                except MarkedError as e:
                    ee(problem=str(e))
                    hadproblem = True
                    continue
            if lhadproblem:
                hadproblem = True
            theme_configs[ext][theme] = config

    top_theme_configs = {}
    for top_theme, top_theme_file in configs['top_themes'].items():
        with open_file(top_theme_file) as config_file_fp:
            try:
                config, lhadproblem = load(config_file_fp)
            except MarkedError as e:
                ee(problem=str(e))
                hadproblem = True
                continue
            if lhadproblem:
                hadproblem = True
            top_theme_configs[top_theme] = config

    for ext, configs in theme_configs.items():
        data = {
            'ext': ext,
            'colorscheme_configs': colorscheme_configs,
            'import_paths': import_paths,
            'main_config': main_config,
            'top_themes': top_theme_configs,
            'ext_theme_configs': configs,
            'colors_config': colors_config
        }
        for theme, config in configs.items():
            data['theme'] = theme
            if theme == '__main__':
                data['theme_type'] = 'main'
                spec = main_theme_spec
            else:
                data['theme_type'] = 'regular'
                spec = theme_spec
            if spec.match(config,
                          context=Context(config),
                          data=data,
                          echoerr=ee)[1]:
                hadproblem = True

    for top_theme, config in top_theme_configs.items():
        data = {
            'ext': ext,
            'colorscheme_configs': colorscheme_configs,
            'import_paths': import_paths,
            'main_config': main_config,
            'theme_configs': theme_configs,
            'ext_theme_configs': configs,
            'colors_config': colors_config
        }
        data['theme_type'] = 'top'
        data['theme'] = top_theme
        if top_theme_spec.match(config,
                                context=Context(config),
                                data=data,
                                echoerr=ee)[1]:
            hadproblem = True

    return hadproblem