mirror of
https://github.com/NixOS/nixpkgs.git
synced 2025-06-16 06:29:17 +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 subprocess
|
||||||
import sys
|
import sys
|
||||||
import tomllib
|
import tomllib
|
||||||
|
from os.path import islink, realpath
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Any, TypedDict, cast
|
from typing import Any, TypedDict, cast
|
||||||
from urllib.parse import unquote
|
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:
|
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_manifest_path = find_crate_manifest_in_tree(git_tree, crate_name)
|
||||||
crate_tree = crate_manifest_path.parent
|
crate_tree = crate_manifest_path.parent
|
||||||
|
|
||||||
eprint(f"Copying to {crate_out_dir}")
|
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)
|
crate_out_dir.chmod(0o755)
|
||||||
|
|
||||||
with open(crate_manifest_path, "r") as f:
|
with open(crate_manifest_path, "r") as f:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue