MCPcopy Create free account
hub / github.com/conda/constructor / check_duplicates_files

Function check_duplicates_files

constructor/fcp.py:152–245  ·  view source on GitHub ↗

Check for duplicate files across packages and compute size/path metrics. Iterates through all files in the provided package cache records to: 1. Detect duplicate files (same path in multiple packages) 2. Compute approximate tarball and extracted sizes 3. Track the longest relat

(
    pc_recs: Iterable[PackageCacheRecord],
    platform: str,
    duplicate_files: Literal["error", "warn", "skip"] = "error",
    env_prefixes: dict[PackageCacheRecord, str] | None = None,
)

Source from the content-addressed store, hash-verified

150
151
152def check_duplicates_files(
153 pc_recs: Iterable[PackageCacheRecord],
154 platform: str,
155 duplicate_files: Literal["error", "warn", "skip"] = "error",
156 env_prefixes: dict[PackageCacheRecord, str] | None = None,
157) -> tuple[int, int, int]:
158 """
159 Check for duplicate files across packages and compute size/path metrics.
160
161 Iterates through all files in the provided package cache records to:
162 1. Detect duplicate files (same path in multiple packages)
163 2. Compute approximate tarball and extracted sizes
164 3. Track the longest relative file path (for MAX_PATH validation on Windows)
165
166 Args:
167 pc_recs: Package cache records to check.
168 platform: Target platform string (e.g., "win-64", "linux-64").
169 duplicate_files: How to handle duplicates - "error", "warn", or "skip".
170 env_prefixes: Optional dict mapping PackageCacheRecord -> path prefix string.
171 Used to account for extra_envs paths which are installed under
172 "envs/<name>/" rather than the base install directory. Records not
173 in this dict are assumed to be in the base environment (no prefix).
174 A trailing separator is added automatically if missing.
175
176 Returns:
177 Tuple of (approx_tarball_size, approx_extracted_size, max_relative_path_length)
178 """
179 assert duplicate_files in ("warn", "skip", "error")
180 if env_prefixes is None:
181 env_prefixes = {}
182 for env, prefix in env_prefixes.items():
183 if prefix and not prefix.endswith("/"):
184 env_prefixes[env] += "/"
185
186 map_members_scase = defaultdict(set)
187 map_members_icase = defaultdict(lambda: {"files": set(), "fns": set()})
188
189 # Keep a min, 50MB buffer size
190 total_tarball_size = 52428800
191 total_extracted_pkgs_size = 52428800
192 max_relative_path_length = 0
193
194 for pc_rec in pc_recs:
195 fn = pc_rec.fn
196 extracted_package_dir = pc_rec.extracted_package_dir
197
198 total_tarball_size += int(pc_rec.get("size", 0))
199
200 paths_data = read_paths_json(extracted_package_dir).paths
201 env_prefix_len = len(env_prefixes.get(pc_rec, ""))
202 for path_data in paths_data:
203 short_path = path_data.path
204 max_relative_path_length = max(
205 max_relative_path_length, env_prefix_len + len(short_path)
206 )
207 try:
208 size = path_data.size_in_bytes or getsize(join(extracted_package_dir, short_path))
209 except AttributeError:

Calls 2

getsizeFunction · 0.85
getMethod · 0.80