Skip to content

Commit

Permalink
Allow setting custom cache directory on all platforms with environmen…
Browse files Browse the repository at this point in the history
…t variable BLACK_CACHE_DIR
  • Loading branch information
percurnicus committed Jan 1, 2022
1 parent 4f5268a commit 262ff18
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 6 deletions.
2 changes: 2 additions & 0 deletions CHANGES.md
Expand Up @@ -17,6 +17,8 @@
- Tuple unpacking on `return` and `yield` constructs now implies 3.8+ (#2700)
- Unparenthesized tuples on annotated assignments (e.g
`values: Tuple[int, ...] = 1, 2, 3`) now implies 3.8+ (#2708)
- Allow setting custom cache directory on all platforms with environment variable
`BLACK_CACHE_DIR` (#2739).

### Packaging

Expand Down
2 changes: 2 additions & 0 deletions docs/contributing/reference/reference_functions.rst
Expand Up @@ -96,6 +96,8 @@ Caching

.. autofunction:: black.cache.filter_cached

.. autofunction:: black.cache.get_cache_dir

.. autofunction:: black.cache.get_cache_file

.. autofunction:: black.cache.get_cache_info
Expand Down
9 changes: 5 additions & 4 deletions docs/usage_and_configuration/file_collection_and_discovery.md
Expand Up @@ -22,10 +22,11 @@ run. The file is non-portable. The standard location on common operating systems
`file-mode` is an int flag that determines whether the file was formatted as 3.6+ only,
as .pyi, and whether string normalization was omitted.

To override the location of these files on macOS or Linux, set the environment variable
`XDG_CACHE_HOME` to your preferred location. For example, if you want to put the cache
in the directory you're running _Black_ from, set `XDG_CACHE_HOME=.cache`. _Black_ will
then write the above files to `.cache/black/<version>/`.
To override the location of these files on all systems, set the environment variable
`BLACK_CACHE_DIR` to the preferred location. Alternatively on macOS and Linux, set
`XDG_CACHE_HOME` to you your preferred location. For example, if you want to put the
cache in the directory you're running _Black_ from, set `BLACK_CACHE_DIR=.cache/black`.
_Black_ will then write the above files to `.cache/black`.

## .gitignore

Expand Down
18 changes: 17 additions & 1 deletion src/black/cache.py
Expand Up @@ -20,7 +20,23 @@
Cache = Dict[str, CacheInfo]


CACHE_DIR = Path(user_cache_dir("black", version=__version__))
def get_cache_dir() -> Path:
"""Get the cache directory used by black.
Users can customize this directory on all systems using `BLACK_CACHE_DIR`
environment variable. By default, the cache directory is the user cache directory
under the black application.
This result is immediately set to a constant `black.cache.CACHE_DIR` as to avoid
repeated calls.
"""
# NOTE: Function mostly exists as a clean way to test getting the cache directory.
default_cache_dir = user_cache_dir("black", version=__version__)
cache_dir = Path(os.environ.get("BLACK_CACHE_DIR", default_cache_dir))
return cache_dir


CACHE_DIR = get_cache_dir()


def read_cache(mode: Mode) -> Cache:
Expand Down
29 changes: 28 additions & 1 deletion tests/test_black.py
Expand Up @@ -40,7 +40,7 @@
import black.files
from black import Feature, TargetVersion
from black import re_compile_maybe_verbose as compile_pattern
from black.cache import get_cache_file
from black.cache import get_cache_dir, get_cache_file
from black.debug import DebugVisitor
from black.output import color_diff, diff
from black.report import Report
Expand Down Expand Up @@ -1616,6 +1616,33 @@ def test_equivalency_ast_parse_failure_includes_error(self) -> None:


class TestCaching:
def test_get_cache_dir(
self,
tmp_path: Path,
monkeypatch: pytest.MonkeyPatch,
) -> None:
# Create multiple cache directories
workspace1 = tmp_path / "ws1"
workspace1.mkdir()
workspace2 = tmp_path / "ws2"
workspace2.mkdir()

# Force user_cache_dir to use the temporary directory for easier assertions
patch_user_cache_dir = patch(
target="black.cache.user_cache_dir",
autospec=True,
return_value=str(workspace1),
)

# If BLACK_CACHE_DIR is not set, use user_cache_dir
monkeypatch.delenv("BLACK_CACHE_DIR", raising=False)
with patch_user_cache_dir:
assert get_cache_dir() == workspace1

# If it is set, use the path provided in the env var.
monkeypatch.setenv("BLACK_CACHE_DIR", str(workspace2))
assert get_cache_dir() == workspace2

def test_cache_broken_file(self) -> None:
mode = DEFAULT_MODE
with cache_dir() as workspace:
Expand Down

0 comments on commit 262ff18

Please sign in to comment.