Skip to content

Commit 3e0cf67

Browse files
ben-ednaspoorcc
authored andcommitted
Make all paths absolute and resolve them
fixes #946
1 parent 6cf1a72 commit 3e0cf67

2 files changed

Lines changed: 22 additions & 6 deletions

File tree

dfetch/project/superproject.py

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
from dfetch.project.git import GitSubProject
2020
from dfetch.project.subproject import SubProject
2121
from dfetch.project.svn import SvnSubProject
22+
from dfetch.util.util import resolve_absolute_path
2223
from dfetch.vcs.git import GitLocalRepo
2324
from dfetch.vcs.svn import SvnRepo
2425

@@ -40,7 +41,9 @@ def __init__(self) -> None:
4041

4142
logger.debug(f"Using manifest {manifest_path}")
4243
self._manifest = parse(manifest_path)
43-
self._root_directory = os.path.dirname(self._manifest.path)
44+
self._root_directory = str(
45+
resolve_absolute_path(os.path.dirname(self._manifest.path))
46+
)
4447

4548
@property
4649
def root_directory(self) -> str:
@@ -63,11 +66,13 @@ def get_sub_project(self, project: ProjectEntry) -> SubProject | None:
6366

6467
def ignored_files(self, path: str) -> Sequence[str]:
6568
"""Return a list of files that can be ignored in a given path."""
66-
if (
67-
os.path.commonprefix((pathlib.Path(path).resolve(), self.root_directory))
68-
!= self.root_directory
69-
):
70-
raise RuntimeError(f"{path} not in superproject {self.root_directory}!")
69+
resolved_path = resolve_absolute_path(path)
70+
root_path = pathlib.Path(self.root_directory)
71+
72+
if not resolved_path.is_relative_to(root_path):
73+
raise RuntimeError(
74+
f"{resolved_path} not in superproject {self.root_directory}! "
75+
)
7176

7277
if GitLocalRepo(self.root_directory).is_git():
7378
return GitLocalRepo.ignored_files(path)

dfetch/util/util.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,3 +159,14 @@ def str_if_possible(data: list[str]) -> Union[str, list[str]]:
159159
if the list is empty, otherwise the original list.
160160
"""
161161
return "" if not data else data[0] if len(data) == 1 else data
162+
163+
164+
def resolve_absolute_path(path: Union[str, Path]) -> Path:
165+
"""
166+
Return a guaranteed absolute Path, resolving symlinks.
167+
168+
Notes:
169+
- Uses os.path.realpath for reliable absolute paths across platforms.
170+
- Handles Windows drive-relative paths and expands '~'.
171+
"""
172+
return Path(os.path.realpath(Path(path).expanduser()))

0 commit comments

Comments
 (0)