diff --git a/.travis.yml b/.travis.yml index e84d8cc1..8f91d702 100644 --- a/.travis.yml +++ b/.travis.yml @@ -28,4 +28,4 @@ after_success: coveralls cache: directories: - $HOME/.cache/pip - - $HOME/.pre-commit + - $HOME/.cache/pre-commit diff --git a/appveyor.yml b/appveyor.yml index 013e1421..ddb9af3c 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -23,4 +23,4 @@ test_script: tox cache: - '%LOCALAPPDATA%\pip\cache' - - '%USERPROFILE%\.pre-commit' + - '%USERPROFILE%\.cache\pre-commit' diff --git a/pre_commit/commands/clean.py b/pre_commit/commands/clean.py index 8cea6fc1..75d0acc0 100644 --- a/pre_commit/commands/clean.py +++ b/pre_commit/commands/clean.py @@ -8,7 +8,9 @@ from pre_commit.util import rmtree def clean(runner): - if os.path.exists(runner.store.directory): - rmtree(runner.store.directory) - output.write_line('Cleaned {}.'.format(runner.store.directory)) + legacy_path = os.path.expanduser('~/.pre-commit') + for directory in (runner.store.directory, legacy_path): + if os.path.exists(directory): + rmtree(directory) + output.write_line('Cleaned {}.'.format(directory)) return 0 diff --git a/pre_commit/error_handler.py b/pre_commit/error_handler.py index b248f934..76662e97 100644 --- a/pre_commit/error_handler.py +++ b/pre_commit/error_handler.py @@ -28,10 +28,11 @@ def _log_and_exit(msg, exc, formatted): _to_bytes(exc), b'\n', )) output.write(error_msg) - output.write_line('Check the log at ~/.pre-commit/pre-commit.log') store = Store() store.require_created() - with open(os.path.join(store.directory, 'pre-commit.log'), 'wb') as log: + log_path = os.path.join(store.directory, 'pre-commit.log') + output.write_line('Check the log at {}'.format(log_path)) + with open(log_path, 'wb') as log: output.write(error_msg, stream=log) output.write_line(formatted, stream=log) raise SystemExit(1) diff --git a/pre_commit/store.py b/pre_commit/store.py index 263b315b..3262bda2 100644 --- a/pre_commit/store.py +++ b/pre_commit/store.py @@ -29,9 +29,9 @@ def _get_default_directory(): `Store.get_default_directory` can be mocked in tests and `_get_default_directory` can be tested. """ - return os.environ.get( - 'PRE_COMMIT_HOME', - os.path.join(os.path.expanduser('~'), '.pre-commit'), + return os.environ.get('PRE_COMMIT_HOME') or os.path.join( + os.environ.get('XDG_CACHE_HOME') or os.path.expanduser('~/.cache'), + 'pre-commit', ) diff --git a/tests/commands/clean_test.py b/tests/commands/clean_test.py index bdbdc998..fddd444d 100644 --- a/tests/commands/clean_test.py +++ b/tests/commands/clean_test.py @@ -2,18 +2,35 @@ from __future__ import unicode_literals import os.path +import mock +import pytest + from pre_commit.commands.clean import clean from pre_commit.util import rmtree -def test_clean(runner_with_mocked_store): +@pytest.fixture(autouse=True) +def fake_old_dir(tempdir_factory): + fake_old_dir = tempdir_factory.get() + + def _expanduser(path, *args, **kwargs): + assert path == '~/.pre-commit' + return fake_old_dir + + with mock.patch.object(os.path, 'expanduser', side_effect=_expanduser): + yield fake_old_dir + + +def test_clean(runner_with_mocked_store, fake_old_dir): + assert os.path.exists(fake_old_dir) assert os.path.exists(runner_with_mocked_store.store.directory) clean(runner_with_mocked_store) + assert not os.path.exists(fake_old_dir) assert not os.path.exists(runner_with_mocked_store.store.directory) def test_clean_empty(runner_with_mocked_store): - """Make sure clean succeeds when we the directory doesn't exist.""" + """Make sure clean succeeds when the directory doesn't exist.""" rmtree(runner_with_mocked_store.store.directory) assert not os.path.exists(runner_with_mocked_store.store.directory) clean(runner_with_mocked_store) diff --git a/tests/error_handler_test.py b/tests/error_handler_test.py index bdc54b6a..d6eaf500 100644 --- a/tests/error_handler_test.py +++ b/tests/error_handler_test.py @@ -81,12 +81,12 @@ def test_log_and_exit(cap_out, mock_out_store_directory): ) printed = cap_out.get() + log_file = os.path.join(mock_out_store_directory, 'pre-commit.log') assert printed == ( 'msg: FatalError: hai\n' - 'Check the log at ~/.pre-commit/pre-commit.log\n' + 'Check the log at {}\n'.format(log_file) ) - log_file = os.path.join(mock_out_store_directory, 'pre-commit.log') assert os.path.exists(log_file) contents = io.open(log_file).read() assert contents == ( @@ -102,6 +102,7 @@ def test_error_handler_non_ascii_exception(mock_out_store_directory): def test_error_handler_no_tty(tempdir_factory): + pre_commit_home = tempdir_factory.get() output = cmd_output_mocked_pre_commit_home( sys.executable, '-c', 'from __future__ import unicode_literals\n' @@ -110,8 +111,10 @@ def test_error_handler_no_tty(tempdir_factory): ' raise ValueError("\\u2603")\n', retcode=1, tempdir_factory=tempdir_factory, + pre_commit_home=pre_commit_home, ) + log_file = os.path.join(pre_commit_home, 'pre-commit.log') assert output[1].replace('\r', '') == ( 'An unexpected error has occurred: ValueError: ☃\n' - 'Check the log at ~/.pre-commit/pre-commit.log\n' + 'Check the log at {}\n'.format(log_file) ) diff --git a/tests/main_test.py b/tests/main_test.py index 4348b8ce..29c9ea29 100644 --- a/tests/main_test.py +++ b/tests/main_test.py @@ -2,6 +2,7 @@ from __future__ import absolute_import from __future__ import unicode_literals import argparse +import os.path import mock import pytest @@ -121,10 +122,11 @@ def test_expected_fatal_error_no_git_repo( with cwd(tempdir_factory.get()): with pytest.raises(SystemExit): main.main([]) + log_file = os.path.join(mock_out_store_directory, 'pre-commit.log') assert cap_out.get() == ( 'An error has occurred: FatalError: git failed. ' 'Is it installed, and are you in a Git repository directory?\n' - 'Check the log at ~/.pre-commit/pre-commit.log\n' + 'Check the log at {}\n'.format(log_file) ) diff --git a/tests/store_test.py b/tests/store_test.py index 106a4645..718f24d0 100644 --- a/tests/store_test.py +++ b/tests/store_test.py @@ -29,7 +29,15 @@ def test_our_session_fixture_works(): def test_get_default_directory_defaults_to_home(): # Not we use the module level one which is not mocked ret = _get_default_directory() - assert ret == os.path.join(os.path.expanduser('~'), '.pre-commit') + assert ret == os.path.join(os.path.expanduser('~/.cache'), 'pre-commit') + + +def test_adheres_to_xdg_specification(): + with mock.patch.dict( + os.environ, {'XDG_CACHE_HOME': '/tmp/fakehome'}, + ): + ret = _get_default_directory() + assert ret == os.path.join('/tmp/fakehome', 'pre-commit') def test_uses_environment_variable_when_present():