Esempio n. 1
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. 2
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
			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,
			)
			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. 3
0
    def get(segment, side):
        segment_type = segment.get('type', 'function')
        try:
            get_segment_info = segment_getters[segment_type]
        except KeyError:
            pl.error('Unknown segment type: {0}', segment_type)
            return None

        try:
            contents, _contents_func, module, function_name, name = get_segment_info(
                data, segment)
        except Exception as e:
            pl.exception('Failed to generate segment from {0!r}: {1}',
                         segment,
                         str(e),
                         prefix='segment_generator')
            return None

        if not get_key(False, segment, module, function_name, name, 'display',
                       True):
            return None

        segment_datas = getattr(_contents_func, 'powerline_segment_datas',
                                None)
        if segment_datas:
            try:
                data['segment_data'] = segment_datas[top_theme]
            except KeyError:
                pass

        if segment_type == 'function':
            highlight_groups = [function_name]
        else:
            highlight_groups = segment.get('highlight_groups') or [name]

        if segment_type in ('function', 'segment_list'):
            args = dict(
                ((str(k), v)
                 for k, v in get_key(True, segment, module, function_name,
                                     name, 'args', {}).items()))

        display_condition = gen_display_condition(segment)

        if segment_type == 'segment_list':
            # Handle startup and shutdown of _contents_func?
            subsegments = [
                subsegment
                for subsegment in (get(subsegment, side)
                                   for subsegment in segment['segments'])
                if subsegment
            ]
            return {
                'name':
                name or function_name,
                'type':
                segment_type,
                'highlight_groups':
                None,
                'divider_highlight_group':
                None,
                'before':
                None,
                'after':
                None,
                'contents_func':
                lambda pl, segment_info, parsed_segments, side, mode,
                colorscheme, **opt:
                (process_segment_lister(pl,
                                        segment_info,
                                        parsed_segments,
                                        side,
                                        mode,
                                        colorscheme,
                                        patcher_args=args,
                                        subsegments=subsegments,
                                        lister=_contents_func,
                                        **opt)),
                'contents':
                None,
                'literal_contents':
                None,
                'priority':
                None,
                'draw_soft_divider':
                None,
                'draw_hard_divider':
                None,
                'draw_inner_divider':
                None,
                'side':
                side,
                'display_condition':
                display_condition,
                'width':
                None,
                'align':
                None,
                'expand':
                None,
                'truncate':
                None,
                'startup':
                None,
                'shutdown':
                None,
                '_rendered_raw':
                '',
                '_rendered_hl':
                '',
                '_len':
                None,
                '_contents_len':
                None,
            }

        if segment_type == 'function':
            startup_func = get_attr_func(_contents_func, 'startup', args)
            shutdown_func = getattr(_contents_func, 'shutdown', None)
            expand_func = get_attr_func(_contents_func, 'expand', args, True)
            truncate_func = get_attr_func(_contents_func, 'truncate', args,
                                          True)

            if hasattr(_contents_func,
                       'powerline_requires_filesystem_watcher'):
                create_watcher = lambda: create_file_watcher(
                    pl, common_config['watcher'])
                args[str('create_watcher')] = create_watcher

            if hasattr(_contents_func, 'powerline_requires_segment_info'):
                contents_func = lambda pl, segment_info, **opt: _contents_func(
                    pl=pl,
                    segment_info=segment_info,
                    **mergedicts_copy(args, opt))
            else:
                contents_func = lambda pl, segment_info, **opt: _contents_func(
                    pl=pl, **mergedicts_copy(args, opt))
        else:
            startup_func = None
            shutdown_func = None
            contents_func = None
            expand_func = None
            truncate_func = None

        return {
            'name':
            name or function_name,
            'type':
            segment_type,
            'highlight_groups':
            highlight_groups,
            'divider_highlight_group':
            None,
            'before':
            get_key(False, segment, module, function_name, name, 'before', ''),
            'after':
            get_key(False, segment, module, function_name, name, 'after', ''),
            'contents_func':
            contents_func,
            'contents':
            contents,
            'literal_contents': (0, ''),
            'priority':
            segment.get('priority', None),
            'draw_hard_divider':
            segment.get('draw_hard_divider', True),
            'draw_soft_divider':
            segment.get('draw_soft_divider', True),
            'draw_inner_divider':
            segment.get('draw_inner_divider', False),
            'side':
            side,
            'display_condition':
            display_condition,
            'width':
            segment.get('width'),
            'align':
            segment.get('align', 'l'),
            'expand':
            expand_func,
            'truncate':
            truncate_func,
            'startup':
            startup_func,
            'shutdown':
            shutdown_func,
            '_rendered_raw':
            '',
            '_rendered_hl':
            '',
            '_len':
            None,
            '_contents_len':
            None,
        }