def get_package_prefix(package_name):
    """
    Return the installation prefix directory of the given package.

    For example, if you install the package 'foo' into
    '/home/user/ros2_ws/install' and you called this function with 'foo' as the
    argument, then it will return that directory.

    :param str package_name: name of the package to locate
    :returns: installation prefix of the package
    :raises: :exc:`PackageNotFoundError` if the package is not found
    :raises: :exc:`ValueError` if the package name is invalid
    """
    # This regex checks for a valid package name as defined by REP-127 including the recommended
    #  exemptions. See https://ros.org/reps/rep-0127.html#name
    if re.fullmatch('[a-zA-Z0-9][a-zA-Z0-9_-]+', package_name, re.ASCII) is None:
        raise ValueError(
            "'{}' is not a valid package name".format(package_name))
    try:
        content, package_prefix = get_resource('packages', package_name)
    except LookupError:
        raise PackageNotFoundError(
            "package '{}' not found, searching: {}".format(package_name, get_search_paths()))
    return package_prefix def get_package_share_directory(package_name, print_warning=True):
    """
    Return the share directory of the given package.

    For example, if you install the package 'foo' into
    '/home/user/ros2_ws/install' and you called this function with 'foo' as the
    argument, then it will return '/home/user/ros2_ws/install/share/foo' as
    the package's share directory.

    :param str package_name: name of the package to locate
    :param bool print_warning: if true, print a warning if the directory does not exist
    :returns: share directory of the package
    :raises: :exc:`PackageNotFoundError` if the package is not found
    :raises: :exc:`ValueError` if the package name is invalid
    """
    path = os.path.join(get_package_prefix(package_name), 'share', package_name)
    if print_warning and not os.path.exists(path):
        warnings.warn(f'Share directory for {package_name} ({path}) does not exist.', stacklevel=2)
    return path def get_package_share_path(package_name, print_warning=True):
    """
    Return the share directory of the given package as a pathlib.Path.

    For example, if you install the package 'foo' into
    '/home/user/ros2_ws/install' and you called this function with 'foo' as the
    argument, then it will return a path representing '/home/user/ros2_ws/install/share/foo'
    and then you could use it to construct the path to a shared file with
    `get_package_share_path('foo') / 'urdf/robot.urdf'`

    :param str package_name: name of the package to locate
    :param bool print_warning: if true, print a warning if the path does not exist
    :returns: share directory of the package as a pathlib.Path
    :raises: :exc:`PackageNotFoundError` if the package is not found
    """
    path = pathlib.Path(get_package_share_directory(package_name, print_warning=False))
    if print_warning and not path.exists():
        warnings.warn(f'Share path for {package_name} ({path}) does not exist.', stacklevel=2)
    return path def get_packages_with_prefixes():
    """
    Return a dict of package names to the prefixes in which they are found.

    :returns: dict of package names to their prefixes
    :rtype: dict
    """
    return get_resources('packages') def get_resource(resource_type, resource_name):
    """
    Get the content of a specific resource and its prefix path.

    :param resource_type: the type of the resource
    :type resource_type: str
    :param resource_names: the name of the resource
    :type resource_name: str
    :returns: a tuple of the content (bytes) of the resource and its prefix path
    :raises: :exc:`EnvironmentError`
    :raises: :exc:`OSError`
    :raises: :exc:`LookupError`
    :raises: :exc:`InvalidResourceTypeNameError`
    :raises: :exc:`InvalidResourceNameError`
    """
    assert resource_type, 'The resource type must not be empty'
    assert resource_name, 'The resource name must not be empty'
    if _name_is_invalid(resource_type):
        raise InvalidResourceTypeNameError(
            "Resource type '%s' is invalid" % resource_type)
    if _name_is_invalid(resource_name):
        raise InvalidResourceNameError(
            "Resource name '%s' is invalid" % resource_name)
    for path in get_search_paths():
        resource_path = os.path.join(path, RESOURCE_INDEX_SUBFOLDER, resource_type, resource_name)
        if os.path.isfile(resource_path):
            try:
                with open(resource_path, 'r') as h:
                    content = h.read()
            except OSError as e:
                raise OSError(
                    "Could not open the resource '%s' of type '%s':\n%s"
                    % (resource_name, resource_type, e))
            return content, path
    raise LookupError(
        "Could not find the resource '%s' of type '%s'" % (resource_name, resource_type)) def get_resource_types():
    """
    Get the resource types.

    :returns: set of resource types within the search paths
    :raises: :exc:`EnvironmentError`
    """
    resource_types = set()
    for path in get_search_paths():
        basepath = os.path.join(path, RESOURCE_INDEX_SUBFOLDER)
        if os.path.isdir(basepath):
            for resource_type in os.listdir(basepath):
                # Ignore non-subdirectories, and anything starting with a dot
                if not os.path.isdir(os.path.join(basepath, resource_type)) \
                        or resource_type.startswith('.'):
                    continue
                resource_types.add(resource_type)
    return resource_types def get_resources(resource_type):
    """
    Get the resource names of all resources of the specified type.

    :param resource_type: the type of the resource
    :type resource_type: str
    :returns: dict of resource names to the prefix path they are in
    :raises: :exc:`EnvironmentError`
    :raises: :exc:`InvalidResourceTypeNameError`
    """
    assert resource_type, 'The resource type must not be empty'
    if _name_is_invalid(resource_type):
        raise InvalidResourceTypeNameError(
            "Resource type '%s' is invalid" % resource_type)
    resources = {}
    for path in get_search_paths():
        resource_path = os.path.join(path, RESOURCE_INDEX_SUBFOLDER, resource_type)
        if os.path.isdir(resource_path):
            for resource in os.listdir(resource_path):
                # Ignore subdirectories, and anything starting with a dot
                if os.path.isdir(os.path.join(resource_path, resource)) \
                        or resource.startswith('.'):
                    continue
                if resource not in resources:
                    resources[resource] = path
    return resources def get_search_paths():
    """
    Get the paths from the environment variable '{AMENT_PREFIX_PATH_ENV_VAR}'.

    :returns: list of paths
    :raises: :exc:`EnvironmentError`
    """.format(AMENT_PREFIX_PATH_ENV_VAR=AMENT_PREFIX_PATH_ENV_VAR)
    ament_prefix_path = os.environ.get(AMENT_PREFIX_PATH_ENV_VAR)
    if not ament_prefix_path:
        raise EnvironmentError(
            "Environment variable '{}' is not set or empty".format(AMENT_PREFIX_PATH_ENV_VAR))

    paths = ament_prefix_path.split(os.pathsep)
    return [p for p in paths if p and os.path.exists(p)] def has_resource(resource_type, resource_name):
    """
    Check if a specific resource exists.

    :param resource_type: the type of the resource
    :type resource_type: str
    :param resource_names: the name of the resource
    :type resource_name: str
    :returns: The prefix path if the resource exists, False otherwise
    :raises: :exc:`EnvironmentError`
    :raises: :exc:`InvalidResourceTypeNameError`
    :raises: :exc:`InvalidResourceNameError`
    """
    assert resource_type, 'The resource type must not be empty'
    assert resource_name, 'The resource name must not be empty'
    if _name_is_invalid(resource_type):
        raise InvalidResourceTypeNameError(
            "Resource type '%s' is invalid" % resource_type)
    if _name_is_invalid(resource_name):
        raise InvalidResourceNameError(
            "Resource name '%s' is invalid" % resource_name)
    for path in get_search_paths():
        resource_path = os.path.join(path, RESOURCE_INDEX_SUBFOLDER, resource_type, resource_name)
        if os.path.isfile(resource_path):
            return path
    return False class InvalidResourceNameError(ValueError):
    """Raised when a resource name is invalid."""

    pass class InvalidResourceTypeNameError(ValueError):
    """Raised when a resource type name is invalid."""

    pass class PackageNotFoundError(KeyError):
    pass
import os
import pytest
from pathlib import Path, PurePath
from ament_index_python import get_package_prefix
from ament_index_python import get_package_share_directory
from ament_index_python import get_package_share_path
from ament_index_python import get_packages_with_prefixes
from ament_index_python import get_resource
from ament_index_python import get_resource_types
from ament_index_python import get_resources
from ament_index_python import get_search_paths
from ament_index_python import has_resource
from ament_index_python import InvalidResourceNameError
from ament_index_python import InvalidResourceTypeNameError
from ament_index_python import PackageNotFoundError
from ament_index_python.cli import main
from ament_index_python.cli import resource_name_completer
from ament_index_python.cli import resource_type_completer
# Copyright 2015 Open Source Robotics Foundation, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.





def set_ament_prefix_path(subfolders):
    paths = []
    base_path = Path(__file__).parent
    for subfolder in subfolders:
        path = base_path / subfolder
        if path.is_dir():
            paths.append(str(path))
    ament_prefix_path = os.pathsep.join(paths)
    os.environ['AMENT_PREFIX_PATH'] = ament_prefix_path


def test_empty_search_paths():
    set_ament_prefix_path([])
    with pytest.raises(EnvironmentError):

        get_search_paths()