|
1 | 1 | import os
|
2 |
| -from collections.abc import Iterator |
| 2 | +import shutil |
| 3 | +from collections.abc import Iterable, Iterator |
3 | 4 | from contextlib import contextmanager
|
4 | 5 | from functools import cached_property
|
5 | 6 | from pathlib import Path
|
6 |
| -from typing import TYPE_CHECKING, Any, Optional |
| 7 | +from typing import TYPE_CHECKING, Any, Optional, Union |
7 | 8 |
|
8 | 9 | from ape.api.config import ApeConfig
|
9 | 10 | from ape.managers.base import BaseManager
|
@@ -113,20 +114,41 @@ def extract_config(cls, manifest: "PackageManifest", **overrides) -> ApeConfig:
|
113 | 114 | return ApeConfig.from_manifest(manifest, **overrides)
|
114 | 115 |
|
115 | 116 | @contextmanager
|
116 |
| - def isolate_data_folder(self) -> Iterator[Path]: |
| 117 | + def isolate_data_folder( |
| 118 | + self, keep: Optional[Union[Iterable[str], str]] = None |
| 119 | + ) -> Iterator[Path]: |
117 | 120 | """
|
118 | 121 | Change Ape's DATA_FOLDER to point a temporary path,
|
119 | 122 | in a context, for testing purposes. Any data
|
120 | 123 | cached to disk will not persist.
|
| 124 | +
|
| 125 | + Args: |
| 126 | + keep (Optional[Union[Iterable[str], str]]): Optionally, pass in |
| 127 | + a key of subdirectory names to include in the new isolated |
| 128 | + data folder. For example, pass ing ``"packages"`` to avoid |
| 129 | + having to re-download dependencies in an isolated environment. |
| 130 | +
|
| 131 | + Returns: |
| 132 | + Iterator[Path]: The temporary data folder. |
121 | 133 | """
|
122 | 134 | original_data_folder = self.DATA_FOLDER
|
123 | 135 | if in_tempdir(original_data_folder):
|
124 | 136 | # Already isolated.
|
125 | 137 | yield original_data_folder
|
126 | 138 |
|
127 | 139 | else:
|
| 140 | + keep = [keep] if isinstance(keep, str) else keep or [] |
128 | 141 | try:
|
129 | 142 | with create_tempdir() as temp_data_folder:
|
| 143 | + # Copy in items from "keep". |
| 144 | + for item in keep: |
| 145 | + path_to_keep = original_data_folder / item |
| 146 | + if not path_to_keep.is_dir(): |
| 147 | + continue |
| 148 | + |
| 149 | + dest_path = temp_data_folder / item |
| 150 | + shutil.copytree(path_to_keep, dest_path) |
| 151 | + |
130 | 152 | self.DATA_FOLDER = temp_data_folder
|
131 | 153 | yield temp_data_folder
|
132 | 154 |
|
|
0 commit comments