From: =?utf-8?q?Timo_R=C3=B6hling?= <roehling@debian.org>
Date: Fri, 6 May 2022 10:46:16 +0200
Subject: Add /usr as implicit AMENT_PREFIX_PATH

---
 ament_index_cpp/src/get_search_paths.cpp            | 15 ++++++++++++---
 ament_index_cpp/test/utest.cpp                      | 21 +++++++++++++++++++++
 .../ament_index_python/search_paths.py              | 10 ++++++++--
 ament_index_python/test/test_ament_index_python.py  |  7 +++++++
 4 files changed, 48 insertions(+), 5 deletions(-)

diff --git a/ament_index_cpp/src/get_search_paths.cpp b/ament_index_cpp/src/get_search_paths.cpp
index 7a411ac..a230d7e 100644
--- a/ament_index_cpp/src/get_search_paths.cpp
+++ b/ament_index_cpp/src/get_search_paths.cpp
@@ -38,17 +38,20 @@ get_search_paths()
   // get environment variable
 #ifndef _WIN32
   ament_prefix_path = getenv(env_var);
+  char* ignore_usr = getenv("AMENT_PREFIX_NO_IMPLICIT_USR");
 #else
   size_t ament_prefix_path_size;
   _dupenv_s(&ament_prefix_path, &ament_prefix_path_size, env_var);
+  char* ignore_usr = 0;
 #endif
-  if (!ament_prefix_path || std::string(ament_prefix_path).empty()) {
-    throw std::runtime_error("Environment variable 'AMENT_PREFIX_PATH' is not set or empty");
+
+  if ((!ament_prefix_path || std::string(ament_prefix_path).empty()) && ignore_usr && ignore_usr[0]) {
+    throw std::runtime_error("Environment variable 'AMENT_PREFIX_PATH' is unset or empty");
   }
 
   // split at token into separate paths
   std::list<std::string> paths;
-  std::stringstream ss(ament_prefix_path);
+  std::stringstream ss(ament_prefix_path ? ament_prefix_path : "");
   std::string tok;
 #ifndef _WIN32
   char delim = ':';
@@ -75,6 +78,12 @@ get_search_paths()
   }
 #endif
 
+#ifndef _WIN32
+  if (!ignore_usr || !ignore_usr[0]) {
+    // Debian-specific
+    paths.push_back("/usr");
+  }
+#endif
   return paths;
 }
 
diff --git a/ament_index_cpp/test/utest.cpp b/ament_index_cpp/test/utest.cpp
index 33baa14..6897b4e 100644
--- a/ament_index_cpp/test/utest.cpp
+++ b/ament_index_cpp/test/utest.cpp
@@ -72,6 +72,27 @@ TEST(AmentIndexCpp, empty_search_paths) {
   EXPECT_THROW(ament_index_cpp::get_search_paths(), std::runtime_error);
 }
 
+#ifndef _WIN32
+TEST(AmentIndexCpp, implicit_usr_empty_var) {
+  std::list<std::string> subfolders;
+  set_ament_prefix_path(subfolders);
+  setenv("AMENT_PREFIX_NO_IMPLICIT_USR", "", 1);
+  std::list<std::string> search_paths = ament_index_cpp::get_search_paths();
+  EXPECT_EQ(search_paths.size(), 1UL);
+  EXPECT_EQ(search_paths.front(), "/usr");
+}
+
+TEST(AmentIndexCpp, implicit_usr_null_var) {
+  std::list<std::string> subfolders;
+  set_ament_prefix_path(subfolders);
+  setenv("AMENT_PREFIX_NO_IMPLICIT_USR", "", 1);
+  unsetenv("AMENT_PREFIX_PATH");
+  std::list<std::string> search_paths = ament_index_cpp::get_search_paths();
+  EXPECT_EQ(search_paths.size(), 1UL);
+  EXPECT_EQ(search_paths.front(), "/usr");
+}
+#endif
+
 TEST(AmentIndexCpp, search_paths) {
   std::list<std::string> subfolders;
   subfolders.push_back("prefix1");
diff --git a/ament_index_python/ament_index_python/search_paths.py b/ament_index_python/ament_index_python/search_paths.py
index 80982a3..6f3c05c 100644
--- a/ament_index_python/ament_index_python/search_paths.py
+++ b/ament_index_python/ament_index_python/search_paths.py
@@ -26,9 +26,15 @@ def get_search_paths() -> List[str]:
     :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:
+    add_usr = not os.environ.get("AMENT_PREFIX_NO_IMPLICIT_USR")
+
+    if not ament_prefix_path and not add_usr:
         raise EnvironmentError(
             "Environment variable '{}' is not set or empty".format(AMENT_PREFIX_PATH_ENV_VAR))
 
-    paths = ament_prefix_path.split(os.pathsep)
+    paths = ament_prefix_path.split(os.pathsep) if ament_prefix_path else []
+    if add_usr:
+        # Debian-specific
+        paths.append("/usr")
+
     return [p for p in paths if p and os.path.exists(p)]
diff --git a/ament_index_python/test/test_ament_index_python.py b/ament_index_python/test/test_ament_index_python.py
index b75a629..ded27b4 100644
--- a/ament_index_python/test/test_ament_index_python.py
+++ b/ament_index_python/test/test_ament_index_python.py
@@ -51,6 +51,13 @@ def test_empty_search_paths():
         get_search_paths()
 
 
+def test_implicit_usr():
+    set_ament_prefix_path([])
+    os.environ['AMENT_PREFIX_NO_IMPLICIT_USR'] = ''
+    search_paths = get_search_paths()
+    assert search_paths == ["/usr"]
+
+
 def test_search_paths():
     set_ament_prefix_path(['prefix1', 'prefix2'])
     search_paths = get_search_paths()
