mirror of
https://github.com/NixOS/nixpkgs.git
synced 2025-06-10 19:55:41 +03:00
rustPlatform.fetchCargoVendor: dereference symlinks from entire git tree
We accidentally broke the symlink dereferencing logic in https://github.com/NixOS/nixpkgs/pull/379049 After that PR, only symlinks inside the crate subtree got dereferened, breaking packages which symlink files from a parent directory to the crate subtree This commit adds a custom ignore function for copytree instead of relying on ignore_dangling_symlinks=True
This commit is contained in:
parent
ec505766bb
commit
e14998cb44
1 changed files with 32 additions and 1 deletions
|
@ -7,6 +7,7 @@ import shutil
|
|||
import subprocess
|
||||
import sys
|
||||
import tomllib
|
||||
from os.path import islink, realpath
|
||||
from pathlib import Path
|
||||
from typing import Any, TypedDict, cast
|
||||
from urllib.parse import unquote
|
||||
|
@ -194,11 +195,41 @@ def find_crate_manifest_in_tree(tree: Path, crate_name: str) -> Path:
|
|||
|
||||
|
||||
def copy_and_patch_git_crate_subtree(git_tree: Path, crate_name: str, crate_out_dir: Path) -> None:
|
||||
|
||||
# This function will get called by copytree to decide which entries of a directory should be copied
|
||||
# We'll copy everything except symlinks that are invalid
|
||||
def ignore_func(dir_str: str, path_strs: list[str]) -> list[str]:
|
||||
ignorelist: list[str] = []
|
||||
|
||||
dir = Path(realpath(dir_str, strict=True))
|
||||
|
||||
for path_str in path_strs:
|
||||
path = dir / path_str
|
||||
if not islink(path):
|
||||
continue
|
||||
|
||||
# Filter out cyclic symlinks and symlinks pointing at nonexistant files
|
||||
try:
|
||||
target_path = Path(realpath(path, strict=True))
|
||||
except OSError:
|
||||
ignorelist.append(path_str)
|
||||
eprint(f"Failed to resolve symlink, ignoring: {path}")
|
||||
continue
|
||||
|
||||
# Filter out symlinks that point outside of the current crate's base git tree
|
||||
# This can be useful if the nix build sandbox is turned off and there is a symlink to a common absolute path
|
||||
if not target_path.is_relative_to(git_tree):
|
||||
ignorelist.append(path_str)
|
||||
eprint(f"Symlink points outside of the crate's base git tree, ignoring: {path} -> {target_path}")
|
||||
continue
|
||||
|
||||
return ignorelist
|
||||
|
||||
crate_manifest_path = find_crate_manifest_in_tree(git_tree, crate_name)
|
||||
crate_tree = crate_manifest_path.parent
|
||||
|
||||
eprint(f"Copying to {crate_out_dir}")
|
||||
shutil.copytree(crate_tree, crate_out_dir, ignore_dangling_symlinks=True)
|
||||
shutil.copytree(crate_tree, crate_out_dir, ignore=ignore_func)
|
||||
crate_out_dir.chmod(0o755)
|
||||
|
||||
with open(crate_manifest_path, "r") as f:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue