Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

path_utilities: allow path parts to be passed #378

Merged
merged 3 commits into from
Aug 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion edk2toollib/uefi/edk2/parsers/base_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ def FindPath(self, *p):
# If that fails, check in every possible Pkg path.
if self._Edk2PathUtil is not None:
target_path = os.path.join(*p)
Path = self._Edk2PathUtil.GetAbsolutePathOnThisSystemFromEdk2RelativePath(target_path, False)
Path = self._Edk2PathUtil.GetAbsolutePathOnThisSystemFromEdk2RelativePath(target_path, log_errors=False)
if Path is not None:
return Path

Expand Down
50 changes: 33 additions & 17 deletions edk2toollib/uefi/edk2/path_utilities.py
Original file line number Diff line number Diff line change
Expand Up @@ -185,20 +185,28 @@ def PackagePathList(self):
"""List of package paths as strings."""
return [str(p) for p in self._package_path_list]

def GetEdk2RelativePathFromAbsolutePath(self, abspath: str):
"""Given an absolute path return a edk2 path relative to workspace or packagespath.
def GetEdk2RelativePathFromAbsolutePath(self, *abspath: str) -> str:
"""Transforms an absolute path to an edk2 path relative to the workspace or a packages path.

Args:
abspath: absolute path to a file or directory. Supports both Windows and Posix style paths
*abspath: absolute path to a file or directory. Can be the entire path or parts of the path provided
separately. Supports both Windows and Posix style paths
Javagedes marked this conversation as resolved.
Show resolved Hide resolved

Returns:
(str): POSIX-like relative path to workspace or packagespath
(None): abspath is none
(str): POSIX-like path relative to the workspace or packages path
(None): abspath is None
(None): path is not valid

Example:
```python
rel_path = edk2path.GetEdk2RelativePathFromAbsolutePath("C:/Workspace/edk2/MdePkg/Include")
rel_path = edk2path.GetEdk2RelativePathFromAbsolutePath("C:/Workspace", "edk2", "MdePkg", "Include")
```
"""
if abspath is None:
if abspath == (None,):
return None
abspath = Path(abspath.replace("\\", "/"))

abspath = Path(*[part.replace("\\", "/") for part in abspath])

relpath = None
found = False
Expand Down Expand Up @@ -234,21 +242,28 @@ def GetEdk2RelativePathFromAbsolutePath(self, abspath: str):
self.logger.error(f'AbsolutePath: {abspath}')
return None

def GetAbsolutePathOnThisSystemFromEdk2RelativePath(self, relpath: str, log_errors: Optional[bool]=True):
"""Given a edk2 relative path return an absolute path to the file in this workspace.
def GetAbsolutePathOnThisSystemFromEdk2RelativePath(self, *relpath: str, log_errors: Optional[bool]=True) -> str:
"""Given a relative path return an absolute path to the file in this workspace.

Args:
relpath: Relative path to convert. Supports both Windows and Posix style paths.
*relpath: Relative path to convert. Can be the entire path or parts of the path provided separately
Javagedes marked this conversation as resolved.
Show resolved Hide resolved
log_errors: whether to log errors

Returns:
(str): absolute path in the OS specific form
(None): invalid relpath
(None): Unable to get the absolute path

Example:
```python
abs_path = edk2path.GetAbsolutePathOnThisSystemFromEdk2RelativePath("MdePkg/Include")
abs_path = edk2path.GetAbsolutePathOnThisSystemFromEdk2RelativePath("MdePkg", "Include")
```
"""
if relpath is None:
if relpath == (None,):
return None
relpath = relpath.replace("\\", "/")

relpath = Path(*[part.replace("\\", "/") for part in relpath])
abspath = self._workspace_path / relpath
if abspath.exists():
return str(abspath)
Expand All @@ -264,15 +279,16 @@ def GetAbsolutePathOnThisSystemFromEdk2RelativePath(self, relpath: str, log_erro
return None

def GetContainingPackage(self, InputPath: str) -> str:
"""Find the package that contains the given path.
"""Finds the package that contains the given path.

This isn't perfect, but at least identifies the direcotry consistently.

This isn't perfect but at least identifies the directory consistently.

Args:
InputPath: absolute path to a file, directory, or module. Supports both windows and linux like paths.
InputPath: absolute path to a file, directory, or module. Supports both windows and posix paths.

Returns:
(str): name of the package that the module is in.
(str): name of the package that the path is in.
"""
self.logger.debug("GetContainingPackage: %s" % InputPath)
InputPath = Path(InputPath.replace("\\", "/"))
Expand Down Expand Up @@ -326,7 +342,7 @@ def GetContainingModules(self, input_path: str) -> list[str]:

Args:
input_path: Absolute path to a file, directory, or module.
Supports both Windows and Posix like paths.
Supports both Windows and Posix like paths.

Returns:
(list[str]): Absolute paths of .inf files that could be the
Expand Down
48 changes: 47 additions & 1 deletion tests.unit/test_path_utilities.py
Original file line number Diff line number Diff line change
Expand Up @@ -753,11 +753,17 @@ def test_get_edk2_relative_path_from_absolute_path_posix(self):
actual_rel_from_abs_path = pathobj.GetEdk2RelativePathFromAbsolutePath(p)
self.assertEqual(expected_rel_from_abs_path, actual_rel_from_abs_path)

actual_rel_from_abs_path = pathobj.GetEdk2RelativePathFromAbsolutePath(pp_pkg_abs, "module1", "module1.INF")
self.assertEqual(expected_rel_from_abs_path, actual_rel_from_abs_path)

p = os.path.join(ws_pkg_abs, "module_2", "X64", "TestFile.inf")
expected_rel_from_abs_path = PurePath(os.path.join(ws_p_name, "module_2", "X64", "TestFile.inf")).as_posix()
actual_rel_from_abs_path = pathobj.GetEdk2RelativePathFromAbsolutePath(p)
self.assertEqual(expected_rel_from_abs_path, actual_rel_from_abs_path)

actual_rel_from_abs_path = pathobj.GetEdk2RelativePathFromAbsolutePath(ws_pkg_abs, "module_2", "X64", "TestFile.inf")
self.assertEqual(expected_rel_from_abs_path, actual_rel_from_abs_path)

def test_get_edk2_relative_path_from_absolute_path(self):
'''Test basic usage of GetEdk2RelativePathFromAbsolutePath with packages path nested
inside the workspace.
Expand Down Expand Up @@ -803,33 +809,40 @@ def test_get_edk2_relative_path_from_absolute_path(self):
# file in workspace
p = os.path.join(ws_pkg_abs, "module2", "X64", "TestFile.c")
self.assertEqual(pathobj.GetEdk2RelativePathFromAbsolutePath(p), f"{ws_p_name}/module2/X64/TestFile.c")
self.assertEqual(pathobj.GetEdk2RelativePathFromAbsolutePath(ws_pkg_abs, "module2", "X64", "TestFile.c"), f"{ws_p_name}/module2/X64/TestFile.c")

# Folder in packages path
p = os.path.join(pp_pkg_abs, "module2", "X64")
self.assertEqual(pathobj.GetEdk2RelativePathFromAbsolutePath(p), f"{pp_p_name}/module2/X64")
self.assertEqual(pathobj.GetEdk2RelativePathFromAbsolutePath(pp_pkg_abs, "module2", "X64"), f"{pp_p_name}/module2/X64")

# Folder in workspace
p = os.path.join(ws_pkg_abs, "module2", "X64")
self.assertEqual(pathobj.GetEdk2RelativePathFromAbsolutePath(p), f"{ws_p_name}/module2/X64")
self.assertEqual(pathobj.GetEdk2RelativePathFromAbsolutePath(ws_pkg_abs, "module2", "X64"), f"{ws_p_name}/module2/X64")

# file not in workspace
p = os.path.join(self.tmp, "module2", "X64", "TestFile.c")
self.assertIsNone(pathobj.GetEdk2RelativePathFromAbsolutePath(p))
self.assertIsNone(pathobj.GetEdk2RelativePathFromAbsolutePath(self.tmp, "module2", "X64", "TestFile.c"))

# pass in bad parameter
self.assertIsNone(pathobj.GetEdk2RelativePathFromAbsolutePath(None))

# file is outside of code tree and not absolute path
p = os.path.join("module2", "X64", "TestFile.c")
self.assertIsNone(pathobj.GetEdk2RelativePathFromAbsolutePath(p))
self.assertIsNone(pathobj.GetAbsolutePathOnThisSystemFromEdk2RelativePath("module2", "X64", "TestFile.c"))

# file is cwd relative but not absolute path
p = os.path.join(ws_rel, ws_p_name, "module2", "X64", "TestFile.c")
self.assertIsNone(pathobj.GetEdk2RelativePathFromAbsolutePath(p))
self.assertIsNone(pathobj.GetEdk2RelativePathFromAbsolutePath(ws_rel, ws_p_name, "module2", "X64", "TestFile.c"))

# ensure converted path keeps original capitalization
p = os.path.join(ws_pkg_abs, "Module2", "x64", "TESTFILE.C")
self.assertEqual(pathobj.GetEdk2RelativePathFromAbsolutePath(p), f"{ws_p_name}/Module2/x64/TESTFILE.C")
self.assertEqual(pathobj.GetEdk2RelativePathFromAbsolutePath(ws_pkg_abs, "Module2", "x64", "TESTFILE.C"), f"{ws_p_name}/Module2/x64/TESTFILE.C")

def test_get_relative_path_when_packages_path_list_contains_substrings(self):
'''Test usage of GetEdk2RelativePathFromAbsolutePath when members of PackagePathList contain
Expand Down Expand Up @@ -868,6 +881,7 @@ def test_get_relative_path_when_packages_path_list_contains_substrings(self):
# file in workspace
p = os.path.join(ws_pkg_abs, "module2", "X64", "TestFile2.c")
self.assertEqual(pathobj.GetEdk2RelativePathFromAbsolutePath(p), f"{ws_p_name}/module2/X64/TestFile2.c")
self.assertEqual(pathobj.GetEdk2RelativePathFromAbsolutePath(ws_pkg_abs, "module2", "X64", "TestFile2.c"), f"{ws_p_name}/module2/X64/TestFile2.c")

def test_get_relative_path_when_package_path_inside_package(self):
'''Test a package_path directory inside the subfolders of a package.
Expand Down Expand Up @@ -905,6 +919,7 @@ def test_get_relative_path_when_package_path_inside_package(self):
pathobj = Edk2Path(folder_ws_abs, [folder_pp1_abs, folder_pp2_abs])
p = os.path.join(pp1_abs, "module2", "X64", "TestFile.c")
self.assertEqual(pathobj.GetEdk2RelativePathFromAbsolutePath(p), f"{pp1_name}/module2/X64/TestFile.c")
self.assertEqual(pathobj.GetEdk2RelativePathFromAbsolutePath(pp1_abs, "module2", "X64", "TestFile.c"), f"{pp1_name}/module2/X64/TestFile.c")

def test_get_relative_path_with_nested_packages(self):
'''Test a two package paths that contain nested packages.
Expand Down Expand Up @@ -1016,10 +1031,18 @@ def test_get_relative_path_when_folder_is_next_to_package(self):
pathobj = Edk2Path(folder_ws_abs, [folder_pp1_abs, folder_pp2_abs])
self.assertEqual(pathobj.GetEdk2RelativePathFromAbsolutePath(p1), f'{pp1_name}/module2/X64/TestFile2.c')
self.assertEqual(pathobj.GetEdk2RelativePathFromAbsolutePath(p2), f'{pp2_name}/module2/X64/TestFile2.c')
self.assertEqual(pathobj.GetEdk2RelativePathFromAbsolutePath(pp1_abs, "module2", "X64", "TestFile2.c"),
f'{pp1_name}/module2/X64/TestFile2.c')
self.assertEqual(pathobj.GetEdk2RelativePathFromAbsolutePath(pp2_abs, "module2", "X64", "TestFile2.c"),
f'{pp2_name}/module2/X64/TestFile2.c')

pathobj = Edk2Path(folder_ws_abs, [folder_pp2_abs, folder_pp1_abs])
self.assertEqual(pathobj.GetEdk2RelativePathFromAbsolutePath(p1), f'{pp1_name}/module2/X64/TestFile2.c')
self.assertEqual(pathobj.GetEdk2RelativePathFromAbsolutePath(p2), f'{pp2_name}/module2/X64/TestFile2.c')
self.assertEqual(pathobj.GetEdk2RelativePathFromAbsolutePath(pp1_abs, "module2", "X64", "TestFile2.c"),
f'{pp1_name}/module2/X64/TestFile2.c')
self.assertEqual(pathobj.GetEdk2RelativePathFromAbsolutePath(pp2_abs, "module2", "X64", "TestFile2.c"),
f'{pp2_name}/module2/X64/TestFile2.c')

def test_get_relative_path_when_path_does_not_exist(self):
'''Test basic usage of GetEdk2RelativePathFromAbsolutePath with packages path nested
Expand Down Expand Up @@ -1062,26 +1085,38 @@ def test_get_relative_path_when_path_does_not_exist(self):
# not existant file in packages path
p = os.path.join(pp_pkg_abs, "module1", "FAKE.INF")
self.assertEqual(pathobj.GetEdk2RelativePathFromAbsolutePath(p), f"{pp_p_name}/module1/FAKE.INF")
p = (pp_pkg_abs, "module1", "FAKE.INF")
self.assertEqual(pathobj.GetEdk2RelativePathFromAbsolutePath(*p), f"{pp_p_name}/module1/FAKE.INF")

# non existant file in non existant directory in packages path
p = os.path.join(ws_pkg_abs, "module2", "X64", "FAKE", "FAKE.c")
self.assertEqual(pathobj.GetEdk2RelativePathFromAbsolutePath(p), f"{ws_p_name}/module2/X64/FAKE/FAKE.c")
p = (ws_pkg_abs, "module2", "X64", "FAKE", "FAKE.c")
self.assertEqual(pathobj.GetEdk2RelativePathFromAbsolutePath(*p), f"{ws_p_name}/module2/X64/FAKE/FAKE.c")

# not existant file in workspace
p = os.path.join(ws_pkg_abs, "module2", "X64", "FAKE.c")
self.assertEqual(pathobj.GetEdk2RelativePathFromAbsolutePath(p), f"{ws_p_name}/module2/X64/FAKE.c")
p = (ws_pkg_abs, "module2", "X64", "FAKE.c")
self.assertEqual(pathobj.GetEdk2RelativePathFromAbsolutePath(*p), f"{ws_p_name}/module2/X64/FAKE.c")

# not existant file not in workspace
p = os.path.join(self.tmp, "module2", "X64", "FAKE.c")
self.assertIsNone(pathobj.GetEdk2RelativePathFromAbsolutePath(p))
p = (self.tmp, "module2", "X64", "FAKE.c")
self.assertIsNone(pathobj.GetEdk2RelativePathFromAbsolutePath(*p))

# not existant file is outside of code tree and not absolute path
p = os.path.join("module2", "X64", "FAKE.c")
self.assertIsNone(pathobj.GetEdk2RelativePathFromAbsolutePath(p))
p = ("module2", "X64", "FAKE.c")
self.assertIsNone(pathobj.GetEdk2RelativePathFromAbsolutePath(*p))

# not existant file is cwd relative but not absolute path
p = os.path.join(ws_rel, ws_p_name, "module2", "X64", "FAKE.c")
self.assertIsNone(pathobj.GetEdk2RelativePathFromAbsolutePath(p))
p = (ws_rel, ws_p_name, "module2", "X64", "FAKE.c")
self.assertIsNone(pathobj.GetEdk2RelativePathFromAbsolutePath(*p))

def test_get_relative_path_when_package_is_not_directly_inside_packages_path(self):
'''Test basic usage of GetEdk2RelativePathFromAbsolutePath when the
Expand Down Expand Up @@ -1116,6 +1151,9 @@ def test_get_relative_path_when_package_is_not_directly_inside_packages_path(sel
p = os.path.join(ws_pkg_abs, "PPTestPkg.dec")
self.assertEqual(pathobj.GetEdk2RelativePathFromAbsolutePath(p),
f"{folder_extra_rel}/{ws_p_name}/{ws_p_name}.dec")
p = (ws_pkg_abs, "PPTestPkg.dec")
self.assertEqual(pathobj.GetEdk2RelativePathFromAbsolutePath(*p),
f"{folder_extra_rel}/{ws_p_name}/{ws_p_name}.dec")

def test_get_edk2_relative_path_with_windows_path_on_linux(self):
'''Test basic usage of GetEdk2RelativePathFromAbsolutePath when the
Expand Down Expand Up @@ -1149,6 +1187,9 @@ def test_get_edk2_relative_path_with_windows_path_on_linux(self):
p = f"{ws_pkg_abs}\\module2\\X64\\TestFile.c"
self.assertEqual(pathobj.GetEdk2RelativePathFromAbsolutePath(p),
f"{folder_extra_rel}/PPTestPkg/module2/X64/TestFile.c")
p = (ws_pkg_abs, "module2", "X64", "TestFile.c")
self.assertEqual(pathobj.GetEdk2RelativePathFromAbsolutePath(*p),
f"{folder_extra_rel}/PPTestPkg/module2/X64/TestFile.c")

def test_get_absolute_path_on_this_system_from_edk2_relative_path(self):
'''Test basic usage of GetAbsolutePathOnThisSystemFromEdk2RelativePath with packages path nested
Expand Down Expand Up @@ -1190,11 +1231,13 @@ def test_get_absolute_path_on_this_system_from_edk2_relative_path(self):

# file in packages path
ep = os.path.join(pp_pkg_abs, "module1", "module1.INF")
self.assertEqual(pathobj.GetAbsolutePathOnThisSystemFromEdk2RelativePath(pp_p_name, "module1", "module1.INF"), ep)
rp = f"{pp_p_name}/module1/module1.INF"
self.assertEqual(pathobj.GetAbsolutePathOnThisSystemFromEdk2RelativePath(rp), ep)

# file in workspace
ep = os.path.join(ws_pkg_abs, "module2", "X64", "TestFile.c")
self.assertEqual(pathobj.GetAbsolutePathOnThisSystemFromEdk2RelativePath(ws_p_name, "module2", "X64", "TestFile.c"), ep)
rp = f"{ws_p_name}/module2/X64/TestFile.c"
self.assertEqual(pathobj.GetAbsolutePathOnThisSystemFromEdk2RelativePath(rp), ep)

Expand Down Expand Up @@ -1236,8 +1279,11 @@ def test_get_absolute_path_then_relative_path_when_path_contains_repeated_packag

# Check getting absolute path from relative path
abspath = pathobj.GetAbsolutePathOnThisSystemFromEdk2RelativePath(
os.path.join(ws_pkg_name, ws_pkg_name + ".dec"))
ws_pkg_name, ws_pkg_name + ".dec")
self.assertEqual(abspath, os.path.join(ws_pkg_abs, "ClientPkg.dec"))

abspath = pathobj.GetAbsolutePathOnThisSystemFromEdk2RelativePath(
os.path.join(ws_pkg_name, ws_pkg_name + ".dec"))
self.assertEqual(abspath, os.path.join(ws_pkg_abs, "ClientPkg.dec"))

# check get relative path from abs path
Expand Down