Skip to content

Commit

Permalink
add package resource related utility functions to cpp API (#27)
Browse files Browse the repository at this point in the history
* add package resource related utility functions to cpp

these already existed in Python, see: #24

* store package name in PackageNotFoundError
  • Loading branch information
wjwwood committed Nov 9, 2017
1 parent 9620efa commit 327994a
Show file tree
Hide file tree
Showing 12 changed files with 302 additions and 1 deletion.
6 changes: 5 additions & 1 deletion ament_index_cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,14 @@ endif()
find_package(ament_cmake REQUIRED)

add_library(${PROJECT_NAME} SHARED
src/get_package_prefix.cpp
src/get_package_share_directory.cpp
src/get_packages_with_prefixes.cpp
src/get_resource.cpp
src/get_resources.cpp
src/get_search_paths.cpp
src/has_resource.cpp)
src/has_resource.cpp
)
target_compile_definitions(${PROJECT_NAME} PRIVATE "AMENT_INDEX_CPP_BUILDING_DLL")
target_include_directories(${PROJECT_NAME} PUBLIC
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>"
Expand Down
51 changes: 51 additions & 0 deletions ament_index_cpp/include/ament_index_cpp/get_package_prefix.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// Copyright 2017 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.

#ifndef AMENT_INDEX_CPP__GET_PACKAGE_PREFIX_HPP_
#define AMENT_INDEX_CPP__GET_PACKAGE_PREFIX_HPP_

#include <stdexcept>
#include <string>

#include "ament_index_cpp/visibility_control.h"

namespace ament_index_cpp
{

/// Thrown when a package is not found.
class PackageNotFoundError : public std::out_of_range
{
public:
AMENT_INDEX_CPP_PUBLIC
explicit PackageNotFoundError(const std::string & package_name);

AMENT_INDEX_CPP_PUBLIC
virtual ~PackageNotFoundError();

const std::string package_name;
};

/// Return the installation prefix of the given package if found.
/**
* \param package_name the name of the package to locate.
* \return installation prefix path in which the package was found.
* \throws PackageNotFoundError when the given package is not found.
*/
AMENT_INDEX_CPP_PUBLIC
std::string
get_package_prefix(const std::string & package_name);

} // namespace ament_index_cpp

#endif // AMENT_INDEX_CPP__GET_PACKAGE_PREFIX_HPP_
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// Copyright 2017 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.

#ifndef AMENT_INDEX_CPP__GET_PACKAGE_SHARE_DIRECTORY_HPP_
#define AMENT_INDEX_CPP__GET_PACKAGE_SHARE_DIRECTORY_HPP_

#include <string>

#include "ament_index_cpp/visibility_control.h"

namespace ament_index_cpp
{

/// Return the share directory of the given package if found.
/**
* \param package_name the name of the package to locate.
* \return share path of the package.
* \throws PackageNotFoundError when the given package is not found.
*/
AMENT_INDEX_CPP_PUBLIC
std::string
get_package_share_directory(const std::string & package_name);

} // namespace ament_index_cpp

#endif // AMENT_INDEX_CPP__GET_PACKAGE_SHARE_DIRECTORY_HPP_
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Copyright 2017 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.

#ifndef AMENT_INDEX_CPP__GET_PACKAGES_WITH_PREFIXES_HPP_
#define AMENT_INDEX_CPP__GET_PACKAGES_WITH_PREFIXES_HPP_

#include <map>
#include <string>

#include "ament_index_cpp/visibility_control.h"

namespace ament_index_cpp
{

/// Return a map of package names to their installation prefix.
AMENT_INDEX_CPP_PUBLIC
std::map<std::string, std::string>
get_packages_with_prefixes();

} // namespace ament_index_cpp

#endif // AMENT_INDEX_CPP__GET_PACKAGES_WITH_PREFIXES_HPP_
59 changes: 59 additions & 0 deletions ament_index_cpp/src/get_package_prefix.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// Copyright 2017 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.

#include "ament_index_cpp/get_package_prefix.hpp"

#include <stdexcept>
#include <string>

#include "ament_index_cpp/get_resource.hpp"
#include "ament_index_cpp/get_search_paths.hpp"

namespace ament_index_cpp
{

static
std::string
format_package_not_found_error_message(const std::string & package_name)
{
std::string message = "package '" + package_name + "' not found, searching: [";
auto search_paths = get_search_paths();
for (const auto & path : search_paths) {
message += path + ", ";
}
if (search_paths.size() > 0) {
message = message.substr(0, message.size() - 2);
}
return message + "]";
}

PackageNotFoundError::PackageNotFoundError(const std::string & _package_name)
: std::out_of_range(format_package_not_found_error_message(_package_name)),
package_name(_package_name)
{}

PackageNotFoundError::~PackageNotFoundError() {}

std::string
get_package_prefix(const std::string & package_name)
{
std::string content;
std::string prefix_path;
if (!get_resource("packages", package_name, content, &prefix_path)) {
throw PackageNotFoundError(package_name);
}
return prefix_path;
}

} // namespace ament_index_cpp
30 changes: 30 additions & 0 deletions ament_index_cpp/src/get_package_share_directory.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Copyright 2017 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.

#include "ament_index_cpp/get_package_share_directory.hpp"

#include <string>

#include "ament_index_cpp/get_package_prefix.hpp"

namespace ament_index_cpp
{

std::string
get_package_share_directory(const std::string & package_name)
{
return get_package_prefix(package_name) + "/share/" + package_name;
}

} // namespace ament_index_cpp
31 changes: 31 additions & 0 deletions ament_index_cpp/src/get_packages_with_prefixes.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Copyright 2017 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.

#include "ament_index_cpp/get_packages_with_prefixes.hpp"

#include <map>
#include <string>

#include "ament_index_cpp/get_resources.hpp"

namespace ament_index_cpp
{

std::map<std::string, std::string>
get_packages_with_prefixes()
{
return get_resources("packages");
}

} // namespace ament_index_cpp
Empty file.
Empty file.
Empty file.
Empty file.
56 changes: 56 additions & 0 deletions ament_index_cpp/test/utest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@
#include <stdexcept>
#include <string>

#include "ament_index_cpp/get_package_prefix.hpp"
#include "ament_index_cpp/get_package_share_directory.hpp"
#include "ament_index_cpp/get_packages_with_prefixes.hpp"
#include "ament_index_cpp/get_resource.hpp"
#include "ament_index_cpp/get_resources.hpp"
#include "ament_index_cpp/get_search_paths.hpp"
Expand Down Expand Up @@ -210,3 +213,56 @@ TEST(AmentIndexCpp, get_resource_underlay_base_path) {
EXPECT_TRUE(success);
EXPECT_EQ(base_path, generate_subfolder_path("prefix2"));
}

TEST(AmentIndexCpp, get_package_prefix) {
// Ensure that a known to exist package is found and that a known to not exist package is not.
std::list<std::string> subfolders;
subfolders.push_back("prefix1"); // only contains foo and bar packages
subfolders.push_back("prefix2"); // only contains bar and baz packages
set_ament_prefix_path(subfolders);
// foo is found in prefix 1
EXPECT_EQ(generate_subfolder_path("prefix1"), ament_index_cpp::get_package_prefix("foo"));
// bar is in both, but prefix 1 takes precedence
EXPECT_EQ(generate_subfolder_path("prefix1"), ament_index_cpp::get_package_prefix("bar"));
// baz is found in prefix 2 only
EXPECT_EQ(generate_subfolder_path("prefix2"), ament_index_cpp::get_package_prefix("baz"));
// exception when package is not found
EXPECT_THROW(
ament_index_cpp::get_package_prefix("does_not_exist"),
ament_index_cpp::PackageNotFoundError);
// exception when the package name is empty
EXPECT_THROW(
ament_index_cpp::get_package_prefix(""),
std::runtime_error);
}

TEST(AmentIndexCpp, get_package_share_directory) {
// Ensure that a known to exist package is found and the share directory is correct.
std::list<std::string> subfolders;
subfolders.push_back("prefix1"); // only contains foo and bar packages
subfolders.push_back("prefix2"); // only contains bar and baz packages
set_ament_prefix_path(subfolders);
// bar is in both, but prefix 1 takes precedence
EXPECT_EQ(
generate_subfolder_path("prefix1") + "/share/bar",
ament_index_cpp::get_package_share_directory("bar"));
}

TEST(AmentIndexCpp, get_packages_with_prefixes) {
// Ensure the list of packages and prefixes matches resource layout.
std::list<std::string> subfolders;
subfolders.push_back("prefix1"); // only contains foo and bar packages
subfolders.push_back("prefix2"); // only contains bar and baz packages
set_ament_prefix_path(subfolders);

std::map<std::string, std::string> packages_with_prefixes =
ament_index_cpp::get_packages_with_prefixes();
// should be exactly three elements
EXPECT_EQ(3UL, packages_with_prefixes.size());
// foo is found in prefix 1
EXPECT_EQ(generate_subfolder_path("prefix1"), packages_with_prefixes["foo"]);
// bar is in both, but prefix 1 takes precedence
EXPECT_EQ(generate_subfolder_path("prefix1"), packages_with_prefixes["bar"]);
// baz is found in prefix 2 only
EXPECT_EQ(generate_subfolder_path("prefix2"), packages_with_prefixes["baz"]);
}

0 comments on commit 327994a

Please sign in to comment.