Exemplo n.º 1
0
def check(path=None, debug=False):
	search_paths = [path] if path else get_config_paths()
	find_config_file = 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)

	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
				sys.stderr.write('Path {0} is supposed to be a directory, but it is not\n'.format(d))

	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)
						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['themes']) ^ set(configs['colorschemes'])
	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':
				sys.stderr.write('{0} extension {1} not present in {2}\n'.format(
					ext,
					'configuration' if (ext in paths['themes'] and ext in paths['colorschemes']) else 'directory',
					typ,
				))

	lhadproblem = [False]

	def load_config(stream):
		r, hadproblem = load(stream)
		if hadproblem:
			lhadproblem[0] = True
		return r

	hadproblem = False
	try:
		main_config = load_json_config(find_config_file('config'), load=load_config, open_file=open_file)
	except IOError:
		main_config = {}
		sys.stderr.write('\nConfiguration file not found: config.json\n')
		hadproblem = True
	except MarkedError as e:
		main_config = {}
		sys.stderr.write(str(e) + '\n')
		hadproblem = True
	else:
		if main_spec.match(main_config, data={'configs': configs, 'lists': lists}, 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_json_config(find_config_file('colors'), load=load_config, open_file=open_file)
	except IOError:
		colors_config = {}
		sys.stderr.write('\nConfiguration file not found: colors.json\n')
		hadproblem = True
	except MarkedError as e:
		colors_config = {}
		sys.stderr.write(str(e) + '\n')
		hadproblem = True
	else:
		if colors_spec.match(colors_config, 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:
				sys.stderr.write(str(e) + '\n')
				hadproblem = True
				continue
		if lhadproblem:
			hadproblem = True
		top_colorscheme_configs[colorscheme] = config
		data['colorscheme'] = colorscheme
		if top_colorscheme_spec.match(config, 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:
					sys.stderr.write(str(e) + '\n')
					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=(('', 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:
					sys.stderr.write(str(e) + '\n')
					hadproblem = True
					continue
			if lhadproblem:
				hadproblem = True
			theme_configs[ext][theme] = config

	for ext, configs in theme_configs.items():
		data = {'ext': ext, 'colorscheme_configs': colorscheme_configs, 'import_paths': import_paths,
				'main_config': main_config, 'ext_theme_configs': configs, 'colors_config': colors_config}
		for theme, config in configs.items():
			data['theme'] = theme
			if theme_spec.match(config, context=(('', config),), data=data, echoerr=ee)[1]:
				hadproblem = True
	return hadproblem
Exemplo 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
Exemplo n.º 3
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
Exemplo n.º 4
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
Exemplo n.º 5
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