• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

abravalheri / validate-pyproject / 11034501584

25 Sep 2024 01:49PM CUT coverage: 97.823% (-0.2%) from 97.976%
11034501584

push

github

abravalheri
Prevent Github action for ignoring files for cache

551 of 571 branches covered (96.5%)

Branch coverage included in aggregate %.

932 of 945 relevant lines covered (98.62%)

5.91 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

100.0
/src/validate_pyproject/caching.py
1
# This module is intentionally kept minimal,
2
# so that it can be imported without triggering imports outside stdlib.
3
import hashlib
6✔
4
import io
6✔
5
import logging
6✔
6
import os
6✔
7
from pathlib import Path
6✔
8
from typing import Callable, Optional, Union
6✔
9

10
PathLike = Union[str, os.PathLike]
6✔
11
_logger = logging.getLogger(__name__)
6✔
12

13

14
def as_file(
6✔
15
    fn: Callable[[str], io.StringIO],
16
    arg: str,
17
    cache_dir: Optional[PathLike] = None,
18
) -> Union[io.StringIO, io.BufferedReader]:
19
    """
20
    Cache the result of calling ``fn(arg)`` into a file inside ``cache_dir``.
21
    The file name is derived from ``arg``.
22
    If no ``cache_dir`` is provided, it is equivalent to calling ``fn(arg)``.
23
    The return value can be used as a context.
24
    """
25
    cache_path = path_for(arg, cache_dir)
6✔
26
    if not cache_path:
6✔
27
        return fn(arg)
6✔
28

29
    if cache_path.exists():
6✔
30
        _logger.debug(f"Using cached {arg} from {cache_path}")
6✔
31
    else:
32
        with fn(arg) as f:
6✔
33
            cache_path.write_text(f.getvalue(), encoding="utf-8")
6✔
34
            _logger.debug(f"Caching {arg} into {cache_path}")
6✔
35

36
    return open(cache_path, "rb")  # noqa: SIM115 -- not relevant
6✔
37

38

39
def path_for(arbitrary_id: str, cache: Optional[PathLike] = None) -> Optional[Path]:
6✔
40
    cache_dir = cache or os.getenv("VALIDATE_PYPROJECT_CACHE_REMOTE")
6✔
41
    if not cache_dir:
6✔
42
        return None
6✔
43

44
    escaped = "".join(c if c.isalnum() else "-" for c in arbitrary_id)
6✔
45
    sha1 = hashlib.sha1(arbitrary_id.encode())  # noqa: S324
6✔
46
    # ^-- Non-crypto context and appending `escaped` should minimise collisions
47
    return Path(os.path.expanduser(cache_dir), f"{sha1.hexdigest()}-{escaped}")
6✔
48
    # ^-- Intentionally uses `os.path` instead of `pathlib` to avoid exception
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc