Skip to content

Commit

Permalink
Support XDG_CONFIG_HOME (#235)
Browse files Browse the repository at this point in the history
* Support XDG_CONFIG_HOME

* Fix a KeyError
  • Loading branch information
Kuniwak committed Aug 20, 2017
1 parent f78b0f0 commit 9816a31
Show file tree
Hide file tree
Showing 12 changed files with 122 additions and 19 deletions.
1 change: 1 addition & 0 deletions requirements.txt
@@ -1,3 +1,4 @@
PyYAML ~= 3.11
ansicolor ~= 0.2.4
chardet >= 2.3.0
typing >= 3.6.2
4 changes: 4 additions & 0 deletions test/fixture/ast/inline_python.vim
@@ -0,0 +1,4 @@
let s:inline_python = 'python << EOF'
exec s:inline_python
import os
EOF
13 changes: 13 additions & 0 deletions test/fixture/config/xdg_config_home/.vintrc.yaml
@@ -0,0 +1,13 @@
cmdargs:
verbose: true
severity: warning
error-limit: 10


policies:
ProhibitSomethingEvil:
# Some comments
enabled: false

ProhibitSomethingDengerous:
enabled: true
30 changes: 22 additions & 8 deletions test/unit/vint/linting/config/test_config_global_source.py
Expand Up @@ -7,31 +7,45 @@
class TestConfigGlobalSource(ConfigSourceAssertion, unittest.TestCase):
def test_get_config_dict(self):
env = {
'home_path': get_fixture_path('dummy_home')
'home_path': get_fixture_path('dummy_home'),
'xdg_config_home': get_fixture_path('unexistent_xdg_config_home'),
}

expected_type = {
expected_config_dict = {
'cmdargs': {
'verbose': bool,
'error-limit': int,
'severity': Enum,
}
}

config_source = self.initialize_config_source_with_env(ConfigGlobalSource, env)
self.assertConfigValueType(config_source, expected_type)
self.assertConfigValueType(config_source, expected_config_dict)


def test_get_config_dict_with_no_global_config(self):
env = {
'home_path': get_fixture_path('unexistent_home')
'home_path': get_fixture_path('unexistent_home'),
'xdg_config_home': get_fixture_path('unexistent_xdg_config_home'),
}

expected_config_dict = {}

config_source = self.initialize_config_source_with_env(ConfigGlobalSource, env)
self.assertConfigDict(config_source, expected_config_dict)


def test_get_config_dict_with_default_xdg_config_home(self):
env = {
'home_path': get_fixture_path('unexistent_home'),
'xdg_config_home': get_fixture_path('xdg_config_home'),
}
expected_config_dict = {
'cmdargs': {
'verbose': bool,
'error-limit': int,
'severity': Enum,
}
}
config_source = self.initialize_config_source_with_env(ConfigGlobalSource, env)
self.assertConfigValueType(config_source, expected_config_dict)


if __name__ == '__main__':
unittest.main()
6 changes: 5 additions & 1 deletion test/unit/vint/linting/test_env.py
Expand Up @@ -11,6 +11,7 @@ class TestEnv(unittest.TestCase):
def test_build_environment(self):
cwd = Path('path', 'to', 'cwd')
home = Path('/', 'home', 'user')
xdg_config_home = Path('/', 'home', 'user', '.config')

cmdargs = {
'verbose': True,
Expand All @@ -33,6 +34,7 @@ def test_build_environment(self):
Path(FIXTURE_PATH, 'sub', '4.vim'),
]),
'home_path': home,
'xdg_config_home': xdg_config_home,
'cwd': cwd,
}

Expand All @@ -42,7 +44,9 @@ def test_build_environment(self):

with mock.patch('os.path.expanduser') as mocked_expanduser:
mocked_expanduser.return_value = str(home)
env = build_environment(cmdargs)

with mock.patch.dict('os.environ', {'XDG_CONFIG_HOME': '/home/user/.config'}):
env = build_environment(cmdargs)

self.maxDiff = 1000
self.assertEqual(env, expected_env)
Expand Down
Empty file.
16 changes: 16 additions & 0 deletions test/unit/vint/utils/test_array.py
@@ -0,0 +1,16 @@
import unittest
from vint.utils.array import flatten, flat_map


class TestUtilsArray(unittest.TestCase):
def test_flatten_empty(self):
result = flatten([])
self.assertEqual(result, [])

def test_flatten_not_empty(self):
result = flatten([[0], [1, 2]])
self.assertEqual(result, [0, 1, 2])

def test_flat_map(self):
result = flat_map(lambda x: [x, x * 2], [0, 1, 2])
self.assertEqual(result, [0, 0, 1, 2, 2, 4])
5 changes: 5 additions & 0 deletions vint/linting/config/config_filenames.py
@@ -0,0 +1,5 @@
CONFIG_FILENAMES = [
'.vintrc.yaml',
'.vintrc.yml',
'.vintrc',
]
34 changes: 28 additions & 6 deletions vint/linting/config/config_global_source.py
@@ -1,16 +1,38 @@
from typing import Dict
from pathlib import Path
from vint.utils.array import flat_map
from vint.asset import get_asset_path
from vint.linting.config.config_filenames import CONFIG_FILENAMES
from vint.linting.config.config_file_source import ConfigFileSource

GLOBAL_CONFIG_FILENAME = '.vintrc.yaml'
VOID_CONFIG_PATH = get_asset_path('void_config.yaml')


class ConfigGlobalSource(ConfigFileSource):
def get_file_path(self, env):
global_config_path = Path(env['home_path'], GLOBAL_CONFIG_FILENAME)
global_config_paths = ConfigGlobalSource._get_filenames_candidates(env)

for global_config_path in global_config_paths:
if global_config_path.is_file():
return global_config_path

return VOID_CONFIG_PATH

@classmethod
def _get_filenames_candidates(cls, env):
# type: (Dict[str, str]) -> [Path]
global_config_dir_candidates = [
env['xdg_config_home'],
env['home_path'],
]

return flat_map(
lambda directory: ConfigGlobalSource._get_filenames_candidates_from_dir(directory),
global_config_dir_candidates
)

@classmethod
def _get_filenames_candidates_from_dir(cls, config_dir):
# type: (str) -> [Path]
return [Path(config_dir, filename) for filename in CONFIG_FILENAMES]

if global_config_path.is_file():
return global_config_path
else:
return VOID_CONFIG_PATH
16 changes: 12 additions & 4 deletions vint/linting/env.py
Expand Up @@ -7,17 +7,18 @@
def build_environment(cmdargs):
return {
'cmdargs': cmdargs,
'home_path': _get_home_path(cmdargs),
'cwd': _get_cwd(cmdargs),
'home_path': _get_home_path(),
'xdg_config_home': _get_xdg_config_home(),
'cwd': _get_cwd(),
'file_paths': _get_file_paths(cmdargs)
}


def _get_cwd(cmdargs):
def _get_cwd():
return Path(os.getcwd())


def _get_home_path(cmdargs):
def _get_home_path():
return Path(os.path.expanduser('~'))


Expand All @@ -28,3 +29,10 @@ def _get_file_paths(cmdargs):
found_file_paths = find_vim_script(map(Path, cmdargs['files']))

return set(found_file_paths)


def _get_xdg_config_home():
return Path(os.environ.get(
"XDG_CONFIG_HOME",
str(_get_home_path().joinpath(".config"))
))
Empty file added vint/utils/__init__.py
Empty file.
16 changes: 16 additions & 0 deletions vint/utils/array.py
@@ -0,0 +1,16 @@
from typing import TypeVar, List, Callable
from functools import reduce
from operator import add

T = TypeVar('T')
S = TypeVar('S')


def flatten(l):
# type: (List[List[T]]) -> List[T]
return reduce(add, l, [])


def flat_map(f, l):
# type: (Callable[[S], List[T]], List[S]) -> List[T]
return flatten([f(x) for x in l])

0 comments on commit 9816a31

Please sign in to comment.