Skip to content

Commit

Permalink
Support passing the name of custom env vars as additional search paths (
Browse files Browse the repository at this point in the history
#13)

Co-authored-by: Silvio Traversaro <silvio.traversaro@iit.it>
  • Loading branch information
flferretti and traversaro authored May 14, 2024
1 parent 3ffc433 commit 6997992
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 6 deletions.
34 changes: 29 additions & 5 deletions src/resolve_robotics_uri_py/resolve_robotics_uri_py.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,19 +76,32 @@ def pathlist_list_to_string(path_list: Iterable[str | pathlib.Path]) -> str:
# ===================


def resolve_robotics_uri(uri: str) -> pathlib.Path:
def resolve_robotics_uri(
uri: str, package_dirs: list[str] | None = None
) -> pathlib.Path:
"""
Resolve a robotics URI to an absolute filename.
Args:
uri: The URI to resolve.
package_dirs: A list of additional paths to look for the file.
Returns:
The absolute filename corresponding to the URI.
Raises:
FileNotFoundError: If no file corresponding to the URI is found.
Note:
By default the function will look for the file in the
default search paths specified by the environment variables in `SupportedEnvVars`.
If the `package_dirs` argument is provided, the model is also searched in the folders
specified in `package_dirs` . In particular if a file is specified by the uri
`package://ModelName/meshes/mesh.stl`, and the actual file is in
`/usr/local/share/ModelName/meshes/mesh.stl`, the `package_dirs` should contain `/usr/local/share`.
"""
package_dirs = package_dirs if isinstance(package_dirs, list) else [package_dirs]

# If the URI has no scheme, use by default file:// which maps the resolved input
# path to a URI with empty authority
Expand All @@ -104,8 +117,8 @@ def resolve_robotics_uri(uri: str) -> pathlib.Path:

if uri.startswith("file:"):
# Strip the scheme from the URI
uri = uri.replace(f"file://", "")
uri = uri.replace(f"file:", "")
uri = uri.replace("file://", "")
uri = uri.replace("file:", "")

# Create the file path, resolving symlinks and '..'
uri_file_path = pathlib.Path(uri).resolve()
Expand Down Expand Up @@ -145,7 +158,11 @@ def resolve_robotics_uri(uri: str) -> pathlib.Path:
model_filenames = []

# Search the resource in the path from the env variables
for folder in set(get_search_paths_from_envs(SupportedEnvVars)):
for folder in set(get_search_paths_from_envs(SupportedEnvVars)) | {
path
for directory in package_dirs
if directory and (path := pathlib.Path(directory)).exists()
}:

# Join the folder from environment variable and the URI path
candidate_file_name = folder / uri_path
Expand Down Expand Up @@ -181,11 +198,18 @@ def main():
)
)
parser.add_argument("uri", metavar="URI", type=str, help="URI to resolve")
parser.add_argument(
"--package_dirs",
metavar="PATH",
type=str,
help="Additional paths to look for the file",
default=None,
)

args = parser.parse_args()

try:
result = resolve_robotics_uri(args.uri)
result = resolve_robotics_uri(args.uri, args.package_dirs)
except FileNotFoundError as e:
print(e, file=sys.stderr)
sys.exit(1)
Expand Down
24 changes: 23 additions & 1 deletion test/test_resolve_robotics_uri_py.py
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,29 @@ def test_scheme_file():
assert path_of_file == temp_name

# Try to find an existing file (the Python executable) without any file:/ scheme
path_of_python_executable = resolve_robotics_uri_py.resolve_robotics_uri(sys.executable)
path_of_python_executable = resolve_robotics_uri_py.resolve_robotics_uri(
sys.executable
)
assert path_of_python_executable == pathlib.Path(sys.executable)


def test_additional_search_path():

import tempfile
import pathlib
import resolve_robotics_uri_py

clear_env_vars()

uri = "model://my_model"

with tempfile.TemporaryDirectory() as temp_dir:

temp_dir_path = pathlib.Path(temp_dir).resolve()
temp_dir_path.mkdir(exist_ok=True)
top_level = temp_dir_path / "my_model"
top_level.touch(exist_ok=True)

# Test resolving a URI with an additional search path
result = resolve_robotics_uri_py.resolve_robotics_uri(uri, temp_dir)
assert result == temp_dir_path / "my_model"

0 comments on commit 6997992

Please sign in to comment.