| 86 | |
| 87 | |
| 88 | class FilesystemMetadataStore(MetadataStore): |
| 89 | def __init__(self, cache_dir_prefix: str) -> None: |
| 90 | # We check startswith instead of equality because the version |
| 91 | # will have already been appended by the time the cache dir is |
| 92 | # passed here. |
| 93 | if cache_dir_prefix.startswith(os.devnull): |
| 94 | self.cache_dir_prefix = None |
| 95 | else: |
| 96 | self.cache_dir_prefix = cache_dir_prefix |
| 97 | |
| 98 | def getmtime(self, name: str) -> float: |
| 99 | if not self.cache_dir_prefix: |
| 100 | raise FileNotFoundError() |
| 101 | |
| 102 | return int(os.path.getmtime(os_path_join(self.cache_dir_prefix, name))) |
| 103 | |
| 104 | def read(self, name: str) -> bytes: |
| 105 | assert not os.path.isabs(name), "Don't use absolute paths!" |
| 106 | |
| 107 | if not self.cache_dir_prefix: |
| 108 | raise FileNotFoundError() |
| 109 | |
| 110 | with open(os_path_join(self.cache_dir_prefix, name), "rb", buffering=0) as f: |
| 111 | return f.read() |
| 112 | |
| 113 | def write(self, name: str, data: bytes, mtime: float | None = None) -> bool: |
| 114 | assert not os.path.isabs(name), "Don't use absolute paths!" |
| 115 | |
| 116 | if not self.cache_dir_prefix: |
| 117 | return False |
| 118 | |
| 119 | path = os_path_join(self.cache_dir_prefix, name) |
| 120 | tmp_filename = path + "." + random_string() |
| 121 | try: |
| 122 | os.makedirs(os.path.dirname(path), exist_ok=True) |
| 123 | with open(tmp_filename, "wb") as f: |
| 124 | f.write(data) |
| 125 | os.replace(tmp_filename, path) |
| 126 | if mtime is not None: |
| 127 | os.utime(path, times=(mtime, mtime)) |
| 128 | |
| 129 | except OSError: |
| 130 | return False |
| 131 | return True |
| 132 | |
| 133 | def remove(self, name: str) -> None: |
| 134 | if not self.cache_dir_prefix: |
| 135 | raise FileNotFoundError() |
| 136 | |
| 137 | os.remove(os_path_join(self.cache_dir_prefix, name)) |
| 138 | |
| 139 | def commit(self) -> None: |
| 140 | pass |
| 141 | |
| 142 | def list_all(self) -> Iterable[str]: |
| 143 | if not self.cache_dir_prefix: |
| 144 | return |
| 145 |
no outgoing calls
no test coverage detected
searching dependent graphs…